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 "DataSource.hpp"
00043 #include "DataSourceAdaptor.hpp"
00044 #include "DataSourceTypeInfo.hpp"
00045 #include "AssignCommand.hpp"
00046 #include <vector>
00047 
00048 namespace RTT
00049 {
00050 
00058     template<typename T>
00059     class ValueDataSource
00060         : public AssignableDataSource<T>
00061     {
00062     protected:
00063         typename DataSource<T>::value_t mdata;
00064 
00065     public:
00069         ~ValueDataSource();
00070 
00071         typedef boost::intrusive_ptr<ValueDataSource<T> > shared_ptr;
00072 
00073         ValueDataSource( T data );
00074 
00075         ValueDataSource( );
00076 
00077         typename DataSource<T>::result_t get() const
00078         {
00079             return mdata;
00080         }
00081 
00082         typename DataSource<T>::result_t value() const
00083         {
00084             return mdata;
00085         }
00086 
00087         void set( typename AssignableDataSource<T>::param_t t );
00088 
00089         typename AssignableDataSource<T>::reference_t set()
00090         {
00091             return mdata;
00092         }
00093 
00094         typename AssignableDataSource<T>::const_reference_t rvalue() const
00095         {
00096             return mdata;
00097         }
00098 
00099         virtual ValueDataSource<T>* clone() const;
00100 
00101         virtual ValueDataSource<T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& replace ) const;
00102     };
00103 
00107     template<>
00108     RTT_API void ValueDataSource<std::string>::set(  AssignableDataSource<std::string>::param_t t );
00109 
00113     template<>
00114     RTT_API ValueDataSource<std::string>::ValueDataSource(std::string t );
00115 
00121     template<typename T>
00122     class ConstantDataSource
00123         : public DataSource<T>
00124     {
00129         typename boost::add_const<typename DataSource<T>::value_t>::type mdata;
00130 
00131     public:
00135         ~ConstantDataSource();
00136 
00137         typedef boost::intrusive_ptr< ConstantDataSource<T> > shared_ptr;
00138 
00139         ConstantDataSource( T value );
00140 
00141         typename DataSource<T>::result_t get() const
00142         {
00143             return mdata;
00144         }
00145 
00146         typename DataSource<T>::result_t value() const
00147         {
00148             return mdata;
00149         }
00150 
00151         virtual ConstantDataSource<T>* clone() const;
00152 
00153         virtual ConstantDataSource<T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const;
00154     };
00155 
00161     template<typename T>
00162     class ReferenceDataSource
00163         : public AssignableDataSource<T>
00164     {
00165         // a reference to a value_t
00166         typename AssignableDataSource<T>::reference_t mref;
00167     public:
00171         ~ReferenceDataSource();
00172 
00173         typedef boost::intrusive_ptr<ReferenceDataSource<T> > shared_ptr;
00174 
00175         ReferenceDataSource( typename AssignableDataSource<T>::reference_t ref );
00176 
00177         typename DataSource<T>::result_t get() const
00178         {
00179             return mref;
00180         }
00181 
00182         typename DataSource<T>::result_t value() const
00183         {
00184             return mref;
00185         }
00186 
00187         void set( typename AssignableDataSource<T>::param_t t );
00188 
00189         typename AssignableDataSource<T>::reference_t set()
00190         {
00191             return mref;
00192         }
00193 
00194         typename AssignableDataSource<T>::const_reference_t rvalue() const
00195         {
00196             return mref;
00197         }
00198 
00199         virtual ReferenceDataSource<T>* clone() const;
00200 
00201         virtual ReferenceDataSource<T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const;
00202     };
00203 
00213     template<typename T, typename Index, typename SetType, typename IPred, typename APred>
00214     class IndexedValueDataSource
00215         : public ValueDataSource<T>
00216     {
00217     public:
00218         typedef boost::intrusive_ptr<IndexedValueDataSource<T, Index, SetType, IPred, APred> > shared_ptr;
00219 
00220         IndexedValueDataSource( T idata )
00221             : ValueDataSource<T>(idata) {}
00222 
00223         IndexedValueDataSource()
00224         {}
00225 
00226         CommandInterface* updateCommand( DataSourceBase* other)
00227         {
00228             DataSourceBase::const_ptr r( other );
00229             typedef typename AssignableDataSource<T>::copy_t copy_t;
00230             typename DataSource< copy_t >::shared_ptr ct = AdaptDataSource<copy_t>()( other );
00231             if ( ct )
00232                 return new detail::AssignContainerCommand<T,APred,copy_t >( this, ct );
00233 
00234 #ifndef ORO_EMBEDDED
00235             throw bad_assignment();
00236 #else
00237             return 0;
00238 #endif
00239         }
00240 
00241         CommandInterface* updatePartCommand( DataSourceBase* index, DataSourceBase* rhs )
00242         {
00243             DataSourceBase::shared_ptr r( rhs );
00244             DataSourceBase::shared_ptr i( index );
00245             typename DataSource<SetType>::shared_ptr t = AdaptDataSource<SetType>()( detail::DataSourceTypeInfo<SetType>::getTypeInfo()->convert(r) );
00246             if ( ! t ) {
00247 #ifndef ORO_EMBEDDED
00248                 throw bad_assignment();
00249 #else
00250                 return 0;
00251 #endif
00252             }
00253             typename DataSource<Index>::shared_ptr ind = AdaptDataSource<Index>()( i );
00254             if ( ! ind ) {
00255 #ifndef ORO_EMBEDDED
00256                 throw bad_assignment();
00257 #else
00258                 return 0;
00259 #endif
00260             }
00261             typename AssignableDataSource<T>::shared_ptr mthis(this);
00262             return new detail::AssignIndexCommand<T, Index, SetType, IPred>( mthis, ind ,t );
00263         }
00264 
00265         IndexedValueDataSource<T, Index, SetType,IPred,APred>* clone() const
00266         {
00267             return new IndexedValueDataSource( this->mdata );
00268         }
00269 
00270         IndexedValueDataSource<T, Index, SetType,IPred,APred>* copy( std::map<const DataSourceBase*, DataSourceBase*>& replace) const
00271         {
00272             // if somehow a copy exists, return the copy, otherwise return this.
00273             if ( replace[this] != 0 ) {
00274                 assert ( (dynamic_cast<IndexedValueDataSource<T, Index, SetType,IPred,APred>*>( replace[this] )
00275                          == static_cast<IndexedValueDataSource<T, Index, SetType,IPred,APred>*>( replace[this] ) ) );
00276                 return static_cast<IndexedValueDataSource<T, Index, SetType,IPred,APred>*>( replace[this] );
00277             }
00278             // Other pieces in the code rely on insertion in the map :
00279             replace[this] = const_cast<IndexedValueDataSource<T, Index, SetType,IPred,APred>*>(this);
00280             // return this instead of a copy.
00281             return const_cast<IndexedValueDataSource<T, Index, SetType,IPred,APred>*>(this);
00282         }
00283     };
00284 
00285     namespace detail {
00297         template<typename BoundType>
00298         class UnboundDataSource
00299             : public BoundType
00300         {
00301         public:
00302             typedef typename BoundType::result_t T;
00303             typedef boost::intrusive_ptr< UnboundDataSource<BoundType> > shared_ptr;
00304 
00305             UnboundDataSource( T data );
00306 
00307             UnboundDataSource( );
00308 
00309             ~UnboundDataSource() {
00310             }
00311 
00312             virtual BoundType* clone() const {
00313                 return BoundType::clone();
00314             }
00315 
00316             virtual UnboundDataSource<BoundType>* copy( std::map<const DataSourceBase*, DataSourceBase*>& replace) const;
00317         };
00318 
00319     }
00320 
00333   template<typename function>
00334   class BinaryDataSource
00335     : public DataSource<typename function::result_type>
00336   {
00337     typedef typename function::result_type value_t;
00338     typedef typename function::first_argument_type  first_arg_t;
00339     typedef typename function::second_argument_type second_arg_t;
00340     typename DataSource<first_arg_t>::shared_ptr mdsa;
00341     typename DataSource<second_arg_t>::shared_ptr mdsb;
00342     function fun;
00343   public:
00344     typedef boost::intrusive_ptr<BinaryDataSource<function> > shared_ptr;
00345 
00350     BinaryDataSource( typename DataSource<first_arg_t>::shared_ptr a,
00351                       typename DataSource<second_arg_t>::shared_ptr b,
00352                       function f )
00353       : mdsa( a ), mdsb( b ), fun( f )
00354       {
00355       }
00356 
00357     virtual value_t get() const
00358       {
00359         first_arg_t a = mdsa->get();
00360         second_arg_t b = mdsb->get();
00361         return fun( a, b );
00362       }
00363 
00364     virtual value_t value() const
00365       {
00366         first_arg_t a = mdsa->value();
00367         second_arg_t b = mdsb->value();
00368         return fun( a, b );
00369       }
00370 
00371     virtual void reset()
00372       {
00373         mdsa->reset();
00374         mdsb->reset();
00375       }
00376 
00377       virtual BinaryDataSource<function>* clone() const
00378       {
00379           return new BinaryDataSource<function>(mdsa.get(), mdsb.get(), fun);
00380       }
00381 
00382       virtual BinaryDataSource<function>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const {
00383           return new BinaryDataSource<function>( mdsa->copy( alreadyCloned ), mdsb->copy( alreadyCloned ), fun );
00384       }
00385   };
00386 
00390   template<typename function>
00391   class TernaryDataSource
00392     : public DataSource<typename function::result_type>
00393   {
00394     typedef typename function::result_type value_t;
00395     typedef typename function::first_argument_type first_arg_t;
00396     typedef typename function::second_argument_type second_arg_t;
00397     typedef typename function::third_argument_type third_arg_t;
00398     typename DataSource<first_arg_t>::shared_ptr mdsa;
00399     typename DataSource<second_arg_t>::shared_ptr mdsb;
00400     typename DataSource<third_arg_t>::shared_ptr mdsc;
00401     function fun;
00402   public:
00403     typedef boost::intrusive_ptr<TernaryDataSource<function> > shared_ptr;
00404 
00409     TernaryDataSource( typename DataSource<first_arg_t>::shared_ptr a,
00410                        typename DataSource<second_arg_t>::shared_ptr b,
00411                        typename DataSource<third_arg_t>::shared_ptr c,
00412                        function f )
00413       : mdsa( a ), mdsb( b ), mdsc( c ), fun( f )
00414       {
00415       }
00416 
00417     virtual value_t get() const
00418       {
00419         first_arg_t a = mdsa->get();
00420         second_arg_t b = mdsb->get();
00421         third_arg_t c = mdsc->get();
00422         return fun( a, b, c );
00423       }
00424 
00425     virtual value_t value() const
00426       {
00427         first_arg_t a = mdsa->value();
00428         second_arg_t b = mdsb->value();
00429         third_arg_t c = mdsc->value();
00430         return fun( a, b, c );
00431       }
00432 
00433     virtual void reset()
00434       {
00435         mdsa->reset();
00436         mdsb->reset();
00437         mdsc->reset();
00438       }
00439 
00440       virtual TernaryDataSource<function>* clone() const
00441       {
00442           return new TernaryDataSource<function>(mdsa.get(), mdsb.get(), mdsc.get(), fun);
00443       }
00444 
00445       virtual TernaryDataSource<function>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const {
00446           return new TernaryDataSource<function>( mdsa->copy( alreadyCloned ), mdsb->copy( alreadyCloned ), mdsc->copy( alreadyCloned ), fun );
00447       }
00448 
00449   };
00450 
00454   template<typename function>
00455   class SixaryDataSource
00456     : public DataSource<typename function::result_type>
00457   {
00458     typedef typename function::result_type value_t;
00459     typedef typename function::first_argument_type first_arg_t;
00460     typedef typename function::second_argument_type second_arg_t;
00461     typedef typename function::third_argument_type third_arg_t;
00462     typedef typename function::fourth_argument_type fourth_arg_t;
00463     typedef typename function::fifth_argument_type fifth_arg_t;
00464     typedef typename function::sixth_argument_type sixth_arg_t;
00465     typename DataSource<first_arg_t>::shared_ptr mdsa;
00466     typename DataSource<second_arg_t>::shared_ptr mdsb;
00467     typename DataSource<third_arg_t>::shared_ptr mdsc;
00468     typename DataSource<fourth_arg_t>::shared_ptr mdsd;
00469     typename DataSource<fifth_arg_t>::shared_ptr mdse;
00470     typename DataSource<sixth_arg_t>::shared_ptr mdsf;
00471     function fun;
00472   public:
00473     typedef boost::intrusive_ptr<SixaryDataSource<function> > shared_ptr;
00474 
00479     SixaryDataSource(
00480                      typename DataSource<first_arg_t>::shared_ptr a,
00481                      typename DataSource<second_arg_t>::shared_ptr b,
00482                      typename DataSource<third_arg_t>::shared_ptr c,
00483                      typename DataSource<fourth_arg_t>::shared_ptr d,
00484                      typename DataSource<fifth_arg_t>::shared_ptr e,
00485                      typename DataSource<sixth_arg_t>::shared_ptr f,
00486                        function _fun )
00487       : mdsa( a ), mdsb( b ), mdsc( c ),mdsd( d ), mdse( e ), mdsf( f ),
00488         fun( _fun )
00489       {
00490       }
00491 
00492     virtual value_t get() const
00493       {
00494         first_arg_t a = mdsa->get();
00495         second_arg_t b = mdsb->get();
00496         third_arg_t c = mdsc->get();
00497         fourth_arg_t d = mdsd->get();
00498         fifth_arg_t e = mdse->get();
00499         sixth_arg_t f = mdsf->get();
00500         return fun( a, b, c, d, e, f );
00501       }
00502 
00503     virtual value_t value() const
00504       {
00505         first_arg_t a = mdsa->value();
00506         second_arg_t b = mdsb->value();
00507         third_arg_t c = mdsc->value();
00508         fourth_arg_t d = mdsd->value();
00509         fifth_arg_t e = mdse->value();
00510         sixth_arg_t f = mdsf->value();
00511         return fun( a, b, c, d, e, f );
00512       }
00513 
00514     virtual void reset()
00515       {
00516         mdsa->reset();
00517         mdsb->reset();
00518         mdsc->reset();
00519         mdsd->reset();
00520         mdse->reset();
00521         mdsf->reset();
00522       }
00523 
00524       virtual SixaryDataSource<function>* clone() const
00525       {
00526           return new SixaryDataSource<function>(mdsa.get(), mdsb.get(), mdsc.get(),
00527                                                 mdsd.get(), mdse.get(), mdsf.get(),
00528                                                 fun);
00529       }
00530 
00531       virtual SixaryDataSource<function>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const {
00532           return new SixaryDataSource<function>( mdsa->copy( alreadyCloned ), mdsb->copy( alreadyCloned ),
00533                                                  mdsc->copy( alreadyCloned ), mdsd->copy( alreadyCloned ),
00534                                                  mdse->copy( alreadyCloned ), mdsf->copy( alreadyCloned ), fun );
00535       }
00536   };
00537 
00543   template <typename function>
00544   class UnaryDataSource
00545     : public DataSource<typename function::result_type>
00546   {
00547     typedef typename function::result_type value_t;
00548     typedef typename function::argument_type arg_t;
00549     typename DataSource<arg_t>::shared_ptr mdsa;
00550     function fun;
00551   public:
00552     typedef boost::intrusive_ptr<UnaryDataSource<function> > shared_ptr;
00553 
00558     UnaryDataSource( typename DataSource<arg_t>::shared_ptr a, function f )
00559       : mdsa( a ), fun( f )
00560       {
00561       }
00562 
00563     virtual value_t get() const
00564       {
00565         return fun( mdsa->get() );
00566       }
00567 
00568     virtual value_t value() const
00569       {
00570         return fun( mdsa->value() );
00571       }
00572 
00573     void reset()
00574       {
00575         mdsa->reset();
00576       }
00577 
00578     virtual UnaryDataSource<function>* clone() const
00579       {
00580           return new UnaryDataSource<function>(mdsa.get(), fun);
00581       }
00582 
00583     virtual UnaryDataSource<function>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const {
00584           return new UnaryDataSource<function>( mdsa->copy( alreadyCloned ), fun );
00585       }
00586   };
00587 
00595   template<typename function>
00596   class NArityDataSource
00597     : public DataSource<typename function::result_type>
00598   {
00599       typedef typename function::result_type value_t;
00600       typedef typename function::argument_type  arg_t;
00601       mutable std::vector<arg_t> margs;
00602       std::vector<typename DataSource<arg_t>::shared_ptr > mdsargs;
00603       function fun;
00604   public:
00605       typedef boost::intrusive_ptr<NArityDataSource<function> > shared_ptr;
00606 
00611       NArityDataSource( function f = function() )
00612           : fun( f )
00613       {
00614       }
00615 
00620       NArityDataSource( function f, const std::vector<typename DataSource<arg_t>::shared_ptr >& dsargs )
00621           : margs( dsargs.size() ), mdsargs(dsargs), fun( f )
00622       {
00623       }
00624 
00625       void add( typename DataSource<arg_t>::shared_ptr ds ) {
00626           mdsargs.push_back(ds);
00627           margs.push_back( ds->value() );
00628       }
00629 
00630       virtual value_t get() const
00631       {
00632           assert( mdsargs.size() == margs.size() );
00633           for( unsigned int i=0; i !=mdsargs.size(); ++i)
00634               margs[i] = mdsargs[i]->get();
00635           return fun( margs );
00636       }
00637 
00638       virtual value_t value() const
00639       {
00640           assert( mdsargs.size() == margs.size() );
00641           for( unsigned int i=0; i !=mdsargs.size(); ++i)
00642               margs[i] = mdsargs[i]->value();
00643           return fun( margs ); // fun is allowed to return margs directly.
00644       }
00645 
00646       virtual void reset()
00647       {
00648           for( unsigned int i=0; i !=mdsargs.size(); ++i)
00649               mdsargs[i]->reset();
00650       }
00651 
00652       virtual NArityDataSource<function>* clone() const
00653       {
00654           return new NArityDataSource<function>(fun, mdsargs);
00655       }
00656 
00657       virtual NArityDataSource<function>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const {
00658           std::vector<typename DataSource<arg_t>::shared_ptr > newargs( mdsargs.size() );
00659           for( unsigned int i=0; i !=mdsargs.size(); ++i)
00660               newargs[i] = mdsargs[i]->copy(alreadyCloned);
00661           return new NArityDataSource<function>( fun, newargs );
00662       }
00663   };
00664 }
00665 
00666 #include "DataSources.inl"
00667 
00668 #endif
00669 
Generated on Thu Dec 23 13:22:37 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3