Orocos Real-Time Toolkit  2.5.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 "carray.hpp"
00084 
00085 namespace RTT
00086 {
00087     namespace types
00088     {
00093         class type_discovery
00094         {
00095         public:
00099             base::DataSourceBase::shared_ptr mparent;
00100 
00101             typedef std::vector<base::DataSourceBase::shared_ptr> Parts;
00102             typedef std::vector<std::string> PartNames;
00106             Parts mparts;
00107 
00112             Parts mcparts;
00113 
00117             PartNames mnames;
00118 
00119             typedef char Elem;
00123             typedef boost::mpl::bool_<true> is_loading;
00127             typedef boost::mpl::bool_<false> is_saving;
00128 
00133             type_discovery(base::DataSourceBase::shared_ptr parent) :
00134                 mparent(parent)
00135             {
00136             }
00137 
00142             type_discovery() :
00143                 mparent()
00144             {
00145             }
00146 
00147             base::DataSourceBase::shared_ptr getMember(const std::string name) {
00148                 PartNames::iterator it = find( mnames.begin(), mnames.end(), name);
00149                 if ( it != mnames.end() && mparts.size() == mnames.size() )
00150                     return mparts.at( it - mnames.begin() );
00151                 return base::DataSourceBase::shared_ptr();
00152             }
00153 
00154             base::DataSourceBase::shared_ptr getConstMember(const std::string name) {
00155                 PartNames::iterator it = find( mnames.begin(), mnames.end(), name);
00156                 if ( it != mnames.end() && mcparts.size() == mnames.size() )
00157                     return mcparts.at( it - mnames.begin() );
00158                 return base::DataSourceBase::shared_ptr();
00159             }
00160 
00161             template<class T>
00162             void discover( T& t) {
00163 #if BOOST_VERSION >= 104100
00164                 boost::archive::detail::load_non_pointer_type<type_discovery>::load_only::invoke(*this,t);
00165 #else
00166                 boost::archive::detail::load_non_pointer_type<type_discovery,T>::load_only::invoke(*this,t);
00167 #endif
00168             }
00169 
00174             unsigned int get_library_version() { return 0; }
00175 
00181             void reset_object_address(const void * new_address, const void * old_address) {}
00182 
00186             void delete_created_pointers() {}
00187 
00193             template<class T>
00194             const boost::archive::detail::basic_pointer_iserializer *
00195             register_type(T * = NULL) {return 0;}
00196 
00202             void load_object(void *x, const boost::archive::detail::basic_oserializer & bos)
00203             {
00204                 assert(false);
00205             }
00206 
00212             template<class T>
00213             type_discovery &operator>>(T &t)
00214             {
00215                 return load_a_type(t, boost::mpl::bool_<boost::serialization::implementation_level<T>::value == boost::serialization::primitive_type>());
00216             }
00217 
00223             template<class T>
00224             type_discovery &operator&(T &t)
00225             {
00226                 return this->operator>>(t);
00227             }
00228 
00234             template<class T>
00235             type_discovery &load_a_type(T &t, boost::mpl::true_)
00236             {
00237                 // stores the part
00238                 if (mparent) {
00239                     mparts.push_back(new internal::PartDataSource<T> (t, mparent));
00240                     mcparts.push_back(new internal::AliasDataSource<T>( new internal::PartDataSource<T> (t, mparent) ));
00241                 }
00242                 return *this;
00243             }
00244 
00250             template<class T>
00251             type_discovery &load_a_type(T &t, boost::mpl::false_)
00252             {
00253                 if (mparent) {
00254                     mparts.push_back(new internal::PartDataSource<T> (t, mparent));
00255                     mcparts.push_back(new internal::AliasDataSource<T>( new internal::PartDataSource<T> (t, mparent) ));
00256                 }
00257                 return *this;
00258             }
00259 
00265             template<class T>
00266             type_discovery &load_a_type(const boost::serialization::array<T> &t, boost::mpl::false_)
00267             {
00268                 if (mparent) {
00269                     mparts.push_back(new internal::PartDataSource< carray<T> > ( carray<T>(t), mparent) );
00270                     mcparts.push_back(new internal::AliasDataSource< carray<T> >( new internal::PartDataSource< carray<T> > ( carray<T>(t), mparent)  ));
00271                 }
00272                 // probably not necessary:
00273                 //mparts.push_back( DataSourceTypeInfo< carray<T> >::getTypeInfo()->buildPart( carray<T>(t), mparent ) );
00274                 return *this;
00275             }
00276 
00282             template<class T, std::size_t N>
00283             type_discovery &load_a_type(boost::array<T,N> &t, boost::mpl::false_)
00284             {
00285                 if (mparent) {
00286                     mparts.push_back(new internal::PartDataSource< carray<T> > ( carray<T>(t), mparent) );
00287                     mcparts.push_back(new internal::AliasDataSource< carray<T> >( new internal::PartDataSource< carray<T> > ( carray<T>(t), mparent)  ));
00288                 }
00289                 // probably not necessary:
00290                 //mparts.push_back( DataSourceTypeInfo< carray<T> >::getTypeInfo()->buildPart( carray<T>(t), mparent ) );
00291                 return *this;
00292             }
00293 
00300             template<class T>
00301             type_discovery &load_a_type(const T* &, boost::mpl::false_)
00302             {
00303                 //pointers can not be serialized.
00304                 //BOOST_STATIC_ASSERT( boost::mpl::false_ );
00305                 return *this;
00306             }
00307 
00309             template<class T>
00310             type_discovery &load_a_type(const boost::serialization::nvp<T> & t, boost::mpl::false_)
00311             {
00312                 // store name of member
00313                 mnames.push_back( t.name() );
00314 
00315                 // serialize the data as usual
00316                 *this & t.value();
00317 
00318                 return *this;
00319             }
00320         };
00321     }
00322 }
00323 
00324 #endif /* TYPE_DISCOVERY_HPP_ */