| // ------------------------------------------------------------------------------ |
| // Copyright (c) 2000 Cadenza New Zealand Ltd |
| // Distributed under the Boost Software License, Version 1.0. (See accompany- |
| // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| // ------------------------------------------------------------------------------ |
| // Boost functional.hpp header file |
| // See http://www.boost.org/libs/functional for documentation. |
| // ------------------------------------------------------------------------------ |
| // $Id: functional.hpp 36246 2006-12-02 14:17:26Z andreas_huber69 $ |
| // ------------------------------------------------------------------------------ |
| |
| #ifndef NDNBOOST_FUNCTIONAL_HPP |
| #define NDNBOOST_FUNCTIONAL_HPP |
| |
| #include <ndnboost/config.hpp> |
| #include <ndnboost/call_traits.hpp> |
| #include <functional> |
| |
| namespace ndnboost |
| { |
| #ifndef NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
| // -------------------------------------------------------------------------- |
| // The following traits classes allow us to avoid the need for ptr_fun |
| // because the types of arguments and the result of a function can be |
| // deduced. |
| // |
| // In addition to the standard types defined in unary_function and |
| // binary_function, we add |
| // |
| // - function_type, the type of the function or function object itself. |
| // |
| // - param_type, the type that should be used for passing the function or |
| // function object as an argument. |
| // -------------------------------------------------------------------------- |
| namespace detail |
| { |
| template <class Operation> |
| struct unary_traits_imp; |
| |
| template <class Operation> |
| struct unary_traits_imp<Operation*> |
| { |
| typedef Operation function_type; |
| typedef const function_type & param_type; |
| typedef typename Operation::result_type result_type; |
| typedef typename Operation::argument_type argument_type; |
| }; |
| |
| template <class R, class A> |
| struct unary_traits_imp<R(*)(A)> |
| { |
| typedef R (*function_type)(A); |
| typedef R (*param_type)(A); |
| typedef R result_type; |
| typedef A argument_type; |
| }; |
| |
| template <class Operation> |
| struct binary_traits_imp; |
| |
| template <class Operation> |
| struct binary_traits_imp<Operation*> |
| { |
| typedef Operation function_type; |
| typedef const function_type & param_type; |
| typedef typename Operation::result_type result_type; |
| typedef typename Operation::first_argument_type first_argument_type; |
| typedef typename Operation::second_argument_type second_argument_type; |
| }; |
| |
| template <class R, class A1, class A2> |
| struct binary_traits_imp<R(*)(A1,A2)> |
| { |
| typedef R (*function_type)(A1,A2); |
| typedef R (*param_type)(A1,A2); |
| typedef R result_type; |
| typedef A1 first_argument_type; |
| typedef A2 second_argument_type; |
| }; |
| } // namespace detail |
| |
| template <class Operation> |
| struct unary_traits |
| { |
| typedef typename detail::unary_traits_imp<Operation*>::function_type function_type; |
| typedef typename detail::unary_traits_imp<Operation*>::param_type param_type; |
| typedef typename detail::unary_traits_imp<Operation*>::result_type result_type; |
| typedef typename detail::unary_traits_imp<Operation*>::argument_type argument_type; |
| }; |
| |
| template <class R, class A> |
| struct unary_traits<R(*)(A)> |
| { |
| typedef R (*function_type)(A); |
| typedef R (*param_type)(A); |
| typedef R result_type; |
| typedef A argument_type; |
| }; |
| |
| template <class Operation> |
| struct binary_traits |
| { |
| typedef typename detail::binary_traits_imp<Operation*>::function_type function_type; |
| typedef typename detail::binary_traits_imp<Operation*>::param_type param_type; |
| typedef typename detail::binary_traits_imp<Operation*>::result_type result_type; |
| typedef typename detail::binary_traits_imp<Operation*>::first_argument_type first_argument_type; |
| typedef typename detail::binary_traits_imp<Operation*>::second_argument_type second_argument_type; |
| }; |
| |
| template <class R, class A1, class A2> |
| struct binary_traits<R(*)(A1,A2)> |
| { |
| typedef R (*function_type)(A1,A2); |
| typedef R (*param_type)(A1,A2); |
| typedef R result_type; |
| typedef A1 first_argument_type; |
| typedef A2 second_argument_type; |
| }; |
| #else // NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
| // -------------------------------------------------------------------------- |
| // If we have no partial specialisation available, decay to a situation |
| // that is no worse than in the Standard, i.e., ptr_fun will be required. |
| // -------------------------------------------------------------------------- |
| |
| template <class Operation> |
| struct unary_traits |
| { |
| typedef Operation function_type; |
| typedef const Operation& param_type; |
| typedef typename Operation::result_type result_type; |
| typedef typename Operation::argument_type argument_type; |
| }; |
| |
| template <class Operation> |
| struct binary_traits |
| { |
| typedef Operation function_type; |
| typedef const Operation & param_type; |
| typedef typename Operation::result_type result_type; |
| typedef typename Operation::first_argument_type first_argument_type; |
| typedef typename Operation::second_argument_type second_argument_type; |
| }; |
| #endif // NDNBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
| |
| // -------------------------------------------------------------------------- |
| // unary_negate, not1 |
| // -------------------------------------------------------------------------- |
| template <class Predicate> |
| class unary_negate |
| : public std::unary_function<typename unary_traits<Predicate>::argument_type,bool> |
| { |
| public: |
| explicit unary_negate(typename unary_traits<Predicate>::param_type x) |
| : |
| pred(x) |
| {} |
| bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const |
| { |
| return !pred(x); |
| } |
| private: |
| typename unary_traits<Predicate>::function_type pred; |
| }; |
| |
| template <class Predicate> |
| unary_negate<Predicate> not1(const Predicate &pred) |
| { |
| // The cast is to placate Borland C++Builder in certain circumstances. |
| // I don't think it should be necessary. |
| return unary_negate<Predicate>((typename unary_traits<Predicate>::param_type)pred); |
| } |
| |
| template <class Predicate> |
| unary_negate<Predicate> not1(Predicate &pred) |
| { |
| return unary_negate<Predicate>(pred); |
| } |
| |
| // -------------------------------------------------------------------------- |
| // binary_negate, not2 |
| // -------------------------------------------------------------------------- |
| template <class Predicate> |
| class binary_negate |
| : public std::binary_function<typename binary_traits<Predicate>::first_argument_type, |
| typename binary_traits<Predicate>::second_argument_type, |
| bool> |
| { |
| public: |
| explicit binary_negate(typename binary_traits<Predicate>::param_type x) |
| : |
| pred(x) |
| {} |
| bool operator()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x, |
| typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const |
| { |
| return !pred(x,y); |
| } |
| private: |
| typename binary_traits<Predicate>::function_type pred; |
| }; |
| |
| template <class Predicate> |
| binary_negate<Predicate> not2(const Predicate &pred) |
| { |
| // The cast is to placate Borland C++Builder in certain circumstances. |
| // I don't think it should be necessary. |
| return binary_negate<Predicate>((typename binary_traits<Predicate>::param_type)pred); |
| } |
| |
| template <class Predicate> |
| binary_negate<Predicate> not2(Predicate &pred) |
| { |
| return binary_negate<Predicate>(pred); |
| } |
| |
| // -------------------------------------------------------------------------- |
| // binder1st, bind1st |
| // -------------------------------------------------------------------------- |
| template <class Operation> |
| class binder1st |
| : public std::unary_function<typename binary_traits<Operation>::second_argument_type, |
| typename binary_traits<Operation>::result_type> |
| { |
| public: |
| binder1st(typename binary_traits<Operation>::param_type x, |
| typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y) |
| : |
| op(x), value(y) |
| {} |
| |
| typename binary_traits<Operation>::result_type |
| operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const |
| { |
| return op(value, x); |
| } |
| |
| protected: |
| typename binary_traits<Operation>::function_type op; |
| typename binary_traits<Operation>::first_argument_type value; |
| }; |
| |
| template <class Operation> |
| inline binder1st<Operation> bind1st(const Operation &op, |
| typename call_traits< |
| typename binary_traits<Operation>::first_argument_type |
| >::param_type x) |
| { |
| // The cast is to placate Borland C++Builder in certain circumstances. |
| // I don't think it should be necessary. |
| return binder1st<Operation>((typename binary_traits<Operation>::param_type)op, x); |
| } |
| |
| template <class Operation> |
| inline binder1st<Operation> bind1st(Operation &op, |
| typename call_traits< |
| typename binary_traits<Operation>::first_argument_type |
| >::param_type x) |
| { |
| return binder1st<Operation>(op, x); |
| } |
| |
| // -------------------------------------------------------------------------- |
| // binder2nd, bind2nd |
| // -------------------------------------------------------------------------- |
| template <class Operation> |
| class binder2nd |
| : public std::unary_function<typename binary_traits<Operation>::first_argument_type, |
| typename binary_traits<Operation>::result_type> |
| { |
| public: |
| binder2nd(typename binary_traits<Operation>::param_type x, |
| typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y) |
| : |
| op(x), value(y) |
| {} |
| |
| typename binary_traits<Operation>::result_type |
| operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const |
| { |
| return op(x, value); |
| } |
| |
| protected: |
| typename binary_traits<Operation>::function_type op; |
| typename binary_traits<Operation>::second_argument_type value; |
| }; |
| |
| template <class Operation> |
| inline binder2nd<Operation> bind2nd(const Operation &op, |
| typename call_traits< |
| typename binary_traits<Operation>::second_argument_type |
| >::param_type x) |
| { |
| // The cast is to placate Borland C++Builder in certain circumstances. |
| // I don't think it should be necessary. |
| return binder2nd<Operation>((typename binary_traits<Operation>::param_type)op, x); |
| } |
| |
| template <class Operation> |
| inline binder2nd<Operation> bind2nd(Operation &op, |
| typename call_traits< |
| typename binary_traits<Operation>::second_argument_type |
| >::param_type x) |
| { |
| return binder2nd<Operation>(op, x); |
| } |
| |
| // -------------------------------------------------------------------------- |
| // mem_fun, etc |
| // -------------------------------------------------------------------------- |
| template <class S, class T> |
| class mem_fun_t : public std::unary_function<T*, S> |
| { |
| public: |
| explicit mem_fun_t(S (T::*p)()) |
| : |
| ptr(p) |
| {} |
| S operator()(T* p) const |
| { |
| return (p->*ptr)(); |
| } |
| private: |
| S (T::*ptr)(); |
| }; |
| |
| template <class S, class T, class A> |
| class mem_fun1_t : public std::binary_function<T*, A, S> |
| { |
| public: |
| explicit mem_fun1_t(S (T::*p)(A)) |
| : |
| ptr(p) |
| {} |
| S operator()(T* p, typename call_traits<A>::param_type x) const |
| { |
| return (p->*ptr)(x); |
| } |
| private: |
| S (T::*ptr)(A); |
| }; |
| |
| template <class S, class T> |
| class const_mem_fun_t : public std::unary_function<const T*, S> |
| { |
| public: |
| explicit const_mem_fun_t(S (T::*p)() const) |
| : |
| ptr(p) |
| {} |
| S operator()(const T* p) const |
| { |
| return (p->*ptr)(); |
| } |
| private: |
| S (T::*ptr)() const; |
| }; |
| |
| template <class S, class T, class A> |
| class const_mem_fun1_t : public std::binary_function<const T*, A, S> |
| { |
| public: |
| explicit const_mem_fun1_t(S (T::*p)(A) const) |
| : |
| ptr(p) |
| {} |
| S operator()(const T* p, typename call_traits<A>::param_type x) const |
| { |
| return (p->*ptr)(x); |
| } |
| private: |
| S (T::*ptr)(A) const; |
| }; |
| |
| template<class S, class T> |
| inline mem_fun_t<S,T> mem_fun(S (T::*f)()) |
| { |
| return mem_fun_t<S,T>(f); |
| } |
| |
| template<class S, class T, class A> |
| inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A)) |
| { |
| return mem_fun1_t<S,T,A>(f); |
| } |
| |
| #ifndef NDNBOOST_NO_POINTER_TO_MEMBER_CONST |
| template<class S, class T> |
| inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) |
| { |
| return const_mem_fun_t<S,T>(f); |
| } |
| |
| template<class S, class T, class A> |
| inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const) |
| { |
| return const_mem_fun1_t<S,T,A>(f); |
| } |
| #endif // NDNBOOST_NO_POINTER_TO_MEMBER_CONST |
| |
| // -------------------------------------------------------------------------- |
| // mem_fun_ref, etc |
| // -------------------------------------------------------------------------- |
| template <class S, class T> |
| class mem_fun_ref_t : public std::unary_function<T&, S> |
| { |
| public: |
| explicit mem_fun_ref_t(S (T::*p)()) |
| : |
| ptr(p) |
| {} |
| S operator()(T& p) const |
| { |
| return (p.*ptr)(); |
| } |
| private: |
| S (T::*ptr)(); |
| }; |
| |
| template <class S, class T, class A> |
| class mem_fun1_ref_t : public std::binary_function<T&, A, S> |
| { |
| public: |
| explicit mem_fun1_ref_t(S (T::*p)(A)) |
| : |
| ptr(p) |
| {} |
| S operator()(T& p, typename call_traits<A>::param_type x) const |
| { |
| return (p.*ptr)(x); |
| } |
| private: |
| S (T::*ptr)(A); |
| }; |
| |
| template <class S, class T> |
| class const_mem_fun_ref_t : public std::unary_function<const T&, S> |
| { |
| public: |
| explicit const_mem_fun_ref_t(S (T::*p)() const) |
| : |
| ptr(p) |
| {} |
| |
| S operator()(const T &p) const |
| { |
| return (p.*ptr)(); |
| } |
| private: |
| S (T::*ptr)() const; |
| }; |
| |
| template <class S, class T, class A> |
| class const_mem_fun1_ref_t : public std::binary_function<const T&, A, S> |
| { |
| public: |
| explicit const_mem_fun1_ref_t(S (T::*p)(A) const) |
| : |
| ptr(p) |
| {} |
| |
| S operator()(const T& p, typename call_traits<A>::param_type x) const |
| { |
| return (p.*ptr)(x); |
| } |
| private: |
| S (T::*ptr)(A) const; |
| }; |
| |
| template<class S, class T> |
| inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) |
| { |
| return mem_fun_ref_t<S,T>(f); |
| } |
| |
| template<class S, class T, class A> |
| inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A)) |
| { |
| return mem_fun1_ref_t<S,T,A>(f); |
| } |
| |
| #ifndef NDNBOOST_NO_POINTER_TO_MEMBER_CONST |
| template<class S, class T> |
| inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) |
| { |
| return const_mem_fun_ref_t<S,T>(f); |
| } |
| |
| template<class S, class T, class A> |
| inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const) |
| { |
| return const_mem_fun1_ref_t<S,T,A>(f); |
| } |
| #endif // NDNBOOST_NO_POINTER_TO_MEMBER_CONST |
| |
| // -------------------------------------------------------------------------- |
| // ptr_fun |
| // -------------------------------------------------------------------------- |
| template <class Arg, class Result> |
| class pointer_to_unary_function : public std::unary_function<Arg,Result> |
| { |
| public: |
| explicit pointer_to_unary_function(Result (*f)(Arg)) |
| : |
| func(f) |
| {} |
| |
| Result operator()(typename call_traits<Arg>::param_type x) const |
| { |
| return func(x); |
| } |
| |
| private: |
| Result (*func)(Arg); |
| }; |
| |
| template <class Arg, class Result> |
| inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg)) |
| { |
| return pointer_to_unary_function<Arg,Result>(f); |
| } |
| |
| template <class Arg1, class Arg2, class Result> |
| class pointer_to_binary_function : public std::binary_function<Arg1,Arg2,Result> |
| { |
| public: |
| explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2)) |
| : |
| func(f) |
| {} |
| |
| Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const |
| { |
| return func(x,y); |
| } |
| |
| private: |
| Result (*func)(Arg1, Arg2); |
| }; |
| |
| template <class Arg1, class Arg2, class Result> |
| inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2)) |
| { |
| return pointer_to_binary_function<Arg1,Arg2,Result>(f); |
| } |
| } // namespace ndnboost |
| |
| #endif |