File indexing completed on 2025-01-18 09:38:21
0001
0002
0003
0004
0005
0006
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
0061 object = base_type::identity_element();
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>
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>
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
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
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
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
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
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
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
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
0419
0420
0421 static argument_type proversion(const argument_type& value)
0422 {
0423 return value;
0424 }
0425
0426
0427
0428
0429
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 }}
0470
0471 #endif
0472
0473