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