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


rtt
Author(s): RTT Developers
autogenerated on Sat Jun 8 2019 18:46:14