Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:34:13

0001 // ------------------------------------------------------------------------------
0002 // Copyright (c) 2000 Cadenza New Zealand Ltd
0003 // Distributed under the Boost Software License, Version 1.0. (See accompany-
0004 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 // ------------------------------------------------------------------------------
0006 // Boost functional.hpp header file
0007 // See http://www.boost.org/libs/functional for documentation.
0008 // ------------------------------------------------------------------------------
0009 // $Id$
0010 // ------------------------------------------------------------------------------
0011 
0012 #ifndef BOOST_FUNCTIONAL_HPP
0013 #define BOOST_FUNCTIONAL_HPP
0014 
0015 #include <boost/config.hpp>
0016 #include <boost/call_traits.hpp>
0017 #include <functional>
0018 
0019 namespace boost
0020 {
0021     namespace functional
0022     {
0023         namespace detail {
0024             // std::unary_function and std::binary_function were both removed
0025             // in C++17.
0026 
0027             template <typename Arg1, typename Result>
0028             struct unary_function
0029             {
0030                 typedef Arg1 argument_type;
0031                 typedef Result result_type;
0032             };
0033 
0034             template <typename Arg1, typename Arg2, typename Result>
0035             struct binary_function
0036             {
0037                 typedef Arg1 first_argument_type;
0038                 typedef Arg2 second_argument_type;
0039                 typedef Result result_type;
0040             };
0041         }
0042     }
0043 
0044 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
0045     // --------------------------------------------------------------------------
0046     // The following traits classes allow us to avoid the need for ptr_fun
0047     // because the types of arguments and the result of a function can be 
0048     // deduced.
0049     //
0050     // In addition to the standard types defined in unary_function and 
0051     // binary_function, we add
0052     //
0053     // - function_type, the type of the function or function object itself.
0054     //
0055     // - param_type, the type that should be used for passing the function or
0056     //   function object as an argument.
0057     // --------------------------------------------------------------------------
0058     namespace detail
0059     {
0060         template <class Operation>
0061         struct unary_traits_imp;
0062         
0063         template <class Operation>
0064         struct unary_traits_imp<Operation*>
0065         {
0066             typedef Operation                         function_type;
0067             typedef const function_type &             param_type;
0068             typedef typename Operation::result_type   result_type;
0069             typedef typename Operation::argument_type argument_type;
0070         };
0071 
0072         template <class R, class A>
0073         struct unary_traits_imp<R(*)(A)>
0074         {
0075             typedef R (*function_type)(A);
0076             typedef R (*param_type)(A);
0077             typedef R result_type;
0078             typedef A argument_type;
0079         };
0080 
0081         template <class Operation>
0082         struct binary_traits_imp;
0083 
0084         template <class Operation>
0085         struct binary_traits_imp<Operation*>
0086         {
0087             typedef Operation                                function_type;
0088             typedef const function_type &                    param_type;
0089             typedef typename Operation::result_type          result_type;
0090             typedef typename Operation::first_argument_type  first_argument_type;
0091             typedef typename Operation::second_argument_type second_argument_type;
0092         };
0093         
0094         template <class R, class A1, class A2>
0095         struct binary_traits_imp<R(*)(A1,A2)>
0096         {
0097             typedef R (*function_type)(A1,A2);
0098             typedef R (*param_type)(A1,A2);
0099             typedef R result_type;
0100             typedef A1 first_argument_type;
0101             typedef A2 second_argument_type;
0102         };
0103     } // namespace detail
0104     
0105     template <class Operation>
0106     struct unary_traits
0107     {
0108         typedef typename detail::unary_traits_imp<Operation*>::function_type function_type;
0109         typedef typename detail::unary_traits_imp<Operation*>::param_type    param_type;
0110         typedef typename detail::unary_traits_imp<Operation*>::result_type   result_type;
0111         typedef typename detail::unary_traits_imp<Operation*>::argument_type argument_type;
0112     }; 
0113 
0114     template <class R, class A>
0115     struct unary_traits<R(*)(A)>
0116     {
0117         typedef R (*function_type)(A);
0118         typedef R (*param_type)(A);
0119         typedef R result_type;
0120         typedef A argument_type;
0121     };
0122 
0123     template <class Operation>
0124     struct binary_traits
0125     {
0126         typedef typename detail::binary_traits_imp<Operation*>::function_type        function_type;
0127         typedef typename detail::binary_traits_imp<Operation*>::param_type           param_type;
0128         typedef typename detail::binary_traits_imp<Operation*>::result_type          result_type;
0129         typedef typename detail::binary_traits_imp<Operation*>::first_argument_type  first_argument_type;
0130         typedef typename detail::binary_traits_imp<Operation*>::second_argument_type second_argument_type;
0131     };
0132     
0133     template <class R, class A1, class A2>
0134     struct binary_traits<R(*)(A1,A2)>
0135     {
0136         typedef R (*function_type)(A1,A2);
0137         typedef R (*param_type)(A1,A2);
0138         typedef R result_type;
0139         typedef A1 first_argument_type;
0140         typedef A2 second_argument_type;
0141     };
0142 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
0143     // --------------------------------------------------------------------------
0144     // If we have no partial specialisation available, decay to a situation
0145     // that is no worse than in the Standard, i.e., ptr_fun will be required.
0146     // --------------------------------------------------------------------------
0147 
0148     template <class Operation>
0149     struct unary_traits
0150     {
0151         typedef Operation                         function_type;
0152         typedef const Operation&                  param_type;
0153         typedef typename Operation::result_type   result_type;
0154         typedef typename Operation::argument_type argument_type;
0155     }; 
0156     
0157     template <class Operation>
0158     struct binary_traits
0159     {
0160         typedef Operation                                function_type;
0161         typedef const Operation &                        param_type;
0162         typedef typename Operation::result_type          result_type;
0163         typedef typename Operation::first_argument_type  first_argument_type;
0164         typedef typename Operation::second_argument_type second_argument_type;
0165     };    
0166 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
0167     
0168     // --------------------------------------------------------------------------
0169     // unary_negate, not1
0170     // --------------------------------------------------------------------------
0171     template <class Predicate>
0172     class unary_negate
0173         : public boost::functional::detail::unary_function<typename unary_traits<Predicate>::argument_type,bool>
0174     {
0175       public:
0176         explicit unary_negate(typename unary_traits<Predicate>::param_type x)
0177             :
0178             pred(x)
0179         {}
0180         bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const
0181         {
0182             return !pred(x);
0183         }
0184       private:
0185         typename unary_traits<Predicate>::function_type pred;
0186     };
0187 
0188     template <class Predicate>
0189     unary_negate<Predicate> not1(const Predicate &pred)
0190     {
0191         // The cast is to placate Borland C++Builder in certain circumstances.
0192         // I don't think it should be necessary.
0193         return unary_negate<Predicate>((typename unary_traits<Predicate>::param_type)pred);
0194     }
0195 
0196     template <class Predicate>
0197     unary_negate<Predicate> not1(Predicate &pred)
0198     {
0199         return unary_negate<Predicate>(pred);
0200     }
0201 
0202     // --------------------------------------------------------------------------
0203     // binary_negate, not2
0204     // --------------------------------------------------------------------------
0205     template <class Predicate>
0206     class binary_negate
0207         : public boost::functional::detail::binary_function<
0208                                       typename binary_traits<Predicate>::first_argument_type,
0209                                       typename binary_traits<Predicate>::second_argument_type,
0210                                       bool>
0211     {
0212       public:
0213         explicit binary_negate(typename binary_traits<Predicate>::param_type x)
0214             :
0215             pred(x)
0216         {}
0217         bool operator()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x,
0218                         typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const
0219         {
0220             return !pred(x,y);
0221         }
0222       private:
0223         typename binary_traits<Predicate>::function_type pred;
0224     };
0225 
0226     template <class Predicate>
0227     binary_negate<Predicate> not2(const Predicate &pred)
0228     {
0229         // The cast is to placate Borland C++Builder in certain circumstances.
0230         // I don't think it should be necessary.
0231         return binary_negate<Predicate>((typename binary_traits<Predicate>::param_type)pred);
0232     }
0233 
0234     template <class Predicate>
0235     binary_negate<Predicate> not2(Predicate &pred)
0236     {
0237         return binary_negate<Predicate>(pred);
0238     }
0239         
0240     // --------------------------------------------------------------------------
0241     // binder1st, bind1st
0242     // --------------------------------------------------------------------------
0243     template <class Operation>
0244     class binder1st
0245         : public boost::functional::detail::unary_function<
0246                                      typename binary_traits<Operation>::second_argument_type,
0247                                      typename binary_traits<Operation>::result_type>
0248     {       
0249       public:
0250         binder1st(typename binary_traits<Operation>::param_type x,
0251                   typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)
0252             :
0253             op(x), value(y)
0254         {}
0255         
0256         typename binary_traits<Operation>::result_type
0257         operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const
0258         {
0259             return op(value, x);
0260         }
0261         
0262       protected:
0263         typename binary_traits<Operation>::function_type op;
0264         typename binary_traits<Operation>::first_argument_type value;
0265     };
0266 
0267     template <class Operation>
0268     inline binder1st<Operation> bind1st(const Operation &op,
0269                                         typename call_traits<
0270                                                     typename binary_traits<Operation>::first_argument_type
0271                                         >::param_type x)
0272     {
0273         // The cast is to placate Borland C++Builder in certain circumstances.
0274         // I don't think it should be necessary.
0275         return binder1st<Operation>((typename binary_traits<Operation>::param_type)op, x);
0276     }
0277 
0278     template <class Operation>
0279     inline binder1st<Operation> bind1st(Operation &op,
0280                                         typename call_traits<
0281                                                     typename binary_traits<Operation>::first_argument_type
0282                                         >::param_type x)
0283     {
0284         return binder1st<Operation>(op, x);
0285     }
0286 
0287     // --------------------------------------------------------------------------
0288     // binder2nd, bind2nd
0289     // --------------------------------------------------------------------------
0290     template <class Operation>
0291     class binder2nd
0292         : public boost::functional::detail::unary_function<
0293                                      typename binary_traits<Operation>::first_argument_type,
0294                                      typename binary_traits<Operation>::result_type>
0295     {
0296       public:
0297         binder2nd(typename binary_traits<Operation>::param_type x,
0298                   typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)
0299             :
0300             op(x), value(y)
0301         {}
0302         
0303         typename binary_traits<Operation>::result_type
0304         operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const
0305         {
0306             return op(x, value);
0307         }               
0308         
0309       protected:
0310         typename binary_traits<Operation>::function_type op;
0311         typename binary_traits<Operation>::second_argument_type value;
0312     };
0313 
0314     template <class Operation>
0315     inline binder2nd<Operation> bind2nd(const Operation &op,
0316                                         typename call_traits<
0317                                                     typename binary_traits<Operation>::second_argument_type
0318                                         >::param_type x)
0319     {
0320         // The cast is to placate Borland C++Builder in certain circumstances.
0321         // I don't think it should be necessary.
0322         return binder2nd<Operation>((typename binary_traits<Operation>::param_type)op, x);
0323     }
0324 
0325     template <class Operation>
0326     inline binder2nd<Operation> bind2nd(Operation &op,
0327                                         typename call_traits<
0328                                                     typename binary_traits<Operation>::second_argument_type
0329                                         >::param_type x)
0330     {
0331         return binder2nd<Operation>(op, x);
0332     }
0333 
0334     // --------------------------------------------------------------------------
0335     // mem_fun, etc
0336     // --------------------------------------------------------------------------
0337     template <class S, class T>
0338     class mem_fun_t : public boost::functional::detail::unary_function<T*, S>
0339     {
0340       public:
0341         explicit mem_fun_t(S (T::*p)())
0342             :
0343             ptr(p)
0344         {}
0345         S operator()(T* p) const
0346         {
0347             return (p->*ptr)();
0348         }
0349       private:
0350         S (T::*ptr)();
0351     };
0352 
0353     template <class S, class T, class A>
0354     class mem_fun1_t : public boost::functional::detail::binary_function<T*, A, S>
0355     {
0356       public:   
0357         explicit mem_fun1_t(S (T::*p)(A))
0358             :
0359             ptr(p)
0360         {}
0361         S operator()(T* p, typename call_traits<A>::param_type x) const
0362         {
0363             return (p->*ptr)(x);
0364         }
0365       private:
0366         S (T::*ptr)(A);
0367     };
0368 
0369     template <class S, class T>
0370     class const_mem_fun_t : public boost::functional::detail::unary_function<const T*, S>
0371     {
0372       public:
0373         explicit const_mem_fun_t(S (T::*p)() const)
0374             :
0375             ptr(p)
0376         {}
0377         S operator()(const T* p) const
0378         {
0379             return (p->*ptr)();
0380         }
0381       private:
0382         S (T::*ptr)() const;        
0383     };
0384 
0385     template <class S, class T, class A>
0386     class const_mem_fun1_t : public boost::functional::detail::binary_function<const T*, A, S>
0387     {
0388       public:
0389         explicit const_mem_fun1_t(S (T::*p)(A) const)
0390             :
0391             ptr(p)
0392         {}
0393         S operator()(const T* p, typename call_traits<A>::param_type x) const
0394         {
0395             return (p->*ptr)(x);
0396         }
0397       private:
0398         S (T::*ptr)(A) const;
0399     };
0400     
0401     template<class S, class T>
0402     inline mem_fun_t<S,T> mem_fun(S (T::*f)())
0403     {
0404         return mem_fun_t<S,T>(f);
0405     }
0406     
0407     template<class S, class T, class A>
0408     inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A))
0409     {
0410         return mem_fun1_t<S,T,A>(f);
0411     }
0412 
0413 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
0414     template<class S, class T>
0415     inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const)
0416     {
0417         return const_mem_fun_t<S,T>(f);
0418     }
0419     
0420     template<class S, class T, class A>
0421     inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const)
0422     {
0423         return const_mem_fun1_t<S,T,A>(f);
0424     }
0425 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
0426 
0427     // --------------------------------------------------------------------------
0428     // mem_fun_ref, etc
0429     // --------------------------------------------------------------------------
0430     template <class S, class T>
0431     class mem_fun_ref_t : public boost::functional::detail::unary_function<T&, S>
0432     {
0433       public:
0434         explicit mem_fun_ref_t(S (T::*p)())
0435             :
0436             ptr(p)
0437         {}
0438         S operator()(T& p) const
0439         {
0440             return (p.*ptr)();
0441         }
0442       private:
0443         S (T::*ptr)();
0444     };
0445 
0446     template <class S, class T, class A>
0447     class mem_fun1_ref_t : public boost::functional::detail::binary_function<T&, A, S>
0448     {
0449       public:
0450         explicit mem_fun1_ref_t(S (T::*p)(A))
0451             :
0452             ptr(p)
0453         {}
0454         S operator()(T& p, typename call_traits<A>::param_type x) const
0455         {
0456             return (p.*ptr)(x);
0457         }
0458       private:
0459         S (T::*ptr)(A);
0460     };
0461     
0462     template <class S, class T>
0463     class const_mem_fun_ref_t : public boost::functional::detail::unary_function<const T&, S>
0464     {
0465       public:
0466         explicit const_mem_fun_ref_t(S (T::*p)() const)
0467             :
0468             ptr(p)
0469         {}
0470         
0471         S operator()(const T &p) const
0472         {
0473             return (p.*ptr)();
0474         }
0475       private:
0476         S (T::*ptr)() const;
0477     };
0478 
0479     template <class S, class T, class A>
0480     class const_mem_fun1_ref_t : public boost::functional::detail::binary_function<const T&, A, S>
0481     {
0482       public:
0483         explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
0484             :
0485             ptr(p)
0486         {}
0487 
0488         S operator()(const T& p, typename call_traits<A>::param_type x) const
0489         {
0490             return (p.*ptr)(x);
0491         }
0492       private:
0493         S (T::*ptr)(A) const;
0494     };
0495     
0496     template<class S, class T>
0497     inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)())
0498     {
0499         return mem_fun_ref_t<S,T>(f);
0500     }
0501 
0502     template<class S, class T, class A>
0503     inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A))
0504     {
0505         return mem_fun1_ref_t<S,T,A>(f);
0506     }
0507 
0508 #ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
0509     template<class S, class T>
0510     inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const)
0511     {
0512         return const_mem_fun_ref_t<S,T>(f);
0513     }
0514 
0515     template<class S, class T, class A>
0516     inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const)
0517     {
0518         return const_mem_fun1_ref_t<S,T,A>(f);
0519     }   
0520 #endif // BOOST_NO_POINTER_TO_MEMBER_CONST
0521 
0522     // --------------------------------------------------------------------------
0523     // ptr_fun
0524     // --------------------------------------------------------------------------
0525     template <class Arg, class Result>
0526     class pointer_to_unary_function : public boost::functional::detail::unary_function<Arg,Result>
0527     {
0528       public:
0529         explicit pointer_to_unary_function(Result (*f)(Arg))
0530             :
0531             func(f)
0532         {}
0533 
0534         Result operator()(typename call_traits<Arg>::param_type x) const
0535         {
0536             return func(x);
0537         }
0538         
0539       private:
0540         Result (*func)(Arg);
0541     };
0542 
0543     template <class Arg, class Result>
0544     inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg))
0545     {
0546         return pointer_to_unary_function<Arg,Result>(f);
0547     }
0548 
0549     template <class Arg1, class Arg2, class Result>
0550     class pointer_to_binary_function : public boost::functional::detail::binary_function<Arg1,Arg2,Result>
0551     {
0552       public:
0553         explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
0554             :
0555             func(f)
0556         {}
0557         
0558         Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const
0559         {
0560             return func(x,y);
0561         }
0562         
0563       private:
0564         Result (*func)(Arg1, Arg2);
0565     };
0566 
0567     template <class Arg1, class Arg2, class Result>
0568     inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2))
0569     {
0570         return pointer_to_binary_function<Arg1,Arg2,Result>(f);
0571     }
0572 } // namespace boost
0573 
0574 #endif