Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:21

0001 /*-----------------------------------------------------------------------------+
0002 Copyright (c) 2007-2009: Joachim Faulhaber
0003 +------------------------------------------------------------------------------+
0004    Distributed under the Boost Software License, Version 1.0.
0005       (See accompanying file LICENCE.txt or copy at
0006            http://www.boost.org/LICENSE_1_0.txt)
0007 +-----------------------------------------------------------------------------*/
0008 #ifndef BOOST_ICL_FUNCTORS_HPP_JOFA_080315
0009 #define BOOST_ICL_FUNCTORS_HPP_JOFA_080315
0010 
0011 #include <boost/type_traits.hpp>
0012 #include <boost/mpl/if.hpp>
0013 #include <boost/icl/type_traits/identity_element.hpp>
0014 #include <boost/icl/type_traits/unit_element.hpp>
0015 #include <boost/icl/type_traits/is_set.hpp>
0016 #include <boost/icl/type_traits/has_set_semantics.hpp>
0017 
0018 namespace boost{namespace icl
0019 {
0020     // ------------------------------------------------------------------------
0021     template <typename Type> struct identity_based_inplace_combine 
0022     {
0023         typedef Type& first_argument_type;
0024         typedef const Type& second_argument_type;
0025         typedef void result_type;
0026         inline static Type identity_element() { return boost::icl::identity_element<Type>::value(); }
0027     };
0028 
0029     // ------------------------------------------------------------------------
0030     template <typename Type> struct unit_element_based_inplace_combine 
0031     {
0032         typedef Type& first_argument_type;
0033         typedef const Type& second_argument_type;
0034         typedef void result_type;
0035         inline static Type identity_element() { return boost::icl::unit_element<Type>::value(); }
0036     };
0037 
0038     // ------------------------------------------------------------------------
0039     template <typename Type> struct inplace_identity 
0040         : public identity_based_inplace_combine<Type>
0041     {
0042         typedef inplace_identity<Type> type;
0043         void operator()(Type&, const Type&)const{}
0044     };
0045 
0046     template<>
0047     inline std::string unary_template_to_string<inplace_identity>::apply() 
0048     { return "i="; }
0049 
0050     // ------------------------------------------------------------------------
0051     template <typename Type> struct inplace_erasure 
0052         : public identity_based_inplace_combine<Type>
0053     {
0054         typedef inplace_erasure<Type> type;
0055         typedef identity_based_inplace_combine<Type> base_type;
0056 
0057         void operator()(Type& object, const Type& operand)const
0058         { 
0059             if(object == operand)
0060                 //identity_element(); //JODO Old gcc-3.4.4 does not compile this
0061                 object = base_type::identity_element(); //<-- but this.
0062         }
0063     };
0064 
0065     template<>
0066     inline std::string unary_template_to_string<inplace_erasure>::apply() 
0067     { return "0="; }
0068 
0069     // ------------------------------------------------------------------------
0070     template <typename Type> struct inplace_plus 
0071         : public identity_based_inplace_combine<Type>
0072     {
0073         typedef inplace_plus<Type> type;
0074 
0075         void operator()(Type& object, const Type& operand)const
0076         { object += operand; }
0077 
0078         static void version(Type&){}
0079     };
0080 
0081     template<>
0082     inline std::string unary_template_to_string<inplace_plus>::apply() { return "+="; }
0083 
0084     // ------------------------------------------------------------------------
0085     template <typename Type> struct inplace_minus 
0086         : public identity_based_inplace_combine<Type>
0087     {
0088         typedef inplace_minus<Type> type;
0089 
0090         void operator()(Type& object, const Type& operand)const
0091         { object -= operand; }
0092     };
0093 
0094     template<>
0095     inline std::string unary_template_to_string<inplace_minus>::apply() { return "-="; }
0096 
0097     // ------------------------------------------------------------------------
0098     template <typename Type> struct inplace_bit_add
0099         : public identity_based_inplace_combine<Type>
0100     {
0101         typedef inplace_bit_add<Type> type;
0102 
0103         void operator()(Type& object, const Type& operand)const
0104         { object |= operand; }
0105 
0106         static void version(Type&){}
0107     };
0108 
0109     template<>
0110     inline std::string unary_template_to_string<inplace_bit_add>::apply() { return "b|="; }
0111 
0112     // ------------------------------------------------------------------------
0113     template <typename Type> struct inplace_bit_subtract
0114         : public identity_based_inplace_combine<Type>
0115     {
0116         typedef inplace_bit_subtract<Type> type;
0117 
0118         void operator()(Type& object, const Type& operand)const
0119         { object &= ~operand; }
0120     };
0121 
0122     template<>
0123     inline std::string unary_template_to_string<inplace_bit_subtract>::apply() { return "b-="; }
0124 
0125     // ------------------------------------------------------------------------
0126     template <typename Type> struct inplace_bit_and
0127         : public identity_based_inplace_combine<Type>
0128     {
0129         typedef inplace_bit_and<Type> type;
0130 
0131         void operator()(Type& object, const Type& operand)const
0132         { object &= operand; }
0133     };
0134 
0135     template<>
0136     inline std::string unary_template_to_string<inplace_bit_and>::apply() { return "b&="; }
0137 
0138     // ------------------------------------------------------------------------
0139     template <typename Type> struct inplace_bit_xor
0140         : public identity_based_inplace_combine<Type>
0141     {
0142         typedef inplace_bit_xor<Type> type;
0143 
0144         void operator()(Type& object, const Type& operand)const
0145         { object ^= operand; }
0146     };
0147 
0148     // ------------------------------------------------------------------------
0149     template <typename Type> struct inplace_et
0150         : public identity_based_inplace_combine<Type>
0151     {
0152         typedef inplace_et<Type> type;
0153 
0154         void operator()(Type& object, const Type& operand)const
0155         { object &= operand; }
0156     };
0157 
0158     template<>
0159     inline std::string unary_template_to_string<inplace_et>::apply() { return "&="; }
0160 
0161     // ------------------------------------------------------------------------
0162     template <typename Type> struct inplace_caret
0163         : public identity_based_inplace_combine<Type>
0164     {
0165         typedef inplace_caret<Type> type;
0166 
0167         void operator()(Type& object, const Type& operand)const
0168         { object ^= operand; }
0169     };
0170 
0171     template<>
0172     inline std::string unary_template_to_string<inplace_caret>::apply() { return "^="; }
0173 
0174     // ------------------------------------------------------------------------
0175     template <typename Type> struct inplace_insert
0176         : public identity_based_inplace_combine<Type>
0177     {
0178         typedef inplace_insert<Type> type;
0179 
0180         void operator()(Type& object, const Type& operand)const
0181         { insert(object,operand); }
0182     };
0183 
0184     template<>
0185     inline std::string unary_template_to_string<inplace_insert>::apply() { return "ins="; }
0186 
0187     // ------------------------------------------------------------------------
0188     template <typename Type> struct inplace_erase
0189         : public identity_based_inplace_combine<Type>
0190     {
0191         typedef inplace_erase<Type> type;
0192 
0193         void operator()(Type& object, const Type& operand)const
0194         { erase(object,operand); }
0195     };
0196 
0197     template<>
0198     inline std::string unary_template_to_string<inplace_erase>::apply() { return "ers="; }
0199 
0200     // ------------------------------------------------------------------------
0201     template <typename Type> struct inplace_star
0202         : public identity_based_inplace_combine<Type> //JODO unit_element_
0203     {
0204         typedef inplace_star<Type> type;
0205 
0206         void operator()(Type& object, const Type& operand)const
0207         { object *= operand; }
0208     };
0209 
0210     template<>
0211     inline std::string unary_template_to_string<inplace_star>::apply() { return "*="; }
0212 
0213     // ------------------------------------------------------------------------
0214     template <typename Type> struct inplace_slash
0215         : public identity_based_inplace_combine<Type> //JODO unit_element_
0216     {
0217         typedef inplace_slash<Type> type;
0218 
0219         void operator()(Type& object, const Type& operand)const
0220         { object /= operand; }
0221     };
0222 
0223     template<>
0224     inline std::string unary_template_to_string<inplace_slash>::apply() { return "/="; }
0225 
0226     // ------------------------------------------------------------------------
0227     template <typename Type> struct inplace_max
0228         : public identity_based_inplace_combine<Type>
0229     {
0230         typedef inplace_max<Type> type;
0231 
0232         void operator()(Type& object, const Type& operand)const
0233         {
0234             if(object < operand)
0235                 object = operand;
0236         }
0237     };
0238 
0239     template<>
0240     inline std::string unary_template_to_string<inplace_max>::apply() { return "max="; }
0241 
0242     // ------------------------------------------------------------------------
0243     template <typename Type> struct inplace_min
0244         : public identity_based_inplace_combine<Type>
0245     {
0246         typedef inplace_min<Type> type;
0247 
0248         void operator()(Type& object, const Type& operand)const
0249         {
0250             if(object > operand)
0251                 object = operand;
0252         }
0253     };
0254 
0255     template<>
0256     inline std::string unary_template_to_string<inplace_min>::apply() { return "min="; }
0257 
0258     //--------------------------------------------------------------------------
0259     // Inter_section functor
0260     //--------------------------------------------------------------------------
0261     template<class Type> struct inter_section
0262         : public identity_based_inplace_combine<Type>
0263     {
0264         typedef typename boost::mpl::
0265             if_<has_set_semantics<Type>,
0266                 icl::inplace_et<Type>, 
0267                 icl::inplace_plus<Type> 
0268                >::type
0269             type;
0270 
0271         void operator()(Type& object, const Type& operand)const
0272         { 
0273             type()(object, operand);
0274         }
0275     };
0276 
0277     //--------------------------------------------------------------------------
0278     // Inverse functor
0279     //--------------------------------------------------------------------------
0280     template<class Functor> struct inverse;
0281 
0282     template<class Type> 
0283     struct inverse<icl::inplace_plus<Type> >
0284     { typedef icl::inplace_minus<Type> type; };
0285 
0286     template<class Type> 
0287     struct inverse<icl::inplace_minus<Type> >
0288     { typedef icl::inplace_plus<Type> type; };
0289 
0290     template<class Type> 
0291     struct inverse<icl::inplace_bit_add<Type> >
0292     { typedef icl::inplace_bit_subtract<Type> type; };
0293 
0294     template<class Type> 
0295     struct inverse<icl::inplace_bit_subtract<Type> >
0296     { typedef icl::inplace_bit_add<Type> type; };
0297 
0298     template<class Type> 
0299     struct inverse<icl::inplace_et<Type> >
0300     { typedef icl::inplace_caret<Type> type; };
0301 
0302     template<class Type> 
0303     struct inverse<icl::inplace_caret<Type> >
0304     { typedef icl::inplace_et<Type> type; };
0305 
0306     template<class Type> 
0307     struct inverse<icl::inplace_bit_and<Type> >
0308     { typedef icl::inplace_bit_xor<Type> type; };
0309 
0310     template<class Type> 
0311     struct inverse<icl::inplace_bit_xor<Type> >
0312     { typedef icl::inplace_bit_and<Type> type; };
0313 
0314     template<class Type> 
0315     struct inverse<icl::inplace_star<Type> >
0316     { typedef icl::inplace_slash<Type> type; };
0317 
0318     template<class Type> 
0319     struct inverse<icl::inplace_slash<Type> >
0320     { typedef icl::inplace_star<Type> type; };
0321 
0322     template<class Type> 
0323     struct inverse<icl::inplace_max<Type> >
0324     { typedef icl::inplace_min<Type> type; };
0325 
0326     template<class Type> 
0327     struct inverse<icl::inplace_min<Type> >
0328     { typedef icl::inplace_max<Type> type; };
0329 
0330     template<class Type> 
0331     struct inverse<icl::inplace_identity<Type> >
0332     { typedef icl::inplace_erasure<Type> type; };
0333 
0334     // If a Functor 
0335     template<class Functor> 
0336     struct inverse
0337     {
0338         typedef typename 
0339             remove_reference<typename Functor::first_argument_type>::type argument_type;
0340         typedef icl::inplace_erasure<argument_type> type; 
0341     };
0342 
0343 
0344     //--------------------------------------------------------------------------
0345     // Inverse inter_section functor
0346     //--------------------------------------------------------------------------
0347     template<class Type> 
0348     struct inverse<icl::inter_section<Type> >
0349         : public identity_based_inplace_combine<Type>
0350     {
0351         typedef typename boost::mpl::
0352             if_<has_set_semantics<Type>,
0353                 icl::inplace_caret<Type>, 
0354                 icl::inplace_minus<Type> 
0355                >::type
0356             type;
0357 
0358         void operator()(Type& object, const Type& operand)const
0359         { 
0360             type()(object, operand);
0361         }
0362     };
0363 
0364 
0365     //--------------------------------------------------------------------------
0366     // Positive or negative functor trait
0367     //--------------------------------------------------------------------------
0368 
0369     // A binary operation - is negative (or inverting) with respect to the
0370     // neutral element iff it yields the inverse element if it is applied to the 
0371     // identity element:
0372     // 0 - x = -x
0373     // For a functor that wraps the inplace of op-assign version this is 
0374     // equivalent to
0375     //
0376     // T x = ..., y;
0377     // y = Functor::identity_element();
0378     // Functor()(y, x); // y == inverse_of(x) 
0379 
0380     template<class Functor> struct is_negative;
0381 
0382     template<class Functor> 
0383     struct is_negative
0384     {
0385         typedef is_negative<Functor> type;
0386         BOOST_STATIC_CONSTANT(bool, value = false);
0387     };
0388 
0389     template<class Type> 
0390     struct is_negative<icl::inplace_minus<Type> >
0391     {
0392         typedef is_negative type;
0393         BOOST_STATIC_CONSTANT(bool, value = true);
0394     };
0395 
0396     template<class Type> 
0397     struct is_negative<icl::inplace_bit_subtract<Type> >
0398     {
0399         typedef is_negative type;
0400         BOOST_STATIC_CONSTANT(bool, value = true);
0401     };
0402 
0403     //--------------------------------------------------------------------------
0404     // Pro- or in-version functor
0405     //--------------------------------------------------------------------------
0406     template<class Combiner> struct conversion;
0407 
0408     template<class Combiner> 
0409     struct conversion
0410     { 
0411         typedef conversion<Combiner> type;
0412         typedef typename
0413             remove_const<
0414                 typename remove_reference<typename Combiner::first_argument_type
0415                 >::type
0416             >::type
0417             argument_type;
0418         // The proversion of an op-assign functor o= lets the value unchanged
0419         // (0 o= x) == x;
0420         // Example += :  (0 += x) == x
0421         static argument_type proversion(const argument_type& value)
0422         { 
0423             return value; 
0424         } 
0425 
0426         // The inversion of an op-assign functor o= inverts the value x
0427         // to it's inverse element -x
0428         // (0 o= x) == -x;
0429         // Example -= :  (0 -= x) == -x
0430         static argument_type inversion(const argument_type& value)
0431         {
0432             argument_type inverse = Combiner::identity_element();
0433             Combiner()(inverse, value);
0434             return inverse;
0435         }
0436     };
0437 
0438     template<class Combiner> struct version : public conversion<Combiner>
0439     {
0440         typedef    version<Combiner> type;
0441         typedef conversion<Combiner> base_type;
0442         typedef typename base_type::argument_type argument_type;
0443 
0444         argument_type operator()(const argument_type& value)
0445         { return base_type::proversion(value); } 
0446     };
0447 
0448     template<>struct version<icl::inplace_minus<short      > >{short       operator()(short       val){return -val;}};
0449     template<>struct version<icl::inplace_minus<int        > >{int         operator()(int         val){return -val;}};
0450     template<>struct version<icl::inplace_minus<long       > >{long        operator()(long        val){return -val;}};
0451     template<>struct version<icl::inplace_minus<long long  > >{long long   operator()(long long   val){return -val;}};
0452     template<>struct version<icl::inplace_minus<float      > >{float       operator()(float       val){return -val;}};
0453     template<>struct version<icl::inplace_minus<double     > >{double      operator()(double      val){return -val;}};
0454     template<>struct version<icl::inplace_minus<long double> >{long double operator()(long double val){return -val;}};
0455 
0456     template<class Type> 
0457     struct version<icl::inplace_minus<Type> > : public conversion<icl::inplace_minus<Type> >
0458     { 
0459         typedef    version<icl::inplace_minus<Type> > type;
0460         typedef conversion<icl::inplace_minus<Type> > base_type;
0461         typedef typename base_type::argument_type argument_type;
0462 
0463         Type operator()(const Type& value)
0464         {
0465             return base_type::inversion(value);
0466         } 
0467     };
0468 
0469 }} // namespace icl boost
0470 
0471 #endif
0472 
0473