$search
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 typedef typename ads_type::element_type element_type; 00139 00140 ads_type a = 00141 boost::dynamic_pointer_cast< AssignableDataSource<ds_arg_type> >( *front ); // note: no conversion done, must be same type. 00142 if ( ! a ) { 00143 ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ads_type()); 00144 } 00145 return a; 00146 } 00147 }; 00148 00149 template<class List, int size> 00150 struct create_sequence_impl; 00151 00180 template<class List> 00181 struct create_sequence: public create_sequence_impl<List, mpl::size< 00182 List>::value> 00183 { 00184 }; 00185 00186 template<class List, int size> 00187 struct create_sequence_impl 00188 { 00192 typedef create_sequence<typename mpl::pop_front<List>::type> tail; 00193 00197 typedef typename mpl::front<List>::type arg_type; 00198 00202 typedef typename remove_cr<arg_type>::type ds_arg_type; 00203 00207 typedef typename mpl::if_<typename is_pure_reference<arg_type>::type, 00208 typename AssignableDataSource< ds_arg_type >::shared_ptr, 00209 typename DataSource<ds_arg_type>::shared_ptr>::type ds_type; 00210 00211 typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type; 00212 00217 typedef typename tail::type tail_type; 00218 00222 typedef bf::cons<ds_type, tail_type> type; 00223 00224 typedef typename tail::atype atail_type; 00225 typedef bf::cons<ads_type, atail_type> atype; 00226 00227 typedef typename tail::data_type arg_tail_type; 00228 00232 typedef bf::cons<arg_type, arg_tail_type> data_type; 00233 00242 static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 ) 00243 { 00244 std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args; 00245 return bf::cons<ds_type, tail_type> 00246 (create_sequence_helper::sources<ds_arg_type, ds_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()), 00247 tail::sources( ++next, argnbr + 1)); 00248 } 00249 00258 static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 ) 00259 { 00260 std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args; 00261 return atype( 00262 create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()), 00263 tail::assignable(++next, argnbr + 1)); 00264 } 00265 00272 static data_type data(const type& seq) { 00273 return data_type( GetArgument<type,arg_type>()(seq), tail::data( bf::pop_front(seq) ) ); 00274 } 00275 00282 static void set(const data_type& in, const atype& seq) { 00283 AssignHelper<atype, data_type>::set(seq, in); 00284 return tail::set( bf::pop_front(in), bf::pop_front(seq) ); 00285 } 00286 00292 static void update(const type&seq) { 00293 UpdateHelper<arg_type>::update( bf::front(seq) ); 00294 return tail::update( bf::pop_front(seq) ); 00295 } 00296 00304 static type copy(const type& seq, std::map< 00305 const base::DataSourceBase*, 00306 base::DataSourceBase*>& alreadyCloned) { 00307 return type( bf::front(seq)->copy(alreadyCloned), tail::copy( bf::pop_front(seq), alreadyCloned ) ); 00308 } 00309 00317 static const types::TypeInfo* GetTypeInfo(int i) { 00318 if ( i <= 0 || i > size) 00319 return 0; 00320 if ( i == 1 ) { 00321 return DataSourceTypeInfo<arg_type>::getTypeInfo(); 00322 } else { 00323 return tail::GetTypeInfo(i-1); 00324 } 00325 } 00326 00334 static std::string GetType(int i) { 00335 if ( i <= 0 || i > size) 00336 return "na"; 00337 if ( i == 1 ) { 00338 return DataSourceTypeInfo<arg_type>::getType(); 00339 } else { 00340 return tail::GetType(i-1); 00341 } 00342 } 00343 }; 00344 00345 template<class List> 00346 struct create_sequence_impl<List, 1> // mpl list of one 00347 { 00348 typedef typename mpl::front<List>::type arg_type; 00349 typedef typename remove_cr<arg_type>::type ds_arg_type; 00350 typedef bf::cons<arg_type> data_type; 00351 00355 typedef typename mpl::if_<typename is_pure_reference<arg_type>::type, 00356 typename AssignableDataSource< ds_arg_type >::shared_ptr, 00357 typename DataSource<ds_arg_type>::shared_ptr>::type ds_type; 00358 typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type; 00359 00360 00361 // the result sequence type is a cons of the last argument in the vector. 00362 typedef bf::cons<ds_type> type; 00363 00364 typedef bf::cons<ads_type> atype; 00365 00366 static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr = 1) 00367 { 00368 return type( 00369 create_sequence_helper::sources<ds_arg_type, ds_type>(front, argnbr, DataSourceTypeInfo<arg_type>::getType())); 00370 } 00371 00372 static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1) 00373 { 00374 return atype( 00375 create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType())); 00376 } 00377 00384 static data_type data(const type& seq) { 00385 return data_type( GetArgument<type,arg_type>()(seq) ); 00386 } 00387 00388 static void update(const type&seq) { 00389 UpdateHelper<arg_type>::update( bf::front(seq) ); 00390 return; 00391 } 00392 00393 static void set(const data_type& in, const atype& seq) { 00394 AssignHelper<atype, data_type>::set(seq, in); 00395 } 00396 00404 static type copy(const type& seq, std::map< 00405 const base::DataSourceBase*, 00406 base::DataSourceBase*>& alreadyCloned) { 00407 return type( bf::front(seq)->copy(alreadyCloned) ); 00408 } 00409 00410 static const types::TypeInfo* GetTypeInfo(int i) { 00411 if ( i != 1) 00412 return 0; 00413 return DataSource<ds_arg_type>::GetTypeInfo(); 00414 } 00415 static std::string GetType(int i) { 00416 if ( i != 1) 00417 return "na"; 00418 return DataSourceTypeInfo<arg_type>::getType(); 00419 } 00420 }; 00421 00422 template<class List> 00423 struct create_sequence_impl<List, 0> // empty mpl list 00424 { 00425 typedef bf::vector<> data_type; 00426 00427 // the result sequence type is a cons of the last argument in the vector. 00428 typedef bf::vector<> type; 00429 00430 typedef bf::vector<> atype; 00431 00432 static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0) 00433 { 00434 return type(); 00435 } 00436 00437 static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0) 00438 { 00439 return atype(); 00440 } 00441 00448 static data_type data(const type& seq) { 00449 return data_type(); 00450 } 00451 00452 static void update(const type&seq) { 00453 return; 00454 } 00455 00456 static void set(const data_type& in, const atype& seq) { 00457 return; 00458 } 00459 00460 00468 static type copy(const type& seq, std::map< 00469 const base::DataSourceBase*, 00470 base::DataSourceBase*>& alreadyCloned) { 00471 return type(); 00472 } 00473 static const types::TypeInfo* GetTypeInfo(int i) { 00474 return 0; 00475 } 00476 static std::string GetType(int i) { 00477 return "na"; 00478 } 00479 }; 00480 } 00481 } 00482 00483 #endif /* ORO_CREATESEQUENCE_HPP_ */