00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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()); }
00078 };
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() ); }
00086 };
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 };
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 ) {}
00100 };
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
00129 ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ds_type());
00130
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 );
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>
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
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>
00424 {
00425 typedef bf::vector<> data_type;
00426
00427
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