Orocos Real-Time Toolkit
2.5.0
|
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/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 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 00088 operator T&() { return *arg;} 00089 }; 00090 00091 template<class T> 00092 std::ostream& operator<<(std::ostream& o, AStore<T>& a) { o << "aarg:"<<a.get(); return o;} 00093 00101 template<class T> 00102 struct RStore { 00103 T arg; 00104 bool executed; 00105 RStore() : arg(), executed(false) {} 00106 00107 bool isExecuted() const { 00108 return executed; 00109 } 00110 00111 //bool operator()() { return executed; } 00112 00113 T& result() { return arg; } 00114 operator T&() { return arg;} 00115 00122 template<class F> 00123 void exec(F f) { 00124 arg = f(); 00125 executed = true; 00126 } 00127 00128 }; 00129 00130 template<class T> 00131 struct RStore<T&> 00132 { 00133 T* arg; 00134 bool executed; 00135 RStore() : arg(0), executed(false) {} 00136 00137 template<class F> 00138 void exec(F f) { 00139 arg = &f(); 00140 executed = true; 00141 } 00142 00143 bool isExecuted() const { 00144 return executed; 00145 } 00146 00147 //bool operator()() { return executed; } 00148 00149 T& result() { return *arg; } 00150 operator T&() { return *arg;} 00151 }; 00152 00153 template<class T> 00154 struct RStore<const T> { 00155 T arg; 00156 bool executed; 00157 RStore() : arg(), executed(false) {} 00158 00159 bool isExecuted() const { 00160 return executed; 00161 } 00162 00163 //bool operator()() { return executed; } 00164 00165 T& result() { return arg; } 00166 operator T&() { return arg;} 00167 00174 template<class F> 00175 void exec(F f) { 00176 arg = f(); 00177 executed = true; 00178 } 00179 00180 }; 00181 00182 template<> 00183 struct RStore<void> { 00184 bool executed; 00185 RStore() :executed(false) {} 00186 00187 template<class F> 00188 void exec(F f) { 00189 f(); 00190 executed = true; 00191 } 00192 00193 bool isExecuted() const { 00194 return executed; 00195 } 00196 00197 //bool operator()() { return executed; } 00198 00199 void result() { return; } 00200 }; 00201 00202 template<class T> 00203 std::ostream& operator<<(std::ostream& o, RStore<T>& a) { o << "rarg:"<<a.result(); return o;} 00204 00212 template<class Arg> 00213 struct is_arg_return : public mpl::false_ {}; 00214 00215 template<class T> 00216 struct is_arg_return<AStore<T&> > : public mpl::true_ 00217 {}; 00218 00219 template<class T> 00220 struct is_arg_return<AStore<T const &> > : public mpl::false_ 00221 {}; 00222 00223 template<> 00224 struct is_arg_return<RStore<void> > : public mpl::false_ 00225 {}; 00226 00227 template<class T> 00228 struct is_arg_return<RStore<T> > : public mpl::true_ 00229 {}; 00230 00234 template<class Arg> 00235 struct is_out_arg : public mpl::false_ {}; 00236 00237 template<class T> 00238 struct is_out_arg<AStore<T&> > : public mpl::true_ 00239 {}; 00240 00241 template<class T> 00242 struct is_out_arg<AStore<T const &> > : public mpl::false_ 00243 {}; 00244 00245 template<int, class T> 00246 struct BindStorageImpl; 00247 00252 template<class ToBind> 00253 struct BindStorageImpl<0, ToBind> 00254 { 00255 typedef typename boost::function_traits<ToBind>::result_type result_type; 00256 typedef RStore<result_type> RStoreType; 00257 00258 boost::function<ToBind> mmeth; 00259 00260 mutable RStore<result_type> retv; 00261 #ifdef ORO_SIGNALLING_OPERATIONS 00262 typename Signal<ToBind>::shared_ptr msig; 00263 #endif 00264 // stores the original function pointer 00265 00266 // the list of all our storage. 00267 bf::vector< RStore<result_type>&> vStore; 00268 BindStorageImpl() : vStore(boost::ref(retv)) {} 00269 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv) {} 00270 00271 void exec() { 00272 #ifdef ORO_SIGNALLING_OPERATIONS 00273 if (msig) msig->emit(); 00274 #endif 00275 if (mmeth) 00276 retv.exec( mmeth ); 00277 else 00278 retv.executed = true; 00279 } 00280 }; 00281 00285 template<class ToBind> 00286 struct BindStorageImpl<1, ToBind> 00287 { 00288 typedef typename boost::function_traits<ToBind>::result_type result_type; 00289 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type; 00290 typedef RStore<result_type> RStoreType; 00291 00292 // stores the original function pointer, supplied by the user. 00293 boost::function<ToBind> mmeth; 00294 // Store the argument. 00295 mutable AStore<arg1_type> a1; 00296 mutable RStore<result_type> retv; 00297 #ifdef ORO_SIGNALLING_OPERATIONS 00298 typename Signal<ToBind>::shared_ptr msig; 00299 #endif 00300 00301 // the list of all our storage. 00302 bf::vector< RStore<result_type>&, AStore<arg1_type>& > vStore; 00303 BindStorageImpl() : vStore(retv,a1) {} 00304 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1) {} 00305 void store(arg1_type t1) { a1(t1); } 00306 void exec() { 00307 #ifdef ORO_SIGNALLING_OPERATIONS 00308 if (msig) (*msig)(a1.get()); 00309 #endif 00310 if (mmeth) 00311 retv.exec( boost::bind(mmeth, boost::ref(a1.get()) ) ); 00312 else 00313 retv.executed = true; 00314 } 00315 00316 }; 00317 00318 template<class ToBind> 00319 struct BindStorageImpl<2, ToBind> 00320 { 00321 typedef typename boost::function_traits<ToBind>::result_type result_type; 00322 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type; 00323 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type; 00324 typedef RStore<result_type> RStoreType; 00325 00326 // stores the original function pointer 00327 boost::function<ToBind> mmeth; 00328 // Store the arguments. 00329 mutable AStore<arg1_type> a1; 00330 mutable AStore<arg2_type> a2; 00331 mutable RStore<result_type> retv; 00332 #ifdef ORO_SIGNALLING_OPERATIONS 00333 typename Signal<ToBind>::shared_ptr msig; 00334 #endif 00335 00336 // the list of all our storage. 00337 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>& > vStore; 00338 BindStorageImpl() : vStore(retv,a1,a2) {} 00339 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2) {} 00340 00341 void store(arg1_type t1, arg2_type t2) { a1(t1); a2(t2); } 00342 void exec() { 00343 #ifdef ORO_SIGNALLING_OPERATIONS 00344 if (msig) (*msig)(a1.get(), a2.get()); 00345 #endif 00346 if (mmeth) 00347 retv.exec( boost::bind(mmeth, boost::ref(a1.get()), boost::ref(a2.get()) ) ); 00348 else 00349 retv.executed = true; 00350 } 00351 00352 }; 00353 00354 template<class ToBind> 00355 struct BindStorageImpl<3, ToBind> 00356 { 00357 typedef typename boost::function_traits<ToBind>::result_type result_type; 00358 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type; 00359 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type; 00360 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type; 00361 typedef RStore<result_type> RStoreType; 00362 00363 // stores the original function pointer 00364 boost::function<ToBind> mmeth; 00365 // Store the arguments. 00366 mutable AStore<arg1_type> a1; 00367 mutable AStore<arg2_type> a2; 00368 mutable AStore<arg3_type> a3; 00369 mutable RStore<result_type> retv; 00370 #ifdef ORO_SIGNALLING_OPERATIONS 00371 typename Signal<ToBind>::shared_ptr msig; 00372 #endif 00373 00374 // the list of all our storage. 00375 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>& > vStore; 00376 BindStorageImpl() : vStore(retv,a1,a2,a3) {} 00377 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3) {} 00378 00379 void store(arg1_type t1, arg2_type t2, arg3_type t3) { a1(t1); a2(t2); a3(t3); } 00380 void exec() { 00381 #ifdef ORO_SIGNALLING_OPERATIONS 00382 if (msig) (*msig)(a1.get(), a2.get(), a3.get()); 00383 #endif 00384 if (mmeth) 00385 retv.exec( boost::bind(mmeth, boost::ref(a1.get()), boost::ref(a2.get()), boost::ref(a3.get()) ) ); 00386 else 00387 retv.executed = true; 00388 } 00389 }; 00390 00391 template<class ToBind> 00392 struct BindStorageImpl<4, ToBind> 00393 { 00394 typedef typename boost::function_traits<ToBind>::result_type result_type; 00395 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type; 00396 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type; 00397 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type; 00398 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type; 00399 typedef RStore<result_type> RStoreType; 00400 00401 // stores the original function pointer 00402 boost::function<ToBind> mmeth; 00403 // Store the arguments. 00404 mutable AStore<arg1_type> a1; 00405 mutable AStore<arg2_type> a2; 00406 mutable AStore<arg3_type> a3; 00407 mutable AStore<arg4_type> a4; 00408 mutable RStore<result_type> retv; 00409 #ifdef ORO_SIGNALLING_OPERATIONS 00410 typename Signal<ToBind>::shared_ptr msig; 00411 #endif 00412 00413 // the list of all our storage. 00414 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>&, AStore<arg4_type>& > vStore; 00415 BindStorageImpl() : vStore(retv,a1,a2,a3,a4) {} 00416 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4) {} 00417 00418 void store(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4) { a1(t1); a2(t2); a3(t3); a4(t4); } 00419 void exec() { 00420 #ifdef ORO_SIGNALLING_OPERATIONS 00421 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get()); 00422 #endif 00423 if (mmeth) 00424 retv.exec( boost::bind( mmeth, boost::ref(a1.get()), boost::ref(a2.get()), boost::ref(a3.get()), boost::ref(a4.get()) ) ); 00425 else 00426 retv.executed = true; 00427 } 00428 }; 00429 00430 template<class ToBind> 00431 struct BindStorageImpl<5, ToBind> 00432 { 00433 typedef typename boost::function_traits<ToBind>::result_type result_type; 00434 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type; 00435 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type; 00436 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type; 00437 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type; 00438 typedef typename boost::function_traits<ToBind>::arg5_type arg5_type; 00439 typedef RStore<result_type> RStoreType; 00440 00441 // stores the original function pointer 00442 boost::function<ToBind> mmeth; 00443 // Store the arguments. 00444 mutable AStore<arg1_type> a1; 00445 mutable AStore<arg2_type> a2; 00446 mutable AStore<arg3_type> a3; 00447 mutable AStore<arg4_type> a4; 00448 mutable AStore<arg5_type> a5; 00449 mutable RStore<result_type> retv; 00450 #ifdef ORO_SIGNALLING_OPERATIONS 00451 typename Signal<ToBind>::shared_ptr msig; 00452 #endif 00453 00454 // the list of all our storage. 00455 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>&, AStore<arg4_type>&, AStore<arg5_type>& > vStore; 00456 BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5) {} 00457 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5) {} 00458 00459 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);} 00460 void exec() { 00461 #ifdef ORO_SIGNALLING_OPERATIONS 00462 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get(), a5.get()); 00463 #endif 00464 if (mmeth) 00465 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()) ) ); 00466 else 00467 retv.executed = true; 00468 } 00469 }; 00470 00471 template<class ToBind> 00472 struct BindStorageImpl<6, ToBind> 00473 { 00474 typedef typename boost::function_traits<ToBind>::result_type result_type; 00475 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type; 00476 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type; 00477 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type; 00478 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type; 00479 typedef typename boost::function_traits<ToBind>::arg5_type arg5_type; 00480 typedef typename boost::function_traits<ToBind>::arg6_type arg6_type; 00481 typedef RStore<result_type> RStoreType; 00482 00483 // stores the original function pointer 00484 boost::function<ToBind> mmeth; 00485 // Store the arguments. 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 AStore<arg6_type> a6; 00492 mutable RStore<result_type> retv; 00493 #ifdef ORO_SIGNALLING_OPERATIONS 00494 typename Signal<ToBind>::shared_ptr msig; 00495 #endif 00496 00497 // the list of all our storage. 00498 bf::vector< RStore<result_type>&, AStore<arg1_type>&, AStore<arg2_type>&, AStore<arg3_type>&, AStore<arg4_type>&, AStore<arg5_type>&, AStore<arg6_type>& > vStore; 00499 BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5,a6) {} 00500 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5,a6) {} 00501 00502 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);} 00503 void exec() { 00504 #ifdef ORO_SIGNALLING_OPERATIONS 00505 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get(), a5.get(), a6.get()); 00506 #endif 00507 if (mmeth) 00508 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()) ) ); 00509 else 00510 retv.executed = true; 00511 } 00512 }; 00513 00514 template<class ToBind> 00515 struct BindStorageImpl<7, ToBind> 00516 { 00517 typedef typename boost::function_traits<ToBind>::result_type result_type; 00518 typedef typename boost::function_traits<ToBind>::arg1_type arg1_type; 00519 typedef typename boost::function_traits<ToBind>::arg2_type arg2_type; 00520 typedef typename boost::function_traits<ToBind>::arg3_type arg3_type; 00521 typedef typename boost::function_traits<ToBind>::arg4_type arg4_type; 00522 typedef typename boost::function_traits<ToBind>::arg5_type arg5_type; 00523 typedef typename boost::function_traits<ToBind>::arg6_type arg6_type; 00524 typedef typename boost::function_traits<ToBind>::arg7_type arg7_type; 00525 typedef RStore<result_type> RStoreType; 00526 00527 // stores the original function pointer 00528 boost::function<ToBind> mmeth; 00529 // Store the arguments. 00530 mutable AStore<arg1_type> a1; 00531 mutable AStore<arg2_type> a2; 00532 mutable AStore<arg3_type> a3; 00533 mutable AStore<arg4_type> a4; 00534 mutable AStore<arg5_type> a5; 00535 mutable AStore<arg6_type> a6; 00536 mutable AStore<arg7_type> a7; 00537 mutable RStore<result_type> retv; 00538 #ifdef ORO_SIGNALLING_OPERATIONS 00539 typename Signal<ToBind>::shared_ptr msig; 00540 #endif 00541 00542 // the list of all our storage. 00543 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; 00544 BindStorageImpl() : vStore(retv,a1,a2,a3,a4,a5,a6,a7) {} 00545 BindStorageImpl(const BindStorageImpl& orig) : mmeth(orig.mmeth), vStore(retv,a1,a2,a3,a4,a5,a6,a7) {} 00546 00547 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);} 00548 void exec() { 00549 #ifdef ORO_SIGNALLING_OPERATIONS 00550 if (msig) (*msig)(a1.get(), a2.get(), a3.get(), a4.get(), a5.get(), a6.get(), a7.get()); 00551 #endif 00552 if (mmeth) 00553 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()) ) ); 00554 else 00555 retv.executed = true; 00556 } 00557 }; 00558 00559 00578 template<class ToBind> 00579 struct BindStorage 00580 : public BindStorageImpl<boost::function_traits<ToBind>::arity, ToBind> 00581 { 00582 }; 00583 } 00584 } 00585 #endif