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
00048 #include "Signal.hpp"
00049
00050 namespace RTT
00051 {
00052 namespace internal
00053 {
00054 namespace bf=boost::fusion;
00055 namespace mpl=boost::mpl;
00060 template<class T>
00061 struct AStore
00062 {
00063 T arg;
00064 AStore() : arg() {}
00065 AStore(T t) : arg(t) {}
00066 AStore(AStore const& o) : arg(o.arg) {}
00067
00068 T& get() { return arg; }
00069 void operator()(T a) { arg = a; }
00070
00071 operator T() { return arg;}
00072 };
00073
00074 template<class T>
00075 struct AStore<T&>
00076 {
00077 T* arg;
00078 AStore() : arg( &NA<T&>::na() ) {}
00079 AStore(T& t) : arg(&t) {}
00080 AStore(AStore const& o) : arg(o.arg) {}
00081
00082 T& get() { return *arg; }
00083 void operator()(T& a) { arg = &a; }
00084
00085 operator T&() { return *arg;}
00086 };
00087
00088 template<class T>
00089 std::ostream& operator<<(std::ostream& o, AStore<T>& a) { o << "aarg:"<<a.get(); return o;}
00090
00098 template<class T>
00099 struct RStore {
00100 T arg;
00101 bool executed;
00102 RStore() : arg(), executed(false) {}
00103
00104 bool isExecuted() const {
00105 return executed;
00106 }
00107
00108
00109
00110 T& result() { return arg; }
00111 operator T&() { return arg;}
00112
00119 template<class F>
00120 void exec(F f) {
00121 arg = f();
00122 executed = true;
00123 }
00124
00125 };
00126
00127 template<class T>
00128 struct RStore<T&>
00129 {
00130 T* arg;
00131 bool executed;
00132 RStore() : arg(0), executed(false) {}
00133
00134 template<class F>
00135 void exec(F f) {
00136 arg = &f();
00137 executed = true;
00138 }
00139
00140 bool isExecuted() const {
00141 return executed;
00142 }
00143
00144
00145
00146 T& result() { return *arg; }
00147 operator T&() { return *arg;}
00148 };
00149
00150 template<class T>
00151 struct RStore<const T> {
00152 T arg;
00153 bool executed;
00154 RStore() : arg(), executed(false) {}
00155
00156 bool isExecuted() const {
00157 return executed;
00158 }
00159
00160
00161
00162 T& result() { return arg; }
00163 operator T&() { return arg;}
00164
00171 template<class F>
00172 void exec(F f) {
00173 arg = f();
00174 executed = true;
00175 }
00176
00177 };
00178
00179 template<>
00180 struct RStore<void> {
00181 bool executed;
00182 RStore() :executed(false) {}
00183
00184 template<class F>
00185 void exec(F f) {
00186 f();
00187 executed = true;
00188 }
00189
00190 bool isExecuted() const {
00191 return executed;
00192 }
00193
00194
00195
00196 void result() { return; }
00197 };
00198
00199 template<class T>
00200 std::ostream& operator<<(std::ostream& o, RStore<T>& a) { o << "rarg:"<<a.result(); return o;}
00201
00209 template<class Arg>
00210 struct is_arg_return : public mpl::false_ {};
00211
00212 template<class T>
00213 struct is_arg_return<AStore<T&> > : public mpl::true_
00214 {};
00215
00216 template<class T>
00217 struct is_arg_return<AStore<T const &> > : public mpl::false_
00218 {};
00219
00220 template<>
00221 struct is_arg_return<RStore<void> > : public mpl::false_
00222 {};
00223
00224 template<class T>
00225 struct is_arg_return<RStore<T> > : public mpl::true_
00226 {};
00227
00231 template<class Arg>
00232 struct is_out_arg : public mpl::false_ {};
00233
00234 template<class T>
00235 struct is_out_arg<AStore<T&> > : public mpl::true_
00236 {};
00237
00238 template<class T>
00239 struct is_out_arg<AStore<T const &> > : public mpl::false_
00240 {};
00241
00242 template<int, class T>
00243 struct BindStorageImpl;
00244
00249 template<class ToBind>
00250 struct BindStorageImpl<0, ToBind>
00251 {
00252 typedef typename boost::function_traits<ToBind>::result_type result_type;
00253 typedef RStore<result_type> RStoreType;
00254
00255 boost::function<ToBind> mmeth;
00256
00257 mutable RStore<result_type> retv;
00258 typename Signal<ToBind>::shared_ptr msig;
00259
00260
00261
00262
00263 bf::vector< RStore<result_type>&> vStore;
00264 BindStorageImpl() : vStore(boost::ref(retv)) {}
00265 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv) {}
00266
00267 void exec() {
00268 if (msig) msig->emit();
00269 if (mmeth)
00270 retv.exec( mmeth );
00271 else
00272 retv.executed = true;
00273 }
00274 };
00275
00279 template<class ToBind>
00280 struct BindStorageImpl<1, ToBind>
00281 {
00282 typedef typename boost::function_traits<ToBind>::result_type result_type;
00283 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00284 typedef RStore<result_type> RStoreType;
00285
00286
00287 boost::function<ToBind> mmeth;
00288
00289 mutable AStore<arg1_type> a1;
00290 mutable RStore<result_type> retv;
00291 typename Signal<ToBind>::shared_ptr msig;
00292
00293
00294 bf::vector< RStore<result_type>&, AStore<arg1_type>& > vStore;
00295 BindStorageImpl() : vStore(retv,a1) {}
00296 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1) {}
00297 void store(arg1_type t1) { a1(t1); }
00298 void exec() {
00299 if (msig) (*msig)(a1.get());
00300 if (mmeth)
00301 retv.exec( boost::bind(mmeth, boost::ref(a1.get()) ) );
00302 else
00303 retv.executed = true;
00304 }
00305
00306 };
00307
00308 template<class ToBind>
00309 struct BindStorageImpl<2, ToBind>
00310 {
00311 typedef typename boost::function_traits<ToBind>::result_type result_type;
00312 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00313 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00314 typedef RStore<result_type> RStoreType;
00315
00316
00317 boost::function<ToBind> mmeth;
00318
00319 mutable AStore<arg1_type> a1;
00320 mutable AStore<arg2_type> a2;
00321 mutable RStore<result_type> retv;
00322 typename Signal<ToBind>::shared_ptr msig;
00323
00324
00325 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>& > vStore;
00326 BindStorageImpl() : vStore(retv,a1,a2) {}
00327 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2) {}
00328
00329 void store(arg1_type t1, arg2_type t2) { a1(t1); a2(t2); }
00330 void exec() {
00331 if (msig) (*msig)(a1.get(), a2.get());
00332 if (mmeth)
00333 retv.exec( boost::bind(mmeth, boost::ref(a1.get()), boost::ref(a2.get()) ) );
00334 else
00335 retv.executed = true;
00336 }
00337
00338 };
00339
00340 template<class ToBind>
00341 struct BindStorageImpl<3, 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 typename boost::function_traits<ToBind>::arg3_type arg3_type;
00347 typedef RStore<result_type> RStoreType;
00348
00349
00350 boost::function<ToBind> mmeth;
00351
00352 mutable AStore<arg1_type> a1;
00353 mutable AStore<arg2_type> a2;
00354 mutable AStore<arg3_type> a3;
00355 mutable RStore<result_type> retv;
00356 typename Signal<ToBind>::shared_ptr msig;
00357
00358
00359 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>& > vStore;
00360 BindStorageImpl() : vStore(retv,a1,a2,a3) {}
00361 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3) {}
00362
00363 void store(arg1_type t1, arg2_type t2, arg3_type t3) { a1(t1); a2(t2); a3(t3); }
00364 void exec() {
00365 if (msig) (*msig)(a1.get(), a2.get(), a3.get());
00366 if (mmeth)
00367 retv.exec( boost::bind(mmeth, boost::ref(a1.get()), boost::ref(a2.get()), boost::ref(a3.get()) ) );
00368 else
00369 retv.executed = true;
00370 }
00371 };
00372
00373 template<class ToBind>
00374 struct BindStorageImpl<4, ToBind>
00375 {
00376 typedef typename boost::function_traits<ToBind>::result_type result_type;
00377 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00378 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00379 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00380 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
00381 typedef RStore<result_type> RStoreType;
00382
00383
00384 boost::function<ToBind> mmeth;
00385
00386 mutable AStore<arg1_type> a1;
00387 mutable AStore<arg2_type> a2;
00388 mutable AStore<arg3_type> a3;
00389 mutable AStore<arg4_type> a4;
00390 mutable RStore<result_type> retv;
00391 typename Signal<ToBind>::shared_ptr msig;
00392
00393
00394 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>&, AStore<arg4_type>& > vStore;
00395 BindStorageImpl() : vStore(retv,a1,a2,a3,a4) {}
00396 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4) {}
00397
00398 void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4) { a1(t1); a2(t2); a3(t3); a4(t4); }
00399 void exec() {
00400 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get());
00401 if (mmeth)
00402 retv.exec( boost::bind( mmeth, boost::ref(a1.get()), boost::ref(a2.get()), boost::ref(a3.get()), boost::ref(a4.get()) ) );
00403 else
00404 retv.executed = true;
00405 }
00406 };
00407
00408 template<class ToBind>
00409 struct BindStorageImpl<5, ToBind>
00410 {
00411 typedef typename boost::function_traits<ToBind>::result_type result_type;
00412 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00413 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00414 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00415 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
00416 typedef typename boost::function_traits<ToBind>::arg5_type arg5_type;
00417 typedef RStore<result_type> RStoreType;
00418
00419
00420 boost::function<ToBind> mmeth;
00421
00422 mutable AStore<arg1_type> a1;
00423 mutable AStore<arg2_type> a2;
00424 mutable AStore<arg3_type> a3;
00425 mutable AStore<arg4_type> a4;
00426 mutable AStore<arg5_type> a5;
00427 mutable RStore<result_type> retv;
00428 typename Signal<ToBind>::shared_ptr msig;
00429
00430
00431 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>&, AStore<arg4_type>&, AStore<arg5_type>& > vStore;
00432 BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5) {}
00433 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5) {}
00434
00435 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);}
00436 void exec() {
00437 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get(), a5.get());
00438 if (mmeth)
00439 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()) ) );
00440 else
00441 retv.executed = true;
00442 }
00443 };
00444
00445 template<class ToBind>
00446 struct BindStorageImpl<6, ToBind>
00447 {
00448 typedef typename boost::function_traits<ToBind>::result_type result_type;
00449 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00450 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00451 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00452 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
00453 typedef typename boost::function_traits<ToBind>::arg5_type arg5_type;
00454 typedef typename boost::function_traits<ToBind>::arg6_type arg6_type;
00455 typedef RStore<result_type> RStoreType;
00456
00457
00458 boost::function<ToBind> mmeth;
00459
00460 mutable AStore<arg1_type> a1;
00461 mutable AStore<arg2_type> a2;
00462 mutable AStore<arg3_type> a3;
00463 mutable AStore<arg4_type> a4;
00464 mutable AStore<arg5_type> a5;
00465 mutable AStore<arg6_type> a6;
00466 mutable RStore<result_type> retv;
00467 typename Signal<ToBind>::shared_ptr msig;
00468
00469
00470 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>&, AStore<arg4_type>&, AStore<arg5_type>&, AStore<arg6_type>& > vStore;
00471 BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5,a6) {}
00472 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5,a6) {}
00473
00474 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);}
00475 void exec() {
00476 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get(), a5.get(), a6.get());
00477 if (mmeth)
00478 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()) ) );
00479 else
00480 retv.executed = true;
00481 }
00482 };
00483
00484 template<class ToBind>
00485 struct BindStorageImpl<7, ToBind>
00486 {
00487 typedef typename boost::function_traits<ToBind>::result_type result_type;
00488 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00489 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00490 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00491 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
00492 typedef typename boost::function_traits<ToBind>::arg5_type arg5_type;
00493 typedef typename boost::function_traits<ToBind>::arg6_type arg6_type;
00494 typedef typename boost::function_traits<ToBind>::arg7_type arg7_type;
00495 typedef RStore<result_type> RStoreType;
00496
00497
00498 boost::function<ToBind> mmeth;
00499
00500 mutable AStore<arg1_type> a1;
00501 mutable AStore<arg2_type> a2;
00502 mutable AStore<arg3_type> a3;
00503 mutable AStore<arg4_type> a4;
00504 mutable AStore<arg5_type> a5;
00505 mutable AStore<arg6_type> a6;
00506 mutable AStore<arg7_type> a7;
00507 mutable RStore<result_type> retv;
00508 typename Signal<ToBind>::shared_ptr msig;
00509
00510
00511 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;
00512 BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5,a6,a7) {}
00513 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5,a6,a7) {}
00514
00515 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);}
00516 void exec() {
00517 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get(), a5.get(), a6.get(), a7.get());
00518 if (mmeth)
00519 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()) ) );
00520 else
00521 retv.executed = true;
00522 }
00523 };
00524
00525
00544 template<class ToBind>
00545 struct BindStorage
00546 : public BindStorageImpl<boost::function_traits<ToBind>::arity, ToBind>
00547 {
00548 };
00549 }
00550 }
00551 #endif