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