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