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 using namespace std;
00061
00062 namespace RTT
00063 {
00064 namespace internal
00065 {
00066 namespace bf = boost::fusion;
00067 namespace mpl = boost::mpl;
00068
00069
00070 template <class T> struct incomplete;
00071
00076 template<class Seq, class Data, class Enable = void >
00077 struct GetArgument {
00078 Data operator()(Seq s) { bf::front(s)->evaluate(); return Data(bf::front(s)->rvalue()); }
00079 };
00080
00084 template<class Seq, class Data>
00085 struct GetArgument<Seq, Data, typename boost::enable_if< is_pure_reference<Data> >::type> {
00086 Data operator()(Seq s) { return Data(bf::front(s)->set() ); }
00087 };
00088
00093 template<class Seq, class Data, class Enable = void >
00094 struct AssignHelper {
00095 static void set( Seq seq, Data in) { bf::front(seq)->set( bf::front(in) ); }
00096 };
00097
00098 template<class Seq, class Data>
00099 struct AssignHelper<Seq, Data, typename boost::enable_if< boost::is_pointer<typename mpl::front<Data>::type> >::type> {
00100 static void set(Seq , Data ) {}
00101 };
00102
00106 template<class T>
00107 struct UpdateHelper {
00108 static void update(typename DataSource<typename remove_cr<T>::type >::shared_ptr) {}
00109 };
00110
00111 template<class T>
00112 struct UpdateHelper<T&> {
00113 static void update(typename DataSource<typename remove_cr<T>::type >::shared_ptr s) { s->updated(); }
00114 };
00115
00120 struct create_sequence_helper {
00121 template<class ds_arg_type, class ds_type>
00122 static ds_type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr, std::string const& tname )
00123 {
00124 typedef typename ds_type::element_type element_type;
00125
00126 ds_type a =
00127 boost::dynamic_pointer_cast< element_type >( DataSourceTypeInfo<ds_arg_type>::getTypeInfo()->convert(*front) );
00128 if ( ! a ) {
00129
00130 ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ds_type());
00131
00132 }
00133 return a;
00134 }
00135
00136 template<class ds_arg_type, class ads_type>
00137 static ads_type assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr, std::string const& tname )
00138 {
00139 typedef typename ads_type::element_type element_type;
00140
00141 ads_type a =
00142 boost::dynamic_pointer_cast< AssignableDataSource<ds_arg_type> >( *front );
00143 if ( ! a ) {
00144 ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ads_type());
00145 }
00146 return a;
00147 }
00148 };
00149
00150 template<class List, int size>
00151 struct create_sequence_impl;
00152
00181 template<class List>
00182 struct create_sequence: public create_sequence_impl<List, mpl::size<
00183 List>::value>
00184 {
00185 };
00186
00187 template<class List, int size>
00188 struct create_sequence_impl
00189 {
00193 typedef create_sequence<typename mpl::pop_front<List>::type> tail;
00194
00198 typedef typename mpl::front<List>::type arg_type;
00199
00203 typedef typename remove_cr<arg_type>::type ds_arg_type;
00204
00208 typedef typename mpl::if_<typename is_pure_reference<arg_type>::type,
00209 typename AssignableDataSource< ds_arg_type >::shared_ptr,
00210 typename DataSource<ds_arg_type>::shared_ptr>::type ds_type;
00211
00212 typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type;
00213
00218 typedef typename tail::type tail_type;
00219
00223 typedef bf::cons<ds_type, tail_type> type;
00224
00225 typedef typename tail::atype atail_type;
00226 typedef bf::cons<ads_type, atail_type> atype;
00227
00228 typedef typename tail::data_type arg_tail_type;
00229
00233 typedef bf::cons<arg_type, arg_tail_type> data_type;
00234
00243 static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 )
00244 {
00245 std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args;
00246 return bf::cons<ds_type, tail_type>
00247 (create_sequence_helper::sources<ds_arg_type, ds_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()),
00248 tail::sources( ++next, argnbr + 1));
00249 }
00250
00259 static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 )
00260 {
00261 std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args;
00262 return atype(
00263 create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()),
00264 tail::assignable(++next, argnbr + 1));
00265 }
00266
00273 static data_type data(const type& seq) {
00274 return data_type( GetArgument<type,arg_type>()(seq), tail::data( bf::pop_front(seq) ) );
00275 }
00276
00283 static void set(const data_type& in, const atype& seq) {
00284 AssignHelper<atype, data_type>::set(seq, in);
00285 return tail::set( bf::pop_front(in), bf::pop_front(seq) );
00286 }
00287
00293 static void update(const type&seq) {
00294 UpdateHelper<arg_type>::update( bf::front(seq) );
00295 return tail::update( bf::pop_front(seq) );
00296 }
00297
00305 static type copy(const type& seq, std::map<
00306 const base::DataSourceBase*,
00307 base::DataSourceBase*>& alreadyCloned) {
00308 return type( bf::front(seq)->copy(alreadyCloned), tail::copy( bf::pop_front(seq), alreadyCloned ) );
00309 }
00310
00318 static const types::TypeInfo* GetTypeInfo(int i) {
00319 if ( i <= 0 || i > size)
00320 return 0;
00321 if ( i == 1 ) {
00322 return DataSourceTypeInfo<arg_type>::getTypeInfo();
00323 } else {
00324 return tail::GetTypeInfo(i-1);
00325 }
00326 }
00327
00335 static std::string GetType(int i) {
00336 if ( i <= 0 || i > size)
00337 return "na";
00338 if ( i == 1 ) {
00339 return DataSourceTypeInfo<arg_type>::getType();
00340 } else {
00341 return tail::GetType(i-1);
00342 }
00343 }
00344 };
00345
00346 template<class List>
00347 struct create_sequence_impl<List, 1>
00348 {
00349 typedef typename mpl::front<List>::type arg_type;
00350 typedef typename remove_cr<arg_type>::type ds_arg_type;
00351 typedef bf::cons<arg_type> data_type;
00352
00356 typedef typename mpl::if_<typename is_pure_reference<arg_type>::type,
00357 typename AssignableDataSource< ds_arg_type >::shared_ptr,
00358 typename DataSource<ds_arg_type>::shared_ptr>::type ds_type;
00359 typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type;
00360
00361
00362
00363 typedef bf::cons<ds_type> type;
00364
00365 typedef bf::cons<ads_type> atype;
00366
00367 static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr = 1)
00368 {
00369 return type(
00370 create_sequence_helper::sources<ds_arg_type, ds_type>(front, argnbr, DataSourceTypeInfo<arg_type>::getType()));
00371 }
00372
00373 static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1)
00374 {
00375 return atype(
00376 create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()));
00377 }
00378
00385 static data_type data(const type& seq) {
00386 return data_type( GetArgument<type,arg_type>()(seq) );
00387 }
00388
00389 static void update(const type&seq) {
00390 UpdateHelper<arg_type>::update( bf::front(seq) );
00391 return;
00392 }
00393
00394 static void set(const data_type& in, const atype& seq) {
00395 AssignHelper<atype, data_type>::set(seq, in);
00396 }
00397
00405 static type copy(const type& seq, std::map<
00406 const base::DataSourceBase*,
00407 base::DataSourceBase*>& alreadyCloned) {
00408 return type( bf::front(seq)->copy(alreadyCloned) );
00409 }
00410
00411 static const types::TypeInfo* GetTypeInfo(int i) {
00412 if ( i != 1)
00413 return 0;
00414 return DataSource<ds_arg_type>::GetTypeInfo();
00415 }
00416 static std::string GetType(int i) {
00417 if ( i != 1)
00418 return "na";
00419 return DataSourceTypeInfo<arg_type>::getType();
00420 }
00421 };
00422
00423 template<class List>
00424 struct create_sequence_impl<List, 0>
00425 {
00426 typedef bf::vector<> data_type;
00427
00428
00429 typedef bf::vector<> type;
00430
00431 typedef bf::vector<> atype;
00432
00433 static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0)
00434 {
00435 return type();
00436 }
00437
00438 static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0)
00439 {
00440 return atype();
00441 }
00442
00449 static data_type data(const type& seq) {
00450 return data_type();
00451 }
00452
00453 static void update(const type&seq) {
00454 return;
00455 }
00456
00457 static void set(const data_type& in, const atype& seq) {
00458 return;
00459 }
00460
00461
00469 static type copy(const type& seq, std::map<
00470 const base::DataSourceBase*,
00471 base::DataSourceBase*>& alreadyCloned) {
00472 return type();
00473 }
00474 static const types::TypeInfo* GetTypeInfo(int i) {
00475 return 0;
00476 }
00477 static std::string GetType(int i) {
00478 return "na";
00479 }
00480 };
00481 }
00482 }
00483
00484 #endif