Orocos Real-Time Toolkit  2.6.0
DataSources.hpp
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