$search
00001 /*************************************************************************** 00002 tag: Peter Soetens Wed Jul 28 09:08:56 CEST 2004 mystd.hpp 00003 00004 mystd.hpp - description 00005 ------------------- 00006 begin : Wed July 28 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 #ifndef ORO_MYSTD_HPP 00039 #define ORO_MYSTD_HPP 00040 00041 #include <boost/type_traits/add_reference.hpp> 00042 #include <boost/type_traits/add_const.hpp> 00043 #include <boost/type_traits/is_same.hpp> 00044 #include <boost/type_traits/is_void.hpp> 00045 #include <boost/type_traits/remove_reference.hpp> 00046 #include <boost/type_traits/remove_const.hpp> 00047 #include <boost/mpl/bool.hpp> 00048 #include <boost/mpl/logical.hpp> 00049 #include <boost/utility.hpp> 00050 #include <functional> 00051 #include <algorithm> 00052 #include <vector> 00053 00054 // here we define some generally useful template stuff that is missing 00055 // from the STL.. 00056 namespace RTT { namespace internal { 00057 using namespace boost; 00058 00059 // combines remove_reference and remove_const 00060 template<typename T> 00061 struct remove_cr 00062 { 00063 typedef typename boost::remove_const< 00064 typename boost::remove_reference<T>::type>::type type; 00065 }; 00066 00067 template<typename T> 00068 struct is_pure_reference 00069 :public boost::mpl::false_ 00070 {}; 00071 00072 template<typename T> 00073 struct is_pure_reference<T&> 00074 :public boost::mpl::true_ 00075 {}; 00076 00077 template<typename T> 00078 struct is_pure_reference<T const&> 00079 :public boost::mpl::false_ 00080 {}; 00081 00082 template<typename iter> 00083 static void delete_all( iter a, iter b ) 00084 { 00085 for ( ; a < b; a++ ) 00086 delete *a; 00087 }; 00088 00089 00090 // SGI extension, does not seem present in current GNU STL 00091 // implementation... 00092 00093 template<typename T> 00094 struct select1st 00095 : public std::unary_function<T, typename T::first_type> 00096 { 00097 typename T::first_type operator()( const T& p ) { 00098 return p.first; 00099 } 00100 }; 00101 00102 template<typename T> 00103 struct select2nd 00104 : public std::unary_function<T, typename T::second_type> 00105 { 00106 typename T::second_type operator()( const T& p ) { 00107 return p.second; 00108 } 00109 }; 00110 00111 #if 0 00112 // Alternative implementations, return const ref. 00113 template<typename PairT> 00114 class select1st 00115 : public std::unary_function<PairT, typename PairT::first_type> 00116 { 00117 typedef typename PairT::first_type ResultT; 00118 public: 00119 const ResultT& operator()( const PairT& p ) 00120 { 00121 return p.first; 00122 }; 00123 }; 00124 00125 template<typename PairT> 00126 class select2nd 00127 : public std::unary_function<PairT, typename PairT::second_type> 00128 { 00129 typedef typename PairT::second_type ResultT; 00130 public: 00131 const ResultT& operator()( const PairT& p ) 00132 { 00133 return p.second; 00134 }; 00135 }; 00136 #endif 00137 00138 00139 // my own handy little extension.. 00140 template<typename MapT> 00141 std::vector<typename MapT::mapped_type> values( const MapT& map ) 00142 { 00143 std::vector<typename MapT::mapped_type> ret; 00144 ret.reserve( map.size() ); 00145 std::transform( map.begin(), map.end(), 00146 std::back_inserter( ret ), 00147 select2nd<typename MapT::value_type>() ); 00148 return ret; 00149 } 00150 00151 template<typename MapT> 00152 std::vector<typename MapT::key_type> keys( const MapT& map ) 00153 { 00154 std::vector<typename MapT::key_type> ret; 00155 ret.reserve( map.size() ); 00156 std::transform( map.begin(), map.end(), 00157 std::back_inserter( ret ), 00158 select1st<typename MapT::value_type>() ); 00159 return ret; 00160 } 00161 } 00162 } 00163 00164 namespace std 00165 { 00166 // must be in std namespace. 00167 // STL specialisations for const references : Add others if necessary. 00168 template <class _Tp> 00169 struct equal_to< const _Tp& > 00170 : public binary_function<const _Tp&, const _Tp& ,bool> 00171 { 00172 bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } 00173 }; 00174 00176 template <class _Tp> 00177 struct not_equal_to<const _Tp&> 00178 : public binary_function<const _Tp&, const _Tp&, bool> 00179 { 00180 bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } 00181 }; 00182 00184 template <class _Tp> 00185 struct greater<const _Tp&> 00186 : public binary_function<const _Tp&,const _Tp&,bool> 00187 { 00188 bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } 00189 }; 00190 00192 template <class _Tp> 00193 struct less<const _Tp&> 00194 : public binary_function<const _Tp&,const _Tp&,bool> 00195 { 00196 bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } 00197 }; 00198 00199 // Ternary functions. 00200 template<class Arg1T, class Arg2T, class Arg3T, class ResultT > 00201 struct ternary_function 00202 { 00203 typedef ResultT result_type; 00204 typedef Arg1T first_argument_type; 00205 typedef Arg2T second_argument_type; 00206 typedef Arg3T third_argument_type; 00207 }; 00208 } 00209 00210 // STL extensions, some are SGI extensions, others are my own.. 00211 namespace RTT 00212 {namespace internal { 00213 00214 template<typename T> 00215 struct identity 00216 : public std::unary_function<T, T> 00217 { 00218 const T& operator()( const T& t ) const 00219 { 00220 return t; 00221 } 00222 }; 00223 00224 // ternary 00225 template<typename ResultT, typename Arg1T, typename Arg2T, typename Arg3T> 00226 struct pointer_to_ternary_function 00227 { 00228 typedef ResultT (Signature)( Arg1T, Arg2T, Arg3T ); 00229 00230 ResultT (*fun)( Arg1T, Arg2T, Arg3T ); 00231 00232 typedef ResultT result_type; 00233 typedef Arg1T first_argument_type; 00234 typedef Arg2T second_argument_type; 00235 typedef Arg3T third_argument_type; 00236 pointer_to_ternary_function( ResultT (*f)(Arg1T, Arg2T, Arg3T ) ) 00237 : fun( f ) 00238 { 00239 } 00240 ResultT operator()( Arg1T a, Arg2T b, Arg3T c ) const 00241 { 00242 return (*fun)( a, b, c ); 00243 } 00244 }; 00245 00246 template<typename ResultT, typename Arg1T, typename Arg2T, typename Arg3T> 00247 pointer_to_ternary_function<ResultT, Arg1T, Arg2T, Arg3T> 00248 ptr_fun( ResultT (*fun)( Arg1T, Arg2T, Arg3T ) ) 00249 { 00250 return pointer_to_ternary_function<ResultT, Arg1T, Arg2T, Arg3T>( fun ); 00251 } 00252 00253 00254 // sixary 00255 template<typename ResultT, typename Arg1T, typename Arg2T, typename Arg3T, 00256 typename Arg4T, typename Arg5T, typename Arg6T > 00257 struct pointer_to_sixary_function 00258 { 00259 typedef ResultT (Signature)( Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T ); 00260 ResultT (*fun)( Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T ); 00261 typedef ResultT result_type; 00262 typedef Arg1T first_argument_type; 00263 typedef Arg2T second_argument_type; 00264 typedef Arg3T third_argument_type; 00265 typedef Arg4T fourth_argument_type; 00266 typedef Arg5T fifth_argument_type; 00267 typedef Arg6T sixth_argument_type; 00268 pointer_to_sixary_function( ResultT (*f)(Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T ) ) 00269 : fun( f ) 00270 { 00271 } 00272 ResultT operator()( Arg1T a, Arg2T b, Arg3T c, Arg4T d, Arg5T e, Arg6T f ) const 00273 { 00274 return (*fun)( a, b, c, d, e, f ); 00275 } 00276 }; 00277 00278 template<typename ResultT, typename Arg1T, typename Arg2T, typename Arg3T, 00279 typename Arg4T, typename Arg5T, typename Arg6T > 00280 pointer_to_sixary_function<ResultT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T> 00281 ptr_fun( ResultT (*fun)( Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T ) ) 00282 { 00283 return pointer_to_sixary_function<ResultT, Arg1T, Arg2T, Arg3T, Arg4T, Arg5T, Arg6T>( fun ); 00284 } 00285 00286 00287 #if 0 00288 00289 // the STL lacks a functor multiplying two objects of distinct 00290 // types.. multiplies<T> requires that a and b are both of type 00291 // T when calling operator()(a,b). So I wrote my own replacement. 00292 // This relies on the GCC typeof C++ extension 00293 template<typename A, typename B> 00294 struct multiplies 00295 { 00296 typedef typeof( A() * B() ) result_type; 00297 typedef A first_argument_type; 00298 typedef B second_argument_type; 00299 00300 result_type operator()( A a, B b ) const 00301 { 00302 return a*b; 00303 } 00304 }; 00305 template<typename A, typename B> 00306 struct divides 00307 { 00308 typedef typeof( A() / B() ) result_type; 00309 typedef A first_argument_type; 00310 typedef B second_argument_type; 00311 00312 result_type operator()( A a, B b ) const 00313 { 00314 return a/b; 00315 } 00316 }; 00317 #else 00318 template<typename R, typename A, typename B> 00319 struct multiplies3 00320 { 00321 typedef R result_type; 00322 typedef A first_argument_type; 00323 typedef B second_argument_type; 00324 00325 result_type operator()( A a, B b ) const 00326 { 00327 return a*b; 00328 } 00329 }; 00330 template<typename R, typename A, typename B> 00331 struct divides3 00332 { 00333 typedef R result_type; 00334 typedef A first_argument_type; 00335 typedef B second_argument_type; 00336 00337 result_type operator()( A a, B b ) const 00338 { 00339 return a/b; 00340 } 00341 }; 00342 template<> 00343 struct divides3<int, int, int> 00344 { 00345 typedef int result_type; 00346 typedef int first_argument_type; 00347 typedef int second_argument_type; 00348 00349 result_type operator()( int a, int b ) const 00350 { 00351 //integer division by zero will throw a fatal 00352 //exception, aborting the program (SIGFPE). This is 00353 // unacceptable, the problem is however that 00354 // we can not signal an erronous expression in Orocos. 00355 // we propagate zero instead. 00356 return b == 0 ? 0 : a/b; 00357 } 00358 }; 00359 template<typename R, typename A, typename B> 00360 struct adds3 00361 { 00362 typedef R result_type; 00363 typedef A first_argument_type; 00364 typedef B second_argument_type; 00365 00366 result_type operator()( A a, B b ) const 00367 { 00368 return a+b; 00369 } 00370 }; 00371 template<typename R, typename A, typename B> 00372 struct subs3 00373 { 00374 typedef R result_type; 00375 typedef A first_argument_type; 00376 typedef B second_argument_type; 00377 00378 result_type operator()( A a, B b ) const 00379 { 00380 return a-b; 00381 } 00382 }; 00383 #endif 00384 }} // namespace RTT 00385 00386 00387 00388 #endif