Orocos Real-Time Toolkit  2.6.0
CollectSignature.hpp
00001 /***************************************************************************
00002   tag: The SourceWorks  Tue Sep 7 00:55:18 CEST 2010  CollectSignature.hpp
00003 
00004                         CollectSignature.hpp -  description
00005                            -------------------
00006     begin                : Tue September 07 2010
00007     copyright            : (C) 2010 The SourceWorks
00008     email                : peter@thesourceworks.com
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_COLLECT_SIGNATURE_HPP
00040 #define ORO_COLLECT_SIGNATURE_HPP
00041 
00042 #include <boost/function_types/function_type.hpp>
00043 #include <boost/function_types/function_arity.hpp>
00044 #include <boost/function_types/result_type.hpp>
00045 #include <boost/function_types/parameter_types.hpp>
00046 #include <boost/mpl/vector.hpp>
00047 #include <boost/mpl/remove_if.hpp>
00048 #include <boost/mpl/push_front.hpp>
00049 #include <boost/mpl/not.hpp>
00050 #include <boost/mpl/logical.hpp>
00051 #include <boost/mpl/if.hpp>
00052 #include <boost/type_traits.hpp>
00053 #include "../SendStatus.hpp"
00054 
00055 namespace RTT
00056 {
00057     namespace internal
00058     {
00059         namespace ft=boost::function_types;
00060         namespace mpl=boost::mpl;
00061         namespace tt=boost;
00062 
00074         template<class F>
00075         struct CollectType
00076         {
00077         private:
00078             // Decompose F into all components (ret, args,...):
00079             // Remove first component and store in ret_type:
00080             typedef typename ft::result_type<F>::type ret_type;
00081             typedef typename ft::parameter_types<F>::type arg_type;
00082             typedef typename tt::remove_const< typename tt::remove_reference<ret_type>::type >::type bare_ret_type;
00083             typedef typename mpl::if_<
00084                 typename mpl::not_< typename tt::is_void<ret_type>::type >::type,
00085                 typename mpl::push_front< arg_type, typename tt::add_reference< bare_ret_type >::type >::type,
00086                 arg_type
00087                 >::type basic_sig;
00088             // basic_sig now needs to be removed of all non-reference arguments.
00089             // we first with removing all consts and const references:
00090             // note about the lambda expression: we pass a struct, not a typenamed 'type'.
00091             typedef typename mpl::remove_if< basic_sig, tt::is_const< tt::remove_reference<mpl::_1> > >::type no_const_sig;
00092             // next we need to remove all non-reference values:
00093             typedef typename mpl::remove_if< no_const_sig, mpl::not_<tt::is_reference<mpl::_1> > >::type no_value_sig;
00094             // Finally, add ret_type as return value (first item in vector):
00095             typedef typename mpl::push_front< no_value_sig, ret_type>::type fttype;
00096         public:
00097             // Form function type again from the mpl vector:
00098             typedef typename ft::function_type<fttype>::type Ft;
00099             // Type is a more standard way of result type.
00100             typedef Ft type;
00101             // The collect type signature as an mpl list
00102             typedef fttype mpl_type;
00103         };
00104 
00111         template<int, class Signature, class ToCollect>
00112         struct CollectSignature;
00113 
00114         // This case is only present if the return value is void
00115         // and all arguments are of in kind.
00116         template<class F, class ToCollect>
00117         struct CollectSignature<0,F,ToCollect>
00118         {
00119             typedef void result_type;
00120             CollectSignature() : cimpl() {}
00121             CollectSignature(ToCollect implementation) : cimpl(implementation) {}
00122             ~CollectSignature() {}
00123 
00124             SendStatus collect()
00125             {
00126                 if (this->cimpl)
00127                     return this->cimpl->collect();
00128                 return SendFailure;
00129             }
00130 
00131             SendStatus collectIfDone()
00132             {
00133                 if (this->cimpl)
00134                     return this->cimpl->collectIfDone();
00135                 return SendFailure;
00136             }
00137 
00138         protected:
00139             ToCollect cimpl;
00140         };
00141 
00142         // Used when return non void with only in kind args OR return void
00143         // and one out/inout arg.
00144         template<class F, class ToCollect>
00145         struct CollectSignature<1,F,ToCollect>
00146         {
00147             typedef typename boost::function_traits<F>::result_type result_type;
00148             typedef typename boost::function_traits<F>::arg1_type arg1_type;
00149 
00150             CollectSignature() : cimpl() {}
00151             CollectSignature(ToCollect implementation) : cimpl(implementation) {}
00152             ~CollectSignature() {}
00153 
00157             SendStatus collect(arg1_type a1)
00158             {
00159                 if (cimpl)
00160                     return cimpl->collect( a1 );
00161                 return SendFailure;
00162             }
00163 
00164             SendStatus collectIfDone(arg1_type a1)
00165             {
00166                 if (cimpl)
00167                     return cimpl->collectIfDone( a1 );
00168                 return SendFailure;
00169             }
00170         protected:
00171             ToCollect cimpl;
00172         };
00173 
00174         template<class F, class ToCollect>
00175         struct CollectSignature<2,F,ToCollect>
00176         {
00177             typedef typename boost::function_traits<F>::arg1_type arg1_type;
00178             typedef typename boost::function_traits<F>::arg2_type arg2_type;
00179 
00180             CollectSignature() : cimpl() {}
00181             CollectSignature(ToCollect implementation) : cimpl(implementation) {}
00182             ~CollectSignature() {}
00183 
00187             SendStatus collect(arg1_type t1, arg2_type t2)
00188             {
00189                 if (cimpl)
00190                     return cimpl->collect(t1, t2);
00191                 return SendFailure;
00192             }
00193 
00194             SendStatus collectIfDone(arg1_type t1, arg2_type t2)
00195             {
00196                 if (cimpl)
00197                     return cimpl->collectIfDone(t1, t2);
00198                 return SendFailure;
00199             }
00200         protected:
00201             ToCollect cimpl;
00202         };
00203 
00204         template<class F, class ToCollect>
00205         struct CollectSignature<3,F,ToCollect>
00206         {
00207             typedef typename boost::function_traits<F>::arg1_type arg1_type;
00208             typedef typename boost::function_traits<F>::arg2_type arg2_type;
00209             typedef typename boost::function_traits<F>::arg3_type arg3_type;
00210 
00211             CollectSignature() : cimpl() {}
00212             CollectSignature(ToCollect implementation) : cimpl(implementation) {}
00213             ~CollectSignature() { }
00214 
00218             SendStatus collect(arg1_type t1, arg2_type t2, arg3_type t3)
00219             {
00220                 if (cimpl)
00221                     return cimpl->collect(t1, t2, t3);
00222                 return SendFailure;
00223             }
00224 
00225             SendStatus collectIfDone(arg1_type t1, arg2_type t2, arg3_type t3)
00226             {
00227                 if (cimpl)
00228                     return cimpl->collectIfDone(t1, t2, t3);
00229                 return SendFailure;
00230             }
00231         protected:
00232             ToCollect cimpl;
00233         };
00234 
00235         template<class F, class ToCollect>
00236         struct CollectSignature<4,F,ToCollect>
00237         {
00238             typedef typename boost::function_traits<F>::arg1_type arg1_type;
00239             typedef typename boost::function_traits<F>::arg2_type arg2_type;
00240             typedef typename boost::function_traits<F>::arg3_type arg3_type;
00241             typedef typename boost::function_traits<F>::arg4_type arg4_type;
00242 
00243             CollectSignature() : cimpl() {}
00244             CollectSignature(ToCollect implementation) : cimpl(implementation) {}
00245             ~CollectSignature() { }
00246 
00250             SendStatus collect(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4)
00251             {
00252                 if (cimpl)
00253                     return cimpl->collect(t1, t2, t3, t4);
00254                 return SendFailure;
00255             }
00256 
00257             SendStatus collectIfDone(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4)
00258             {
00259                 if (cimpl)
00260                     return cimpl->collect(t1, t2, t3, t4);
00261                 return SendFailure;
00262             }
00263         protected:
00264             ToCollect cimpl;
00265         };
00266 
00267         template<class F, class ToCollect>
00268         struct CollectSignature<5,F,ToCollect>
00269         {
00270             typedef typename boost::function_traits<F>::arg1_type arg1_type;
00271             typedef typename boost::function_traits<F>::arg2_type arg2_type;
00272             typedef typename boost::function_traits<F>::arg3_type arg3_type;
00273             typedef typename boost::function_traits<F>::arg4_type arg4_type;
00274             typedef typename boost::function_traits<F>::arg5_type arg5_type;
00275 
00276             CollectSignature() : cimpl() {}
00277             CollectSignature(ToCollect implementation) : cimpl(implementation) {}
00278             ~CollectSignature() { }
00279 
00283             SendStatus collect(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5)
00284             {
00285                 if (cimpl)
00286                     return cimpl->collect(t1, t2, t3, t4, t5);
00287                 return SendFailure;
00288             }
00289 
00290             SendStatus collectIfDone(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5)
00291             {
00292                 if (cimpl)
00293                     return cimpl->collect(t1, t2, t3, t4, t5);
00294                 return SendFailure;
00295             }
00296         protected:
00297             ToCollect cimpl;
00298         };
00299 
00300         template<class F, class ToCollect>
00301         struct CollectSignature<6,F,ToCollect>
00302         {
00303             typedef typename boost::function_traits<F>::arg1_type arg1_type;
00304             typedef typename boost::function_traits<F>::arg2_type arg2_type;
00305             typedef typename boost::function_traits<F>::arg3_type arg3_type;
00306             typedef typename boost::function_traits<F>::arg4_type arg4_type;
00307             typedef typename boost::function_traits<F>::arg5_type arg5_type;
00308             typedef typename boost::function_traits<F>::arg6_type arg6_type;
00309 
00310             CollectSignature() : cimpl() {}
00311             CollectSignature(ToCollect implementation) : cimpl(implementation) {}
00312             ~CollectSignature() { }
00313 
00317             SendStatus collect(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5, arg6_type t6)
00318             {
00319                 if (cimpl)
00320                     return cimpl->collect(t1, t2, t3, t4, t5, t6);
00321                 return SendFailure;
00322             }
00323 
00324             SendStatus collectIfDone(arg1_type t1, arg2_type t2, arg3_type t3, arg4_type t4, arg5_type t5, arg6_type t6)
00325             {
00326                 if (cimpl)
00327                     return cimpl->collect(t1, t2, t3, t4, t5, t6);
00328                 return SendFailure;
00329             }
00330         protected:
00331             ToCollect cimpl;
00332         };
00333 
00334     }
00335 }
00336 #endif