Orocos Real-Time Toolkit  2.9.0
CreateSequence.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 CreateSequence.hpp
3 
4  CreateSequence.hpp - description
5  -------------------
6  begin : Tue September 07 2010
7  copyright : (C) 2010 The SourceWorks
8  email : peter@thesourceworks.com
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 #ifndef ORO_CREATESEQUENCE_HPP_
40 #define ORO_CREATESEQUENCE_HPP_
41 
42 #include <boost/fusion/include/cons.hpp>
43 #include <boost/fusion/include/front.hpp>
44 #include <boost/fusion/include/vector.hpp>
45 
46 #include <vector>
47 #include <boost/mpl/front.hpp>
48 #include <boost/mpl/pop_front.hpp>
49 #include <boost/mpl/print.hpp>
50 // The fusion <--> MPL link header
51 #include <boost/fusion/mpl.hpp>
52 #include <boost/utility/enable_if.hpp>
53 
54 #include "BindStorage.hpp"
55 #include "DataSource.hpp"
56 #include "Exceptions.hpp"
57 #include "../FactoryExceptions.hpp"
58 #include "mystd.hpp"
59 
60 #include <iostream>
61 
62 namespace RTT
63 {
64  namespace internal
65  {
66  namespace bf = boost::fusion;
67  namespace mpl = boost::mpl;
68 
73  template<class Seq, class Data, class Enable = void >
74  struct GetArgument {
75  Data operator()(Seq s) { bf::front(s)->evaluate(); return Data(bf::front(s)->rvalue()); /* front(s) is a DataSource<Data> */}
76  }; // normal type
77 
81  template<class Seq, class Data>
82  struct GetArgument<Seq, Data, typename boost::enable_if< is_pure_reference<Data> >::type> {
83  Data operator()(Seq s) { return Data(bf::front(s)->set() ); /* Case of reference.*/ }
84  }; // shared_ptr type
85 
90  template<class Seq, class Data, class Enable = void >
91  struct AssignHelper {
92  static void set( Seq seq, Data in) { bf::front(seq)->set( bf::front(in) ); }
93  }; // normal type
94 
95  template<class Seq, class Data>
96  struct AssignHelper<Seq, Data, typename boost::enable_if< boost::is_pointer<typename mpl::front<Data>::type> >::type> {
97  static void set(Seq , Data ) {} // nop
98  }; // shared_ptr type
99 
103  template<class T>
104  struct UpdateHelper {
105  static void update(typename DataSource<typename remove_cr<T>::type >::shared_ptr) {}
106  };
107 
108  template<class T>
109  struct UpdateHelper<T&> {
110  static void update(typename DataSource<typename remove_cr<T>::type >::shared_ptr s) { s->updated(); }
111  };
112 
118  template<class ds_arg_type, class ds_type>
119  static ds_type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr, std::string const& tname )
120  {
121  typedef typename ds_type::element_type element_type;
122 
123  ds_type a =
124  boost::dynamic_pointer_cast< element_type >( *front );
125  if ( ! a ) {
126  a = boost::dynamic_pointer_cast< element_type >( DataSourceTypeInfo<ds_arg_type>::getTypeInfo()->convert(*front) );
127  }
128  if ( ! a ) {
129  //cout << typeid(DataSource<ds_arg_type>).name() << endl;
130  ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ds_type());
131  //ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, typeid(DataSource<ds_arg_type>).name(), typeid(front).name() ), type());
132  }
133  return a;
134  }
135 
136  template<class ds_arg_type, class ads_type>
137  static ads_type assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr, std::string const& tname )
138  {
139  typedef typename ads_type::element_type element_type;
140 
141  ads_type a =
142  boost::dynamic_pointer_cast< element_type >( *front ); // note: no conversion done, must be same type.
143  if ( ! a ) {
144  ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ads_type());
145  }
146  return a;
147  }
148  };
149 
150  template<class List, int size>
152 
181  template<class List>
182  struct create_sequence: public create_sequence_impl<List, mpl::size<
183  List>::value>
184  {
185  };
186 
187  template<class List, int size>
188  struct create_sequence_impl
189  {
194 
198  typedef typename mpl::front<List>::type arg_type;
199 
204 
209 
213  typedef typename mpl::if_<typename is_pure_reference<arg_type>::type,
216 
217  typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type;
218 
223  typedef typename tail::type tail_type;
224 
228  typedef bf::cons<ds_type, tail_type> type;
229 
230  typedef typename tail::atype atail_type;
231  typedef bf::cons<ads_type, atail_type> atype;
232 
233  typedef typename tail::data_type arg_tail_type;
235 
239  typedef bf::cons<arg_type, arg_tail_type> data_type;
240 
244  typedef bf::cons<arg_store_type, arg_store_tail_type> data_store_type;
245 
254  static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 )
255  {
256  std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args;
257  return bf::cons<ds_type, tail_type>
258  (create_sequence_helper::sources<ds_arg_type, ds_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()),
259  tail::sources( ++next, argnbr + 1));
260  }
261 
270  static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 )
271  {
272  std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args;
273  return atype(
274  create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()),
275  tail::assignable(++next, argnbr + 1));
276  }
277 
284  static data_type data(const type& seq) {
285  return data_type( GetArgument<type,arg_type>()(seq), tail::data( bf::pop_front(seq) ) );
286  }
287 
294  static void set(const data_type& in, const atype& seq) {
296  tail::set( bf::pop_front(in), bf::pop_front(seq) );
297  }
298 
307  static void load(const data_store_type& in, const atype& seq) {
309  tail::load( bf::pop_front(in), bf::pop_front(seq) );
310  }
311 
320  static data_store_type store(const data_type& in ) {
321  return data_store_type(bf::front(in), tail::store(bf::pop_front(in)));
322  }
323 
329  static void update(const type&seq) {
330  UpdateHelper<arg_type>::update( bf::front(seq) );
331  tail::update( bf::pop_front(seq) );
332  }
333 
341  static type copy(const type& seq, std::map<
342  const base::DataSourceBase*,
343  base::DataSourceBase*>& alreadyCloned) {
344  return type( bf::front(seq)->copy(alreadyCloned), tail::copy( bf::pop_front(seq), alreadyCloned ) );
345  }
346 
354  static const types::TypeInfo* GetTypeInfo(int i) {
355  if ( i <= 0 || i > size)
356  return 0;
357  if ( i == 1 ) {
359  } else {
360  return tail::GetTypeInfo(i-1);
361  }
362  }
363 
371  static std::string GetType(int i) {
372  if ( i <= 0 || i > size)
373  return "na";
374  if ( i == 1 ) {
376  } else {
377  return tail::GetType(i-1);
378  }
379  }
380 };
381 
382  template<class List>
383  struct create_sequence_impl<List, 1> // mpl list of one
384  {
385  typedef typename mpl::front<List>::type arg_type;
387  typedef bf::cons<arg_type> data_type;
388 
390  typedef bf::cons<arg_store_type > data_store_type;
391 
395  typedef typename mpl::if_<typename is_pure_reference<arg_type>::type,
398  typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type;
399 
400 
401  // the result sequence type is a cons of the last argument in the vector.
402  typedef bf::cons<ds_type> type;
403 
404  typedef bf::cons<ads_type> atype;
405 
406  static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr = 1)
407  {
408  return type(
409  create_sequence_helper::sources<ds_arg_type, ds_type>(front, argnbr, DataSourceTypeInfo<arg_type>::getType()));
410  }
411 
412  static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1)
413  {
414  return atype(
415  create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()));
416  }
417 
424  static data_type data(const type& seq) {
425  return data_type( GetArgument<type,arg_type>()(seq) );
426  }
427 
428  static void update(const type&seq) {
429  UpdateHelper<arg_type>::update( bf::front(seq) );
430  }
431 
432  static void set(const data_type& in, const atype& seq) {
434  }
435 
436  static void load(const data_store_type& in, const atype& seq) {
438  }
439 
440  static data_store_type store(const data_type& in ) {
441  return data_store_type( bf::front(in) );
442  }
443 
451  static type copy(const type& seq, std::map<
452  const base::DataSourceBase*,
453  base::DataSourceBase*>& alreadyCloned) {
454  return type( bf::front(seq)->copy(alreadyCloned) );
455  }
456 
457  static const types::TypeInfo* GetTypeInfo(int i) {
458  if ( i != 1)
459  return 0;
461  }
462  static std::string GetType(int i) {
463  if ( i != 1)
464  return "na";
466  }
467  };
468 
469  template<class List>
470  struct create_sequence_impl<List, 0> // empty mpl list
471  {
472  typedef bf::vector<> data_type;
473  typedef bf::vector<> data_store_type;
474 
475  // the result sequence type is a cons of the last argument in the vector.
476  typedef bf::vector<> type;
477 
478  typedef bf::vector<> atype;
479 
480  static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0)
481  {
482  return type();
483  }
484 
485  static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0)
486  {
487  return atype();
488  }
489 
496  static data_type data(const type& seq) {
497  return data_type();
498  }
499 
500  static void update(const type&seq) {
501  return;
502  }
503 
504  static void set(const data_type& in, const atype& seq) {
505  return;
506  }
507 
508  static void load(const data_store_type& in, const atype& seq) {
509  return;
510  }
511 
512  static data_store_type store(const data_type& in ) {
513  return data_store_type();
514  }
515 
523  static type copy(const type& seq, std::map<
524  const base::DataSourceBase*,
525  base::DataSourceBase*>& alreadyCloned) {
526  return type();
527  }
528  static const types::TypeInfo* GetTypeInfo(int i) {
529  return 0;
530  }
531  static std::string GetType(int i) {
532  return "na";
533  }
534  };
535  }
536 }
537 
538 #endif /* ORO_CREATESEQUENCE_HPP_ */
DataSource is a base class representing a generic way to read data of type T.
Definition: DataSource.hpp:94
static type sources(std::vector< base::DataSourceBase::shared_ptr >::const_iterator front, int argnbr=1)
static data_type data(const type &seq)
Returns the data contained in the data source as a Fusion Sequence.
bf::cons< arg_store_type, arg_store_tail_type > data_store_type
The joint T data storage type of head and tail.
static atype assignable(std::vector< base::DataSourceBase::shared_ptr >::const_iterator args, int argnbr=0)
This object represents the default queue implementation used by Orocos objects.
Definition: List.hpp:65
base::DataSourceBase::shared_ptr convert(base::DataSourceBase::shared_ptr arg) const
Automatic conversion: convert a internal::DataSource to this type.
Definition: TypeInfo.cpp:118
static data_store_type store(const data_type &in)
Stores the values of a sequence of data_type into a data_store_type sequence for later retrieval duri...
static data_store_type store(const data_type &in)
static void set(Seq seq, Data in)
remove_cr< arg_type >::type ds_arg_type
The data source value type of an assignable data source is non-const, non-reference.
static void load(const data_store_type &in, const atype &seq)
The base class for all internal data representations.
This class can create three kinds of Boost Fusion Sequences.
Helper class for extracting the bare pointer from a shared_ptr data source.
Store a bound argument which may be a reference, const reference or any other type.
Definition: BindStorage.hpp:65
#define ORO_THROW_OR_RETURN(x, rv)
Definition: Exceptions.hpp:53
AssignableDataSource< ds_arg_type >::shared_ptr ads_type
When Orocos is compiled without exceptions (define ORO_EMBEDDED), the functions which would throw an ...
tail::type tail_type
The type of the tail (List - head) of our sequence.
mpl::front< List >::type arg_type
The argument type.
static void update(typename DataSource< typename remove_cr< T >::type >::shared_ptr)
static std::string GetType(int i)
Returns the i&#39;th argument type name as returned by DataSource<ArgI>::GetType(), starting from 1...
static type copy(const type &seq, std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned)
Copies a sequence of DataSource<T>::shared_ptr according to the copy/clone semantics of data sources...
static void load(const data_store_type &in, const atype &seq)
Sets the values of a sequence of AssignableDataSource<T> data sources ot the values contained in in u...
static atype assignable(std::vector< base::DataSourceBase::shared_ptr >::const_iterator args, int argnbr=1)
Converts a std::vector of DataSourceBase types into a boost::fusion Sequence of AssignableDataSources...
static const types::TypeInfo * GetTypeInfo()
Return the Orocos type info.
Definition: DataSource.inl:49
static type copy(const type &seq, std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned)
Copies a sequence of DataSource<T>::shared_ptr according to the copy/clone semantics of data sources...
static const std::string & getType()
Return the qualified type.
Helper class for avoiding assigning a bare pointer to a shared_ptr data source.
static data_type data(const type &seq)
Returns the data contained in the data source as a Fusion Sequence.
Helper to only update data sources that hold references.
static const types::TypeInfo * GetTypeInfo(int i)
tail::data_store_type arg_store_tail_type
static data_type data(const type &seq)
Returns the data contained in the data sources as a Fusion Sequence.
create_sequence< typename mpl::pop_front< List >::type > tail
The tail is ourselves minus the head.
static const types::TypeInfo * getTypeInfo()
Return the typeinfo object.
static type copy(const type &seq, std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned)
Copies a sequence of DataSource<T>::shared_ptr according to the copy/clone semantics of data sources...
static type sources(std::vector< base::DataSourceBase::shared_ptr >::const_iterator args, int argnbr=1)
Converts a std::vector of DataSourceBase types into a boost::fusion Sequence of DataSources of the ty...
static atype assignable(std::vector< base::DataSourceBase::shared_ptr >::const_iterator args, int argnbr=1)
A class for representing a user type, and which can build instances of that type. ...
Definition: TypeInfo.hpp:67
mpl::if_< typename is_pure_reference< arg_type >::type, typename AssignableDataSource< ds_arg_type >::shared_ptr, typename DataSource< ds_arg_type >::shared_ptr >::type ds_type
The type of a single element of the vector.
static ds_type sources(std::vector< base::DataSourceBase::shared_ptr >::const_iterator front, int argnbr, std::string const &tname)
bf::cons< arg_type, arg_tail_type > data_type
The joint T data type of head and tail.
static data_store_type store(const data_type &in)
AssignableDataSource< ds_arg_type >::shared_ptr ads_type
static void update(typename DataSource< typename remove_cr< T >::type >::shared_ptr s)
boost::intrusive_ptr< DataSource< T > > shared_ptr
Definition: DataSource.hpp:115
boost::intrusive_ptr< AssignableDataSource< T > > shared_ptr
Use this type to store a pointer to an AssignableDataSource.
Definition: DataSource.hpp:198
Every DataSource of type T has a type info class which it can ask type information.
static void load(const data_store_type &in, const atype &seq)
bf::cons< ds_type, tail_type > type
The joint DataSource<T>::shared_ptr type of head and tail, again a fusion cons.
static const types::TypeInfo * GetTypeInfo(int i)
Returns the i&#39;th argument type info as returned by DataSource<ArgI>::GetTypeInfo(), starting from 1.
static const types::TypeInfo * GetTypeInfo(int i)
AStore< arg_type > arg_store_type
The argument storage type.
Exception thrown when a factory is requested to create an object, but a wrong argument type was given...
static type sources(std::vector< base::DataSourceBase::shared_ptr >::const_iterator args, int argnbr=0)
boost::remove_const< typename boost::remove_reference< T >::type >::type type
Definition: mystd.hpp:63
Helper to convert a single data source base to a DataSource or AssignableDataSource.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
mpl::if_< typename is_pure_reference< arg_type >::type, typename AssignableDataSource< ds_arg_type >::shared_ptr, typename DataSource< ds_arg_type >::shared_ptr >::type ds_type
The type of a single element of the vector.
static ads_type assignable(std::vector< base::DataSourceBase::shared_ptr >::const_iterator front, int argnbr, std::string const &tname)
static void update(const type &seq)
Calls the DataSourceBase::updated() function for each element in sequence seq, in case the element is...