Orocos Real-Time Toolkit  2.6.0
type_discovery.hpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: The SourceWorks  Tue Sep 7 00:55:18 CEST 2010  type_discovery.hpp
00003 
00004                         type_discovery.hpp -  description
00005                            -------------------
00006     begin                : Tue September 07 2010
00007     copyright            : (C) 2010 The SourceWorks
00008     email                : peter@thesourceworks.com
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037 
00038 
00039 #ifndef TYPE_DISCOVERY_HPP_
00040 #define TYPE_DISCOVERY_HPP_
00041 
00042 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
00043 // (C) Copyright 2009 Peter Soetens - http://www.thesourceworks.com .
00044 // Use, modification and distribution is subject to the Boost Software
00045 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
00046 // http://www.boost.org/LICENSE_1_0.txt)
00047 
00048 //  See http://www.boost.org for updates, documentation, and revision history.
00049 
00050 
00064 #include <cassert>
00065 #include <boost/version.hpp>
00066 #include <boost/serialization/serialization.hpp>
00067 #include <boost/serialization/is_bitwise_serializable.hpp>
00068 #include <boost/serialization/vector.hpp>
00069 #include <boost/serialization/string.hpp>
00070 #include <boost/serialization/array.hpp>
00071 #include <boost/archive/detail/iserializer.hpp>
00072 #include <boost/archive/detail/oserializer.hpp>
00073 #include <boost/archive/archive_exception.hpp>
00074 #include <boost/config.hpp>
00075 #include <boost/mpl/bool.hpp>
00076 #include <boost/array.hpp>
00077 
00078 #include <vector>
00079 #include <string>
00080 #include "../base/DataSourceBase.hpp"
00081 #include "../internal/PartDataSource.hpp"
00082 #include "../internal/DataSources.hpp"
00083 #include "../internal/Reference.hpp"
00084 #include "carray.hpp"
00085 
00086 namespace RTT
00087 {
00088     namespace types
00089     {
00094         class type_discovery
00095         {
00096         public:
00100             base::DataSourceBase::shared_ptr mparent;
00101 
00102             typedef std::vector<base::DataSourceBase::shared_ptr> Parts;
00103             typedef std::vector<std::string> PartNames;
00107             Parts mparts;
00108 
00112             PartNames mnames;
00113 
00117             std::string membername;
00118 
00123             internal::Reference* mref;
00124 
00125             typedef char Elem;
00129             typedef boost::mpl::bool_<true> is_loading;
00133             typedef boost::mpl::bool_<false> is_saving;
00134 
00139             type_discovery(base::DataSourceBase::shared_ptr parent) :
00140                 mparent(parent), mref(0)
00141             {
00142             }
00143 
00148             type_discovery() :
00149                 mparent(), mref(0)
00150             {
00151             }
00152 
00153             base::DataSourceBase::shared_ptr getMember(const std::string name) {
00154                 PartNames::iterator it = find( mnames.begin(), mnames.end(), name);
00155                 if ( it != mnames.end() && mparts.size() == mnames.size() )
00156                     return mparts.at( it - mnames.begin() );
00157                 return base::DataSourceBase::shared_ptr();
00158             }
00159 
00166             template<class T>
00167             void discover( T& t) {
00168 #if BOOST_VERSION >= 104100
00169                 boost::archive::detail::load_non_pointer_type<type_discovery>::load_only::invoke(*this,t);
00170 #else
00171                 boost::archive::detail::load_non_pointer_type<type_discovery,T>::load_only::invoke(*this,t);
00172 #endif
00173             }
00174 
00180             template<class T>
00181             base::DataSourceBase::shared_ptr discoverMember( T& t, const std::string name) {
00182                 membername = name;
00183                 discover( t );
00184                 if ( ! mparts.empty() )
00185                     return mparts[0];
00186                 return base::DataSourceBase::shared_ptr();
00187             }
00188 
00193             template<class T>
00194             bool referenceMember(internal::Reference* ref, T& t, const std::string name) {
00195                 assert(ref);
00196                 membername = name;
00197                 mref = ref;
00198                 discover( t );
00199                 if (mref == 0) // we found it
00200                     return true;
00201                 return false;
00202             }
00203 
00208             unsigned int get_library_version() { return 0; }
00209 
00215             void reset_object_address(const void * new_address, const void * old_address) {}
00216 
00220             void delete_created_pointers() {}
00221 
00227             template<class T>
00228             const boost::archive::detail::basic_pointer_iserializer *
00229             register_type(T * = NULL) {return 0;}
00230 
00236             void load_object(void *x, const boost::archive::detail::basic_oserializer & bos)
00237             {
00238                 assert(false);
00239             }
00240 
00246             template<class T>
00247             type_discovery &operator>>(T &t)
00248             {
00249                 return load_a_type(t, boost::mpl::bool_<boost::serialization::implementation_level<T>::value == boost::serialization::primitive_type>());
00250             }
00251 
00257             template<class T>
00258             type_discovery &operator&(T &t)
00259             {
00260                 return this->operator>>(t);
00261             }
00262 
00268             template<class T>
00269             type_discovery &load_a_type(T &t, boost::mpl::true_)
00270             {
00271                 // stores the part
00272                 if (mparent) {
00273                     mparts.push_back(new internal::PartDataSource<T> (t, mparent));
00274                 }
00275                 return *this;
00276             }
00277 
00283             template<class T>
00284             type_discovery &load_a_type(T &t, boost::mpl::false_)
00285             {
00286                 mparts.push_back(new internal::PartDataSource<T> (t, mparent));
00287                 return *this;
00288             }
00289 
00295             template<class T>
00296             type_discovery &load_a_type(const boost::serialization::array<T> &t, boost::mpl::false_)
00297             {
00298                 mparts.push_back(new internal::PartDataSource< carray<T> > ( carray<T>(t), mparent) );
00299                 return *this;
00300             }
00301 
00307             template<class T, std::size_t N>
00308             type_discovery &load_a_type(boost::array<T,N> &t, boost::mpl::false_)
00309             {
00310                 mparts.push_back(new internal::PartDataSource< carray<T> > ( carray<T>(t), mparent) );
00311                 return *this;
00312             }
00313 
00320             template<class T>
00321             type_discovery &load_a_type(const T* &, boost::mpl::false_)
00322             {
00323                 //pointers can not be serialized.
00324                 //BOOST_STATIC_ASSERT( boost::mpl::false_ );
00325                 return *this;
00326             }
00327 
00330             template<class T>
00331             type_discovery &load_a_type(const boost::serialization::nvp<T> & t, boost::mpl::false_)
00332             {
00333                 // check for single-member extraction first:
00334                 if ( !membername.empty() ) {
00335                     // Only serialize if the name matches:
00336                     if ( t.name() == membername ) {
00337                         if ( !mref ) {
00338                             *this & t.value();
00339                         } else {
00340                             mref->setReference( (void*) & t.value() );
00341                             mref = 0; // signals' we're done.
00342                         }
00343                     }
00344                 } else {
00345                     // Full extraction of all parts:
00346                     // store name of member
00347                     mnames.push_back( t.name() );
00348 
00349                     // serialize the data as usual
00350                     if (mparent)
00351                         *this & t.value();
00352                 }
00353 
00354                 return *this;
00355             }
00356         };
00357     }
00358 }
00359 
00360 #endif /* TYPE_DISCOVERY_HPP_ */