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/mem_fn.hpp>
00046 #include "boost/function_types/function_type.hpp"
00047 #include "boost/function_types/function_type_arity.hpp"
00048
00049 namespace RTT
00050 {
00051 namespace detail
00052 {
00053 template<class F, class O, int>
00054 struct quickbind_impl;
00055
00056 template<class F, class O>
00057 struct quickbind_impl<F,O,0>
00058 {
00059 F mf;
00060 O mo;
00061
00062 quickbind_impl(F f, O o)
00063 : mf(f), mo(o) {}
00064
00065 bool operator()() {
00066 return (mo->*mf)();
00067 }
00068
00069 template<class T1>
00070 bool operator()(T1) {
00071 return (mo->*mf)();
00072 }
00073
00074 template<class T1, class T2>
00075 bool operator()(T1, T2) {
00076 return (mo->*mf)();
00077 }
00078
00079 template<class T1, class T2, class T3>
00080 bool operator()(T1, T2, T3) {
00081 return (mo->*mf)();
00082 }
00083
00084 template<class T1, class T2, class T3, class T4>
00085 bool operator()(T1, T2, T3, T4) {
00086 return (mo->*mf)();
00087 }
00088 };
00089
00090 template<class F, class O>
00091 struct quickbind_impl<F,O,1>
00092 {
00093 F mf;
00094 O mo;
00095
00096 quickbind_impl(F f, O o)
00097 : mf(f), mo(o) {}
00098
00099 template<class T1>
00100 bool operator()(T1& t1) {
00101 return (mo->*mf)(t1);
00102 }
00103
00104 template<class T1, class T2>
00105 bool operator()(T1& t1, T2) {
00106 return (mo->*mf)(t1);
00107 }
00108
00109 template<class T1, class T2, class T3>
00110 bool operator()(T1& t1, T2, T3) {
00111 return (mo->*mf)(t1);
00112 }
00113
00114 template<class T1, class T2, class T3, class T4>
00115 bool operator()(T1& t1, T2, T3, T4) {
00116 return (mo->*mf)(t1);
00117 }
00118 };
00119
00120 template<class F, class O>
00121 struct quickbind_impl<F,O,2>
00122 {
00123 F mf;
00124 O mo;
00125
00126 quickbind_impl(F f, O o)
00127 : mf(f), mo(o) {}
00128
00129 template<class T1, class T2>
00130 bool operator()(T1& t1, T2& t2) {
00131 return (mo->*mf)(t1,t2);
00132 }
00133
00134 template<class T1, class T2, class T3>
00135 bool operator()(T1& t1, T2 t2, T3) {
00136 return (mo->*mf)(t1,t2);
00137 }
00138
00139 template<class T1, class T2, class T3, class T4>
00140 bool operator()(T1& t1, T2 t2, T3, T4) {
00141 return (mo->*mf)(t1,t2);
00142 }
00143 };
00144
00145 template<class F, class O>
00146 struct quickbind_impl<F,O,3>
00147 {
00148 F mf;
00149 O mo;
00150
00151 quickbind_impl(F f, O o)
00152 : mf(f), mo(o) {}
00153
00154 template<class T1, class T2, class T3>
00155 bool operator()(T1& t1, T2 t2, T3 t3) {
00156 return (mo->*mf)(t1,t2,t3);
00157 }
00158
00159 template<class T1, class T2, class T3, class T4>
00160 bool operator()(T1& t1, T2 t2, T3 t3, T4) {
00161 return (mo->*mf)(t1,t2,t3);
00162 }
00163 };
00164
00165 template<class F, class O>
00166 struct quickbind_impl<F,O,4>
00167 {
00168 F mf;
00169 O mo;
00170
00171 quickbind_impl(F f, O o)
00172 : mf(f), mo(o) {}
00173
00174 template<class T1, class T2, class T3, class T4>
00175 bool operator()(T1& t1, T2 t2, T3 t3, T4 t4) {
00176 return (mo->*mf)(t1,t2,t3,t4);
00177 }
00178 };
00179
00180
00181 template<class F, int>
00182 struct quickbindC_impl;
00183
00184 template<class F>
00185 struct quickbindC_impl<F,0>
00186 {
00187 F mf;
00188
00189 quickbindC_impl(F f)
00190 : mf(f) {}
00191
00192 bool operator()() {
00193 return mf();
00194 }
00195
00196 template<class T1>
00197 bool operator()(T1) {
00198 return mf();
00199 }
00200
00201 template<class T1, class T2>
00202 bool operator()(T1, T2) {
00203 return mf();
00204 }
00205
00206 template<class T1, class T2, class T3>
00207 bool operator()(T1, T2, T3) {
00208 return mf();
00209 }
00210
00211 template<class T1, class T2, class T3, class T4>
00212 bool operator()(T1, T2, T3, T4) {
00213 return mf();
00214 }
00215 };
00216
00217 template<class F>
00218 struct quickbindC_impl<F,1>
00219 {
00220 F mf;
00221
00222 quickbindC_impl(F f)
00223 : mf(f) {}
00224
00225 template<class T1>
00226 bool operator()(T1& t1) {
00227 return mf(t1);
00228 }
00229
00230 template<class T1, class T2>
00231 bool operator()(T1& t1, T2) {
00232 return mf(t1);
00233 }
00234
00235 template<class T1, class T2, class T3>
00236 bool operator()(T1& t1, T2, T3) {
00237 return mf(t1);
00238 }
00239
00240 template<class T1, class T2, class T3, class T4>
00241 bool operator()(T1& t1, T2, T3, T4) {
00242 return mf(t1);
00243 }
00244 };
00245
00246 template<class F>
00247 struct quickbindC_impl<F,2>
00248 {
00249 F mf;
00250
00251 quickbindC_impl(F f)
00252 : mf(f) {}
00253
00254 template<class T1,class T2>
00255 bool operator()(T1& t1, T2& t2) {
00256 return mf(t1,t2);
00257 }
00258
00259 template<class T1,class T2, class T3>
00260 bool operator()(T1& t1, T2& t2, T3) {
00261 return mf(t1,t2);
00262 }
00263
00264 template<class T1, class T2, class T3, class T4>
00265 bool operator()(T1& t1, T2& t2, T3, T4) {
00266 return mf(t1,t2);
00267 }
00268 };
00269
00270 template<class F>
00271 struct quickbindC_impl<F,3>
00272 {
00273 F mf;
00274
00275 quickbindC_impl(F f)
00276 : mf(f) {}
00277
00278 template<class T1, class T2, class T3>
00279 bool operator()(T1& t1, T2& t2, T3& t3) {
00280 return mf(t1,t2,t3);
00281 }
00282
00283 template<class T1, class T2, class T3, class T4>
00284 bool operator()(T1& t1, T2& t2, T3& t3, T4) {
00285 return mf(t1,t2,t3);
00286 }
00287 };
00288
00289 template<class F>
00290 struct quickbindC_impl<F,4>
00291 {
00292 F mf;
00293
00294 quickbindC_impl(F f)
00295 : mf(f) {}
00296 template<class T1, class T2, class T3, class T4>
00297 bool operator()(T1& t1, T2& t2, T3& t3, T4& t4) {
00298 return mf(t1,t2,t3,t4);
00299 }
00300 };
00301
00306 template<class F, class O>
00307 struct quickbind
00308 : public quickbind_impl<F,O, boost::function_type_arity<F>::value>
00309 {
00310 quickbind(F f, O o)
00311 : quickbind_impl<F,O, boost::function_type_arity<F>::value>(f,o) {}
00312 };
00313
00318 template<class F>
00319 struct quickbindC
00320 : public quickbindC_impl<F, boost::function_type_arity<F>::value>
00321 {
00322 quickbindC(F f)
00323 : quickbindC_impl<F, boost::function_type_arity<F>::value>(f) {}
00324 };
00325
00330 template<class T>
00331 struct AStore {
00332 T arg;
00333 AStore() : arg() {}
00334 AStore(T t) : arg(t) {}
00335
00336 T operator()() { return arg; }
00337 void operator()(T a) { arg = a; }
00338 };
00339
00340 template<class T>
00341 struct AStore<T&>
00342 {
00343 T* arg;
00344 AStore() : arg(0) {}
00345 AStore(T& t) : arg(&t) {}
00346
00347 T& operator()() { return *arg; }
00348 void operator()(T& a) { arg = &a; }
00349 };
00350
00351 template<class T>
00352 struct AStore<const T &>
00353 {
00354 const T* arg;
00355 AStore() : arg(0) {}
00356 AStore(const T& t) : arg(&t) {}
00357
00358 const T& operator()() { return *arg; }
00359 void operator()(const T& a) { arg = &a; }
00360 };
00361
00362 template<int, class T>
00363 struct BindStorageImpl;
00364
00369 template<class ToBind>
00370 struct BindStorageImpl<0, ToBind>
00371 {
00372 typedef bool result_type;
00373
00374
00375 boost::function<ToBind> exec;
00376 boost::function<ToBind> check;
00377
00378 template<class F, class C, class ObjectType>
00379 void setup(F f, C c, ObjectType t)
00380 {
00381 exec = quickbind<F,ObjectType>( f, t);
00382 check = quickbind<C,ObjectType>( c, t);
00383 }
00384
00385 template<class F, class C>
00386 void setup(F f, C c)
00387 {
00388 exec = f;
00389 check = c;
00390 }
00391
00392 void setup(boost::function<ToBind> f, boost::function<ToBind> c)
00393 {
00394 exec = f;
00395 check = c;
00396 }
00397
00398 boost::function<ToBind> command() const {return exec;}
00399 boost::function<ToBind> condition() const {return check;}
00400 };
00401
00405 template<class ToBind>
00406 struct BindStorageImpl<1, ToBind>
00407 {
00408 typedef bool result_type;
00409 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00410
00411
00412 boost::function<ToBind> comm;
00413
00414 boost::function<ToBind> cond;
00415
00416 mutable AStore<arg1_type> a1;
00417
00418 void store(arg1_type t1) { a1(t1); }
00419 bool exec() { return comm( a1() ); }
00420 bool check() const { return cond( a1() ); }
00421
00426 template<class F, class C, class ObjectType>
00427 void setup(F f, C c, ObjectType t)
00428 {
00429 comm = quickbind<F,ObjectType>( f, t);
00430 cond = quickbind<C,ObjectType>( c, t);
00431 }
00432
00433 template<class F, class C>
00434 void setup(F f, C c)
00435 {
00436 comm = quickbindC<F>(f);
00437 cond = quickbindC<C>(c);
00438 }
00439
00440 void setup(boost::function<ToBind> f, boost::function<ToBind> c)
00441 {
00442 comm = f;
00443 cond = c;
00444 }
00445
00446 boost::function<ToBind> command() const {return comm;}
00447 boost::function<ToBind> condition() const {return cond;}
00448 };
00449
00450 template<class ToBind>
00451 struct BindStorageImpl<2, ToBind>
00452 {
00453 typedef bool result_type;
00454 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00455 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00456
00457
00458 boost::function<ToBind> comm;
00459 boost::function<ToBind> cond;
00460
00461 mutable AStore<arg1_type> a1;
00462 mutable AStore<arg2_type> a2;
00463
00464 void store(arg1_type t1, arg2_type t2) { a1(t1); a2(t2); }
00465 bool exec() { return comm( a1(), a2() ); }
00466 bool check() const { return cond( a1(), a2() ); }
00467
00468 template<class F, class C, class ObjectType>
00469 void setup(F f, C c, ObjectType t)
00470 {
00471 comm = boost::bind<bool>( boost::mem_fn(f), t, _1, _2 );
00472 cond = quickbind<C,ObjectType>( c, t);
00473 }
00474
00475 template<class F, class C>
00476 void setup(F f, C c)
00477 {
00478 comm = boost::bind<bool>( f, _1, _2 );
00479 cond = quickbindC<C>(c);
00480 }
00481
00482 void setup(boost::function<ToBind> f, boost::function<ToBind> c)
00483 {
00484 comm = f;
00485 cond = c;
00486 }
00487
00488 boost::function<ToBind> command() const {return comm;}
00489 boost::function<ToBind> condition() const {return cond;}
00490 };
00491
00492 template<class ToBind>
00493 struct BindStorageImpl<3, ToBind>
00494 {
00495 typedef bool result_type;
00496 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00497 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00498 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00499
00500
00501 boost::function<ToBind> comm;
00502 boost::function<ToBind> cond;
00503
00504 mutable AStore<arg1_type> a1;
00505 mutable AStore<arg2_type> a2;
00506 mutable AStore<arg3_type> a3;
00507
00508 void store(arg1_type t1, arg2_type t2, arg3_type t3) { a1(t1); a2(t2); a3(t3); }
00509 bool exec() { return comm( a1(), a2(), a3() ); }
00510 bool check() const { return cond( a1(), a2(), a3() ); }
00511
00512 template<class F, class C, class ObjectType>
00513 void setup(F f, C c, ObjectType t)
00514 {
00515 comm = boost::bind<bool>( boost::mem_fn(f), t, _1, _2, _3 );
00516 cond = quickbind<C,ObjectType>( c, t);
00517 }
00518
00519 boost::function<ToBind> command() const {return comm;}
00520 boost::function<ToBind> condition() const {return cond;}
00521 };
00522
00523 template<class ToBind>
00524 struct BindStorageImpl<4, ToBind>
00525 {
00526 typedef bool result_type;
00527 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type;
00528 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type;
00529 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type;
00530 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type;
00531
00532
00533 boost::function<ToBind> comm;
00534 boost::function<ToBind> cond;
00535
00536 mutable AStore<arg1_type> a1;
00537 mutable AStore<arg2_type> a2;
00538 mutable AStore<arg3_type> a3;
00539 mutable AStore<arg4_type> a4;
00540
00541 void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4) { a1(t1); a2(t2); a3(t3); a4(t4); }
00542 bool exec() { return comm( a1(), a2(), a3(), a4() ); }
00543 bool check() const { return cond( a1(), a2(), a3(), a4() ); }
00544
00545 template<class F, class C, class ObjectType>
00546 void setup(F f, C c, ObjectType t)
00547 {
00548 comm = boost::bind<bool>( boost::mem_fn(f), t, _1, _2, _3, _4 );
00549 cond = quickbind<C,ObjectType>( c, t);
00550 }
00551
00552 boost::function<ToBind> command() const {return comm;}
00553 boost::function<ToBind> condition() const {return cond;}
00554 };
00555
00556
00563 template<class ToBind>
00564 struct BindStorage
00565 : public BindStorageImpl<boost::function_traits<ToBind>::arity, ToBind>
00566 {
00567 };
00568
00569 template<int, class F>
00570 struct MethodBinderImpl;
00571
00572 template<class F>
00573 struct MethodBinderImpl<0,F>
00574 {
00575 template<class M, class O>
00576 boost::function<F> operator()(M m, O o) {
00577 return boost::bind( boost::mem_fn(m), o );
00578 }
00579 };
00580
00581 template<class F>
00582 struct MethodBinderImpl<1,F>
00583 {
00584 template<class M, class O>
00585 boost::function<F> operator()(M m, O o) {
00586 return boost::bind( boost::mem_fn(m), o, _1 );
00587 }
00588 };
00589
00590 template<class F>
00591 struct MethodBinderImpl<2,F>
00592 {
00593 template<class M, class O>
00594 boost::function<F> operator()(M m, O o) {
00595 return boost::bind( boost::mem_fn(m), o, _1, _2 );
00596 }
00597 };
00598
00599 template<class F>
00600 struct MethodBinderImpl<3,F>
00601 {
00602 template<class M, class O>
00603 boost::function<F> operator()(M m, O o) {
00604 return boost::bind( boost::mem_fn(m), o, _1, _2, _3 );
00605 }
00606 };
00607
00608 template<class F>
00609 struct MethodBinderImpl<4,F>
00610 {
00611 template<class M, class O>
00612 boost::function<F> operator()(M m, O o) {
00613 return boost::bind( boost::mem_fn(m), o, _1, _2, _3, _4 );
00614 }
00615 };
00616
00617 template<class F>
00618 struct MethodBinder
00619 : public MethodBinderImpl<boost::function_traits<F>::arity, F>
00620 {};
00621 }
00622 }
00623 #endif