123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- /*-----------------------------------------------------------------------------+
- 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 <boost/type_traits.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/icl/type_traits/identity_element.hpp>
- #include <boost/icl/type_traits/unit_element.hpp>
- #include <boost/icl/type_traits/is_set.hpp>
- #include <boost/icl/type_traits/has_set_semantics.hpp>
- namespace boost{namespace icl
- {
- // ------------------------------------------------------------------------
- template <typename Type> struct identity_based_inplace_combine
- {
- typedef Type& first_argument_type;
- typedef const Type& second_argument_type;
- typedef void result_type;
- inline static Type identity_element() { return boost::icl::identity_element<Type>::value(); }
- };
- // ------------------------------------------------------------------------
- template <typename Type> struct unit_element_based_inplace_combine
- {
- typedef Type& first_argument_type;
- typedef const Type& second_argument_type;
- typedef void result_type;
- inline static Type identity_element() { return boost::icl::unit_element<Type>::value(); }
- };
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_identity
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_identity<Type> type;
- void operator()(Type&, const Type&)const{}
- };
- template<>
- inline std::string unary_template_to_string<inplace_identity>::apply()
- { return "i="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_erasure
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_erasure<Type> type;
- typedef identity_based_inplace_combine<Type> 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<inplace_erasure>::apply()
- { return "0="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_plus
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_plus<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object += operand; }
- static void version(Type&){}
- };
- template<>
- inline std::string unary_template_to_string<inplace_plus>::apply() { return "+="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_minus
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_minus<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object -= operand; }
- };
- template<>
- inline std::string unary_template_to_string<inplace_minus>::apply() { return "-="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_bit_add
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_bit_add<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object |= operand; }
- static void version(Type&){}
- };
- template<>
- inline std::string unary_template_to_string<inplace_bit_add>::apply() { return "b|="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_bit_subtract
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_bit_subtract<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object &= ~operand; }
- };
- template<>
- inline std::string unary_template_to_string<inplace_bit_subtract>::apply() { return "b-="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_bit_and
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_bit_and<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object &= operand; }
- };
- template<>
- inline std::string unary_template_to_string<inplace_bit_and>::apply() { return "b&="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_bit_xor
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_bit_xor<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object ^= operand; }
- };
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_et
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_et<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object &= operand; }
- };
- template<>
- inline std::string unary_template_to_string<inplace_et>::apply() { return "&="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_caret
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_caret<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object ^= operand; }
- };
- template<>
- inline std::string unary_template_to_string<inplace_caret>::apply() { return "^="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_insert
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_insert<Type> type;
- void operator()(Type& object, const Type& operand)const
- { insert(object,operand); }
- };
- template<>
- inline std::string unary_template_to_string<inplace_insert>::apply() { return "ins="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_erase
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_erase<Type> type;
- void operator()(Type& object, const Type& operand)const
- { erase(object,operand); }
- };
- template<>
- inline std::string unary_template_to_string<inplace_erase>::apply() { return "ers="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_star
- : public identity_based_inplace_combine<Type> //JODO unit_element_
- {
- typedef inplace_star<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object *= operand; }
- };
- template<>
- inline std::string unary_template_to_string<inplace_star>::apply() { return "*="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_slash
- : public identity_based_inplace_combine<Type> //JODO unit_element_
- {
- typedef inplace_slash<Type> type;
- void operator()(Type& object, const Type& operand)const
- { object /= operand; }
- };
- template<>
- inline std::string unary_template_to_string<inplace_slash>::apply() { return "/="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_max
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_max<Type> type;
- void operator()(Type& object, const Type& operand)const
- {
- if(object < operand)
- object = operand;
- }
- };
- template<>
- inline std::string unary_template_to_string<inplace_max>::apply() { return "max="; }
- // ------------------------------------------------------------------------
- template <typename Type> struct inplace_min
- : public identity_based_inplace_combine<Type>
- {
- typedef inplace_min<Type> type;
- void operator()(Type& object, const Type& operand)const
- {
- if(object > operand)
- object = operand;
- }
- };
- template<>
- inline std::string unary_template_to_string<inplace_min>::apply() { return "min="; }
- //--------------------------------------------------------------------------
- // Inter_section functor
- //--------------------------------------------------------------------------
- template<class Type> struct inter_section
- : public identity_based_inplace_combine<Type>
- {
- typedef typename boost::mpl::
- if_<has_set_semantics<Type>,
- icl::inplace_et<Type>,
- icl::inplace_plus<Type>
- >::type
- type;
- void operator()(Type& object, const Type& operand)const
- {
- type()(object, operand);
- }
- };
- //--------------------------------------------------------------------------
- // Inverse functor
- //--------------------------------------------------------------------------
- template<class Functor> struct inverse;
- template<class Type>
- struct inverse<icl::inplace_plus<Type> >
- { typedef icl::inplace_minus<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_minus<Type> >
- { typedef icl::inplace_plus<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_bit_add<Type> >
- { typedef icl::inplace_bit_subtract<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_bit_subtract<Type> >
- { typedef icl::inplace_bit_add<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_et<Type> >
- { typedef icl::inplace_caret<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_caret<Type> >
- { typedef icl::inplace_et<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_bit_and<Type> >
- { typedef icl::inplace_bit_xor<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_bit_xor<Type> >
- { typedef icl::inplace_bit_and<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_star<Type> >
- { typedef icl::inplace_slash<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_slash<Type> >
- { typedef icl::inplace_star<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_max<Type> >
- { typedef icl::inplace_min<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_min<Type> >
- { typedef icl::inplace_max<Type> type; };
- template<class Type>
- struct inverse<icl::inplace_identity<Type> >
- { typedef icl::inplace_erasure<Type> type; };
- // If a Functor
- template<class Functor>
- struct inverse
- {
- typedef typename
- remove_reference<typename Functor::first_argument_type>::type argument_type;
- typedef icl::inplace_erasure<argument_type> type;
- };
- //--------------------------------------------------------------------------
- // Inverse inter_section functor
- //--------------------------------------------------------------------------
- template<class Type>
- struct inverse<icl::inter_section<Type> >
- : public identity_based_inplace_combine<Type>
- {
- typedef typename boost::mpl::
- if_<has_set_semantics<Type>,
- icl::inplace_caret<Type>,
- icl::inplace_minus<Type>
- >::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<class Functor> struct is_negative;
- template<class Functor>
- struct is_negative
- {
- typedef is_negative<Functor> type;
- BOOST_STATIC_CONSTANT(bool, value = false);
- };
- template<class Type>
- struct is_negative<icl::inplace_minus<Type> >
- {
- typedef is_negative type;
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
- template<class Type>
- struct is_negative<icl::inplace_bit_subtract<Type> >
- {
- typedef is_negative type;
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
- //--------------------------------------------------------------------------
- // Pro- or in-version functor
- //--------------------------------------------------------------------------
- template<class Combiner> struct conversion;
- template<class Combiner>
- struct conversion
- {
- typedef conversion<Combiner> type;
- typedef typename
- remove_const<
- typename remove_reference<typename Combiner::first_argument_type
- >::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<class Combiner> struct version : public conversion<Combiner>
- {
- typedef version<Combiner> type;
- typedef conversion<Combiner> 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<icl::inplace_minus<short > >{short operator()(short val){return -val;}};
- template<>struct version<icl::inplace_minus<int > >{int operator()(int val){return -val;}};
- template<>struct version<icl::inplace_minus<long > >{long operator()(long val){return -val;}};
- template<>struct version<icl::inplace_minus<long long > >{long long operator()(long long val){return -val;}};
- template<>struct version<icl::inplace_minus<float > >{float operator()(float val){return -val;}};
- template<>struct version<icl::inplace_minus<double > >{double operator()(double val){return -val;}};
- template<>struct version<icl::inplace_minus<long double> >{long double operator()(long double val){return -val;}};
- template<class Type>
- struct version<icl::inplace_minus<Type> > : public conversion<icl::inplace_minus<Type> >
- {
- typedef version<icl::inplace_minus<Type> > type;
- typedef conversion<icl::inplace_minus<Type> > base_type;
- typedef typename base_type::argument_type argument_type;
- Type operator()(const Type& value)
- {
- return base_type::inversion(value);
- }
- };
- }} // namespace icl boost
- #endif
|