CreateSequence.hpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: The SourceWorks  Tue Sep 7 00:55:18 CEST 2010  CreateSequence.hpp
00003 
00004                         CreateSequence.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 ORO_CREATESEQUENCE_HPP_
00040 #define ORO_CREATESEQUENCE_HPP_
00041 
00042 #include <boost/fusion/include/cons.hpp>
00043 #include <boost/fusion/include/front.hpp>
00044 #include <boost/fusion/include/vector.hpp>
00045 
00046 #include <vector>
00047 #include <boost/mpl/front.hpp>
00048 #include <boost/mpl/pop_front.hpp>
00049 #include <boost/mpl/print.hpp>
00050 // The fusion <--> MPL link header
00051 #include <boost/fusion/mpl.hpp>
00052 #include <boost/utility/enable_if.hpp>
00053 
00054 #include "DataSource.hpp"
00055 #include "Exceptions.hpp"
00056 #include "../FactoryExceptions.hpp"
00057 #include "mystd.hpp"
00058 
00059 #include <iostream>
00060 
00061 namespace RTT
00062 {
00063     namespace internal
00064     {
00065         namespace bf = boost::fusion;
00066         namespace mpl = boost::mpl;
00067 
00068 
00069         template <class T> struct incomplete;
00070 
00075         template<class Seq, class Data, class Enable = void >
00076         struct GetArgument {
00077             Data operator()(Seq s) { bf::front(s)->evaluate(); return Data(bf::front(s)->rvalue()); /* front(s) is a DataSource<Data> */}
00078         }; // normal type
00079 
00083         template<class Seq, class Data>
00084         struct GetArgument<Seq, Data, typename boost::enable_if< is_pure_reference<Data> >::type> {
00085             Data operator()(Seq s) { return Data(bf::front(s)->set() ); /* Case of reference.*/ }
00086         }; // shared_ptr type
00087 
00092         template<class Seq, class Data, class Enable = void >
00093         struct AssignHelper {
00094             static void set( Seq seq, Data in) { bf::front(seq)->set( bf::front(in) ); }
00095         }; // normal type
00096 
00097         template<class Seq, class Data>
00098         struct AssignHelper<Seq, Data, typename boost::enable_if< boost::is_pointer<typename mpl::front<Data>::type> >::type> {
00099             static void set(Seq , Data ) {} // nop
00100         }; // shared_ptr type
00101 
00105         template<class T>
00106         struct UpdateHelper {
00107             static void update(typename DataSource<typename remove_cr<T>::type >::shared_ptr) {}
00108         };
00109 
00110         template<class T>
00111         struct UpdateHelper<T&> {
00112             static void update(typename DataSource<typename remove_cr<T>::type >::shared_ptr s) { s->updated(); }
00113         };
00114 
00119         struct create_sequence_helper {
00120             template<class ds_arg_type, class ds_type>
00121             static ds_type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr, std::string const& tname )
00122             {
00123                 typedef typename ds_type::element_type element_type;
00124 
00125                 ds_type a =
00126                     boost::dynamic_pointer_cast< element_type >( DataSourceTypeInfo<ds_arg_type>::getTypeInfo()->convert(*front) );
00127                 if ( ! a ) {
00128                     //cout << typeid(DataSource<ds_arg_type>).name() << endl;
00129                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ds_type());
00130                     //ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, typeid(DataSource<ds_arg_type>).name(), typeid(front).name() ), type());
00131                 }
00132                 return a;
00133             }
00134 
00135             template<class ds_arg_type, class ads_type>
00136             static ads_type assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr, std::string const& tname )
00137             {
00138                 ads_type a =
00139                     boost::dynamic_pointer_cast< AssignableDataSource<ds_arg_type> >( *front ); // note: no conversion done, must be same type.
00140                 if ( ! a ) {
00141                     ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ads_type());
00142                 }
00143                 return a;
00144             }
00145         };
00146 
00147         template<class List, int size>
00148         struct create_sequence_impl;
00149 
00178         template<class List>
00179         struct create_sequence: public create_sequence_impl<List, mpl::size<
00180                 List>::value>
00181         {
00182         };
00183 
00184         template<class List, int size>
00185         struct create_sequence_impl
00186         {
00190             typedef create_sequence<typename mpl::pop_front<List>::type> tail;
00191 
00195             typedef typename mpl::front<List>::type arg_type;
00196 
00200             typedef typename remove_cr<arg_type>::type ds_arg_type;
00201 
00205             typedef typename mpl::if_<typename is_pure_reference<arg_type>::type,
00206                     typename AssignableDataSource< ds_arg_type >::shared_ptr,
00207                     typename DataSource<ds_arg_type>::shared_ptr>::type ds_type;
00208 
00209             typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type;
00210 
00215             typedef typename tail::type tail_type;
00216 
00220             typedef bf::cons<ds_type, tail_type> type;
00221 
00222             typedef typename tail::atype atail_type;
00223             typedef bf::cons<ads_type, atail_type> atype;
00224 
00225             typedef typename tail::data_type arg_tail_type;
00226 
00230             typedef bf::cons<arg_type, arg_tail_type> data_type;
00231 
00240             static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 )
00241             {
00242                 std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args;
00243                 return bf::cons<ds_type, tail_type>
00244                     (create_sequence_helper::sources<ds_arg_type, ds_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()),
00245                      tail::sources( ++next, argnbr + 1));
00246             }
00247 
00256             static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 )
00257             {
00258                 std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args;
00259                 return atype(
00260                         create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()),
00261                         tail::assignable(++next, argnbr + 1));
00262             }
00263 
00270             static data_type data(const type& seq) {
00271                 return data_type( GetArgument<type,arg_type>()(seq), tail::data( bf::pop_front(seq) ) );
00272             }
00273 
00280             static void set(const data_type& in, const atype& seq) {
00281                 AssignHelper<atype, data_type>::set(seq, in);
00282                 return tail::set( bf::pop_front(in), bf::pop_front(seq) );
00283             }
00284 
00290             static void update(const type&seq) {
00291                 UpdateHelper<arg_type>::update( bf::front(seq) );
00292                 return tail::update( bf::pop_front(seq) );
00293             }
00294 
00302             static type copy(const type& seq, std::map<
00303                               const base::DataSourceBase*,
00304                               base::DataSourceBase*>& alreadyCloned) {
00305                 return type( bf::front(seq)->copy(alreadyCloned), tail::copy( bf::pop_front(seq), alreadyCloned ) );
00306             }
00307 
00315             static const types::TypeInfo* GetTypeInfo(int i) {
00316                 if ( i <= 0 || i > size)
00317                     return 0;
00318                 if ( i == 1 ) {
00319                     return DataSourceTypeInfo<arg_type>::getTypeInfo();
00320                 } else {
00321                     return tail::GetTypeInfo(i-1);
00322                 }
00323             }
00324 
00332             static std::string GetType(int i) {
00333                 if ( i <= 0 || i > size)
00334                     return "na";
00335                 if ( i == 1 ) {
00336                     return DataSourceTypeInfo<arg_type>::getType();
00337                 } else {
00338                     return tail::GetType(i-1);
00339                 }
00340             }
00341 };
00342 
00343         template<class List>
00344         struct create_sequence_impl<List, 1> // mpl list of one
00345         {
00346             typedef typename mpl::front<List>::type arg_type;
00347             typedef typename remove_cr<arg_type>::type ds_arg_type;
00348             typedef bf::cons<arg_type> data_type;
00349 
00353             typedef typename mpl::if_<typename is_pure_reference<arg_type>::type,
00354                     typename AssignableDataSource< ds_arg_type >::shared_ptr,
00355                     typename DataSource<ds_arg_type>::shared_ptr>::type ds_type;
00356             typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type;
00357 
00358 
00359             // the result sequence type is a cons of the last argument in the vector.
00360             typedef bf::cons<ds_type> type;
00361 
00362             typedef bf::cons<ads_type> atype;
00363 
00364             static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr = 1)
00365             {
00366                 return type(
00367                         create_sequence_helper::sources<ds_arg_type, ds_type>(front, argnbr, DataSourceTypeInfo<arg_type>::getType()));
00368             }
00369 
00370             static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1)
00371             {
00372                 return atype(
00373                         create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()));
00374             }
00375 
00382             static data_type data(const type& seq) {
00383                 return data_type( GetArgument<type,arg_type>()(seq) );
00384             }
00385 
00386             static void update(const type&seq) {
00387                 UpdateHelper<arg_type>::update( bf::front(seq) );
00388                 return;
00389             }
00390 
00391             static void set(const data_type& in, const atype& seq) {
00392                 AssignHelper<atype, data_type>::set(seq, in);
00393             }
00394 
00402             static type copy(const type& seq, std::map<
00403                               const base::DataSourceBase*,
00404                               base::DataSourceBase*>& alreadyCloned) {
00405                 return type( bf::front(seq)->copy(alreadyCloned) );
00406             }
00407 
00408             static const types::TypeInfo* GetTypeInfo(int i) {
00409                 if ( i != 1)
00410                     return 0;
00411                 return DataSource<ds_arg_type>::GetTypeInfo();
00412             }
00413             static std::string GetType(int i) {
00414                 if ( i != 1)
00415                     return "na";
00416                 return DataSourceTypeInfo<arg_type>::getType();
00417             }
00418         };
00419 
00420         template<class List>
00421         struct create_sequence_impl<List, 0> // empty mpl list
00422         {
00423             typedef bf::vector<> data_type;
00424 
00425             // the result sequence type is a cons of the last argument in the vector.
00426             typedef bf::vector<> type;
00427 
00428             typedef bf::vector<> atype;
00429 
00430             static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0)
00431             {
00432                 return type();
00433             }
00434 
00435             static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0)
00436             {
00437                 return atype();
00438             }
00439 
00446             static data_type data(const type& seq) {
00447                 return data_type();
00448             }
00449 
00450             static void update(const type&seq) {
00451                 return;
00452             }
00453 
00454             static void set(const data_type& in, const atype& seq) {
00455                 return;
00456             }
00457 
00458 
00466             static type copy(const type& seq, std::map<
00467                               const base::DataSourceBase*,
00468                               base::DataSourceBase*>& alreadyCloned) {
00469                 return type();
00470             }
00471             static const types::TypeInfo* GetTypeInfo(int i) {
00472                 return 0;
00473             }
00474             static std::string GetType(int i) {
00475                 return "na";
00476             }
00477         };
00478     }
00479 }
00480 
00481 #endif /* ORO_CREATESEQUENCE_HPP_ */


rtt
Author(s): RTT Developers
autogenerated on Wed Aug 26 2015 16:15:47