Orocos Real-Time Toolkit
2.6.0
|
00001 /*************************************************************************** 00002 tag: Peter Soetens Mon Jun 26 13:25:56 CEST 2006 DataSources.hpp 00003 00004 DataSources.hpp - description 00005 ------------------- 00006 begin : Mon June 26 2006 00007 copyright : (C) 2006 Peter Soetens 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_CORELIB_DATASOURCES_HPP 00040 #define ORO_CORELIB_DATASOURCES_HPP 00041 00042 #include "mystd.hpp" 00043 #include "DataSource.hpp" 00044 #include "DataSourceTypeInfo.hpp" 00045 #include "Reference.hpp" 00046 #include <vector> 00047 00048 namespace RTT 00049 { 00050 namespace internal { 00051 00059 template<typename T> 00060 class ValueDataSource 00061 : public AssignableDataSource<T> 00062 { 00063 protected: 00064 mutable typename DataSource<T>::value_t mdata; 00065 00066 public: 00070 ~ValueDataSource(); 00071 00072 typedef boost::intrusive_ptr<ValueDataSource<T> > shared_ptr; 00073 00074 ValueDataSource( T data ); 00075 00076 ValueDataSource( ); 00077 00078 typename DataSource<T>::result_t get() const 00079 { 00080 return mdata; 00081 } 00082 00083 typename DataSource<T>::result_t value() const 00084 { 00085 return mdata; 00086 } 00087 00088 void set( typename AssignableDataSource<T>::param_t t ); 00089 00090 typename AssignableDataSource<T>::reference_t set() 00091 { 00092 return mdata; 00093 } 00094 00095 typename AssignableDataSource<T>::const_reference_t rvalue() const 00096 { 00097 return mdata; 00098 } 00099 00100 virtual ValueDataSource<T>* clone() const; 00101 00102 virtual ValueDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& replace ) const; 00103 }; 00104 00108 template<> 00109 RTT_API void ValueDataSource<std::string>::set( AssignableDataSource<std::string>::param_t t ); 00110 00114 template<> 00115 RTT_API ValueDataSource<std::string>::ValueDataSource(std::string t ); 00116 00122 template<typename T> 00123 class ConstantDataSource 00124 : public DataSource<T> 00125 { 00130 typename boost::add_const<typename DataSource<T>::value_t>::type mdata; 00131 00132 public: 00136 ~ConstantDataSource(); 00137 00138 typedef boost::intrusive_ptr< ConstantDataSource<T> > shared_ptr; 00139 00140 ConstantDataSource( T value ); 00141 00142 typename DataSource<T>::result_t get() const 00143 { 00144 return mdata; 00145 } 00146 00147 typename DataSource<T>::result_t value() const 00148 { 00149 return mdata; 00150 } 00151 00152 typename DataSource<T>::const_reference_t rvalue() const 00153 { 00154 return mdata; 00155 } 00156 00157 virtual ConstantDataSource<T>* clone() const; 00158 00159 virtual ConstantDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const; 00160 }; 00161 00167 template<typename T> 00168 class ConstReferenceDataSource 00169 : public DataSource<T> 00170 { 00171 // a reference to a value_t 00172 typename DataSource<T>::const_reference_t mref; 00173 public: 00177 ~ConstReferenceDataSource(); 00178 00179 typedef boost::intrusive_ptr<ConstReferenceDataSource<T> > shared_ptr; 00180 00181 ConstReferenceDataSource( typename DataSource<T>::const_reference_t ref ); 00182 00183 typename DataSource<T>::result_t get() const 00184 { 00185 return mref; 00186 } 00187 00188 typename DataSource<T>::result_t value() const 00189 { 00190 return mref; 00191 } 00192 00193 typename DataSource<T>::const_reference_t rvalue() const 00194 { 00195 return mref; 00196 } 00197 00198 virtual ConstReferenceDataSource<T>* clone() const; 00199 00200 virtual ConstReferenceDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const; 00201 }; 00202 00203 00209 template<typename T> 00210 class ReferenceDataSource 00211 : public AssignableDataSource<T>, public Reference 00212 { 00213 // a pointer to a value_t 00214 T* mptr; 00215 public: 00219 ~ReferenceDataSource(); 00220 00221 typedef boost::intrusive_ptr<ReferenceDataSource<T> > shared_ptr; 00222 00223 ReferenceDataSource( typename AssignableDataSource<T>::reference_t ref ); 00224 00225 void setReference(void* ref) 00226 { 00227 mptr = static_cast<T*>(ref); 00228 } 00229 bool setReference(base::DataSourceBase::shared_ptr dsb) 00230 { 00231 typename AssignableDataSource<T>::shared_ptr ads = boost::dynamic_pointer_cast<AssignableDataSource<T> >(dsb); 00232 if (ads) { 00233 ads->evaluate(); 00234 mptr = &ads->set(); 00235 return true; 00236 } else { 00237 return false; 00238 } 00239 } 00240 00241 typename DataSource<T>::result_t get() const 00242 { 00243 return *mptr; 00244 } 00245 00246 typename DataSource<T>::result_t value() const 00247 { 00248 return *mptr; 00249 } 00250 00251 void set( typename AssignableDataSource<T>::param_t t ); 00252 00253 typename AssignableDataSource<T>::reference_t set() 00254 { 00255 return *mptr; 00256 } 00257 00258 typename AssignableDataSource<T>::const_reference_t rvalue() const 00259 { 00260 return *mptr; 00261 } 00262 00263 virtual ReferenceDataSource<T>* clone() const; 00264 00265 virtual ReferenceDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const; 00266 }; 00267 00274 template<typename T> 00275 class AliasDataSource 00276 : public DataSource<T> 00277 { 00278 typename DataSource<T>::shared_ptr alias; 00279 public: 00280 typedef boost::intrusive_ptr<AliasDataSource<T> > shared_ptr; 00281 00282 AliasDataSource(DataSource<T>* ds) 00283 : alias(ds) 00284 {} 00285 00286 ~AliasDataSource() { } 00287 00288 bool evaluate() const { 00289 return alias->evaluate(); 00290 } 00291 00292 typename DataSource<T>::result_t get() const 00293 { 00294 return alias->get(); 00295 } 00296 00297 typename DataSource<T>::result_t value() const 00298 { 00299 return alias->value(); 00300 } 00301 00302 typename DataSource<T>::const_reference_t rvalue() const 00303 { 00304 return alias->rvalue(); 00305 } 00306 00307 virtual void reset() { alias->reset(); } 00308 00309 virtual AliasDataSource<T>* clone() const { 00310 return new AliasDataSource(alias.get()); 00311 } 00312 virtual AliasDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const { 00313 return new AliasDataSource(alias->copy(alreadyCloned) ); 00314 } 00315 }; 00316 00317 00323 template<typename T> 00324 class ArrayDataSource 00325 : public AssignableDataSource<T> 00326 { 00327 protected: 00328 typename T::value_type* mdata; 00329 T marray; 00330 00331 public: 00335 ~ArrayDataSource(); 00336 00337 typedef boost::intrusive_ptr<ArrayDataSource<T> > shared_ptr; 00338 00344 ArrayDataSource( std::size_t size = 0); 00345 00351 ArrayDataSource( T const& odata ); 00359 void newArray( std::size_t size ); 00360 00361 typename DataSource<T>::result_t get() const 00362 { 00363 return marray; 00364 } 00365 00366 typename DataSource<T>::result_t value() const 00367 { 00368 return marray; 00369 } 00370 00371 void set( typename AssignableDataSource<T>::param_t t ); 00372 00373 typename AssignableDataSource<T>::reference_t set() 00374 { 00375 return marray; 00376 } 00377 00378 typename AssignableDataSource<T>::const_reference_t rvalue() const 00379 { 00380 return marray; 00381 } 00382 00383 virtual ArrayDataSource<T>* clone() const; 00384 00385 virtual ArrayDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& replace ) const; 00386 }; 00387 00396 template<typename T> 00397 class LateReferenceDataSource 00398 : public AssignableDataSource<T> 00399 { 00400 // a reference to a value_t 00401 typename AssignableDataSource<T>::value_t* mptr; 00402 public: 00403 00404 typedef boost::intrusive_ptr<LateReferenceDataSource<T> > shared_ptr; 00405 00406 LateReferenceDataSource( typename AssignableDataSource<T>::value_t* ptr = 0) 00407 :mptr(ptr) {} 00408 00409 void setPointer( typename AssignableDataSource<T>::value_t* ptr ) { 00410 mptr = ptr; 00411 } 00412 00413 typename DataSource<T>::result_t get() const 00414 { 00415 return *mptr; 00416 } 00417 00418 typename DataSource<T>::result_t value() const 00419 { 00420 return *mptr; 00421 } 00422 00423 void const* getRawDataConst() 00424 { 00425 return mptr; 00426 } 00427 void* getRawData() 00428 { 00429 return mptr; 00430 } 00431 00432 void set( typename AssignableDataSource<T>::param_t t ) { 00433 *mptr = t; 00434 } 00435 00436 typename AssignableDataSource<T>::reference_t set() 00437 { 00438 return *mptr; 00439 } 00440 00441 typename AssignableDataSource<T>::const_reference_t rvalue() const 00442 { 00443 return *mptr; 00444 } 00445 00446 virtual LateReferenceDataSource<T>* clone() const { 00447 return new LateReferenceDataSource<T>( mptr ); 00448 } 00449 00450 virtual LateReferenceDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& ) const { 00451 return const_cast<LateReferenceDataSource<T>* >(this); 00452 } 00453 }; 00454 00463 template<typename T> 00464 class LateConstReferenceDataSource 00465 : public DataSource<T> 00466 { 00467 // a reference to a value_t 00468 const typename DataSource<T>::value_t* mptr; 00469 public: 00470 00471 typedef boost::intrusive_ptr<LateConstReferenceDataSource<T> > shared_ptr; 00472 00473 LateConstReferenceDataSource(const typename DataSource<T>::value_t* ptr = 0) 00474 :mptr(ptr) {} 00475 00476 void setPointer(const typename AssignableDataSource<T>::value_t* ptr ) { 00477 mptr = ptr; 00478 } 00479 00480 void const* getRawDataConst() 00481 { 00482 return mptr; 00483 } 00484 00485 typename DataSource<T>::result_t get() const 00486 { 00487 return *mptr; 00488 } 00489 00490 typename DataSource<T>::result_t value() const 00491 { 00492 return *mptr; 00493 } 00494 00495 typename DataSource<T>::const_reference_t rvalue() const 00496 { 00497 return *mptr; 00498 } 00499 00500 virtual LateConstReferenceDataSource<T>* clone() const { 00501 return new LateConstReferenceDataSource<T>( mptr ); 00502 } 00503 00504 virtual LateConstReferenceDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& ) const { 00505 return const_cast<LateConstReferenceDataSource<T>* >(this); 00506 } 00507 }; 00508 00509 00515 template<typename T> 00516 class ActionAliasDataSource 00517 : public DataSource<T> 00518 { 00519 base::ActionInterface* action; 00520 typename DataSource<T>::shared_ptr alias; 00521 public: 00522 typedef boost::intrusive_ptr<ActionAliasDataSource<T> > shared_ptr; 00523 00524 ActionAliasDataSource(base::ActionInterface* act, DataSource<T>* ds) 00525 : action(act), alias(ds) 00526 {} 00527 00528 ~ActionAliasDataSource() { delete action; } 00529 00530 bool evaluate() const { 00531 // since get() may return a copy, we override evaluate() to 00532 // call alias->get() with alias->evaluate(). 00533 action->readArguments(); 00534 bool r = action->execute(); 00535 action->reset(); 00536 // alias may only be evaluated after action was executed. 00537 alias->evaluate(); 00538 return r; 00539 } 00540 00541 typename DataSource<T>::result_t get() const 00542 { 00543 action->readArguments(); 00544 action->execute(); 00545 action->reset(); 00546 return alias->get(); 00547 } 00548 00549 typename DataSource<T>::result_t value() const 00550 { 00551 return alias->value(); 00552 } 00553 00554 typename DataSource<T>::const_reference_t rvalue() const 00555 { 00556 return alias->rvalue(); 00557 } 00558 00559 virtual void reset() { alias->reset(); } 00560 00561 virtual ActionAliasDataSource<T>* clone() const { 00562 return new ActionAliasDataSource(action, alias.get()); 00563 } 00564 virtual ActionAliasDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const { 00565 return new ActionAliasDataSource( action->copy(alreadyCloned), alias->copy(alreadyCloned) ); 00566 } 00567 }; 00568 00569 00575 template<typename T> 00576 class ActionAliasAssignableDataSource 00577 : public AssignableDataSource<T> 00578 { 00579 base::ActionInterface* action; 00580 typename AssignableDataSource<T>::shared_ptr alias; 00581 public: 00582 typedef boost::intrusive_ptr<ActionAliasDataSource<T> > shared_ptr; 00583 00584 ActionAliasAssignableDataSource(base::ActionInterface* act, AssignableDataSource<T>* ds) 00585 : action(act), alias(ds) 00586 {} 00587 00588 ~ActionAliasAssignableDataSource() { delete action;} 00589 00590 bool evaluate() const { 00591 // since get() may return a copy, we override evaluate() to 00592 // call alias->get() with alias->evaluate(). 00593 action->readArguments(); 00594 bool r = action->execute(); 00595 action->reset(); 00596 // alias may only be evaluated after action was executed. 00597 alias->evaluate(); 00598 return r; 00599 } 00600 00601 typename DataSource<T>::result_t get() const 00602 { 00603 action->readArguments(); 00604 action->execute(); 00605 action->reset(); 00606 return alias->get(); 00607 } 00608 00609 typename DataSource<T>::result_t value() const 00610 { 00611 return alias->value(); 00612 } 00613 00614 void set( typename AssignableDataSource<T>::param_t t ) { 00615 alias->set( t ); 00616 } 00617 00618 typename AssignableDataSource<T>::reference_t set() 00619 { 00620 return alias->set(); 00621 } 00622 00623 typename AssignableDataSource<T>::const_reference_t rvalue() const 00624 { 00625 return alias->rvalue(); 00626 } 00627 00628 virtual void reset() { alias->reset(); } 00629 00630 virtual ActionAliasAssignableDataSource<T>* clone() const { 00631 return new ActionAliasAssignableDataSource(action, alias.get()); 00632 } 00633 virtual ActionAliasAssignableDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const { 00634 return new ActionAliasAssignableDataSource( action->copy(alreadyCloned), alias->copy(alreadyCloned) ); 00635 } 00636 }; 00637 00652 template<typename BoundType> 00653 class UnboundDataSource 00654 : public BoundType 00655 { 00656 public: 00657 typedef typename BoundType::result_t T; 00658 typedef boost::intrusive_ptr< UnboundDataSource<BoundType> > shared_ptr; 00659 00660 UnboundDataSource( T data ); 00661 00662 UnboundDataSource( ); 00663 00664 ~UnboundDataSource() { 00665 } 00666 00667 virtual BoundType* clone() const { 00668 return BoundType::clone(); 00669 } 00670 00671 virtual UnboundDataSource<BoundType>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& replace) const; 00672 }; 00673 00686 template<typename function> 00687 class BinaryDataSource 00688 : public DataSource< typename remove_cr<typename function::result_type>::type > 00689 { 00690 typedef typename remove_cr<typename function::result_type>::type value_t; 00691 typedef typename remove_cr<typename function::first_argument_type>::type first_arg_t; 00692 typedef typename remove_cr<typename function::second_argument_type>::type second_arg_t; 00693 typename DataSource<first_arg_t>::shared_ptr mdsa; 00694 typename DataSource<second_arg_t>::shared_ptr mdsb; 00695 function fun; 00696 mutable value_t mdata; 00697 public: 00698 typedef boost::intrusive_ptr<BinaryDataSource<function> > shared_ptr; 00699 00704 BinaryDataSource( typename DataSource<first_arg_t>::shared_ptr a, 00705 typename DataSource<second_arg_t>::shared_ptr b, 00706 function f ) 00707 : mdsa( a ), mdsb( b ), fun( f ) 00708 { 00709 } 00710 00711 virtual value_t get() const 00712 { 00713 first_arg_t a = mdsa->get(); 00714 second_arg_t b = mdsb->get(); 00715 return mdata = fun( a, b ); 00716 } 00717 00718 virtual value_t value() const 00719 { 00720 return mdata; 00721 } 00722 00723 typename DataSource<value_t>::const_reference_t rvalue() const 00724 { 00725 return mdata; 00726 } 00727 00728 virtual void reset() 00729 { 00730 mdsa->reset(); 00731 mdsb->reset(); 00732 } 00733 00734 virtual BinaryDataSource<function>* clone() const 00735 { 00736 return new BinaryDataSource<function>(mdsa.get(), mdsb.get(), fun); 00737 } 00738 00739 virtual BinaryDataSource<function>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const { 00740 return new BinaryDataSource<function>( mdsa->copy( alreadyCloned ), mdsb->copy( alreadyCloned ), fun ); 00741 } 00742 }; 00743 00749 template <typename function> 00750 class UnaryDataSource 00751 : public DataSource<typename remove_cr<typename function::result_type>::type> 00752 { 00753 typedef typename remove_cr<typename function::result_type>::type value_t; 00754 typedef typename remove_cr<typename function::argument_type>::type arg_t; 00755 typename DataSource<arg_t>::shared_ptr mdsa; 00756 function fun; 00757 mutable value_t mdata; 00758 public: 00759 typedef boost::intrusive_ptr<UnaryDataSource<function> > shared_ptr; 00760 00765 UnaryDataSource( typename DataSource<arg_t>::shared_ptr a, function f ) 00766 : mdsa( a ), fun( f ) 00767 { 00768 } 00769 00770 virtual value_t get() const 00771 { 00772 return mdata = fun( mdsa->get() ); 00773 } 00774 00775 virtual value_t value() const 00776 { 00777 return mdata; 00778 } 00779 00780 typename DataSource<value_t>::const_reference_t rvalue() const 00781 { 00782 return mdata; 00783 } 00784 00785 00786 void reset() 00787 { 00788 mdsa->reset(); 00789 } 00790 00791 virtual UnaryDataSource<function>* clone() const 00792 { 00793 return new UnaryDataSource<function>(mdsa.get(), fun); 00794 } 00795 00796 virtual UnaryDataSource<function>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const { 00797 return new UnaryDataSource<function>( mdsa->copy( alreadyCloned ), fun ); 00798 } 00799 }; 00800 00808 template<typename function> 00809 class NArityDataSource 00810 : public DataSource<typename remove_cr<typename function::result_type>::type> 00811 { 00812 typedef typename remove_cr<typename function::result_type>::type value_t; 00813 typedef typename remove_cr<typename function::argument_type>::type arg_t; 00814 mutable std::vector<arg_t> margs; 00815 std::vector<typename DataSource<arg_t>::shared_ptr > mdsargs; 00816 function fun; 00817 mutable value_t mdata; 00818 public: 00819 typedef boost::intrusive_ptr<NArityDataSource<function> > shared_ptr; 00820 00825 NArityDataSource( function f = function() ) 00826 : fun( f ) 00827 { 00828 } 00829 00834 NArityDataSource( function f, const std::vector<typename DataSource<arg_t>::shared_ptr >& dsargs ) 00835 : margs( dsargs.size() ), mdsargs(dsargs), fun( f ) 00836 { 00837 } 00838 00839 void add( typename DataSource<arg_t>::shared_ptr ds ) { 00840 mdsargs.push_back(ds); 00841 margs.push_back( ds->value() ); 00842 } 00843 00844 virtual value_t get() const 00845 { 00846 assert( mdsargs.size() == margs.size() ); 00847 for( unsigned int i=0; i !=mdsargs.size(); ++i) 00848 margs[i] = mdsargs[i]->get(); 00849 return mdata = fun( margs ); 00850 } 00851 00852 virtual value_t value() const 00853 { 00854 return mdata; 00855 } 00856 00857 typename DataSource<value_t>::const_reference_t rvalue() const 00858 { 00859 return mdata; 00860 } 00861 00862 virtual void reset() 00863 { 00864 for( unsigned int i=0; i !=mdsargs.size(); ++i) 00865 mdsargs[i]->reset(); 00866 } 00867 00868 virtual NArityDataSource<function>* clone() const 00869 { 00870 return new NArityDataSource<function>(fun, mdsargs); 00871 } 00872 00873 virtual NArityDataSource<function>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& alreadyCloned ) const { 00874 std::vector<typename DataSource<arg_t>::shared_ptr > newargs( mdsargs.size() ); 00875 for( unsigned int i=0; i !=mdsargs.size(); ++i) 00876 newargs[i] = mdsargs[i]->copy(alreadyCloned); 00877 return new NArityDataSource<function>( fun, newargs ); 00878 } 00879 }; 00880 } 00881 } 00882 00883 #include "DataSources.inl" 00884 00885 #endif 00886