$search
00001 /*************************************************************************** 00002 tag: FMTC do nov 2 13:06:13 CET 2006 DataSourceStorage.hpp 00003 00004 DataSourceStorage.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_DATASOURCE_STORAGE_HPP 00040 #define ORO_TASK_DATASOURCE_STORAGE_HPP 00041 00042 #include <boost/function.hpp> 00043 #include <boost/bind.hpp> 00044 #include <boost/mem_fn.hpp> 00045 #include <boost/function_types/function_type.hpp> 00046 #include <boost/function_types/function_arity.hpp> 00047 #include "DataSources.hpp" 00048 #include "BindStorage.hpp" 00049 00050 namespace RTT 00051 { 00052 namespace internal 00053 { 00060 template<class T> 00061 struct DSRStore { 00062 T arg; 00063 DSRStore() : arg() {} 00064 00065 T& result() { return arg; } 00066 operator T&() { return arg; } 00067 }; 00068 00069 template<class T> 00070 struct DSRStore<T&> 00071 { 00072 typedef typename boost::remove_const<T>::type result_type; 00073 result_type arg; 00074 DSRStore() : arg() {} 00075 result_type& result() { return arg; } // non const return 00076 operator result_type&() { return arg; } 00077 }; 00078 00079 template<> 00080 struct DSRStore<void> { 00081 DSRStore() {} 00082 void result() { return; } 00083 }; 00084 00085 template<> 00086 struct is_arg_return<DSRStore<void> > : public mpl::false_ 00087 {}; 00088 00089 template<class T> 00090 struct is_arg_return<DSRStore<T> > : public mpl::true_ 00091 {}; 00092 00093 00096 template<class R> 00097 struct DataSourceResultStorage 00098 { 00099 typedef typename remove_cr<R>::type ds_type; 00100 DSRStore<R> retn; 00101 typename ReferenceDataSource<ds_type>::shared_ptr result; 00102 00103 DataSourceResultStorage() 00104 : result( new ReferenceDataSource<ds_type>(retn.result()) ) 00105 { 00106 } 00107 00108 template<class ContainerT> 00109 void initRet(ContainerT& cc) { 00110 cc.ret(base::DataSourceBase::shared_ptr(result)); 00111 } 00112 00113 R getResult() { 00114 return retn.result(); 00115 } 00116 }; 00117 00118 template<> 00119 struct DataSourceResultStorage<void> 00120 { 00121 typedef void result_type; 00122 DSRStore<void> retn; 00123 DataSourceResultStorage() 00124 { 00125 } 00126 00127 template<class ContainerT> 00128 void initRet(ContainerT& ) {} 00129 00130 void getResult() {} 00131 }; 00132 00135 template<class R> 00136 struct DataSourceResultStorage<R const&> 00137 { 00138 typedef R const& result_type; 00139 typedef R ds_type; 00140 DSRStore<result_type> retn; 00141 typename ReferenceDataSource<ds_type>::shared_ptr result; 00142 00143 DataSourceResultStorage() 00144 : result( new ReferenceDataSource<ds_type>( retn.result() ) ) 00145 { 00146 } 00147 00148 template<class ContainerT> 00149 void initRet(ContainerT& cc) { 00150 cc.ret(base::DataSourceBase::shared_ptr(result)); 00151 } 00152 00153 result_type getResult() { 00154 return result->rvalue(); 00155 } 00156 }; 00157 00164 template<class A> 00165 struct DataSourceArgStorage 00166 { 00167 typedef typename remove_cr<A>::type ds_type; 00168 typedef AStore<A&> Store; 00169 typename ValueDataSource<ds_type>::shared_ptr value; 00170 AStore<A&> arg; 00171 DataSourceArgStorage() 00172 : value( new ValueDataSource<ds_type>() ) 00173 {} 00174 // We store the copy of 'a' in the data source, such that 00175 // that copy is always valid memory (refcounted). If we 00176 // would store it in 'arg' and use a LateReferenceDataSource, 00177 // we would loose/corrupt the data if this object is destroyed. 00178 // This is acceptable for ref/constref cases, but not for 00179 // value cases, which are often living on the stack and by 00180 // definition short lived. 00181 void newarg(A a) { arg( value->set() ); value->set(a); } 00182 }; 00183 00185 template<class A> 00186 struct DataSourceArgStorage<A &> 00187 { 00188 typedef AStore<A&> Store; 00189 AStore<A&> arg; 00190 typedef typename remove_cr<A>::type ds_type; 00191 typename LateReferenceDataSource<ds_type>::shared_ptr value; 00192 DataSourceArgStorage() 00193 : value( new LateReferenceDataSource<ds_type>() ) 00194 {} 00195 void newarg(A& a) { arg(a); value->setPointer(&arg.get()); } 00196 }; 00197 00199 template<class A> 00200 struct DataSourceArgStorage<A const&> 00201 { 00202 typedef AStore<A const&> Store; 00203 AStore<A const&> arg; 00204 // without const&: 00205 typename LateConstReferenceDataSource<A>::shared_ptr value; 00206 DataSourceArgStorage() 00207 : value( new LateConstReferenceDataSource<A>() ) 00208 {} 00209 void newarg(A const& a) { arg(a); value->setPointer(&arg.get());} 00210 }; 00211 00212 template<int, class T> 00213 struct DataSourceStorageImpl; 00214 00218 template<class DataType> 00219 struct DataSourceStorageImpl<0, DataType> 00220 : public DataSourceResultStorage<typename boost::function_traits<DataType>::result_type> 00221 { 00222 typedef typename boost::function_traits<DataType>::result_type result_type; 00223 DataSourceStorageImpl() {} 00224 DataSourceStorageImpl(const DataSourceStorageImpl& orig) {} 00225 template<class ContainerT> 00226 void initArgs(ContainerT& ) {} 00227 }; 00228 00232 template<class DataType> 00233 struct DataSourceStorageImpl<1, DataType> 00234 : public DataSourceResultStorage<typename boost::function_traits<DataType>::result_type> 00235 { 00236 typedef typename boost::function_traits<DataType>::result_type result_type; 00237 typedef typename boost::function_traits<DataType>::arg1_type arg1_type; 00238 DataSourceArgStorage<arg1_type> ma1; 00239 typedef typename DataSourceArgStorage<arg1_type>::Store AStore1; 00240 00241 DataSourceStorageImpl() {} 00242 DataSourceStorageImpl(const DataSourceStorageImpl& orig) {} 00243 00244 template<class ContainerT> 00245 void initArgs(ContainerT& cc) { 00246 cc.arg( base::DataSourceBase::shared_ptr(ma1.value.get()) ); 00247 } 00248 00249 void store(arg1_type a1) { 00250 ma1.newarg(a1); 00251 } 00252 }; 00253 00254 template<class DataType> 00255 struct DataSourceStorageImpl<2, DataType> 00256 : public DataSourceResultStorage<typename boost::function_traits<DataType>::result_type> 00257 { 00258 typedef typename boost::function_traits<DataType>::result_type result_type; 00259 typedef typename boost::function_traits<DataType>::arg1_type arg1_type; 00260 typedef typename boost::function_traits<DataType>::arg2_type arg2_type; 00261 DataSourceArgStorage<arg1_type> ma1; 00262 DataSourceArgStorage<arg2_type> ma2; 00263 typedef typename DataSourceArgStorage<arg1_type>::Store AStore1; 00264 typedef typename DataSourceArgStorage<arg2_type>::Store AStore2; 00265 00266 DataSourceStorageImpl() {} 00267 DataSourceStorageImpl(const DataSourceStorageImpl& orig) {} 00268 00269 template<class ContainerT> 00270 void initArgs(ContainerT& cc) { 00271 cc.arg( base::DataSourceBase::shared_ptr(ma1.value) ); 00272 cc.arg( base::DataSourceBase::shared_ptr(ma2.value) ); 00273 } 00274 void store(arg1_type a1, arg2_type a2) { 00275 ma1.newarg(a1); 00276 ma2.newarg(a2); 00277 } 00278 }; 00279 00280 template<class DataType> 00281 struct DataSourceStorageImpl<3, DataType> 00282 : public DataSourceResultStorage<typename boost::function_traits<DataType>::result_type> 00283 { 00284 typedef typename boost::function_traits<DataType>::result_type result_type; 00285 typedef typename boost::function_traits<DataType>::arg1_type arg1_type; 00286 typedef typename boost::function_traits<DataType>::arg2_type arg2_type; 00287 typedef typename boost::function_traits<DataType>::arg3_type arg3_type; 00288 DataSourceArgStorage<arg1_type> ma1; 00289 DataSourceArgStorage<arg2_type> ma2; 00290 DataSourceArgStorage<arg3_type> ma3; 00291 typedef typename DataSourceArgStorage<arg1_type>::Store AStore1; 00292 typedef typename DataSourceArgStorage<arg2_type>::Store AStore2; 00293 typedef typename DataSourceArgStorage<arg3_type>::Store AStore3; 00294 00295 DataSourceStorageImpl() {} 00296 DataSourceStorageImpl(const DataSourceStorageImpl& orig) {} 00297 00298 template<class ContainerT> 00299 void initArgs(ContainerT& cc) { 00300 cc.arg( base::DataSourceBase::shared_ptr(ma1.value) ); 00301 cc.arg( base::DataSourceBase::shared_ptr(ma2.value) ); 00302 cc.arg( base::DataSourceBase::shared_ptr(ma3.value) ); 00303 } 00304 void store(arg1_type a1, arg2_type a2, arg3_type a3) { 00305 ma1.newarg(a1); 00306 ma2.newarg(a2); 00307 ma3.newarg(a3); 00308 } 00309 }; 00310 00311 template<class DataType> 00312 struct DataSourceStorageImpl<4, DataType> 00313 : public DataSourceResultStorage<typename boost::function_traits<DataType>::result_type> 00314 { 00315 typedef typename boost::function_traits<DataType>::result_type result_type; 00316 typedef typename boost::function_traits<DataType>::arg1_type arg1_type; 00317 typedef typename boost::function_traits<DataType>::arg2_type arg2_type; 00318 typedef typename boost::function_traits<DataType>::arg3_type arg3_type; 00319 typedef typename boost::function_traits<DataType>::arg4_type arg4_type; 00320 DataSourceArgStorage<arg1_type> ma1; 00321 DataSourceArgStorage<arg2_type> ma2; 00322 DataSourceArgStorage<arg3_type> ma3; 00323 DataSourceArgStorage<arg4_type> ma4; 00324 typedef typename DataSourceArgStorage<arg1_type>::Store AStore1; 00325 typedef typename DataSourceArgStorage<arg2_type>::Store AStore2; 00326 typedef typename DataSourceArgStorage<arg3_type>::Store AStore3; 00327 typedef typename DataSourceArgStorage<arg4_type>::Store AStore4; 00328 00329 DataSourceStorageImpl() {} 00330 DataSourceStorageImpl(const DataSourceStorageImpl& orig) {} 00331 00332 template<class ContainerT> 00333 void initArgs(ContainerT& cc) { 00334 cc.arg( base::DataSourceBase::shared_ptr(ma1.value) ); 00335 cc.arg( base::DataSourceBase::shared_ptr(ma2.value) ); 00336 cc.arg( base::DataSourceBase::shared_ptr(ma3.value) ); 00337 cc.arg( base::DataSourceBase::shared_ptr(ma4.value) ); 00338 } 00339 void store(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) { 00340 ma1.newarg(a1); 00341 ma2.newarg(a2); 00342 ma3.newarg(a3); 00343 ma4.newarg(a4); 00344 } 00345 }; 00346 00347 template<class DataType> 00348 struct DataSourceStorageImpl<5, DataType> 00349 : public DataSourceResultStorage<typename boost::function_traits<DataType>::result_type> 00350 { 00351 typedef typename boost::function_traits<DataType>::result_type result_type; 00352 typedef typename boost::function_traits<DataType>::arg1_type arg1_type; 00353 typedef typename boost::function_traits<DataType>::arg2_type arg2_type; 00354 typedef typename boost::function_traits<DataType>::arg3_type arg3_type; 00355 typedef typename boost::function_traits<DataType>::arg4_type arg4_type; 00356 typedef typename boost::function_traits<DataType>::arg5_type arg5_type; 00357 DataSourceArgStorage<arg1_type> ma1; 00358 DataSourceArgStorage<arg2_type> ma2; 00359 DataSourceArgStorage<arg3_type> ma3; 00360 DataSourceArgStorage<arg4_type> ma4; 00361 DataSourceArgStorage<arg5_type> ma5; 00362 typedef typename DataSourceArgStorage<arg1_type>::Store AStore1; 00363 typedef typename DataSourceArgStorage<arg2_type>::Store AStore2; 00364 typedef typename DataSourceArgStorage<arg3_type>::Store AStore3; 00365 typedef typename DataSourceArgStorage<arg4_type>::Store AStore4; 00366 typedef typename DataSourceArgStorage<arg5_type>::Store AStore5; 00367 00368 DataSourceStorageImpl() {} 00369 DataSourceStorageImpl(const DataSourceStorageImpl& orig) {} 00370 00371 template<class ContainerT> 00372 void initArgs(ContainerT& cc) { 00373 cc.arg( base::DataSourceBase::shared_ptr(ma1.value) ); 00374 cc.arg( base::DataSourceBase::shared_ptr(ma2.value) ); 00375 cc.arg( base::DataSourceBase::shared_ptr(ma3.value) ); 00376 cc.arg( base::DataSourceBase::shared_ptr(ma4.value) ); 00377 cc.arg( base::DataSourceBase::shared_ptr(ma5.value) ); 00378 } 00379 void store(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, arg5_type a5) { 00380 ma1.newarg(a1); 00381 ma2.newarg(a2); 00382 ma3.newarg(a3); 00383 ma4.newarg(a4); 00384 ma5.newarg(a5); 00385 } 00386 }; 00387 00388 template<class DataType> 00389 struct DataSourceStorageImpl<6, DataType> 00390 : public DataSourceResultStorage<typename boost::function_traits<DataType>::result_type> 00391 { 00392 typedef typename boost::function_traits<DataType>::result_type result_type; 00393 typedef typename boost::function_traits<DataType>::arg1_type arg1_type; 00394 typedef typename boost::function_traits<DataType>::arg2_type arg2_type; 00395 typedef typename boost::function_traits<DataType>::arg3_type arg3_type; 00396 typedef typename boost::function_traits<DataType>::arg4_type arg4_type; 00397 typedef typename boost::function_traits<DataType>::arg5_type arg5_type; 00398 typedef typename boost::function_traits<DataType>::arg6_type arg6_type; 00399 DataSourceArgStorage<arg1_type> ma1; 00400 DataSourceArgStorage<arg2_type> ma2; 00401 DataSourceArgStorage<arg3_type> ma3; 00402 DataSourceArgStorage<arg4_type> ma4; 00403 DataSourceArgStorage<arg5_type> ma5; 00404 DataSourceArgStorage<arg6_type> ma6; 00405 typedef typename DataSourceArgStorage<arg1_type>::Store AStore1; 00406 typedef typename DataSourceArgStorage<arg2_type>::Store AStore2; 00407 typedef typename DataSourceArgStorage<arg3_type>::Store AStore3; 00408 typedef typename DataSourceArgStorage<arg4_type>::Store AStore4; 00409 typedef typename DataSourceArgStorage<arg5_type>::Store AStore5; 00410 typedef typename DataSourceArgStorage<arg6_type>::Store AStore6; 00411 00412 DataSourceStorageImpl() {} 00413 DataSourceStorageImpl(const DataSourceStorageImpl& orig) {} 00414 00415 template<class ContainerT> 00416 void initArgs(ContainerT& cc) { 00417 cc.arg( base::DataSourceBase::shared_ptr(ma1.value) ); 00418 cc.arg( base::DataSourceBase::shared_ptr(ma2.value) ); 00419 cc.arg( base::DataSourceBase::shared_ptr(ma3.value) ); 00420 cc.arg( base::DataSourceBase::shared_ptr(ma4.value) ); 00421 cc.arg( base::DataSourceBase::shared_ptr(ma5.value) ); 00422 cc.arg( base::DataSourceBase::shared_ptr(ma6.value) ); 00423 } 00424 void store(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, arg5_type a5, arg6_type a6) { 00425 ma1.newarg(a1); 00426 ma2.newarg(a2); 00427 ma3.newarg(a3); 00428 ma4.newarg(a4); 00429 ma5.newarg(a5); 00430 ma6.newarg(a6); 00431 } 00432 }; 00433 00434 template<class DataType> 00435 struct DataSourceStorageImpl<7, DataType> 00436 : public DataSourceResultStorage<typename boost::function_traits<DataType>::result_type> 00437 { 00438 typedef typename boost::function_traits<DataType>::result_type result_type; 00439 typedef typename boost::function_traits<DataType>::arg1_type arg1_type; 00440 typedef typename boost::function_traits<DataType>::arg2_type arg2_type; 00441 typedef typename boost::function_traits<DataType>::arg3_type arg3_type; 00442 typedef typename boost::function_traits<DataType>::arg4_type arg4_type; 00443 typedef typename boost::function_traits<DataType>::arg5_type arg5_type; 00444 typedef typename boost::function_traits<DataType>::arg6_type arg6_type; 00445 typedef typename boost::function_traits<DataType>::arg7_type arg7_type; 00446 DataSourceArgStorage<arg1_type> ma1; 00447 DataSourceArgStorage<arg2_type> ma2; 00448 DataSourceArgStorage<arg3_type> ma3; 00449 DataSourceArgStorage<arg4_type> ma4; 00450 DataSourceArgStorage<arg5_type> ma5; 00451 DataSourceArgStorage<arg6_type> ma6; 00452 DataSourceArgStorage<arg7_type> ma7; 00453 typedef typename DataSourceArgStorage<arg1_type>::Store AStore1; 00454 typedef typename DataSourceArgStorage<arg2_type>::Store AStore2; 00455 typedef typename DataSourceArgStorage<arg3_type>::Store AStore3; 00456 typedef typename DataSourceArgStorage<arg4_type>::Store AStore4; 00457 typedef typename DataSourceArgStorage<arg5_type>::Store AStore5; 00458 typedef typename DataSourceArgStorage<arg6_type>::Store AStore6; 00459 typedef typename DataSourceArgStorage<arg7_type>::Store AStore7; 00460 00461 DataSourceStorageImpl() {} 00462 DataSourceStorageImpl(const DataSourceStorageImpl& orig) {} 00463 00464 template<class ContainerT> 00465 void initArgs(ContainerT& cc) { 00466 cc.arg( base::DataSourceBase::shared_ptr(ma1.value) ); 00467 cc.arg( base::DataSourceBase::shared_ptr(ma2.value) ); 00468 cc.arg( base::DataSourceBase::shared_ptr(ma3.value) ); 00469 cc.arg( base::DataSourceBase::shared_ptr(ma4.value) ); 00470 cc.arg( base::DataSourceBase::shared_ptr(ma5.value) ); 00471 cc.arg( base::DataSourceBase::shared_ptr(ma6.value) ); 00472 cc.arg( base::DataSourceBase::shared_ptr(ma7.value) ); 00473 } 00474 void store(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, arg5_type a5, arg6_type a6, arg7_type a7) { 00475 ma1.newarg(a1); 00476 ma2.newarg(a2); 00477 ma3.newarg(a3); 00478 ma4.newarg(a4); 00479 ma5.newarg(a5); 00480 ma6.newarg(a6); 00481 ma7.newarg(a7); 00482 } 00483 }; 00484 00491 template<class DataType> 00492 struct DataSourceStorage 00493 : public DataSourceStorageImpl<boost::function_traits<DataType>::arity, DataType> 00494 { 00495 }; 00496 } 00497 } 00498 #endif