mystd.hpp

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