$search
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