FunctorDataSource.hpp

00001 /***************************************************************************
00002   tag: Peter Soetens  Tue Dec 21 22:43:08 CET 2004  TemplateMemberFactory.hpp
00003 
00004                         TemplateMemberFactory.hpp -  description
00005                            -------------------
00006     begin                : Tue December 21 2004
00007     copyright            : (C) 2004 Peter Soetens
00008     email                : peter.soetens@mech.kuleuven.ac.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 FUNCTORDATASOURCE_HPP
00040 #define FUNCTORDATASOURCE_HPP
00041 
00042 #include "DataSource.hpp"
00043 #include <boost/bind.hpp>
00044 #include <boost/type_traits.hpp>
00045 
00046 namespace RTT
00047 {
00048 
00049     namespace detail {
00050 
00054         template<typename R, typename FunctorT>
00055         struct FunctionForwarder
00056         {
00057             typedef typename boost::remove_const<R>::type result_type;
00058 
00059             FunctorT gen;
00060             result_type res;
00061 
00062             result_type result() { return res; }
00063 
00064             FunctionForwarder(FunctorT& f)
00065                 :gen(f)
00066             {}
00067 
00068             R invoke() {
00069                 res = gen();
00070                 return res;
00071             }
00072 
00073             template<typename Arg1T>
00074             R invoke(DataSource<Arg1T>* arg1) {
00075                 // The "Forwarding problem" : gen is a boost::bind functor
00076                 // and can not be given non-const temporaries or literal constants.
00077                 // thus _to_be_sure_, we _must_ copy the result to a local variable
00078                 // and then pass that variable on. Fortunately, if Arg1T is a reference,
00079                 // this does not involve a value copy and if Arg1T is a value,
00080                 // the gen( ) function takes a reference to it, thus, again,
00081                 // no additional copy is made.
00082                 Arg1T a1 = arg1->get();
00083                 res = gen(a1);
00084                 arg1->updated();
00085                 return res;
00086             }
00087             template<typename Arg1T, typename Arg2T>
00088             R invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2) {
00089                 Arg1T a1 = arg1->get();
00090                 Arg2T a2 = arg2->get();
00091                 res = gen(a1,a2);
00092                 arg1->updated();
00093                 arg2->updated();
00094                 return res;
00095             }
00096 
00097             template< typename Arg1T, typename Arg2T, typename Arg3T>
00098             R invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3) {
00099                 Arg1T a1 = arg1->get();
00100                 Arg2T a2 = arg2->get();
00101                 Arg3T a3 = arg3->get();
00102                 res = gen(a1,a2,a3);
00103                 arg1->updated();
00104                 arg2->updated();
00105                 arg3->updated();
00106                 return res;
00107             }
00108 
00109             template< typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T>
00110             R invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3, DataSource<Arg4T>* arg4) {
00111                 Arg1T a1 = arg1->get();
00112                 Arg2T a2 = arg2->get();
00113                 Arg3T a3 = arg3->get();
00114                 Arg4T a4 = arg4->get();
00115                 res = gen(a1,a2,a3,a4);
00116                 arg1->updated();
00117                 arg2->updated();
00118                 arg3->updated();
00119                 arg4->updated();
00120                 return res;
00121             }
00122 
00123             template< typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T, typename Arg5T>
00124             R invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3, DataSource<Arg4T>* arg4, DataSource<Arg5T>* arg5) {
00125                 Arg1T a1 = arg1->get();
00126                 Arg2T a2 = arg2->get();
00127                 Arg3T a3 = arg3->get();
00128                 Arg4T a4 = arg4->get();
00129                 Arg5T a5 = arg5->get();
00130                 res = gen(a1,a2,a3,a4,a5);
00131                 arg1->updated();
00132                 arg2->updated();
00133                 arg3->updated();
00134                 arg4->updated();
00135                 arg5->updated();
00136                 return res;
00137             }
00138 
00139             template< typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T, typename Arg5T, typename Arg6T>
00140             R invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3, DataSource<Arg4T>* arg4, DataSource<Arg5T>* arg5, DataSource<Arg6T>* arg6) {
00141                 Arg1T a1 = arg1->get();
00142                 Arg2T a2 = arg2->get();
00143                 Arg3T a3 = arg3->get();
00144                 Arg4T a4 = arg4->get();
00145                 Arg5T a5 = arg5->get();
00146                 Arg6T a6 = arg6->get();
00147                 res = gen(a1,a2,a3,a4,a5,a6);
00148                 arg1->updated();
00149                 arg2->updated();
00150                 arg3->updated();
00151                 arg4->updated();
00152                 arg5->updated();
00153                 arg6->updated();
00154                 return res;
00155             }
00156         };
00157 
00158         template<typename FunctorT>
00159         struct FunctionForwarder<void, FunctorT>
00160         {
00161             FunctorT gen;
00162             typedef void result_type;
00163 
00164             FunctionForwarder(FunctorT& f)
00165                 :gen(f)
00166             {}
00167 
00168             result_type result() {}
00169 
00170             void invoke() {
00171                 gen();
00172             }
00173 
00174             template< typename Arg1T>
00175             void invoke(DataSource<Arg1T>* arg1) {
00176                 // The "Forwarding problem" : gen is a boost::bind functor
00177                 // and can not be given non-const temporaries or literal constants.
00178                 // thus _to_be_sure_, we _must_ copy the result to a local variable
00179                 // and then pass that variable on. Fortunately, if Arg1T is a reference,
00180                 // this does not involve a value copy and if Arg1T is a value,
00181                 // the gen( ) function takes a reference to it, thus, again,
00182                 // no additional copy is made.
00183                 Arg1T a1 = arg1->get();
00184                 gen(a1);
00185                 arg1->updated();
00186             }
00187             template< typename Arg1T, typename Arg2T>
00188             void invoke(DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2) {
00189                 Arg1T a1 = arg1->get();
00190                 Arg2T a2 = arg2->get();
00191                 gen(a1,a2);
00192                 arg1->updated();
00193                 arg2->updated();
00194             }
00195 
00196             template< typename Arg1T, typename Arg2T, typename Arg3T>
00197             void invoke(DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3) {
00198                 Arg1T a1 = arg1->get();
00199                 Arg2T a2 = arg2->get();
00200                 Arg3T a3 = arg3->get();
00201                 gen(a1,a2,a3);
00202                 arg1->updated();
00203                 arg2->updated();
00204                 arg3->updated();
00205             }
00206 
00207             template< typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T>
00208             void invoke(DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3, DataSource<Arg4T>* arg4) {
00209                 Arg1T a1 = arg1->get();
00210                 Arg2T a2 = arg2->get();
00211                 Arg3T a3 = arg3->get();
00212                 Arg4T a4 = arg4->get();
00213                 gen(a1,a2,a3,a4);
00214                 arg1->updated();
00215                 arg2->updated();
00216                 arg3->updated();
00217                 arg4->updated();
00218             }
00219 
00220             template< typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T, typename Arg5T>
00221             void invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3, DataSource<Arg4T>* arg4, DataSource<Arg5T>* arg5) {
00222                 Arg1T a1 = arg1->get();
00223                 Arg2T a2 = arg2->get();
00224                 Arg3T a3 = arg3->get();
00225                 Arg4T a4 = arg4->get();
00226                 Arg5T a5 = arg5->get();
00227                 gen(a1,a2,a3,a4,a5);
00228                 arg1->updated();
00229                 arg2->updated();
00230                 arg3->updated();
00231                 arg4->updated();
00232                 arg5->updated();
00233             }
00234 
00235             template< typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T, typename Arg5T, typename Arg6T>
00236             void invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3, DataSource<Arg4T>* arg4, DataSource<Arg5T>* arg5, DataSource<Arg6T>* arg6) {
00237                 Arg1T a1 = arg1->get();
00238                 Arg2T a2 = arg2->get();
00239                 Arg3T a3 = arg3->get();
00240                 Arg4T a4 = arg4->get();
00241                 Arg5T a5 = arg5->get();
00242                 Arg6T a6 = arg6->get();
00243                 gen(a1,a2,a3,a4,a5,a6);
00244                 arg1->updated();
00245                 arg2->updated();
00246                 arg3->updated();
00247                 arg4->updated();
00248                 arg5->updated();
00249                 arg6->updated();
00250             }
00251         };
00252 
00256         template<typename R, typename FunctorT>
00257         struct FunctionForwarder<R&, FunctorT>
00258         {
00259             // The trick is to store the result (a reference) of the function
00260             // in a pointer.
00261             typedef R& result_type;
00262             typedef R*  store_type;
00263 
00264             FunctorT gen;
00265             store_type res;
00266 
00267             result_type result() {
00268                 return *res;
00269             }
00270 
00271             FunctionForwarder(FunctorT& f)
00272                 :gen(f), res(0)
00273             {}
00274 
00275             result_type invoke() {
00276                 res = &(gen());
00277                 return *res;
00278             }
00279 
00280             template<typename Arg1T>
00281             result_type invoke(DataSource<Arg1T>* arg1) {
00282                 // The "Forwarding problem" : gen is a boost::bind functor
00283                 // and can not be given non-const temporaries or literal constants.
00284                 // thus _to_be_sure_, we _must_ copy the result to a local variable
00285                 // and then pass that variable on. Fortunately, if Arg1T is a reference,
00286                 // this does not involve a value copy and if Arg1T is a value,
00287                 // the gen( ) function takes a reference to it, thus, again,
00288                 // no additional copy is made.
00289                 Arg1T a1 = arg1->get();
00290                 res = &gen(a1);
00291                 arg1->updated();
00292                 return *res;
00293             }
00294             template<typename Arg1T, typename Arg2T>
00295             result_type invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2) {
00296                 Arg1T a1 = arg1->get();
00297                 Arg2T a2 = arg2->get();
00298                 res = &gen(a1,a2);
00299                 arg1->updated();
00300                 arg2->updated();
00301                 return *res;
00302             }
00303 
00304             template< typename Arg1T, typename Arg2T, typename Arg3T>
00305             result_type invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3) {
00306                 Arg1T a1 = arg1->get();
00307                 Arg2T a2 = arg2->get();
00308                 Arg3T a3 = arg3->get();
00309                 res = &gen(a1,a2,a3);
00310                 arg1->updated();
00311                 arg2->updated();
00312                 arg3->updated();
00313                 return *res;
00314             }
00315 
00316             template< typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T>
00317             result_type invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3, DataSource<Arg4T>* arg4) {
00318                 Arg1T a1 = arg1->get();
00319                 Arg2T a2 = arg2->get();
00320                 Arg3T a3 = arg3->get();
00321                 Arg4T a4 = arg4->get();
00322                 res = &gen(a1,a2,a3,a4);
00323                 arg1->updated();
00324                 arg2->updated();
00325                 arg3->updated();
00326                 arg4->updated();
00327                 return *res;
00328             }
00329 
00330             template< typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T, typename Arg5T>
00331             result_type invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3, DataSource<Arg4T>* arg4, DataSource<Arg5T>* arg5) {
00332                 Arg1T a1 = arg1->get();
00333                 Arg2T a2 = arg2->get();
00334                 Arg3T a3 = arg3->get();
00335                 Arg4T a4 = arg4->get();
00336                 Arg5T a5 = arg5->get();
00337                 res = &gen(a1,a2,a3,a4,a5);
00338                 arg1->updated();
00339                 arg2->updated();
00340                 arg3->updated();
00341                 arg4->updated();
00342                 arg5->updated();
00343                 return *res;
00344             }
00345 
00346             template< typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T, typename Arg5T, typename Arg6T>
00347             result_type invoke( DataSource<Arg1T>* arg1, DataSource<Arg2T>* arg2, DataSource<Arg3T>* arg3, DataSource<Arg4T>* arg4, DataSource<Arg5T>* arg5, DataSource<Arg6T>* arg6) {
00348                 Arg1T a1 = arg1->get();
00349                 Arg2T a2 = arg2->get();
00350                 Arg3T a3 = arg3->get();
00351                 Arg4T a4 = arg4->get();
00352                 Arg5T a5 = arg5->get();
00353                 Arg6T a6 = arg6->get();
00354                 res = &gen(a1,a2,a3,a4,a5,a6);
00355                 arg1->updated();
00356                 arg2->updated();
00357                 arg3->updated();
00358                 arg4->updated();
00359                 arg5->updated();
00360                 arg6->updated();
00361                 return *res;
00362             }
00363         };
00364 
00365 
00366 
00373     template<typename FunctorT>
00374     struct FunctorDataSource0
00375       : public DataSource< typename FunctorT::result_type >
00376     {
00377       typedef typename FunctorT::result_type value_t;
00378       mutable FunctionForwarder<value_t,FunctorT> ff;
00379     public:
00380         typedef boost::intrusive_ptr< FunctorDataSource0<FunctorT> > shared_ptr;
00381 
00382         FunctorDataSource0( FunctorT g )
00383             : ff( g )
00384         {
00385         }
00386 
00387         typename DataSource<value_t>::result_t get() const
00388         {
00389           return ff.invoke();
00390         }
00391 
00392         typename DataSource<value_t>::result_t value() const
00393         {
00394           return ff.result();
00395         }
00396 
00397         virtual FunctorDataSource0* clone() const
00398         {
00399             return new FunctorDataSource0( ff.gen );
00400         }
00401         virtual FunctorDataSource0* copy( std::map<const DataSourceBase*, DataSourceBase*>& /*alreadyCloned*/ ) const
00402         {
00403           return new FunctorDataSource0<FunctorT>( ff.gen );
00404         }
00405     };
00406 
00407   template<typename FunctorT, typename Arg1T>
00408   struct FunctorDataSource1
00409       : public DataSource< typename FunctorT::result_type >
00410   {
00411     typedef typename FunctorT::result_type value_t;
00412     mutable FunctionForwarder<value_t,FunctorT> ff;
00413     typename DataSource<Arg1T>::shared_ptr arg1;
00414   public:
00415       typedef boost::intrusive_ptr< FunctorDataSource1<FunctorT,Arg1T> > shared_ptr;
00416 
00417       FunctorDataSource1( FunctorT g, DataSource<Arg1T>* a1 = 0 )
00418           : ff( g ), arg1( a1 )
00419       {
00420       }
00421 
00422       void setArguments(DataSource<Arg1T>* a1)
00423       {
00424           arg1 = a1;
00425       }
00426 
00427       value_t value() const
00428       {
00429           return ff.result();
00430       }
00431 
00432       value_t get() const
00433       {
00434           return ff.invoke( arg1.get() );
00435       }
00436 
00437     virtual FunctorDataSource1<FunctorT, Arg1T>* clone() const
00438       {
00439         return new FunctorDataSource1<FunctorT, Arg1T>( ff.gen, arg1.get() );
00440       }
00441     virtual FunctorDataSource1<FunctorT, Arg1T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const
00442       {
00443         return new FunctorDataSource1<FunctorT, Arg1T>( ff.gen, arg1->copy( alreadyCloned ) );
00444       }
00445   };
00446 
00451     template<typename ComponentT, typename FunctorT>
00452     class FunctorDataSourceDS0
00453       : public DataSource< typename FunctorT::result_type >
00454     {
00455     public:
00456         typedef typename FunctorT::result_type value_t;
00457         typedef typename DataSource<value_t>::value_t plain_t;
00458     private:
00459         typename DataSource<boost::weak_ptr<ComponentT> >::shared_ptr ds;
00460         mutable FunctorT gen;
00461         mutable plain_t res;
00462         static plain_t empty_return;
00463     public:
00464         typedef boost::intrusive_ptr< FunctorDataSourceDS0<ComponentT,FunctorT> > shared_ptr;
00465 
00466       FunctorDataSourceDS0(DataSource<boost::weak_ptr<ComponentT> >*c, FunctorT g )
00467         : ds(c), gen( g )
00468         {
00469         }
00470 
00471         value_t get() const
00472         {
00473             boost::shared_ptr<ComponentT> c = ds->get().lock();
00474             if(c) {
00475                 ComponentT* ct = c.get();
00476                 res = gen( ct );
00477                 return res;
00478             }else
00479                 return empty_return;
00480         }
00481 
00482         value_t value() const
00483         {
00484             return res;
00485         }
00486 
00487         virtual FunctorDataSourceDS0<ComponentT,FunctorT>* clone() const
00488         {
00489             return new FunctorDataSourceDS0<ComponentT,FunctorT>( ds.get(),  gen );
00490         }
00491       virtual FunctorDataSourceDS0<ComponentT,FunctorT>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const
00492         {
00493           return new FunctorDataSourceDS0<ComponentT, FunctorT>( ds->copy(alreadyCloned),  gen );
00494         }
00495     };
00496         // static empty return type.
00497         template<typename ComponentT, typename FunctorT>
00498         typename FunctorDataSourceDS0<ComponentT, FunctorT>::plain_t
00499         FunctorDataSourceDS0<ComponentT, FunctorT>::empty_return;
00500 
00504   template<typename ComponentT, typename FunctorT, typename Arg1T>
00505   class FunctorDataSourceDS1
00506       : public DataSource< typename FunctorT::result_type >
00507   {
00508   public:
00509     typedef typename FunctorT::result_type value_t;
00510     typedef typename DataSource<value_t>::value_t plain_t;
00511   private:
00512       typename DataSource<boost::weak_ptr<ComponentT> >::shared_ptr ds;
00513       mutable FunctorT gen;
00514       typename DataSource<Arg1T>::shared_ptr arg1;
00515       mutable plain_t res;
00516       static plain_t empty_return;
00517   public:
00518         typedef boost::intrusive_ptr< FunctorDataSourceDS1<ComponentT,FunctorT,Arg1T> > shared_ptr;
00519 
00520     FunctorDataSourceDS1(DataSource<boost::weak_ptr<ComponentT> >* c, FunctorT g, DataSource<Arg1T>* a1 = 0 )
00521       : ds(c), gen( g ), arg1( a1 )
00522       {
00523       }
00524 
00525     value_t get() const
00526       {
00527         Arg1T a = arg1->get();
00528         boost::shared_ptr<ComponentT> c = ds->get().lock();
00529         if (c) {
00530             ComponentT* ct = c.get();
00531             res = gen( ct, a );
00532             arg1->updated();
00533             return res;
00534         } else
00535             return empty_return;
00536       }
00537 
00538       void setArguments(DataSource<Arg1T>* a1)
00539       {
00540           arg1 = a1;
00541       }
00542 
00543         value_t value() const
00544         {
00545             return res;
00546         }
00547 
00548     virtual FunctorDataSourceDS1<ComponentT, FunctorT, Arg1T>* clone() const
00549       {
00550         return new FunctorDataSourceDS1<ComponentT, FunctorT, Arg1T>( ds.get(), gen, arg1.get() );
00551       }
00552     virtual FunctorDataSourceDS1<ComponentT, FunctorT, Arg1T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const
00553       {
00554         return new FunctorDataSourceDS1<ComponentT, FunctorT, Arg1T>( ds->copy(alreadyCloned),  gen, arg1->copy( alreadyCloned ) );
00555       }
00556   };
00557         // static empty return type.
00558         template<typename ComponentT, typename FunctorT, typename A>
00559         typename FunctorDataSourceDS1<ComponentT, FunctorT, A>::plain_t
00560         FunctorDataSourceDS1<ComponentT, FunctorT, A>::empty_return;
00561 
00562   template<typename FunctorT, typename Arg1T, typename Arg2T>
00563   struct FunctorDataSource2
00564       : public DataSource< typename FunctorT::result_type >
00565   {
00566     typedef typename FunctorT::result_type value_t;
00567     mutable FunctionForwarder<value_t,FunctorT> ff;
00568     typename DataSource<Arg1T>::shared_ptr arg1;
00569     typename DataSource<Arg2T>::shared_ptr arg2;
00570   public:
00571       typedef boost::intrusive_ptr< FunctorDataSource2<FunctorT,Arg1T,Arg2T> > shared_ptr;
00572 
00573       FunctorDataSource2( FunctorT g, DataSource<Arg1T>* a1 = 0, DataSource<Arg2T>* a2 = 0 )
00574           : ff( g ), arg1( a1 ), arg2(a2)
00575       {
00576       }
00577 
00578       void setArguments(DataSource<Arg1T>* a1, DataSource<Arg2T>* a2)
00579       {
00580           arg1 = a1;
00581           arg2 = a2;
00582       }
00583 
00584       value_t value() const
00585       {
00586           return ff.result();
00587       }
00588 
00589       value_t get() const
00590       {
00591           return ff.invoke( arg1.get(), arg2.get() );
00592       }
00593 
00594     virtual FunctorDataSource2<FunctorT, Arg1T, Arg2T>* clone() const
00595       {
00596         return new FunctorDataSource2<FunctorT, Arg1T, Arg2T>( ff.gen, arg1.get(), arg2.get() );
00597       }
00598     virtual FunctorDataSource2<FunctorT, Arg1T, Arg2T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const
00599       {
00600         return new FunctorDataSource2<FunctorT, Arg1T, Arg2T>( ff.gen, arg1->copy( alreadyCloned ), arg2->copy( alreadyCloned) );
00601       }
00602   };
00603 
00604   template<typename FunctorT, typename Arg1T, typename Arg2T, typename Arg3T>
00605   class FunctorDataSource3
00606       : public DataSource< typename FunctorT::result_type >
00607   {
00608     typedef typename FunctorT::result_type value_t;
00609     mutable FunctionForwarder<value_t,FunctorT> ff;
00610     typename DataSource<Arg1T>::shared_ptr arg1;
00611     typename DataSource<Arg2T>::shared_ptr arg2;
00612     typename DataSource<Arg3T>::shared_ptr arg3;
00613   public:
00614       typedef boost::intrusive_ptr< FunctorDataSource3<FunctorT,Arg1T,Arg2T,Arg3T> > shared_ptr;
00615 
00616       FunctorDataSource3( FunctorT g, DataSource<Arg1T>* a1 = 0, DataSource<Arg2T>* a2 = 0, DataSource<Arg3T>* a3 = 0)
00617           : ff( g ), arg1( a1 ), arg2(a2), arg3(a3)
00618       {
00619       }
00620 
00621       void setArguments(DataSource<Arg1T>* a1, DataSource<Arg2T>* a2, DataSource<Arg3T>* a3)
00622       {
00623           arg1 = a1;
00624           arg2 = a2;
00625           arg3 = a3;
00626       }
00627 
00628 
00629       value_t value() const
00630       {
00631           return ff.result();
00632       }
00633 
00634       value_t get() const
00635       {
00636           return ff.invoke( arg1.get(), arg2.get(), arg3.get() );
00637       }
00638 
00639     virtual FunctorDataSource3<FunctorT, Arg1T, Arg2T, Arg3T>* clone() const
00640       {
00641         return new FunctorDataSource3<FunctorT, Arg1T, Arg2T, Arg3T>( ff.gen, arg1.get(), arg2.get(), arg3.get() );
00642       }
00643     virtual FunctorDataSource3<FunctorT, Arg1T, Arg2T, Arg3T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const
00644       {
00645         return new FunctorDataSource3<FunctorT, Arg1T, Arg2T, Arg3T>( ff.gen, arg1->copy( alreadyCloned ), arg2->copy( alreadyCloned), arg3->copy( alreadyCloned) );
00646       }
00647   };
00648 
00649   template<typename FunctorT, typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T>
00650   class FunctorDataSource4
00651       : public DataSource< typename FunctorT::result_type >
00652   {
00653     typedef typename FunctorT::result_type value_t;
00654       mutable FunctionForwarder<value_t,FunctorT> ff;
00655     typename DataSource<Arg1T>::shared_ptr arg1;
00656     typename DataSource<Arg2T>::shared_ptr arg2;
00657     typename DataSource<Arg3T>::shared_ptr arg3;
00658     typename DataSource<Arg4T>::shared_ptr arg4;
00659   public:
00660       typedef boost::intrusive_ptr< FunctorDataSource4<FunctorT,Arg1T,Arg2T,Arg3T,Arg4T> > shared_ptr;
00661 
00662       FunctorDataSource4( FunctorT g, DataSource<Arg1T>* a1 = 0, DataSource<Arg2T>* a2 = 0,
00663                           DataSource<Arg3T>* a3 = 0, DataSource<Arg4T>* a4 = 0)
00664           : ff( g ), arg1( a1 ), arg2(a2), arg3(a3), arg4(a4)
00665       {
00666       }
00667 
00668       value_t value() const
00669       {
00670           return ff.result();
00671       }
00672 
00673       void setArguments(DataSource<Arg1T>* a1, DataSource<Arg2T>* a2, DataSource<Arg3T>* a3, DataSource<Arg4T>* a4)
00674       {
00675           arg1 = a1;
00676           arg2 = a2;
00677           arg3 = a3;
00678           arg4 = a4;
00679       }
00680 
00681       value_t get() const
00682       {
00683           return ff.invoke( arg1.get(), arg2.get(), arg3.get(), arg4.get() );
00684       }
00685 
00686     virtual FunctorDataSource4<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T>* clone() const
00687       {
00688         return new FunctorDataSource4<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T>( ff.gen, arg1.get(), arg2.get(),
00689                                                                              arg3.get(), arg4.get() );
00690       }
00691     virtual FunctorDataSource4<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const
00692       {
00693         return new FunctorDataSource4<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T>( ff.gen, arg1->copy( alreadyCloned ), arg2->copy( alreadyCloned), arg3->copy( alreadyCloned), arg4->copy( alreadyCloned) );
00694       }
00695   };
00696 
00697   template<typename FunctorT, typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T, typename Arg5T>
00698   class FunctorDataSource5
00699       : public DataSource< typename FunctorT::result_type >
00700   {
00701     typedef typename FunctorT::result_type value_t;
00702       mutable FunctionForwarder<value_t,FunctorT> ff;
00703     typename DataSource<Arg1T>::shared_ptr arg1;
00704     typename DataSource<Arg2T>::shared_ptr arg2;
00705     typename DataSource<Arg3T>::shared_ptr arg3;
00706     typename DataSource<Arg4T>::shared_ptr arg4;
00707     typename DataSource<Arg5T>::shared_ptr arg5;
00708   public:
00709       typedef boost::intrusive_ptr< FunctorDataSource5<FunctorT,Arg1T,Arg2T,Arg3T,Arg4T,Arg5T> > shared_ptr;
00710 
00711       FunctorDataSource5( FunctorT g, DataSource<Arg1T>* a1 = 0, DataSource<Arg2T>* a2 = 0,
00712                           DataSource<Arg3T>* a3 = 0, DataSource<Arg4T>* a4 = 0,
00713                           DataSource<Arg5T>* a5 = 0)
00714           : ff( g ), arg1( a1 ), arg2(a2), arg3(a3), arg4(a4), arg5(a5)
00715       {
00716       }
00717 
00718       value_t value() const
00719       {
00720           return ff.result();
00721       }
00722 
00723       void setArguments(DataSource<Arg1T>* a1, DataSource<Arg2T>* a2,
00724                         DataSource<Arg3T>* a3, DataSource<Arg4T>* a4,
00725                         DataSource<Arg5T>* a5)
00726       {
00727           arg1 = a1;
00728           arg2 = a2;
00729           arg3 = a3;
00730           arg4 = a4;
00731           arg5 = a5;
00732       }
00733 
00734       value_t get() const
00735       {
00736           return ff.invoke( arg1.get(), arg2.get(), arg3.get(), arg4.get(), arg5.get() );
00737       }
00738 
00739     virtual FunctorDataSource5<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T>* clone() const
00740       {
00741         return new FunctorDataSource5<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T>( ff.gen, arg1.get(), arg2.get(),
00742                                                                              arg3.get(), arg4.get(), arg5.get() );
00743       }
00744     virtual FunctorDataSource5<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const
00745       {
00746         return new FunctorDataSource5<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T>( ff.gen, arg1->copy( alreadyCloned ), arg2->copy( alreadyCloned), arg3->copy( alreadyCloned), arg4->copy( alreadyCloned), arg5->copy(alreadyCloned) );
00747       }
00748   };
00749 
00750   template<typename FunctorT, typename Arg1T, typename Arg2T, typename Arg3T, typename Arg4T, typename Arg5T, typename Arg6T>
00751   class FunctorDataSource6
00752       : public DataSource< typename FunctorT::result_type >
00753   {
00754     typedef typename FunctorT::result_type value_t;
00755       mutable FunctionForwarder<value_t,FunctorT> ff;
00756     typename DataSource<Arg1T>::shared_ptr arg1;
00757     typename DataSource<Arg2T>::shared_ptr arg2;
00758     typename DataSource<Arg3T>::shared_ptr arg3;
00759     typename DataSource<Arg4T>::shared_ptr arg4;
00760     typename DataSource<Arg5T>::shared_ptr arg5;
00761     typename DataSource<Arg6T>::shared_ptr arg6;
00762   public:
00763       typedef boost::intrusive_ptr< FunctorDataSource6<FunctorT,Arg1T,Arg2T,Arg3T,Arg4T,Arg5T,Arg6T> > shared_ptr;
00764 
00765       FunctorDataSource6( FunctorT g, DataSource<Arg1T>* a1 = 0, DataSource<Arg2T>* a2 = 0,
00766                           DataSource<Arg3T>* a3 = 0, DataSource<Arg4T>* a4 = 0,
00767                           DataSource<Arg5T>* a5 = 0, DataSource<Arg6T>* a6 = 0)
00768           : ff( g ), arg1( a1 ), arg2(a2), arg3(a3), arg4(a4), arg5(a5),arg6(a6)
00769       {
00770       }
00771 
00772       value_t value() const
00773       {
00774           return ff.result();
00775       }
00776 
00777       void setArguments(DataSource<Arg1T>* a1, DataSource<Arg2T>* a2,
00778                         DataSource<Arg3T>* a3, DataSource<Arg4T>* a4,
00779                         DataSource<Arg5T>* a5, DataSource<Arg6T>* a6)
00780       {
00781           arg1 = a1;
00782           arg2 = a2;
00783           arg3 = a3;
00784           arg4 = a4;
00785           arg5 = a5;
00786           arg6 = a6;
00787       }
00788 
00789       value_t get() const
00790       {
00791           return ff.invoke( arg1.get(), arg2.get(), arg3.get(), arg4.get(), arg5.get(), arg6.get() );
00792       }
00793 
00794     virtual FunctorDataSource6<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T>* clone() const
00795       {
00796         return new FunctorDataSource6<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T>( ff.gen, arg1.get(), arg2.get(),
00797                                                                              arg3.get(), arg4.get(), arg5.get(), arg6.get() );
00798       }
00799     virtual FunctorDataSource6<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T>* copy( std::map<const DataSourceBase*, DataSourceBase*>& alreadyCloned ) const
00800       {
00801         return new FunctorDataSource6<FunctorT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T>( ff.gen, arg1->copy( alreadyCloned ), arg2->copy( alreadyCloned), arg3->copy( alreadyCloned), arg4->copy( alreadyCloned), arg5->copy(alreadyCloned), arg6->copy(alreadyCloned) );
00802       }
00803   };
00804 
00805 
00806 
00807         template<int, class F>
00808         struct FunctorDataSourceI;
00809 
00810         template<class F>
00811         struct FunctorDataSourceI<0,F>
00812             : public FunctorDataSource0<F>
00813         {
00814             FunctorDataSourceI( F f )
00815                 : FunctorDataSource0<F>(f) {}
00816         };
00817 
00818         template<class F>
00819         struct FunctorDataSourceI<1,F>
00820             : public FunctorDataSource1<F, typename F::arg1_type>
00821         {
00822             FunctorDataSourceI( F f )
00823                 : FunctorDataSource1<F, typename F::arg1_type>(f) {}
00824         };
00825 
00826         template<class F>
00827         struct FunctorDataSourceI<2,F>
00828             : public FunctorDataSource2<F, typename F::arg1_type, typename F::arg2_type>
00829         {
00830             FunctorDataSourceI( F f )
00831                 : FunctorDataSource2<F, typename F::arg1_type, typename F::arg2_type>(f) {}
00832         };
00833 
00834         template<class F>
00835         struct FunctorDataSourceI<3,F>
00836             : public FunctorDataSource3<F, typename F::arg1_type, typename F::arg2_type, typename F::arg3_type>
00837         {
00838             FunctorDataSourceI( F f )
00839                 : FunctorDataSource3<F, typename F::arg1_type, typename F::arg2_type, typename F::arg3_type>(f) {}
00840         };
00841 
00842         template<class F>
00843         struct FunctorDataSourceI<4,F>
00844             : public FunctorDataSource4<F, typename F::arg1_type, typename F::arg2_type,typename F::arg3_type, typename F::arg4_type>
00845         {
00846             FunctorDataSourceI( F f )
00847                 : FunctorDataSource4<F, typename F::arg1_type, typename F::arg2_type,typename F::arg3_type, typename F::arg4_type>(f) {}
00848         };
00849 
00850         template<class F>
00851         struct FunctorDataSourceI<5,F>
00852             : public FunctorDataSource5<F, typename F::arg1_type, typename F::arg2_type,
00853                                         typename F::arg3_type, typename F::arg4_type,
00854                                         typename F::arg5_type>
00855         {
00856             FunctorDataSourceI( F f )
00857                 : FunctorDataSource5<F, typename F::arg1_type, typename F::arg2_type,
00858                                      typename F::arg3_type, typename F::arg4_type,
00859                                      typename F::arg5_type>(f) {}
00860         };
00861 
00862 
00863         template<class F>
00864         struct FunctorDataSourceI<6,F>
00865             : public FunctorDataSource6<F, typename F::arg1_type, typename F::arg2_type,
00866                                         typename F::arg3_type, typename F::arg4_type,
00867                                         typename F::arg5_type, typename F::arg6_type>
00868         {
00869             FunctorDataSourceI( F f )
00870                 : FunctorDataSource6<F, typename F::arg1_type, typename F::arg2_type,
00871                                      typename F::arg3_type, typename F::arg4_type,
00872                                      typename F::arg5_type, typename F::arg6_type>(f) {}
00873         };
00874 
00875         template<class F>
00876         struct FunctorDataSource
00877             : public FunctorDataSourceI<F::arity, F>
00878         {
00879             FunctorDataSource( F f )
00880                 : FunctorDataSourceI<F::arity, F>(f) {}
00881         };
00882 
00883     }
00884 }
00885 
00886 #endif
Generated on Thu Dec 23 13:22:37 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3