BindStorage.hpp

00001 /***************************************************************************
00002   tag: FMTC  do nov 2 13:06:12 CET 2006  BindStorage.hpp
00003 
00004                         BindStorage.hpp -  description
00005                            -------------------
00006     begin                : do november 02 2006
00007     copyright            : (C) 2006 FMTC
00008     email                : peter.soetens@fmtc.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
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             // stores the original function pointer
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); // allocates
00382                 check  = quickbind<C,ObjectType>( c, t); // allocates
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             // stores the original function pointer, supplied by the user.
00412             boost::function<ToBind>  comm;
00413             // Wrap the condition.
00414             boost::function<ToBind> cond;
00415             // Store the argument.
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); // allocates
00430                 cond = quickbind<C,ObjectType>( c, t); // allocates
00431             }
00432 
00433             template<class F, class C>
00434             void setup(F f, C c)
00435             {
00436                 comm = quickbindC<F>(f); // allocates
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             // stores the original function pointer
00458             boost::function<ToBind> comm;
00459             boost::function<ToBind> cond;
00460             // Store the arguments.
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 ); // allocates
00472                 cond = quickbind<C,ObjectType>( c, t); // allocates
00473             }
00474 
00475             template<class F, class C>
00476             void setup(F f, C c)
00477             {
00478                 comm = boost::bind<bool>( f, _1, _2 ); // allocates
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             // stores the original function pointer
00501             boost::function<ToBind> comm;
00502             boost::function<ToBind> cond;
00503             // Store the arguments.
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 ); // allocates
00516                 cond = quickbind<C,ObjectType>( c, t); // allocates
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             // stores the original function pointer
00533             boost::function<ToBind> comm;
00534             boost::function<ToBind> cond;
00535             // Store the arguments.
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 ); // allocates
00549                 cond = quickbind<C,ObjectType>( c, t); // allocates
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
Generated on Thu Dec 23 13:22:36 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3