| 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
 |