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