Chris@16: /*-----------------------------------------------------------------------------+ Chris@16: Copyright (c) 2007-2009: Joachim Faulhaber Chris@16: +------------------------------------------------------------------------------+ Chris@16: Distributed under the Boost Software License, Version 1.0. Chris@16: (See accompanying file LICENCE.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt) Chris@16: +-----------------------------------------------------------------------------*/ Chris@16: #ifndef BOOST_ICL_FUNCTORS_HPP_JOFA_080315 Chris@16: #define BOOST_ICL_FUNCTORS_HPP_JOFA_080315 Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost{namespace icl Chris@16: { Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct identity_based_inplace_combine Chris@16: : public std::binary_function Chris@16: { Chris@16: inline static Type identity_element() { return boost::icl::identity_element::value(); } Chris@16: }; Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct unit_element_based_inplace_combine Chris@16: : public std::binary_function Chris@16: { Chris@16: inline static Type identity_element() { return boost::icl::unit_element::value(); } Chris@16: }; Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_identity Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_identity type; Chris@16: void operator()(Type&, const Type&)const{} Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() Chris@16: { return "i="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_erasure Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_erasure type; Chris@16: typedef identity_based_inplace_combine base_type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { Chris@16: if(object == operand) Chris@16: //identity_element(); //JODO Old gcc-3.4.4 does not compile this Chris@16: object = base_type::identity_element(); //<-- but this. Chris@16: } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() Chris@16: { return "0="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_plus Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_plus type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object += operand; } Chris@16: Chris@16: static void version(Type&){} Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "+="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_minus Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_minus type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object -= operand; } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "-="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_bit_add Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_bit_add type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object |= operand; } Chris@16: Chris@16: static void version(Type&){} Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "b|="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_bit_subtract Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_bit_subtract type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object &= ~operand; } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "b-="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_bit_and Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_bit_and type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object &= operand; } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "b&="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_bit_xor Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_bit_xor type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object ^= operand; } Chris@16: }; Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_et Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_et type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object &= operand; } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "&="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_caret Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_caret type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object ^= operand; } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "^="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_insert Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_insert type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { insert(object,operand); } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "ins="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_erase Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_erase type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { erase(object,operand); } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "ers="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_star Chris@16: : public identity_based_inplace_combine //JODO unit_element_ Chris@16: { Chris@16: typedef inplace_star type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object *= operand; } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "*="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_slash Chris@16: : public identity_based_inplace_combine //JODO unit_element_ Chris@16: { Chris@16: typedef inplace_slash type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { object /= operand; } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "/="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_max Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_max type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { Chris@16: if(object < operand) Chris@16: object = operand; Chris@16: } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "max="; } Chris@16: Chris@16: // ------------------------------------------------------------------------ Chris@16: template struct inplace_min Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef inplace_min type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { Chris@16: if(object > operand) Chris@16: object = operand; Chris@16: } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: inline std::string unary_template_to_string::apply() { return "min="; } Chris@16: Chris@16: //-------------------------------------------------------------------------- Chris@16: // Inter_section functor Chris@16: //-------------------------------------------------------------------------- Chris@16: template struct inter_section Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef typename boost::mpl:: Chris@16: if_, Chris@16: icl::inplace_et, Chris@16: icl::inplace_plus Chris@16: >::type Chris@16: type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { Chris@16: type()(object, operand); Chris@16: } Chris@16: }; Chris@16: Chris@16: //-------------------------------------------------------------------------- Chris@16: // Inverse functor Chris@16: //-------------------------------------------------------------------------- Chris@16: template struct inverse; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_minus type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_plus type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_bit_subtract type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_bit_add type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_caret type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_et type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_bit_xor type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_bit_and type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_slash type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_star type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_min type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_max type; }; Chris@16: Chris@16: template Chris@16: struct inverse > Chris@16: { typedef icl::inplace_erasure type; }; Chris@16: Chris@16: // If a Functor Chris@16: template Chris@16: struct inverse Chris@16: { Chris@16: typedef typename Chris@16: remove_reference::type argument_type; Chris@16: typedef icl::inplace_erasure type; Chris@16: }; Chris@16: Chris@16: Chris@16: //-------------------------------------------------------------------------- Chris@16: // Inverse inter_section functor Chris@16: //-------------------------------------------------------------------------- Chris@16: template Chris@16: struct inverse > Chris@16: : public identity_based_inplace_combine Chris@16: { Chris@16: typedef typename boost::mpl:: Chris@16: if_, Chris@16: icl::inplace_caret, Chris@16: icl::inplace_minus Chris@16: >::type Chris@16: type; Chris@16: Chris@16: void operator()(Type& object, const Type& operand)const Chris@16: { Chris@16: type()(object, operand); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: //-------------------------------------------------------------------------- Chris@16: // Positive or negative functor trait Chris@16: //-------------------------------------------------------------------------- Chris@16: Chris@16: // A binary operation - is negative (or inverting) with respect to the Chris@16: // neutral element iff it yields the inverse element if it is applied to the Chris@16: // identity element: Chris@16: // 0 - x = -x Chris@16: // For a functor that wraps the inplace of op-assign version this is Chris@16: // equivalent to Chris@16: // Chris@16: // T x = ..., y; Chris@16: // y = Functor::identity_element(); Chris@16: // Functor()(y, x); // y == inverse_of(x) Chris@16: Chris@16: template struct is_negative; Chris@16: Chris@16: template Chris@16: struct is_negative Chris@16: { Chris@16: typedef is_negative type; Chris@16: BOOST_STATIC_CONSTANT(bool, value = false); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_negative > Chris@16: { Chris@16: typedef is_negative type; Chris@16: BOOST_STATIC_CONSTANT(bool, value = true); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct is_negative > Chris@16: { Chris@16: typedef is_negative type; Chris@16: BOOST_STATIC_CONSTANT(bool, value = true); Chris@16: }; Chris@16: Chris@16: //-------------------------------------------------------------------------- Chris@16: // Pro- or in-version functor Chris@16: //-------------------------------------------------------------------------- Chris@16: template struct conversion; Chris@16: Chris@16: template Chris@16: struct conversion Chris@16: { Chris@16: typedef conversion type; Chris@16: typedef typename Chris@16: remove_const< Chris@16: typename remove_reference::type Chris@16: >::type Chris@16: argument_type; Chris@16: // The proversion of an op-assign functor o= lets the value unchanged Chris@16: // (0 o= x) == x; Chris@16: // Example += : (0 += x) == x Chris@16: static argument_type proversion(const argument_type& value) Chris@16: { Chris@16: return value; Chris@16: } Chris@16: Chris@16: // The inversion of an op-assign functor o= inverts the value x Chris@16: // to it's inverse element -x Chris@16: // (0 o= x) == -x; Chris@16: // Example -= : (0 -= x) == -x Chris@16: static argument_type inversion(const argument_type& value) Chris@16: { Chris@16: argument_type inverse = Combiner::identity_element(); Chris@16: Combiner()(inverse, value); Chris@16: return inverse; Chris@16: } Chris@16: }; Chris@16: Chris@16: template struct version : public conversion Chris@16: { Chris@16: typedef version type; Chris@16: typedef conversion base_type; Chris@16: typedef typename base_type::argument_type argument_type; Chris@16: Chris@16: argument_type operator()(const argument_type& value) Chris@16: { return base_type::proversion(value); } Chris@16: }; Chris@16: Chris@16: template<>struct version >{short operator()(short val){return -val;}}; Chris@16: template<>struct version >{int operator()(int val){return -val;}}; Chris@16: template<>struct version >{long operator()(long val){return -val;}}; Chris@16: template<>struct version >{long long operator()(long long val){return -val;}}; Chris@16: template<>struct version >{float operator()(float val){return -val;}}; Chris@16: template<>struct version >{double operator()(double val){return -val;}}; Chris@16: template<>struct version >{long double operator()(long double val){return -val;}}; Chris@16: Chris@16: template Chris@16: struct version > : public conversion > Chris@16: { Chris@16: typedef version > type; Chris@16: typedef conversion > base_type; Chris@16: typedef typename base_type::argument_type argument_type; Chris@16: Chris@16: Type operator()(const Type& value) Chris@16: { Chris@16: return base_type::inversion(value); Chris@16: } Chris@16: }; Chris@16: Chris@16: }} // namespace icl boost Chris@16: Chris@16: #endif Chris@16: Chris@16: