Orocos Real-Time Toolkit  2.8.3
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 "DataSource.hpp"
55 #include "Exceptions.hpp"
56 #include "../FactoryExceptions.hpp"
57 #include "mystd.hpp"
58 
59 #include <iostream>
60 
61 namespace RTT
62 {
63  namespace internal
64  {
65  namespace bf = boost::fusion;
66  namespace mpl = boost::mpl;
67 
68 
69  template <class T> struct incomplete;
70 
75  template<class Seq, class Data, class Enable = void >
76  struct GetArgument {
77  Data operator()(Seq s) { bf::front(s)->evaluate(); return Data(bf::front(s)->rvalue()); /* front(s) is a DataSource<Data> */}
78  }; // normal type
79 
83  template<class Seq, class Data>
84  struct GetArgument<Seq, Data, typename boost::enable_if< is_pure_reference<Data> >::type> {
85  Data operator()(Seq s) { return Data(bf::front(s)->set() ); /* Case of reference.*/ }
86  }; // shared_ptr type
87 
92  template<class Seq, class Data, class Enable = void >
93  struct AssignHelper {
94  static void set( Seq seq, Data in) { bf::front(seq)->set( bf::front(in) ); }
95  }; // normal type
96 
97  template<class Seq, class Data>
98  struct AssignHelper<Seq, Data, typename boost::enable_if< boost::is_pointer<typename mpl::front<Data>::type> >::type> {
99  static void set(Seq , Data ) {} // nop
100  }; // shared_ptr type
101 
105  template<class T>
106  struct UpdateHelper {
107  static void update(typename DataSource<typename remove_cr<T>::type >::shared_ptr) {}
108  };
109 
110  template<class T>
111  struct UpdateHelper<T&> {
112  static void update(typename DataSource<typename remove_cr<T>::type >::shared_ptr s) { s->updated(); }
113  };
114 
120  template<class ds_arg_type, class ds_type>
121  static ds_type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr, std::string const& tname )
122  {
123  typedef typename ds_type::element_type element_type;
124 
125  ds_type a =
126  boost::dynamic_pointer_cast< element_type >( DataSourceTypeInfo<ds_arg_type>::getTypeInfo()->convert(*front) );
127  if ( ! a ) {
128  //cout << typeid(DataSource<ds_arg_type>).name() << endl;
129  ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ds_type());
130  //ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, typeid(DataSource<ds_arg_type>).name(), typeid(front).name() ), type());
131  }
132  return a;
133  }
134 
135  template<class ds_arg_type, class ads_type>
136  static ads_type assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr, std::string const& tname )
137  {
138  ads_type a =
139  boost::dynamic_pointer_cast< AssignableDataSource<ds_arg_type> >( *front ); // note: no conversion done, must be same type.
140  if ( ! a ) {
141  ORO_THROW_OR_RETURN(wrong_types_of_args_exception( argnbr, tname, (*front)->getType() ), ads_type());
142  }
143  return a;
144  }
145  };
146 
147  template<class List, int size>
149 
178  template<class List>
179  struct create_sequence: public create_sequence_impl<List, mpl::size<
180  List>::value>
181  {
182  };
183 
184  template<class List, int size>
185  struct create_sequence_impl
186  {
191 
195  typedef typename mpl::front<List>::type arg_type;
196 
201 
205  typedef typename mpl::if_<typename is_pure_reference<arg_type>::type,
208 
209  typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type;
210 
215  typedef typename tail::type tail_type;
216 
220  typedef bf::cons<ds_type, tail_type> type;
221 
222  typedef typename tail::atype atail_type;
223  typedef bf::cons<ads_type, atail_type> atype;
224 
225  typedef typename tail::data_type arg_tail_type;
226 
230  typedef bf::cons<arg_type, arg_tail_type> data_type;
231 
240  static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 )
241  {
242  std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args;
243  return bf::cons<ds_type, tail_type>
244  (create_sequence_helper::sources<ds_arg_type, ds_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()),
245  tail::sources( ++next, argnbr + 1));
246  }
247 
256  static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1 )
257  {
258  std::vector<base::DataSourceBase::shared_ptr>::const_iterator next = args;
259  return atype(
260  create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()),
261  tail::assignable(++next, argnbr + 1));
262  }
263 
270  static data_type data(const type& seq) {
271  return data_type( GetArgument<type,arg_type>()(seq), tail::data( bf::pop_front(seq) ) );
272  }
273 
280  static void set(const data_type& in, const atype& seq) {
282  return tail::set( bf::pop_front(in), bf::pop_front(seq) );
283  }
284 
290  static void update(const type&seq) {
291  UpdateHelper<arg_type>::update( bf::front(seq) );
292  return tail::update( bf::pop_front(seq) );
293  }
294 
302  static type copy(const type& seq, std::map<
303  const base::DataSourceBase*,
304  base::DataSourceBase*>& alreadyCloned) {
305  return type( bf::front(seq)->copy(alreadyCloned), tail::copy( bf::pop_front(seq), alreadyCloned ) );
306  }
307 
315  static const types::TypeInfo* GetTypeInfo(int i) {
316  if ( i <= 0 || i > size)
317  return 0;
318  if ( i == 1 ) {
320  } else {
321  return tail::GetTypeInfo(i-1);
322  }
323  }
324 
332  static std::string GetType(int i) {
333  if ( i <= 0 || i > size)
334  return "na";
335  if ( i == 1 ) {
337  } else {
338  return tail::GetType(i-1);
339  }
340  }
341 };
342 
343  template<class List>
344  struct create_sequence_impl<List, 1> // mpl list of one
345  {
346  typedef typename mpl::front<List>::type arg_type;
348  typedef bf::cons<arg_type> data_type;
349 
353  typedef typename mpl::if_<typename is_pure_reference<arg_type>::type,
356  typedef typename AssignableDataSource< ds_arg_type >::shared_ptr ads_type;
357 
358 
359  // the result sequence type is a cons of the last argument in the vector.
360  typedef bf::cons<ds_type> type;
361 
362  typedef bf::cons<ads_type> atype;
363 
364  static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator front, int argnbr = 1)
365  {
366  return type(
367  create_sequence_helper::sources<ds_arg_type, ds_type>(front, argnbr, DataSourceTypeInfo<arg_type>::getType()));
368  }
369 
370  static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 1)
371  {
372  return atype(
373  create_sequence_helper::assignable<ds_arg_type, ads_type>(args, argnbr, DataSourceTypeInfo<arg_type>::getType()));
374  }
375 
382  static data_type data(const type& seq) {
383  return data_type( GetArgument<type,arg_type>()(seq) );
384  }
385 
386  static void update(const type&seq) {
387  UpdateHelper<arg_type>::update( bf::front(seq) );
388  return;
389  }
390 
391  static void set(const data_type& in, const atype& seq) {
393  }
394 
402  static type copy(const type& seq, std::map<
403  const base::DataSourceBase*,
404  base::DataSourceBase*>& alreadyCloned) {
405  return type( bf::front(seq)->copy(alreadyCloned) );
406  }
407 
408  static const types::TypeInfo* GetTypeInfo(int i) {
409  if ( i != 1)
410  return 0;
412  }
413  static std::string GetType(int i) {
414  if ( i != 1)
415  return "na";
417  }
418  };
419 
420  template<class List>
421  struct create_sequence_impl<List, 0> // empty mpl list
422  {
423  typedef bf::vector<> data_type;
424 
425  // the result sequence type is a cons of the last argument in the vector.
426  typedef bf::vector<> type;
427 
428  typedef bf::vector<> atype;
429 
430  static type sources(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0)
431  {
432  return type();
433  }
434 
435  static atype assignable(std::vector<base::DataSourceBase::shared_ptr>::const_iterator args, int argnbr = 0)
436  {
437  return atype();
438  }
439 
446  static data_type data(const type& seq) {
447  return data_type();
448  }
449 
450  static void update(const type&seq) {
451  return;
452  }
453 
454  static void set(const data_type& in, const atype& seq) {
455  return;
456  }
457 
458 
466  static type copy(const type& seq, std::map<
467  const base::DataSourceBase*,
468  base::DataSourceBase*>& alreadyCloned) {
469  return type();
470  }
471  static const types::TypeInfo* GetTypeInfo(int i) {
472  return 0;
473  }
474  static std::string GetType(int i) {
475  return "na";
476  }
477  };
478  }
479 }
480 
481 #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.
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 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.
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.
#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 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)
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:66
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.
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.
bf::cons< ds_type, tail_type > type
The joint DataSource<T>::shared_ptr type of head and tail, again a fusion cons.
A DataSource which has set() methods.
Definition: DataSource.hpp:184
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)
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:51
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...