Orocos Real-Time Toolkit  2.9.0
BindStorage.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: FMTC do nov 2 13:06:12 CET 2006 BindStorage.hpp
3 
4  BindStorage.hpp - description
5  -------------------
6  begin : do november 02 2006
7  copyright : (C) 2006 FMTC
8  email : peter.soetens@fmtc.be
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_TASK_BIND_STORAGE_HPP
40 #define ORO_TASK_BIND_STORAGE_HPP
41 
42 #include <boost/function.hpp>
43 #include <boost/type_traits/function_traits.hpp>
44 #include <boost/bind.hpp>
45 #include <boost/fusion/include/vector.hpp>
46 #include <boost/fusion/include/filter_if.hpp>
47 #include "NA.hpp"
48 #include "../Logger.hpp"
49 
50 #ifdef ORO_SIGNALLING_OPERATIONS
51 #include "Signal.hpp"
52 #endif
53 
54 namespace RTT
55 {
56  namespace internal
57  {
58  namespace bf=boost::fusion;
59  namespace mpl=boost::mpl;
64  template<class T>
65  struct AStore
66  {
67  typedef T arg_type;
68  T arg;
69  AStore() : arg() {}
70  AStore(T t) : arg(t) {}
71  AStore(AStore const& o) : arg(o.arg) {}
72 
73  T& get() { return arg; }
74  void operator()(T a) { arg = a; }
75  operator T&() { return arg; }
76  };
77 
78  template<class T>
79  struct AStore<T&>
80  {
81  typedef T& arg_type;
82  T* arg;
83  AStore() : arg( &NA<T&>::na() ) {}
84  AStore(T& t) : arg(&t) {}
85  AStore(AStore const& o) : arg(o.arg) {}
86 
87  T& get() { return *arg; }
88  void operator()(T& a) { arg = &a; }
89  operator T&() { return *arg; }
90  };
91 
92  template<class T>
93  std::ostream& operator<<(std::ostream& o, AStore<T>& a) { o << "aarg:"<<a.get(); return o;}
94 
95  template<>
96  struct RStore<void> {
97  bool executed;
98  bool error;
99  RStore() : executed(false), error(false) {}
100 
101  void checkError() const {
102  if(error) throw std::runtime_error("Unable to complete the operation call. The called operation has thrown an exception");
103  }
104 
105  bool isError() const {
106  return error;
107  }
108 
109  bool isExecuted() const {
110  return executed;
111  }
112 
113  template<class F>
114  void exec(F f) {
115  error = false;
116  try{
117  f();
118  } catch (std::exception& e) {
119  log(Error) << "Exception raised while executing an operation : " << e.what() << endlog();
120  error = true;
121  } catch (...) {
122  log(Error) << "Unknown exception raised while executing an operation." << endlog();
123  error = true;
124  }
125  executed = true;
126  }
127 
128  void result() { checkError(); return; }
129  };
130 
131 
139  template<class T>
140  struct RStore : public RStore<void> {
141  T arg;
142  RStore() : arg() {}
143 
144  T& result() { checkError(); return arg; }
145  operator T&() { return arg;}
146 
153  template<class F>
154  void exec(F f) {
155  error = false;
156  try{
157  arg = f();
158  } catch (std::exception& e) {
159  log(Error) << "Exception raised while executing an operation : " << e.what() << endlog();
160  error = true;
161  } catch (...) {
162  log(Error) << "Unknown exception raised while executing an operation." << endlog();
163  error = true;
164  }
165  executed = true;
166  }
167  };
168 
169  template<class T>
170  struct RStore<T&> : public RStore<void>
171  {
172  T* arg;
173  RStore() : arg() {}
174 
175  template<class F>
176  void exec(F f) {
177  error = false;
178  try{
179  arg = &f();
180  } catch (std::exception& e) {
181  log(Error) << "Exception raised while executing an operation : " << e.what() << endlog();
182  error = true;
183  } catch (...) {
184  log(Error) << "Unknown exception raised while executing an operation." << endlog();
185  error = true;
186  }
187  executed = true;
188  }
189 
190  //bool operator()() { return executed; }
191 
192  T& result() { checkError(); return *arg; }
193  operator T&() { checkError(); return *arg;}
194  };
195 
196  template<class T>
197  struct RStore<const T> : public RStore<void> {
198  T arg;
199  RStore() : arg() {}
200 
201  T& result() { checkError(); return arg; }
202  operator T&() { checkError(); return arg;}
203 
210  template<class F>
211  void exec(F f) {
212  error = false;
213  try{
214  arg = f();
215  } catch (std::exception& e) {
216  log(Error) << "Exception raised while executing an operation : " << e.what() << endlog();
217  error = true;
218  } catch(...) {
219  log(Error) << "Unknown exception raised while executing an operation." << endlog();
220  error = true;
221  }
222  executed = true;
223  }
224 
225  };
226 
227  template<class T>
228  std::ostream& operator<<(std::ostream& o, RStore<T>& a) { o << "rarg:"<<a.result(); return o;}
229 
237  template<class Arg>
238  struct is_arg_return : public mpl::false_ {};
239 
240  template<class T>
241  struct is_arg_return<AStore<T&> > : public mpl::true_
242  {};
243 
244  template<class T>
245  struct is_arg_return<AStore<T const &> > : public mpl::false_
246  {};
247 
248  template<>
249  struct is_arg_return<RStore<void> > : public mpl::false_
250  {};
251 
252  template<class T>
253  struct is_arg_return<RStore<T> > : public mpl::true_
254  {};
255 
259  template<class Arg>
260  struct is_out_arg : public mpl::false_ {};
261 
262  template<class T>
263  struct is_out_arg<AStore<T&> > : public mpl::true_
264  {};
265 
266  template<class T>
267  struct is_out_arg<AStore<T const &> > : public mpl::false_
268  {};
269 
270  template<int, class T>
272 
277  template<class ToBind>
278  struct BindStorageImpl<0, ToBind>
279  {
280  typedef typename boost::function_traits<ToBind>::result_type result_type;
282 
283  // stores the original function pointer
284  boost::function<ToBind> mmeth;
286  // the list of all our storage.
287  bf::vector< RStore<result_type>&> vStore;
288 #ifdef ORO_SIGNALLING_OPERATIONS
289  typename Signal<ToBind>::shared_ptr msig;
290 #endif
291 
292  BindStorageImpl() : vStore(retv) {}
293  BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv)
295  , msig(orig.msig)
296 #endif
297  {}
298 
299  void exec() {
300 #ifdef ORO_SIGNALLING_OPERATIONS
301  if (msig) msig->emit();
302 #endif
303  if (mmeth)
304  retv.exec( mmeth );
305  else
306  retv.executed = true;
307  }
308  };
309 
313  template<class ToBind>
314  struct BindStorageImpl<1, ToBind>
315  {
316  typedef typename boost::function_traits<ToBind>::result_type result_type;
317  typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
319 
320  // stores the original function pointer, supplied by the user.
321  boost::function<ToBind> mmeth;
322  // Store the argument.
325  // the list of all our storage.
326  bf::vector< RStore<result_type>&, AStore<arg1_type>& > vStore;
327 #ifdef ORO_SIGNALLING_OPERATIONS
328  typename Signal<ToBind>::shared_ptr msig;
329 #endif
330 
331  BindStorageImpl() : vStore(retv,a1) {}
332  BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1)
334  , msig(orig.msig)
335 #endif
336  {}
337  void store(arg1_type t1) { a1(t1); }
338  void exec() {
339 #ifdef ORO_SIGNALLING_OPERATIONS
340  if (msig) (*msig)(a1);
341 #endif
342  if (mmeth)
343  retv.exec( boost::bind(mmeth, a1 ) );
344  else
345  retv.executed = true;
346  }
347 
348  };
349 
350  template<class ToBind>
351  struct BindStorageImpl<2, ToBind>
352  {
353  typedef typename boost::function_traits<ToBind>::result_type result_type;
354  typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
355  typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
357 
358  // stores the original function pointer
359  boost::function<ToBind> mmeth;
360  // Store the arguments.
364  // the list of all our storage.
365  bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>& > vStore;
366 #ifdef ORO_SIGNALLING_OPERATIONS
367  typename Signal<ToBind>::shared_ptr msig;
368 #endif
369 
370  BindStorageImpl() : vStore(retv,a1,a2) {}
371  BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2)
373  , msig(orig.msig)
374 #endif
375  {}
376 
377  void store(arg1_type t1, arg2_type t2) { a1(t1); a2(t2); }
378  void exec() {
379 #ifdef ORO_SIGNALLING_OPERATIONS
380  if (msig) (*msig)(a1, a2);
381 #endif
382  if (mmeth)
383  retv.exec( boost::bind(mmeth, a1, a2 ) );
384  else
385  retv.executed = true;
386  }
387 
388  };
389 
390  template<class ToBind>
391  struct BindStorageImpl<3, ToBind>
392  {
393  typedef typename boost::function_traits<ToBind>::result_type result_type;
394  typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
395  typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
396  typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
398 
399  // stores the original function pointer
400  boost::function<ToBind> mmeth;
401  // Store the arguments.
406  // the list of all our storage.
407  bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>& > vStore;
408 #ifdef ORO_SIGNALLING_OPERATIONS
409  typename Signal<ToBind>::shared_ptr msig;
410 #endif
411 
412  BindStorageImpl() : vStore(retv,a1,a2,a3) {}
413  BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3)
415  , msig(orig.msig)
416 #endif
417  {}
418 
419  void store(arg1_type t1, arg2_type t2, arg3_type t3) { a1(t1); a2(t2); a3(t3); }
420  void exec() {
421 #ifdef ORO_SIGNALLING_OPERATIONS
422  if (msig) (*msig)(a1, a2, a3);
423 #endif
424  if (mmeth)
425  retv.exec( boost::bind(mmeth, a1, a2, a3 ) );
426  else
427  retv.executed = true;
428  }
429  };
430 
431  template<class ToBind>
432  struct BindStorageImpl<4, ToBind>
433  {
434  typedef typename boost::function_traits<ToBind>::result_type result_type;
435  typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
436  typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
437  typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
438  typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
440 
441  // stores the original function pointer
442  boost::function<ToBind> mmeth;
443  // Store the arguments.
449  // the list of all our storage.
451 #ifdef ORO_SIGNALLING_OPERATIONS
452  typename Signal<ToBind>::shared_ptr msig;
453 #endif
454 
455  BindStorageImpl() : vStore(retv,a1,a2,a3,a4) {}
456  BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4)
458  , msig(orig.msig)
459 #endif
460  {}
461 
462  void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4) { a1(t1); a2(t2); a3(t3); a4(t4); }
463  void exec() {
464 #ifdef ORO_SIGNALLING_OPERATIONS
465  if (msig) (*msig)(a1, a2, a3, a4);
466 #endif
467  if (mmeth)
468  retv.exec( boost::bind( mmeth, a1, a2, a3, a4 ) );
469  else
470  retv.executed = true;
471  }
472  };
473 
474  template<class ToBind>
475  struct BindStorageImpl<5, ToBind>
476  {
477  typedef typename boost::function_traits<ToBind>::result_type result_type;
478  typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
479  typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
480  typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
481  typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
482  typedef typename boost::function_traits<ToBind>::arg5_type arg5_type;
484 
485  // stores the original function pointer
486  boost::function<ToBind> mmeth;
487  // Store the arguments.
494  // the list of all our storage.
496 #ifdef ORO_SIGNALLING_OPERATIONS
497  typename Signal<ToBind>::shared_ptr msig;
498 #endif
499 
500  BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5) {}
501  BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5)
503  , msig(orig.msig)
504 #endif
505  {}
506 
507  void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5) { a1(t1); a2(t2); a3(t3); a4(t4); a5(t5);}
508  void exec() {
509 #ifdef ORO_SIGNALLING_OPERATIONS
510  if (msig) (*msig)(a1, a2, a3, a4, a5);
511 #endif
512  if (mmeth)
513  retv.exec( boost::bind( mmeth, a1, a2, a3, a4, a5 ) );
514  else
515  retv.executed = true;
516  }
517  };
518 
519  template<class ToBind>
520  struct BindStorageImpl<6, ToBind>
521  {
522  typedef typename boost::function_traits<ToBind>::result_type result_type;
523  typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
524  typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
525  typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
526  typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
527  typedef typename boost::function_traits<ToBind>::arg5_type arg5_type;
528  typedef typename boost::function_traits<ToBind>::arg6_type arg6_type;
530 
531  // stores the original function pointer
532  boost::function<ToBind> mmeth;
533  // Store the arguments.
541  // the list of all our storage.
543 #ifdef ORO_SIGNALLING_OPERATIONS
544  typename Signal<ToBind>::shared_ptr msig;
545 #endif
546 
547  BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5,a6) {}
548  BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5,a6)
550  , msig(orig.msig)
551 #endif
552  {}
553 
554  void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5, arg6_type t6) { a1(t1); a2(t2); a3(t3); a4(t4); a5(t5); a6(t6);}
555  void exec() {
556 #ifdef ORO_SIGNALLING_OPERATIONS
557  if (msig) (*msig)(a1, a2, a3, a4, a5, a6);
558 #endif
559  if (mmeth)
560  retv.exec( boost::bind( mmeth, a1, a2, a3, a4, a5, a6 ) );
561  else
562  retv.executed = true;
563  }
564  };
565 
566  template<class ToBind>
567  struct BindStorageImpl<7, ToBind>
568  {
569  typedef typename boost::function_traits<ToBind>::result_type result_type;
570  typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
571  typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
572  typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
573  typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
574  typedef typename boost::function_traits<ToBind>::arg5_type arg5_type;
575  typedef typename boost::function_traits<ToBind>::arg6_type arg6_type;
576  typedef typename boost::function_traits<ToBind>::arg7_type arg7_type;
578 
579  // stores the original function pointer
580  boost::function<ToBind> mmeth;
581  // Store the arguments.
590  // the list of all our storage.
592 #ifdef ORO_SIGNALLING_OPERATIONS
593  typename Signal<ToBind>::shared_ptr msig;
594 #endif
595 
596  BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5,a6,a7) {}
597  BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5,a6,a7)
599  , msig(orig.msig)
600 #endif
601  {}
602 
603  void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5, arg6_type t6, arg7_type t7) { a1(t1); a2(t2); a3(t3); a4(t4); a5(t5); a6(t6); a7(t7);}
604  void exec() {
605 #ifdef ORO_SIGNALLING_OPERATIONS
606  if (msig) (*msig)(a1, a2, a3, a4, a5, a6, a7);
607 #endif
608  if (mmeth)
609  retv.exec( boost::bind( mmeth, a1, a2, a3, a4, a5, a6, a7 ) );
610  else
611  retv.executed = true;
612  }
613  };
614 
615 
634  template<class ToBind>
635  struct BindStorage
636  : public BindStorageImpl<boost::function_traits<ToBind>::arity, ToBind>
637  {
638  };
639  }
640 }
641 #endif
bf::vector< RStore< result_type > &, AStore< arg1_type > & > vStore
bf::vector< RStore< result_type > &, AStore< arg1_type > &, AStore< arg2_type > &, AStore< arg3_type > &, AStore< arg4_type > &, AStore< arg5_type > & > vStore
boost::function_traits< ToBind >::arg2_type arg2_type
boost::function_traits< ToBind >::arg5_type arg5_type
boost::function_traits< ToBind >::arg5_type arg5_type
BindStorageImpl(const BindStorageImpl &orig)
boost::function_traits< ToBind >::result_type result_type
boost::function_traits< ToBind >::arg3_type arg3_type
boost::function_traits< ToBind >::arg1_type arg1_type
void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5, arg6_type t6, arg7_type t7)
boost::function_traits< ToBind >::arg1_type arg1_type
boost::function_traits< ToBind >::result_type result_type
bf::vector< RStore< result_type > &, AStore< arg1_type > &, AStore< arg2_type > &, AStore< arg3_type > &, AStore< arg4_type > & > vStore
void store(arg1_type t1, arg2_type t2, arg3_type t3)
Store a bound argument which may be a reference, const reference or any other type.
Definition: BindStorage.hpp:65
bf::vector< RStore< result_type > &, AStore< arg1_type > &, AStore< arg2_type > & > vStore
void exec(F f)
Stores the result of a function.
bf::vector< RStore< result_type > &, AStore< arg1_type > &, AStore< arg2_type > &, AStore< arg3_type > & > vStore
boost::function_traits< ToBind >::result_type result_type
boost::function_traits< ToBind >::arg2_type arg2_type
bf::vector< RStore< result_type > & > vStore
void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5, arg6_type t6)
boost::function_traits< ToBind >::arg6_type arg6_type
boost::function_traits< ToBind >::arg2_type arg2_type
BindStorageImpl(const BindStorageImpl &orig)
boost::function_traits< ToBind >::arg4_type arg4_type
boost::function_traits< ToBind >::arg4_type arg4_type
boost::function_traits< ToBind >::arg3_type arg3_type
boost::function_traits< ToBind >::result_type result_type
bf::vector< RStore< result_type > &, AStore< arg1_type > &, AStore< arg2_type > &, AStore< arg3_type > &, AStore< arg4_type > &, AStore< arg5_type > &, AStore< arg6_type > & > vStore
BindStorageImpl(const BindStorageImpl &orig)
boost::function_traits< ToBind >::arg1_type arg1_type
Store a return value which may be a void, reference, const reference or any other type...
boost::function_traits< ToBind >::result_type result_type
BindStorageImpl(const BindStorageImpl &orig)
A helper-class for the Command implementation which stores the command and collition function objects...
void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4)
#define ORO_SIGNALLING_OPERATIONS
boost::function_traits< ToBind >::arg7_type arg7_type
void store(arg1_type t1, arg2_type t2)
boost::function_traits< ToBind >::arg1_type arg1_type
boost::function_traits< ToBind >::arg3_type arg3_type
boost::shared_ptr< Signal< Signature, TSlotFunction > > shared_ptr
Definition: Signal.hpp:215
bf::vector< RStore< result_type > &, AStore< arg1_type > &, AStore< arg2_type > &, AStore< arg3_type > &, AStore< arg4_type > &, AStore< arg5_type > &, AStore< arg6_type > &, AStore< arg7_type > & > vStore
boost::function_traits< ToBind >::arg1_type arg1_type
BindStorageImpl(const BindStorageImpl &orig)
void exec(F f)
Stores the result of a function.
boost::function_traits< ToBind >::arg5_type arg5_type
boost::function_traits< ToBind >::arg4_type arg4_type
Outargs are of type AStore and contain a pure reference.
This class is used to return a &#39;default&#39; value when no value is available (&#39;Not Available&#39;).
Definition: NA.hpp:53
boost::function_traits< ToBind >::arg1_type arg1_type
boost::function_traits< ToBind >::arg6_type arg6_type
BindStorageImpl(const BindStorageImpl &orig)
void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5)
boost::function_traits< ToBind >::arg2_type arg2_type
BindStorageImpl(const BindStorageImpl &orig)
AStore(AStore const &o)
Definition: BindStorage.hpp:71
boost::function_traits< ToBind >::arg4_type arg4_type
boost::function_traits< ToBind >::arg1_type arg1_type
boost::function_traits< ToBind >::arg3_type arg3_type
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
boost::function_traits< ToBind >::result_type result_type
This helper struct is required to filter out the AStore elements that don&#39;t need to be returned to th...
boost::function_traits< ToBind >::result_type result_type
boost::function_traits< ToBind >::arg3_type arg3_type
boost::function_traits< ToBind >::arg2_type arg2_type
boost::function_traits< ToBind >::result_type result_type
boost::function_traits< ToBind >::arg2_type arg2_type
BindStorageImpl(const BindStorageImpl &orig)