]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/icl/functors.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / icl / functors.hpp
1 /*-----------------------------------------------------------------------------+
2 Copyright (c) 2007-2009: Joachim Faulhaber
3 +------------------------------------------------------------------------------+
4 Distributed under the Boost Software License, Version 1.0.
5 (See accompanying file LICENCE.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt)
7 +-----------------------------------------------------------------------------*/
8 #ifndef BOOST_ICL_FUNCTORS_HPP_JOFA_080315
9 #define BOOST_ICL_FUNCTORS_HPP_JOFA_080315
10
11 #include <boost/type_traits.hpp>
12 #include <boost/mpl/if.hpp>
13 #include <boost/icl/type_traits/identity_element.hpp>
14 #include <boost/icl/type_traits/unit_element.hpp>
15 #include <boost/icl/type_traits/is_set.hpp>
16 #include <boost/icl/type_traits/has_set_semantics.hpp>
17
18 namespace boost{namespace icl
19 {
20 // ------------------------------------------------------------------------
21 template <typename Type> struct identity_based_inplace_combine
22 {
23 typedef Type& first_argument_type;
24 typedef const Type& second_argument_type;
25 typedef void result_type;
26 inline static Type identity_element() { return boost::icl::identity_element<Type>::value(); }
27 };
28
29 // ------------------------------------------------------------------------
30 template <typename Type> struct unit_element_based_inplace_combine
31 {
32 typedef Type& first_argument_type;
33 typedef const Type& second_argument_type;
34 typedef void result_type;
35 inline static Type identity_element() { return boost::icl::unit_element<Type>::value(); }
36 };
37
38 // ------------------------------------------------------------------------
39 template <typename Type> struct inplace_identity
40 : public identity_based_inplace_combine<Type>
41 {
42 typedef inplace_identity<Type> type;
43 void operator()(Type&, const Type&)const{}
44 };
45
46 template<>
47 inline std::string unary_template_to_string<inplace_identity>::apply()
48 { return "i="; }
49
50 // ------------------------------------------------------------------------
51 template <typename Type> struct inplace_erasure
52 : public identity_based_inplace_combine<Type>
53 {
54 typedef inplace_erasure<Type> type;
55 typedef identity_based_inplace_combine<Type> base_type;
56
57 void operator()(Type& object, const Type& operand)const
58 {
59 if(object == operand)
60 //identity_element(); //JODO Old gcc-3.4.4 does not compile this
61 object = base_type::identity_element(); //<-- but this.
62 }
63 };
64
65 template<>
66 inline std::string unary_template_to_string<inplace_erasure>::apply()
67 { return "0="; }
68
69 // ------------------------------------------------------------------------
70 template <typename Type> struct inplace_plus
71 : public identity_based_inplace_combine<Type>
72 {
73 typedef inplace_plus<Type> type;
74
75 void operator()(Type& object, const Type& operand)const
76 { object += operand; }
77
78 static void version(Type&){}
79 };
80
81 template<>
82 inline std::string unary_template_to_string<inplace_plus>::apply() { return "+="; }
83
84 // ------------------------------------------------------------------------
85 template <typename Type> struct inplace_minus
86 : public identity_based_inplace_combine<Type>
87 {
88 typedef inplace_minus<Type> type;
89
90 void operator()(Type& object, const Type& operand)const
91 { object -= operand; }
92 };
93
94 template<>
95 inline std::string unary_template_to_string<inplace_minus>::apply() { return "-="; }
96
97 // ------------------------------------------------------------------------
98 template <typename Type> struct inplace_bit_add
99 : public identity_based_inplace_combine<Type>
100 {
101 typedef inplace_bit_add<Type> type;
102
103 void operator()(Type& object, const Type& operand)const
104 { object |= operand; }
105
106 static void version(Type&){}
107 };
108
109 template<>
110 inline std::string unary_template_to_string<inplace_bit_add>::apply() { return "b|="; }
111
112 // ------------------------------------------------------------------------
113 template <typename Type> struct inplace_bit_subtract
114 : public identity_based_inplace_combine<Type>
115 {
116 typedef inplace_bit_subtract<Type> type;
117
118 void operator()(Type& object, const Type& operand)const
119 { object &= ~operand; }
120 };
121
122 template<>
123 inline std::string unary_template_to_string<inplace_bit_subtract>::apply() { return "b-="; }
124
125 // ------------------------------------------------------------------------
126 template <typename Type> struct inplace_bit_and
127 : public identity_based_inplace_combine<Type>
128 {
129 typedef inplace_bit_and<Type> type;
130
131 void operator()(Type& object, const Type& operand)const
132 { object &= operand; }
133 };
134
135 template<>
136 inline std::string unary_template_to_string<inplace_bit_and>::apply() { return "b&="; }
137
138 // ------------------------------------------------------------------------
139 template <typename Type> struct inplace_bit_xor
140 : public identity_based_inplace_combine<Type>
141 {
142 typedef inplace_bit_xor<Type> type;
143
144 void operator()(Type& object, const Type& operand)const
145 { object ^= operand; }
146 };
147
148 // ------------------------------------------------------------------------
149 template <typename Type> struct inplace_et
150 : public identity_based_inplace_combine<Type>
151 {
152 typedef inplace_et<Type> type;
153
154 void operator()(Type& object, const Type& operand)const
155 { object &= operand; }
156 };
157
158 template<>
159 inline std::string unary_template_to_string<inplace_et>::apply() { return "&="; }
160
161 // ------------------------------------------------------------------------
162 template <typename Type> struct inplace_caret
163 : public identity_based_inplace_combine<Type>
164 {
165 typedef inplace_caret<Type> type;
166
167 void operator()(Type& object, const Type& operand)const
168 { object ^= operand; }
169 };
170
171 template<>
172 inline std::string unary_template_to_string<inplace_caret>::apply() { return "^="; }
173
174 // ------------------------------------------------------------------------
175 template <typename Type> struct inplace_insert
176 : public identity_based_inplace_combine<Type>
177 {
178 typedef inplace_insert<Type> type;
179
180 void operator()(Type& object, const Type& operand)const
181 { insert(object,operand); }
182 };
183
184 template<>
185 inline std::string unary_template_to_string<inplace_insert>::apply() { return "ins="; }
186
187 // ------------------------------------------------------------------------
188 template <typename Type> struct inplace_erase
189 : public identity_based_inplace_combine<Type>
190 {
191 typedef inplace_erase<Type> type;
192
193 void operator()(Type& object, const Type& operand)const
194 { erase(object,operand); }
195 };
196
197 template<>
198 inline std::string unary_template_to_string<inplace_erase>::apply() { return "ers="; }
199
200 // ------------------------------------------------------------------------
201 template <typename Type> struct inplace_star
202 : public identity_based_inplace_combine<Type> //JODO unit_element_
203 {
204 typedef inplace_star<Type> type;
205
206 void operator()(Type& object, const Type& operand)const
207 { object *= operand; }
208 };
209
210 template<>
211 inline std::string unary_template_to_string<inplace_star>::apply() { return "*="; }
212
213 // ------------------------------------------------------------------------
214 template <typename Type> struct inplace_slash
215 : public identity_based_inplace_combine<Type> //JODO unit_element_
216 {
217 typedef inplace_slash<Type> type;
218
219 void operator()(Type& object, const Type& operand)const
220 { object /= operand; }
221 };
222
223 template<>
224 inline std::string unary_template_to_string<inplace_slash>::apply() { return "/="; }
225
226 // ------------------------------------------------------------------------
227 template <typename Type> struct inplace_max
228 : public identity_based_inplace_combine<Type>
229 {
230 typedef inplace_max<Type> type;
231
232 void operator()(Type& object, const Type& operand)const
233 {
234 if(object < operand)
235 object = operand;
236 }
237 };
238
239 template<>
240 inline std::string unary_template_to_string<inplace_max>::apply() { return "max="; }
241
242 // ------------------------------------------------------------------------
243 template <typename Type> struct inplace_min
244 : public identity_based_inplace_combine<Type>
245 {
246 typedef inplace_min<Type> type;
247
248 void operator()(Type& object, const Type& operand)const
249 {
250 if(object > operand)
251 object = operand;
252 }
253 };
254
255 template<>
256 inline std::string unary_template_to_string<inplace_min>::apply() { return "min="; }
257
258 //--------------------------------------------------------------------------
259 // Inter_section functor
260 //--------------------------------------------------------------------------
261 template<class Type> struct inter_section
262 : public identity_based_inplace_combine<Type>
263 {
264 typedef typename boost::mpl::
265 if_<has_set_semantics<Type>,
266 icl::inplace_et<Type>,
267 icl::inplace_plus<Type>
268 >::type
269 type;
270
271 void operator()(Type& object, const Type& operand)const
272 {
273 type()(object, operand);
274 }
275 };
276
277 //--------------------------------------------------------------------------
278 // Inverse functor
279 //--------------------------------------------------------------------------
280 template<class Functor> struct inverse;
281
282 template<class Type>
283 struct inverse<icl::inplace_plus<Type> >
284 { typedef icl::inplace_minus<Type> type; };
285
286 template<class Type>
287 struct inverse<icl::inplace_minus<Type> >
288 { typedef icl::inplace_plus<Type> type; };
289
290 template<class Type>
291 struct inverse<icl::inplace_bit_add<Type> >
292 { typedef icl::inplace_bit_subtract<Type> type; };
293
294 template<class Type>
295 struct inverse<icl::inplace_bit_subtract<Type> >
296 { typedef icl::inplace_bit_add<Type> type; };
297
298 template<class Type>
299 struct inverse<icl::inplace_et<Type> >
300 { typedef icl::inplace_caret<Type> type; };
301
302 template<class Type>
303 struct inverse<icl::inplace_caret<Type> >
304 { typedef icl::inplace_et<Type> type; };
305
306 template<class Type>
307 struct inverse<icl::inplace_bit_and<Type> >
308 { typedef icl::inplace_bit_xor<Type> type; };
309
310 template<class Type>
311 struct inverse<icl::inplace_bit_xor<Type> >
312 { typedef icl::inplace_bit_and<Type> type; };
313
314 template<class Type>
315 struct inverse<icl::inplace_star<Type> >
316 { typedef icl::inplace_slash<Type> type; };
317
318 template<class Type>
319 struct inverse<icl::inplace_slash<Type> >
320 { typedef icl::inplace_star<Type> type; };
321
322 template<class Type>
323 struct inverse<icl::inplace_max<Type> >
324 { typedef icl::inplace_min<Type> type; };
325
326 template<class Type>
327 struct inverse<icl::inplace_min<Type> >
328 { typedef icl::inplace_max<Type> type; };
329
330 template<class Type>
331 struct inverse<icl::inplace_identity<Type> >
332 { typedef icl::inplace_erasure<Type> type; };
333
334 // If a Functor
335 template<class Functor>
336 struct inverse
337 {
338 typedef typename
339 remove_reference<typename Functor::first_argument_type>::type argument_type;
340 typedef icl::inplace_erasure<argument_type> type;
341 };
342
343
344 //--------------------------------------------------------------------------
345 // Inverse inter_section functor
346 //--------------------------------------------------------------------------
347 template<class Type>
348 struct inverse<icl::inter_section<Type> >
349 : public identity_based_inplace_combine<Type>
350 {
351 typedef typename boost::mpl::
352 if_<has_set_semantics<Type>,
353 icl::inplace_caret<Type>,
354 icl::inplace_minus<Type>
355 >::type
356 type;
357
358 void operator()(Type& object, const Type& operand)const
359 {
360 type()(object, operand);
361 }
362 };
363
364
365 //--------------------------------------------------------------------------
366 // Positive or negative functor trait
367 //--------------------------------------------------------------------------
368
369 // A binary operation - is negative (or inverting) with respect to the
370 // neutral element iff it yields the inverse element if it is applied to the
371 // identity element:
372 // 0 - x = -x
373 // For a functor that wraps the inplace of op-assign version this is
374 // equivalent to
375 //
376 // T x = ..., y;
377 // y = Functor::identity_element();
378 // Functor()(y, x); // y == inverse_of(x)
379
380 template<class Functor> struct is_negative;
381
382 template<class Functor>
383 struct is_negative
384 {
385 typedef is_negative<Functor> type;
386 BOOST_STATIC_CONSTANT(bool, value = false);
387 };
388
389 template<class Type>
390 struct is_negative<icl::inplace_minus<Type> >
391 {
392 typedef is_negative type;
393 BOOST_STATIC_CONSTANT(bool, value = true);
394 };
395
396 template<class Type>
397 struct is_negative<icl::inplace_bit_subtract<Type> >
398 {
399 typedef is_negative type;
400 BOOST_STATIC_CONSTANT(bool, value = true);
401 };
402
403 //--------------------------------------------------------------------------
404 // Pro- or in-version functor
405 //--------------------------------------------------------------------------
406 template<class Combiner> struct conversion;
407
408 template<class Combiner>
409 struct conversion
410 {
411 typedef conversion<Combiner> type;
412 typedef typename
413 remove_const<
414 typename remove_reference<typename Combiner::first_argument_type
415 >::type
416 >::type
417 argument_type;
418 // The proversion of an op-assign functor o= lets the value unchanged
419 // (0 o= x) == x;
420 // Example += : (0 += x) == x
421 static argument_type proversion(const argument_type& value)
422 {
423 return value;
424 }
425
426 // The inversion of an op-assign functor o= inverts the value x
427 // to it's inverse element -x
428 // (0 o= x) == -x;
429 // Example -= : (0 -= x) == -x
430 static argument_type inversion(const argument_type& value)
431 {
432 argument_type inverse = Combiner::identity_element();
433 Combiner()(inverse, value);
434 return inverse;
435 }
436 };
437
438 template<class Combiner> struct version : public conversion<Combiner>
439 {
440 typedef version<Combiner> type;
441 typedef conversion<Combiner> base_type;
442 typedef typename base_type::argument_type argument_type;
443
444 argument_type operator()(const argument_type& value)
445 { return base_type::proversion(value); }
446 };
447
448 template<>struct version<icl::inplace_minus<short > >{short operator()(short val){return -val;}};
449 template<>struct version<icl::inplace_minus<int > >{int operator()(int val){return -val;}};
450 template<>struct version<icl::inplace_minus<long > >{long operator()(long val){return -val;}};
451 template<>struct version<icl::inplace_minus<long long > >{long long operator()(long long val){return -val;}};
452 template<>struct version<icl::inplace_minus<float > >{float operator()(float val){return -val;}};
453 template<>struct version<icl::inplace_minus<double > >{double operator()(double val){return -val;}};
454 template<>struct version<icl::inplace_minus<long double> >{long double operator()(long double val){return -val;}};
455
456 template<class Type>
457 struct version<icl::inplace_minus<Type> > : public conversion<icl::inplace_minus<Type> >
458 {
459 typedef version<icl::inplace_minus<Type> > type;
460 typedef conversion<icl::inplace_minus<Type> > base_type;
461 typedef typename base_type::argument_type argument_type;
462
463 Type operator()(const Type& value)
464 {
465 return base_type::inversion(value);
466 }
467 };
468
469 }} // namespace icl boost
470
471 #endif
472
473