ossrv_pub/boost_apis/boost/functional.hpp
changeset 31 ce057bb09d0b
parent 0 e4d67989cc36
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     1 // ------------------------------------------------------------------------------
       
     2 // Copyright (c) 2000 Cadenza New Zealand Ltd
       
     3 // Distributed under the Boost Software License, Version 1.0. (See accompany-
       
     4 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       
     5 // ------------------------------------------------------------------------------
       
     6 // Boost functional.hpp header file
       
     7 // See http://www.boost.org/libs/functional for documentation.
       
     8 // ------------------------------------------------------------------------------
       
     9 // $Id: functional.hpp,v 1.4.20.1 2006/12/02 14:17:26 andreas_huber69 Exp $
       
    10 // ------------------------------------------------------------------------------
       
    11 
       
    12 #ifndef BOOST_FUNCTIONAL_HPP
       
    13 #define BOOST_FUNCTIONAL_HPP
       
    14 
       
    15 #include <boost/config.hpp>
       
    16 #include <boost/call_traits.hpp>
       
    17 #include <functional>
       
    18 
       
    19 namespace boost
       
    20 {
       
    21 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
       
    22     // --------------------------------------------------------------------------
       
    23     // The following traits classes allow us to avoid the need for ptr_fun
       
    24     // because the types of arguments and the result of a function can be 
       
    25     // deduced.
       
    26     //
       
    27     // In addition to the standard types defined in unary_function and 
       
    28     // binary_function, we add
       
    29     //
       
    30     // - function_type, the type of the function or function object itself.
       
    31     //
       
    32     // - param_type, the type that should be used for passing the function or
       
    33     //   function object as an argument.
       
    34     // --------------------------------------------------------------------------
       
    35     namespace detail
       
    36     {
       
    37         template <class Operation>
       
    38         struct unary_traits_imp;
       
    39         
       
    40         template <class Operation>
       
    41         struct unary_traits_imp<Operation*>
       
    42         {
       
    43             typedef Operation                         function_type;
       
    44             typedef const function_type &             param_type;
       
    45             typedef typename Operation::result_type   result_type;
       
    46             typedef typename Operation::argument_type argument_type;
       
    47         };
       
    48 
       
    49         template <class R, class A>
       
    50         struct unary_traits_imp<R(*)(A)>
       
    51         {
       
    52             typedef R (*function_type)(A);
       
    53             typedef R (*param_type)(A);
       
    54             typedef R result_type;
       
    55             typedef A argument_type;
       
    56         };
       
    57 
       
    58         template <class Operation>
       
    59         struct binary_traits_imp;
       
    60 
       
    61         template <class Operation>
       
    62         struct binary_traits_imp<Operation*>
       
    63         {
       
    64             typedef Operation                                function_type;
       
    65             typedef const function_type &                    param_type;
       
    66             typedef typename Operation::result_type          result_type;
       
    67             typedef typename Operation::first_argument_type  first_argument_type;
       
    68             typedef typename Operation::second_argument_type second_argument_type;
       
    69         };
       
    70         
       
    71         template <class R, class A1, class A2>
       
    72         struct binary_traits_imp<R(*)(A1,A2)>
       
    73         {
       
    74             typedef R (*function_type)(A1,A2);
       
    75             typedef R (*param_type)(A1,A2);
       
    76             typedef R result_type;
       
    77             typedef A1 first_argument_type;
       
    78             typedef A2 second_argument_type;
       
    79         };
       
    80     } // namespace detail
       
    81     
       
    82     template <class Operation>
       
    83     struct unary_traits
       
    84     {
       
    85         typedef typename detail::unary_traits_imp<Operation*>::function_type function_type;
       
    86         typedef typename detail::unary_traits_imp<Operation*>::param_type    param_type;
       
    87         typedef typename detail::unary_traits_imp<Operation*>::result_type   result_type;
       
    88         typedef typename detail::unary_traits_imp<Operation*>::argument_type argument_type;
       
    89     }; 
       
    90 
       
    91     template <class R, class A>
       
    92     struct unary_traits<R(*)(A)>
       
    93     {
       
    94         typedef R (*function_type)(A);
       
    95         typedef R (*param_type)(A);
       
    96         typedef R result_type;
       
    97         typedef A argument_type;
       
    98     };
       
    99 
       
   100     template <class Operation>
       
   101     struct binary_traits
       
   102     {
       
   103         typedef typename detail::binary_traits_imp<Operation*>::function_type        function_type;
       
   104         typedef typename detail::binary_traits_imp<Operation*>::param_type           param_type;
       
   105         typedef typename detail::binary_traits_imp<Operation*>::result_type          result_type;
       
   106         typedef typename detail::binary_traits_imp<Operation*>::first_argument_type  first_argument_type;
       
   107         typedef typename detail::binary_traits_imp<Operation*>::second_argument_type second_argument_type;
       
   108     };
       
   109     
       
   110     template <class R, class A1, class A2>
       
   111     struct binary_traits<R(*)(A1,A2)>
       
   112     {
       
   113         typedef R (*function_type)(A1,A2);
       
   114         typedef R (*param_type)(A1,A2);
       
   115         typedef R result_type;
       
   116         typedef A1 first_argument_type;
       
   117         typedef A2 second_argument_type;
       
   118     };
       
   119 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
       
   120     // --------------------------------------------------------------------------
       
   121     // If we have no partial specialisation available, decay to a situation
       
   122     // that is no worse than in the Standard, i.e., ptr_fun will be required.
       
   123     // --------------------------------------------------------------------------
       
   124 
       
   125     template <class Operation>
       
   126     struct unary_traits
       
   127     {
       
   128         typedef Operation                         function_type;
       
   129         typedef const Operation&                  param_type;
       
   130         typedef typename Operation::result_type   result_type;
       
   131         typedef typename Operation::argument_type argument_type;
       
   132     }; 
       
   133     
       
   134     template <class Operation>
       
   135     struct binary_traits
       
   136     {
       
   137         typedef Operation                                function_type;
       
   138         typedef const Operation &                        param_type;
       
   139         typedef typename Operation::result_type          result_type;
       
   140         typedef typename Operation::first_argument_type  first_argument_type;
       
   141         typedef typename Operation::second_argument_type second_argument_type;
       
   142     };    
       
   143 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
       
   144     
       
   145     // --------------------------------------------------------------------------
       
   146     // unary_negate, not1
       
   147     // --------------------------------------------------------------------------
       
   148     template <class Predicate>
       
   149     class unary_negate
       
   150         : public std::unary_function<typename unary_traits<Predicate>::argument_type,bool>
       
   151     {
       
   152       public:
       
   153         explicit unary_negate(typename unary_traits<Predicate>::param_type x)
       
   154             :
       
   155             pred(x)
       
   156         {}
       
   157         bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const
       
   158         {
       
   159             return !pred(x);
       
   160         }
       
   161       private:
       
   162         typename unary_traits<Predicate>::function_type pred;
       
   163     };
       
   164 
       
   165     template <class Predicate>
       
   166     unary_negate<Predicate> not1(const Predicate &pred)
       
   167     {
       
   168         // The cast is to placate Borland C++Builder in certain circumstances.
       
   169         // I don't think it should be necessary.
       
   170         return unary_negate<Predicate>((typename unary_traits<Predicate>::param_type)pred);
       
   171     }
       
   172 
       
   173     template <class Predicate>
       
   174     unary_negate<Predicate> not1(Predicate &pred)
       
   175     {
       
   176         return unary_negate<Predicate>(pred);
       
   177     }
       
   178 
       
   179     // --------------------------------------------------------------------------
       
   180     // binary_negate, not2
       
   181     // --------------------------------------------------------------------------
       
   182     template <class Predicate>
       
   183     class binary_negate
       
   184         : public std::binary_function<typename binary_traits<Predicate>::first_argument_type,
       
   185                                       typename binary_traits<Predicate>::second_argument_type,
       
   186                                       bool>
       
   187     {
       
   188       public:
       
   189         explicit binary_negate(typename binary_traits<Predicate>::param_type x)
       
   190             :
       
   191             pred(x)
       
   192         {}
       
   193         bool operator()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x,
       
   194                         typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const
       
   195         {
       
   196             return !pred(x,y);
       
   197         }
       
   198       private:
       
   199         typename binary_traits<Predicate>::function_type pred;
       
   200     };
       
   201 
       
   202     template <class Predicate>
       
   203     binary_negate<Predicate> not2(const Predicate &pred)
       
   204     {
       
   205         // The cast is to placate Borland C++Builder in certain circumstances.
       
   206         // I don't think it should be necessary.
       
   207         return binary_negate<Predicate>((typename binary_traits<Predicate>::param_type)pred);
       
   208     }
       
   209 
       
   210     template <class Predicate>
       
   211     binary_negate<Predicate> not2(Predicate &pred)
       
   212     {
       
   213         return binary_negate<Predicate>(pred);
       
   214     }
       
   215         
       
   216     // --------------------------------------------------------------------------
       
   217     // binder1st, bind1st
       
   218     // --------------------------------------------------------------------------
       
   219     template <class Operation>
       
   220     class binder1st
       
   221         : public std::unary_function<typename binary_traits<Operation>::second_argument_type,
       
   222                                      typename binary_traits<Operation>::result_type>
       
   223     {       
       
   224       public:
       
   225         binder1st(typename binary_traits<Operation>::param_type x,
       
   226                   typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)
       
   227             :
       
   228             op(x), value(y)
       
   229         {}
       
   230         
       
   231         typename binary_traits<Operation>::result_type
       
   232         operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const
       
   233         {
       
   234             return op(value, x);
       
   235         }
       
   236         
       
   237       protected:
       
   238         typename binary_traits<Operation>::function_type op;
       
   239         typename binary_traits<Operation>::first_argument_type value;
       
   240     };
       
   241 
       
   242     template <class Operation>
       
   243     inline binder1st<Operation> bind1st(const Operation &op,
       
   244                                         typename call_traits<
       
   245                                                     typename binary_traits<Operation>::first_argument_type
       
   246                                         >::param_type x)
       
   247     {
       
   248         // The cast is to placate Borland C++Builder in certain circumstances.
       
   249         // I don't think it should be necessary.
       
   250         return binder1st<Operation>((typename binary_traits<Operation>::param_type)op, x);
       
   251     }
       
   252 
       
   253     template <class Operation>
       
   254     inline binder1st<Operation> bind1st(Operation &op,
       
   255                                         typename call_traits<
       
   256                                                     typename binary_traits<Operation>::first_argument_type
       
   257                                         >::param_type x)
       
   258     {
       
   259         return binder1st<Operation>(op, x);
       
   260     }
       
   261 
       
   262     // --------------------------------------------------------------------------
       
   263     // binder2nd, bind2nd
       
   264     // --------------------------------------------------------------------------
       
   265     template <class Operation>
       
   266     class binder2nd
       
   267         : public std::unary_function<typename binary_traits<Operation>::first_argument_type,
       
   268                                      typename binary_traits<Operation>::result_type>
       
   269     {
       
   270       public:
       
   271         binder2nd(typename binary_traits<Operation>::param_type x,
       
   272                   typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)
       
   273             :
       
   274             op(x), value(y)
       
   275         {}
       
   276         
       
   277         typename binary_traits<Operation>::result_type
       
   278         operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const
       
   279         {
       
   280             return op(x, value);
       
   281         }               
       
   282         
       
   283       protected:
       
   284         typename binary_traits<Operation>::function_type op;
       
   285         typename binary_traits<Operation>::second_argument_type value;
       
   286     };
       
   287 
       
   288     template <class Operation>
       
   289     inline binder2nd<Operation> bind2nd(const Operation &op,
       
   290                                         typename call_traits<
       
   291                                                     typename binary_traits<Operation>::second_argument_type
       
   292                                         >::param_type x)
       
   293     {
       
   294         // The cast is to placate Borland C++Builder in certain circumstances.
       
   295         // I don't think it should be necessary.
       
   296         return binder2nd<Operation>((typename binary_traits<Operation>::param_type)op, x);
       
   297     }
       
   298 
       
   299     template <class Operation>
       
   300     inline binder2nd<Operation> bind2nd(Operation &op,
       
   301                                         typename call_traits<
       
   302                                                     typename binary_traits<Operation>::second_argument_type
       
   303                                         >::param_type x)
       
   304     {
       
   305         return binder2nd<Operation>(op, x);
       
   306     }
       
   307 
       
   308     // --------------------------------------------------------------------------
       
   309     // mem_fun, etc
       
   310     // --------------------------------------------------------------------------
       
   311     template <class S, class T>
       
   312     class mem_fun_t : public std::unary_function<T*, S>
       
   313     {
       
   314       public:
       
   315         explicit mem_fun_t(S (T::*p)())
       
   316             :
       
   317             ptr(p)
       
   318         {}
       
   319         S operator()(T* p) const
       
   320         {
       
   321             return (p->*ptr)();
       
   322         }
       
   323       private:
       
   324         S (T::*ptr)();
       
   325     };
       
   326 
       
   327     template <class S, class T, class A>
       
   328     class mem_fun1_t : public std::binary_function<T*, A, S>
       
   329     {
       
   330       public:   
       
   331         explicit mem_fun1_t(S (T::*p)(A))
       
   332             :
       
   333             ptr(p)
       
   334         {}
       
   335         S operator()(T* p, typename call_traits<A>::param_type x) const
       
   336         {
       
   337             return (p->*ptr)(x);
       
   338         }
       
   339       private:
       
   340         S (T::*ptr)(A);
       
   341     };
       
   342 
       
   343     template <class S, class T>
       
   344     class const_mem_fun_t : public std::unary_function<const T*, S>
       
   345     {
       
   346       public:
       
   347         explicit const_mem_fun_t(S (T::*p)() const)
       
   348             :
       
   349             ptr(p)
       
   350         {}
       
   351         S operator()(const T* p) const
       
   352         {
       
   353             return (p->*ptr)();
       
   354         }
       
   355       private:
       
   356         S (T::*ptr)() const;        
       
   357     };
       
   358 
       
   359     template <class S, class T, class A>
       
   360     class const_mem_fun1_t : public std::binary_function<const T*, A, S>
       
   361     {
       
   362       public:
       
   363         explicit const_mem_fun1_t(S (T::*p)(A) const)
       
   364             :
       
   365             ptr(p)
       
   366         {}
       
   367         S operator()(const T* p, typename call_traits<A>::param_type x) const
       
   368         {
       
   369             return (p->*ptr)(x);
       
   370         }
       
   371       private:
       
   372         S (T::*ptr)(A) const;
       
   373     };
       
   374     
       
   375     template<class S, class T>
       
   376     inline mem_fun_t<S,T> mem_fun(S (T::*f)())
       
   377     {
       
   378         return mem_fun_t<S,T>(f);
       
   379     }
       
   380     
       
   381     template<class S, class T, class A>
       
   382     inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A))
       
   383     {
       
   384         return mem_fun1_t<S,T,A>(f);
       
   385     }
       
   386 
       
   387 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
       
   388     template<class S, class T>
       
   389     inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const)
       
   390     {
       
   391         return const_mem_fun_t<S,T>(f);
       
   392     }
       
   393     
       
   394     template<class S, class T, class A>
       
   395     inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const)
       
   396     {
       
   397         return const_mem_fun1_t<S,T,A>(f);
       
   398     }
       
   399 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
       
   400 
       
   401     // --------------------------------------------------------------------------
       
   402     // mem_fun_ref, etc
       
   403     // --------------------------------------------------------------------------
       
   404     template <class S, class T>
       
   405     class mem_fun_ref_t : public std::unary_function<T&, S>
       
   406     {
       
   407       public:
       
   408         explicit mem_fun_ref_t(S (T::*p)())
       
   409             :
       
   410             ptr(p)
       
   411         {}
       
   412         S operator()(T& p) const
       
   413         {
       
   414             return (p.*ptr)();
       
   415         }
       
   416       private:
       
   417         S (T::*ptr)();
       
   418     };
       
   419 
       
   420     template <class S, class T, class A>
       
   421     class mem_fun1_ref_t : public std::binary_function<T&, A, S>
       
   422     {
       
   423       public:
       
   424         explicit mem_fun1_ref_t(S (T::*p)(A))
       
   425             :
       
   426             ptr(p)
       
   427         {}
       
   428         S operator()(T& p, typename call_traits<A>::param_type x) const
       
   429         {
       
   430             return (p.*ptr)(x);
       
   431         }
       
   432       private:
       
   433         S (T::*ptr)(A);
       
   434     };
       
   435     
       
   436     template <class S, class T>
       
   437     class const_mem_fun_ref_t : public std::unary_function<const T&, S>
       
   438     {
       
   439       public:
       
   440         explicit const_mem_fun_ref_t(S (T::*p)() const)
       
   441             :
       
   442             ptr(p)
       
   443         {}
       
   444         
       
   445         S operator()(const T &p) const
       
   446         {
       
   447             return (p.*ptr)();
       
   448         }
       
   449       private:
       
   450         S (T::*ptr)() const;
       
   451     };
       
   452 
       
   453     template <class S, class T, class A>
       
   454     class const_mem_fun1_ref_t : public std::binary_function<const T&, A, S>
       
   455     {
       
   456       public:
       
   457         explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
       
   458             :
       
   459             ptr(p)
       
   460         {}
       
   461 
       
   462         S operator()(const T& p, typename call_traits<A>::param_type x) const
       
   463         {
       
   464             return (p.*ptr)(x);
       
   465         }
       
   466       private:
       
   467         S (T::*ptr)(A) const;
       
   468     };
       
   469     
       
   470     template<class S, class T>
       
   471     inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)())
       
   472     {
       
   473         return mem_fun_ref_t<S,T>(f);
       
   474     }
       
   475 
       
   476     template<class S, class T, class A>
       
   477     inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A))
       
   478     {
       
   479         return mem_fun1_ref_t<S,T,A>(f);
       
   480     }
       
   481 
       
   482 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
       
   483     template<class S, class T>
       
   484     inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const)
       
   485     {
       
   486         return const_mem_fun_ref_t<S,T>(f);
       
   487     }
       
   488 
       
   489     template<class S, class T, class A>
       
   490     inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const)
       
   491     {
       
   492         return const_mem_fun1_ref_t<S,T,A>(f);
       
   493     }   
       
   494 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
       
   495 
       
   496     // --------------------------------------------------------------------------
       
   497     // ptr_fun
       
   498     // --------------------------------------------------------------------------
       
   499     template <class Arg, class Result>
       
   500     class pointer_to_unary_function : public std::unary_function<Arg,Result>
       
   501     {
       
   502       public:
       
   503         explicit pointer_to_unary_function(Result (*f)(Arg))
       
   504             :
       
   505             func(f)
       
   506         {}
       
   507 
       
   508         Result operator()(typename call_traits<Arg>::param_type x) const
       
   509         {
       
   510             return func(x);
       
   511         }
       
   512         
       
   513       private:
       
   514         Result (*func)(Arg);
       
   515     };
       
   516 
       
   517     template <class Arg, class Result>
       
   518     inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg))
       
   519     {
       
   520         return pointer_to_unary_function<Arg,Result>(f);
       
   521     }
       
   522 
       
   523     template <class Arg1, class Arg2, class Result>
       
   524     class pointer_to_binary_function : public std::binary_function<Arg1,Arg2,Result>
       
   525     {
       
   526       public:
       
   527         explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
       
   528             :
       
   529             func(f)
       
   530         {}
       
   531         
       
   532         Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const
       
   533         {
       
   534             return func(x,y);
       
   535         }
       
   536         
       
   537       private:
       
   538         Result (*func)(Arg1, Arg2);
       
   539     };
       
   540 
       
   541     template <class Arg1, class Arg2, class Result>
       
   542     inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2))
       
   543     {
       
   544         return pointer_to_binary_function<Arg1,Arg2,Result>(f);
       
   545     }
       
   546 } // namespace boost
       
   547 
       
   548 #endif