Orocos Real-Time Toolkit  2.8.3
type_discovery.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 type_discovery.hpp
3 
4  type_discovery.hpp - description
5  -------------------
6  begin : Tue September 07 2010
7  copyright : (C) 2010 The SourceWorks
8  email : peter@thesourceworks.com
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 #ifndef TYPE_DISCOVERY_HPP_
40 #define TYPE_DISCOVERY_HPP_
41 
42 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
43 // (C) Copyright 2009 Peter Soetens - http://www.thesourceworks.com .
44 // Use, modification and distribution is subject to the Boost Software
45 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
46 // http://www.boost.org/LICENSE_1_0.txt)
47 
48 // See http://www.boost.org for updates, documentation, and revision history.
49 
50 
64 #include <cassert>
65 #include <boost/version.hpp>
66 #if BOOST_VERSION >= 106400
67 // The class name has been changed from boost::serialization::array<T> to array_wrapper<T> in Boost 1.61,
68 // but the header has only be renamed in Boost 1.64. Starting from Boost 1.65 array.hpp includes array_wrapper.hpp,
69 // but with 1.64 compilation fails if array_wrapper.hpp is not included.
70 # include <boost/serialization/array_wrapper.hpp>
71 #else
72 # include <boost/serialization/array.hpp>
73 #endif
74 #include <boost/serialization/serialization.hpp>
75 #include <boost/serialization/is_bitwise_serializable.hpp>
76 #include <boost/serialization/vector.hpp>
77 #include <boost/serialization/string.hpp>
78 #include <boost/archive/detail/iserializer.hpp>
79 #include <boost/archive/detail/oserializer.hpp>
80 #include <boost/archive/archive_exception.hpp>
81 #include <boost/config.hpp>
82 #include <boost/mpl/bool.hpp>
83 #include <boost/array.hpp>
84 
85 #include <vector>
86 #include <string>
87 #include "../base/DataSourceBase.hpp"
88 #include "../internal/PartDataSource.hpp"
89 #include "../internal/DataSources.hpp"
90 #include "../internal/Reference.hpp"
91 #include "carray.hpp"
92 
93 namespace RTT
94 {
95  namespace types
96  {
102  {
103  public:
108 
109  typedef std::vector<base::DataSourceBase::shared_ptr> Parts;
110  typedef std::vector<std::string> PartNames;
114  Parts mparts;
115 
119  PartNames mnames;
120 
124  std::string membername;
125 
131 
132  typedef char Elem;
136  typedef boost::mpl::bool_<true> is_loading;
140  typedef boost::mpl::bool_<false> is_saving;
141 
147  mparent(parent), mref(0)
148  {
149  }
150 
156  mparent(), mref(0)
157  {
158  }
159 
160  base::DataSourceBase::shared_ptr getMember(const std::string name) {
161  PartNames::iterator it = find( mnames.begin(), mnames.end(), name);
162  if ( it != mnames.end() && mparts.size() == mnames.size() )
163  return mparts.at( it - mnames.begin() );
165  }
166 
173  template<class T>
174  void discover( T& t) {
175 #if BOOST_VERSION >= 104100
176  boost::archive::detail::load_non_pointer_type<type_discovery>::load_only::invoke(*this,t);
177 #else
178  boost::archive::detail::load_non_pointer_type<type_discovery,T>::load_only::invoke(*this,t);
179 #endif
180  }
181 
187  template<class T>
188  base::DataSourceBase::shared_ptr discoverMember( T& t, const std::string name) {
189  membername = name;
190  discover( t );
191  if ( ! mparts.empty() )
192  return mparts[0];
194  }
195 
200  template<class T>
201  bool referenceMember(internal::Reference* ref, T& t, const std::string name) {
202  assert(ref);
203  membername = name;
204  mref = ref;
205  discover( t );
206  if (mref == 0) // we found it
207  return true;
208  return false;
209  }
210 
215  unsigned int get_library_version() { return 0; }
216 
222  void reset_object_address(const void * new_address, const void * old_address) {}
223 
228 
234  template<class T>
235  const boost::archive::detail::basic_pointer_iserializer *
236  register_type(T * = NULL) {return 0;}
237 
243  void load_object(void *x, const boost::archive::detail::basic_oserializer & bos)
244  {
245  assert(false);
246  }
247 
253  template<class T>
255  {
256  return load_a_type(t, boost::mpl::bool_<boost::serialization::implementation_level<T>::value == boost::serialization::primitive_type>());
257  }
258 
264  template<class T>
266  {
267  return this->operator>>(t);
268  }
269 
275  template<class T>
276  type_discovery &load_a_type(T &t, boost::mpl::true_)
277  {
278  // stores the part
279  if (mparent) {
280  mparts.push_back(new internal::PartDataSource<T> (t, mparent));
281  }
282  return *this;
283  }
284 
290  template<class T>
291  type_discovery &load_a_type(T &t, boost::mpl::false_)
292  {
293  mparts.push_back(new internal::PartDataSource<T> (t, mparent));
294  return *this;
295  }
296 
302  template<class T>
303 #if BOOST_VERSION >= 106100
304  type_discovery &load_a_type(const boost::serialization::array_wrapper<T> &t, boost::mpl::false_)
305 #else
306  type_discovery &load_a_type(const boost::serialization::array<T> &t, boost::mpl::false_)
307 #endif
308  {
309  mparts.push_back(new internal::PartDataSource< carray<T> > ( carray<T>(t), mparent) );
310  return *this;
311  }
312 
318  template<class T, std::size_t N>
319  type_discovery &load_a_type(boost::array<T,N> &t, boost::mpl::false_)
320  {
321  mparts.push_back(new internal::PartDataSource< carray<T> > ( carray<T>(t), mparent) );
322  return *this;
323  }
324 
331  template<class T>
332  type_discovery &load_a_type(const T* &, boost::mpl::false_)
333  {
334  //pointers can not be serialized.
335  //BOOST_STATIC_ASSERT( boost::mpl::false_ );
336  return *this;
337  }
338 
341  template<class T>
342  type_discovery &load_a_type(const boost::serialization::nvp<T> & t, boost::mpl::false_)
343  {
344  // check for single-member extraction first:
345  if ( !membername.empty() ) {
346  // Only serialize if the name matches:
347  if ( t.name() == membername ) {
348  if ( !mref ) {
349  *this & t.value();
350  } else {
351  mref->setReference( (void*) & t.value() );
352  mref = 0; // signals' we're done.
353  }
354  }
355  } else {
356  // Full extraction of all parts:
357  // store name of member
358  mnames.push_back( t.name() );
359 
360  // serialize the data as usual
361  if (mparent)
362  *this & t.value();
363  }
364 
365  return *this;
366  }
367  };
368  }
369 }
370 
371 #endif /* TYPE_DISCOVERY_HPP_ */
A DataSource which is used to manipulate a reference to a part of a data source.
type_discovery & load_a_type(const T *&, boost::mpl::false_)
We do not support pointer types.
void load_object(void *x, const boost::archive::detail::basic_oserializer &bos)
Note: not in LoadArchive concept but required when we use archive::load !
internal::Reference * mref
If non-empty, use this reference to the member with name membername.
boost::mpl::bool_< true > is_loading
Saving Archive Concept::is_loading.
virtual void setReference(void *ref)=0
Sets the reference to a given pointer.
type_discovery()
Constructor which only introspects the part names.
Wraps a C array such that we can return a C array from a DataSource.
Definition: carray.hpp:77
base::DataSourceBase::shared_ptr getMember(const std::string name)
type_discovery & load_a_type(boost::array< T, N > &t, boost::mpl::false_)
Specialisation that converts a boost::array into a RTT types carray.
type_discovery & operator>>(T &t)
Saving Archive Concept::operator<<.
base::DataSourceBase::shared_ptr discoverMember(T &t, const std::string name)
This function discovers a single part of a serializable struct and returns an assignable datasource t...
PartNames mnames
The names of the parts of the parent struct.
type_discovery & operator&(T &t)
Saving Archive Concept::operator&.
type_discovery & load_a_type(const boost::serialization::array< T > &t, boost::mpl::false_)
Specialisation that converts a boost serialization array into a RTT types carray. ...
void delete_created_pointers()
Loading Archive Concept::delete_created_pointers()
void reset_object_address(const void *new_address, const void *old_address)
Loading Archive Concept::reset_object_address(v,u)
base::DataSourceBase::shared_ptr mparent
The parent struct we&#39;re deserializing.
std::vector< std::string > PartNames
std::vector< base::DataSourceBase::shared_ptr > Parts
const boost::archive::detail::basic_pointer_iserializer * register_type(T *=NULL)
Loading Archive Concept::register_type<T>() and ::register_type(u)
Parts mparts
The parts of the parent struct.
type_discovery & load_a_type(T &t, boost::mpl::false_)
Specialisation for writing out composite types (objects).
unsigned int get_library_version()
Loading Archive Concept::get_library_version()
type_discovery & load_a_type(T &t, boost::mpl::true_)
Specialisation for writing out primitive types.
This archive is capable of decomposing objects of serialization level 1 and 2 into part data sources...
Object that may receive a reference to some data by means of a pointer or data source.
Definition: Reference.hpp:15
boost::intrusive_ptr< DataSourceBase > shared_ptr
Use this type to store a pointer to a DataSourceBase.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:51
type_discovery(base::DataSourceBase::shared_ptr parent)
Constructor which inspects part names and creates part data sources.
std::string membername
If non-empty, only discover the member with this name.
bool referenceMember(internal::Reference *ref, T &t, const std::string name)
This function discovers a single part of a serializable struct and sets a reference to that member of...
boost::mpl::bool_< false > is_saving
Saving Archive Concept::is_saving.
type_discovery & load_a_type(const boost::serialization::nvp< T > &t, boost::mpl::false_)
special treatment for name-value pairs.
void discover(T &t)
This function discovers all parts of a serializable struct and creates a DataSource object for each m...