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