diff options
Diffstat (limited to 'boost/functional.hpp')
-rw-r--r-- | boost/functional.hpp | 548 |
1 files changed, 548 insertions, 0 deletions
diff --git a/boost/functional.hpp b/boost/functional.hpp new file mode 100644 index 0000000000..3e0588e00f --- /dev/null +++ b/boost/functional.hpp @@ -0,0 +1,548 @@ +// ------------------------------------------------------------------------------ +// 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 BOOST_FUNCTIONAL_HPP +#define BOOST_FUNCTIONAL_HPP + +#include <boost/config.hpp> +#include <boost/call_traits.hpp> +#include <functional> + +namespace boost +{ +#ifndef BOOST_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 // BOOST_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 // BOOST_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 BOOST_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 // BOOST_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 BOOST_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 // BOOST_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 boost + +#endif |