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_TASK_BIND_STORAGE_HPP
00040 #define ORO_TASK_BIND_STORAGE_HPP
00041
00042 #include <boost/function.hpp>
00043 #include <boost/type_traits/function_traits.hpp>
00044 #include <boost/bind.hpp>
00045 #include <boost/fusion/include/vector.hpp>
00046 #include <boost/fusion/include/filter_if.hpp>
00047 #include "NA.hpp"
00048 #include "../Logger.hpp"
00049
00050 #ifdef ORO_SIGNALLING_OPERATIONS
00051 #include "Signal.hpp"
00052 #endif
00053
00054 namespace RTT
00055 {
00056 namespace internal
00057 {
00058 namespace bf=boost::fusion;
00059 namespace mpl=boost::mpl;
00064 template<class T>
00065 struct AStore
00066 {
00067 T arg;
00068 AStore() : arg() {}
00069 AStore(T t) : arg(t) {}
00070 AStore(AStore const& o) : arg(o.arg) {}
00071
00072 T& get() { return arg; }
00073 void operator()(T a) { arg = a; }
00074 operator T() { return arg;}
00075 };
00076
00077 template<class T>
00078 struct AStore<T&>
00079 {
00080 T* arg;
00081 AStore() : arg( &NA<T&>::na() ) {}
00082 AStore(T& t) : arg(&t) {}
00083 AStore(AStore const& o) : arg(o.arg) {}
00084
00085 T& get() { return *arg; }
00086 void operator()(T& a) { arg = &a; }
00087 operator T&() { return *arg;}
00088 };
00089
00090 template<class T>
00091 std::ostream& operator<<(std::ostream& o, AStore<T>& a) { o << "aarg:"<<a.get(); return o;}
00092
00093 template<>
00094 struct RStore<void> {
00095 bool executed;
00096 bool error;
00097 RStore() : executed(false), error(false) {}
00098
00099 void checkError() const {
00100 if(error) throw std::runtime_error("Unable to complete the operation call. The called operation has thrown an exception");
00101 }
00102
00103 bool isError() const {
00104 return error;
00105 }
00106
00107 bool isExecuted() const {
00108 return executed;
00109 }
00110
00111 template<class F>
00112 void exec(F f) {
00113 error = false;
00114 try{
00115 f();
00116 } catch (std::exception& e) {
00117 log(Error) << "Exception raised while executing an operation : " << e.what() << endlog();
00118 error = true;
00119 } catch (...) {
00120 log(Error) << "Unknown exception raised while executing an operation." << endlog();
00121 error = true;
00122 }
00123 executed = true;
00124 }
00125
00126 void result() { checkError(); return; }
00127 };
00128
00129
00137 template<class T>
00138 struct RStore : public RStore<void> {
00139 T arg;
00140 RStore() : arg() {}
00141
00142 T& result() { checkError(); return arg; }
00143 operator T&() { return arg;}
00144
00151 template<class F>
00152 void exec(F f) {
00153 error = false;
00154 try{
00155 arg = f();
00156 } catch (std::exception& e) {
00157 log(Error) << "Exception raised while executing an operation : " << e.what() << endlog();
00158 error = true;
00159 } catch (...) {
00160 log(Error) << "Unknown exception raised while executing an operation." << endlog();
00161 error = true;
00162 }
00163 executed = true;
00164 }
00165 };
00166
00167 template<class T>
00168 struct RStore<T&> : public RStore<void>
00169 {
00170 T* arg;
00171 RStore() : arg() {}
00172
00173 template<class F>
00174 void exec(F f) {
00175 error = false;
00176 try{
00177 arg = &f();
00178 } catch (std::exception& e) {
00179 log(Error) << "Exception raised while executing an operation : " << e.what() << endlog();
00180 error = true;
00181 } catch (...) {
00182 log(Error) << "Unknown exception raised while executing an operation." << endlog();
00183 error = true;
00184 }
00185 executed = true;
00186 }
00187
00188
00189
00190 T& result() { checkError(); return *arg; }
00191 operator T&() { checkError(); return *arg;}
00192 };
00193
00194 template<class T>
00195 struct RStore<const T> : public RStore<void> {
00196 T arg;
00197 RStore() : arg() {}
00198
00199 T& result() { checkError(); return arg; }
00200 operator T&() { checkError(); return arg;}
00201
00208 template<class F>
00209 void exec(F f) {
00210 error = false;
00211 try{
00212 arg = f();
00213 } catch (std::exception& e) {
00214 log(Error) << "Exception raised while executing an operation : " << e.what() << endlog();
00215 error = true;
00216 } catch(...) {
00217 log(Error) << "Unknown exception raised while executing an operation." << endlog();
00218 error = true;
00219 }
00220 executed = true;
00221 }
00222
00223 };
00224
00225 template<class T>
00226 std::ostream& operator<<(std::ostream& o, RStore<T>& a) { o << "rarg:"<<a.result(); return o;}
00227
00235 template<class Arg>
00236 struct is_arg_return : public mpl::false_ {};
00237
00238 template<class T>
00239 struct is_arg_return<AStore<T&> > : public mpl::true_
00240 {};
00241
00242 template<class T>
00243 struct is_arg_return<AStore<T const &> > : public mpl::false_
00244 {};
00245
00246 template<>
00247 struct is_arg_return<RStore<void> > : public mpl::false_
00248 {};
00249
00250 template<class T>
00251 struct is_arg_return<RStore<T> > : public mpl::true_
00252 {};
00253
00257 template<class Arg>
00258 struct is_out_arg : public mpl::false_ {};
00259
00260 template<class T>
00261 struct is_out_arg<AStore<T&> > : public mpl::true_
00262 {};
00263
00264 template<class T>
00265 struct is_out_arg<AStore<T const &> > : public mpl::false_
00266 {};
00267
00268 template<int, class T>
00269 struct BindStorageImpl;
00270
00275 template<class ToBind>
00276 struct BindStorageImpl<0, ToBind>
00277 {
00278 typedef typename boost::function_traits<ToBind>::result_type result_type;
00279 typedef RStore<result_type> RStoreType;
00280
00281
00282 boost::function<ToBind> mmeth;
00283 mutable RStore<result_type> retv;
00284
00285 bf::vector< RStore<result_type>&> vStore;
00286 #ifdef ORO_SIGNALLING_OPERATIONS
00287 typename Signal<ToBind>::shared_ptr msig;
00288 #endif
00289
00290 BindStorageImpl() : vStore(boost::ref(retv)) {}
00291 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv)
00292 #ifdef ORO_SIGNALLING_OPERATIONS
00293 , msig(orig.msig)
00294 #endif
00295 {}
00296
00297 void exec() {
00298 #ifdef ORO_SIGNALLING_OPERATIONS
00299 if (msig) msig->emit();
00300 #endif
00301 if (mmeth)
00302 retv.exec( mmeth );
00303 else
00304 retv.executed = true;
00305 }
00306 };
00307
00311 template<class ToBind>
00312 struct BindStorageImpl<1, ToBind>
00313 {
00314 typedef typename boost::function_traits<ToBind>::result_type result_type;
00315 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00316 typedef RStore<result_type> RStoreType;
00317
00318
00319 boost::function<ToBind> mmeth;
00320
00321 mutable AStore<arg1_type> a1;
00322 mutable RStore<result_type> retv;
00323
00324 bf::vector< RStore<result_type>&, AStore<arg1_type>& > vStore;
00325 #ifdef ORO_SIGNALLING_OPERATIONS
00326 typename Signal<ToBind>::shared_ptr msig;
00327 #endif
00328
00329 BindStorageImpl() : vStore(retv,a1) {}
00330 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1)
00331 #ifdef ORO_SIGNALLING_OPERATIONS
00332 , msig(orig.msig)
00333 #endif
00334 {}
00335 void store(arg1_type t1) { a1(t1); }
00336 void exec() {
00337 #ifdef ORO_SIGNALLING_OPERATIONS
00338 if (msig) (*msig)(a1.get());
00339 #endif
00340 if (mmeth)
00341 retv.exec( boost::bind(mmeth, boost::ref(a1.get()) ) );
00342 else
00343 retv.executed = true;
00344 }
00345
00346 };
00347
00348 template<class ToBind>
00349 struct BindStorageImpl<2, ToBind>
00350 {
00351 typedef typename boost::function_traits<ToBind>::result_type result_type;
00352 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00353 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00354 typedef RStore<result_type> RStoreType;
00355
00356
00357 boost::function<ToBind> mmeth;
00358
00359 mutable AStore<arg1_type> a1;
00360 mutable AStore<arg2_type> a2;
00361 mutable RStore<result_type> retv;
00362
00363 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>& > vStore;
00364 #ifdef ORO_SIGNALLING_OPERATIONS
00365 typename Signal<ToBind>::shared_ptr msig;
00366 #endif
00367
00368 BindStorageImpl() : vStore(retv,a1,a2) {}
00369 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2)
00370 #ifdef ORO_SIGNALLING_OPERATIONS
00371 , msig(orig.msig)
00372 #endif
00373 {}
00374
00375 void store(arg1_type t1, arg2_type t2) { a1(t1); a2(t2); }
00376 void exec() {
00377 #ifdef ORO_SIGNALLING_OPERATIONS
00378 if (msig) (*msig)(a1.get(), a2.get());
00379 #endif
00380 if (mmeth)
00381 retv.exec( boost::bind(mmeth, boost::ref(a1.get()), boost::ref(a2.get()) ) );
00382 else
00383 retv.executed = true;
00384 }
00385
00386 };
00387
00388 template<class ToBind>
00389 struct BindStorageImpl<3, ToBind>
00390 {
00391 typedef typename boost::function_traits<ToBind>::result_type result_type;
00392 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00393 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00394 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00395 typedef RStore<result_type> RStoreType;
00396
00397
00398 boost::function<ToBind> mmeth;
00399
00400 mutable AStore<arg1_type> a1;
00401 mutable AStore<arg2_type> a2;
00402 mutable AStore<arg3_type> a3;
00403 mutable RStore<result_type> retv;
00404
00405 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>& > vStore;
00406 #ifdef ORO_SIGNALLING_OPERATIONS
00407 typename Signal<ToBind>::shared_ptr msig;
00408 #endif
00409
00410 BindStorageImpl() : vStore(retv,a1,a2,a3) {}
00411 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3)
00412 #ifdef ORO_SIGNALLING_OPERATIONS
00413 , msig(orig.msig)
00414 #endif
00415 {}
00416
00417 void store(arg1_type t1, arg2_type t2, arg3_type t3) { a1(t1); a2(t2); a3(t3); }
00418 void exec() {
00419 #ifdef ORO_SIGNALLING_OPERATIONS
00420 if (msig) (*msig)(a1.get(), a2.get(), a3.get());
00421 #endif
00422 if (mmeth)
00423 retv.exec( boost::bind(mmeth, boost::ref(a1.get()), boost::ref(a2.get()), boost::ref(a3.get()) ) );
00424 else
00425 retv.executed = true;
00426 }
00427 };
00428
00429 template<class ToBind>
00430 struct BindStorageImpl<4, ToBind>
00431 {
00432 typedef typename boost::function_traits<ToBind>::result_type result_type;
00433 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00434 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00435 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00436 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
00437 typedef RStore<result_type> RStoreType;
00438
00439
00440 boost::function<ToBind> mmeth;
00441
00442 mutable AStore<arg1_type> a1;
00443 mutable AStore<arg2_type> a2;
00444 mutable AStore<arg3_type> a3;
00445 mutable AStore<arg4_type> a4;
00446 mutable RStore<result_type> retv;
00447
00448 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>&, AStore<arg4_type>& > vStore;
00449 #ifdef ORO_SIGNALLING_OPERATIONS
00450 typename Signal<ToBind>::shared_ptr msig;
00451 #endif
00452
00453 BindStorageImpl() : vStore(retv,a1,a2,a3,a4) {}
00454 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4)
00455 #ifdef ORO_SIGNALLING_OPERATIONS
00456 , msig(orig.msig)
00457 #endif
00458 {}
00459
00460 void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4) { a1(t1); a2(t2); a3(t3); a4(t4); }
00461 void exec() {
00462 #ifdef ORO_SIGNALLING_OPERATIONS
00463 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get());
00464 #endif
00465 if (mmeth)
00466 retv.exec( boost::bind( mmeth, boost::ref(a1.get()), boost::ref(a2.get()), boost::ref(a3.get()), boost::ref(a4.get()) ) );
00467 else
00468 retv.executed = true;
00469 }
00470 };
00471
00472 template<class ToBind>
00473 struct BindStorageImpl<5, ToBind>
00474 {
00475 typedef typename boost::function_traits<ToBind>::result_type result_type;
00476 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00477 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00478 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00479 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
00480 typedef typename boost::function_traits<ToBind>::arg5_type arg5_type;
00481 typedef RStore<result_type> RStoreType;
00482
00483
00484 boost::function<ToBind> mmeth;
00485
00486 mutable AStore<arg1_type> a1;
00487 mutable AStore<arg2_type> a2;
00488 mutable AStore<arg3_type> a3;
00489 mutable AStore<arg4_type> a4;
00490 mutable AStore<arg5_type> a5;
00491 mutable RStore<result_type> retv;
00492
00493 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>&, AStore<arg4_type>&, AStore<arg5_type>& > vStore;
00494 #ifdef ORO_SIGNALLING_OPERATIONS
00495 typename Signal<ToBind>::shared_ptr msig;
00496 #endif
00497
00498 BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5) {}
00499 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5)
00500 #ifdef ORO_SIGNALLING_OPERATIONS
00501 , msig(orig.msig)
00502 #endif
00503 {}
00504
00505 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);}
00506 void exec() {
00507 #ifdef ORO_SIGNALLING_OPERATIONS
00508 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get(), a5.get());
00509 #endif
00510 if (mmeth)
00511 retv.exec( boost::bind( mmeth, boost::ref(a1.get()), boost::ref(a2.get()), boost::ref(a3.get()), boost::ref(a4.get()), boost::ref(a5.get()) ) );
00512 else
00513 retv.executed = true;
00514 }
00515 };
00516
00517 template<class ToBind>
00518 struct BindStorageImpl<6, ToBind>
00519 {
00520 typedef typename boost::function_traits<ToBind>::result_type result_type;
00521 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00522 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00523 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00524 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
00525 typedef typename boost::function_traits<ToBind>::arg5_type arg5_type;
00526 typedef typename boost::function_traits<ToBind>::arg6_type arg6_type;
00527 typedef RStore<result_type> RStoreType;
00528
00529
00530 boost::function<ToBind> mmeth;
00531
00532 mutable AStore<arg1_type> a1;
00533 mutable AStore<arg2_type> a2;
00534 mutable AStore<arg3_type> a3;
00535 mutable AStore<arg4_type> a4;
00536 mutable AStore<arg5_type> a5;
00537 mutable AStore<arg6_type> a6;
00538 mutable RStore<result_type> retv;
00539
00540 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>&, AStore<arg4_type>&, AStore<arg5_type>&, AStore<arg6_type>& > vStore;
00541 #ifdef ORO_SIGNALLING_OPERATIONS
00542 typename Signal<ToBind>::shared_ptr msig;
00543 #endif
00544
00545 BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5,a6) {}
00546 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5,a6)
00547 #ifdef ORO_SIGNALLING_OPERATIONS
00548 , msig(orig.msig)
00549 #endif
00550 {}
00551
00552 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);}
00553 void exec() {
00554 #ifdef ORO_SIGNALLING_OPERATIONS
00555 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get(), a5.get(), a6.get());
00556 #endif
00557 if (mmeth)
00558 retv.exec( boost::bind( mmeth, boost::ref(a1.get()), boost::ref(a2.get()), boost::ref(a3.get()), boost::ref(a4.get()), boost::ref(a5.get()), boost::ref(a6.get()) ) );
00559 else
00560 retv.executed = true;
00561 }
00562 };
00563
00564 template<class ToBind>
00565 struct BindStorageImpl<7, ToBind>
00566 {
00567 typedef typename boost::function_traits<ToBind>::result_type result_type;
00568 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00569 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00570 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00571 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
00572 typedef typename boost::function_traits<ToBind>::arg5_type arg5_type;
00573 typedef typename boost::function_traits<ToBind>::arg6_type arg6_type;
00574 typedef typename boost::function_traits<ToBind>::arg7_type arg7_type;
00575 typedef RStore<result_type> RStoreType;
00576
00577
00578 boost::function<ToBind> mmeth;
00579
00580 mutable AStore<arg1_type> a1;
00581 mutable AStore<arg2_type> a2;
00582 mutable AStore<arg3_type> a3;
00583 mutable AStore<arg4_type> a4;
00584 mutable AStore<arg5_type> a5;
00585 mutable AStore<arg6_type> a6;
00586 mutable AStore<arg7_type> a7;
00587 mutable RStore<result_type> retv;
00588
00589 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;
00590 #ifdef ORO_SIGNALLING_OPERATIONS
00591 typename Signal<ToBind>::shared_ptr msig;
00592 #endif
00593
00594 BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5,a6,a7) {}
00595 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5,a6,a7)
00596 #ifdef ORO_SIGNALLING_OPERATIONS
00597 , msig(orig.msig)
00598 #endif
00599 {}
00600
00601 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);}
00602 void exec() {
00603 #ifdef ORO_SIGNALLING_OPERATIONS
00604 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get(), a5.get(), a6.get(), a7.get());
00605 #endif
00606 if (mmeth)
00607 retv.exec( boost::bind( mmeth, boost::ref(a1.get()), boost::ref(a2.get()), boost::ref(a3.get()), boost::ref(a4.get()), boost::ref(a5.get()), boost::ref(a6.get()), boost::ref(a7.get()) ) );
00608 else
00609 retv.executed = true;
00610 }
00611 };
00612
00613
00632 template<class ToBind>
00633 struct BindStorage
00634 : public BindStorageImpl<boost::function_traits<ToBind>::arity, ToBind>
00635 {
00636 };
00637 }
00638 }
00639 #endif