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 ads_type a =
00139 boost::dynamic_pointer_cast< AssignableDataSource<ds_arg_type> >( *front );
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>
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
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>
00422 {
00423 typedef bf::vector<> data_type;
00424
00425
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