]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/utility/include/boost/detail/ob_compressed_pair.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / utility / include / boost / detail / ob_compressed_pair.hpp
1 // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
2 // Use, modification and distribution are subject to the Boost Software License,
3 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt).
5 //
6 // See http://www.boost.org/libs/utility for most recent version including documentation.
7 // see libs/utility/compressed_pair.hpp
8 //
9 /* Release notes:
10 20 Jan 2001:
11 Fixed obvious bugs (David Abrahams)
12 07 Oct 2000:
13 Added better single argument constructor support.
14 03 Oct 2000:
15 Added VC6 support (JM).
16 23rd July 2000:
17 Additional comments added. (JM)
18 Jan 2000:
19 Original version: this version crippled for use with crippled compilers
20 - John Maddock Jan 2000.
21 */
22
23
24 #ifndef BOOST_OB_COMPRESSED_PAIR_HPP
25 #define BOOST_OB_COMPRESSED_PAIR_HPP
26
27 #include <algorithm>
28 #ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
29 #include <boost/type_traits/object_traits.hpp>
30 #endif
31 #ifndef BOOST_SAME_TRAITS_HPP
32 #include <boost/type_traits/same_traits.hpp>
33 #endif
34 #ifndef BOOST_CALL_TRAITS_HPP
35 #include <boost/call_traits.hpp>
36 #endif
37
38 namespace boost
39 {
40 #ifdef BOOST_MSVC6_MEMBER_TEMPLATES
41 //
42 // use member templates to emulate
43 // partial specialisation. Note that due to
44 // problems with overload resolution with VC6
45 // each of the compressed_pair versions that follow
46 // have one template single-argument constructor
47 // in place of two specific constructors:
48 //
49
50 template <class T1, class T2>
51 class compressed_pair;
52
53 namespace detail{
54
55 template <class A, class T1, class T2>
56 struct best_conversion_traits
57 {
58 typedef char one;
59 typedef char (&two)[2];
60 static A a;
61 static one test(T1);
62 static two test(T2);
63
64 enum { value = sizeof(test(a)) };
65 };
66
67 template <int>
68 struct init_one;
69
70 template <>
71 struct init_one<1>
72 {
73 template <class A, class T1, class T2>
74 static void init(const A& a, T1* p1, T2*)
75 {
76 *p1 = a;
77 }
78 };
79
80 template <>
81 struct init_one<2>
82 {
83 template <class A, class T1, class T2>
84 static void init(const A& a, T1*, T2* p2)
85 {
86 *p2 = a;
87 }
88 };
89
90
91 // T1 != T2, both non-empty
92 template <class T1, class T2>
93 class compressed_pair_0
94 {
95 private:
96 T1 _first;
97 T2 _second;
98 public:
99 typedef T1 first_type;
100 typedef T2 second_type;
101 typedef typename call_traits<first_type>::param_type first_param_type;
102 typedef typename call_traits<second_type>::param_type second_param_type;
103 typedef typename call_traits<first_type>::reference first_reference;
104 typedef typename call_traits<second_type>::reference second_reference;
105 typedef typename call_traits<first_type>::const_reference first_const_reference;
106 typedef typename call_traits<second_type>::const_reference second_const_reference;
107
108 compressed_pair_0() : _first(), _second() {}
109 compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
110 template <class A>
111 explicit compressed_pair_0(const A& val)
112 {
113 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
114 }
115 compressed_pair_0(const ::boost::compressed_pair<T1,T2>& x)
116 : _first(x.first()), _second(x.second()) {}
117
118 #if 0
119 compressed_pair_0& operator=(const compressed_pair_0& x) {
120 cout << "assigning compressed pair 0" << endl;
121 _first = x._first;
122 _second = x._second;
123 cout << "finished assigning compressed pair 0" << endl;
124 return *this;
125 }
126 #endif
127
128 first_reference first() { return _first; }
129 first_const_reference first() const { return _first; }
130
131 second_reference second() { return _second; }
132 second_const_reference second() const { return _second; }
133
134 void swap(compressed_pair_0& y)
135 {
136 using std::swap;
137 swap(_first, y._first);
138 swap(_second, y._second);
139 }
140 };
141
142 // T1 != T2, T2 empty
143 template <class T1, class T2>
144 class compressed_pair_1 : T2
145 {
146 private:
147 T1 _first;
148 public:
149 typedef T1 first_type;
150 typedef T2 second_type;
151 typedef typename call_traits<first_type>::param_type first_param_type;
152 typedef typename call_traits<second_type>::param_type second_param_type;
153 typedef typename call_traits<first_type>::reference first_reference;
154 typedef typename call_traits<second_type>::reference second_reference;
155 typedef typename call_traits<first_type>::const_reference first_const_reference;
156 typedef typename call_traits<second_type>::const_reference second_const_reference;
157
158 compressed_pair_1() : T2(), _first() {}
159 compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}
160
161 template <class A>
162 explicit compressed_pair_1(const A& val)
163 {
164 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
165 }
166
167 compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
168 : T2(x.second()), _first(x.first()) {}
169
170 first_reference first() { return _first; }
171 first_const_reference first() const { return _first; }
172
173 second_reference second() { return *this; }
174 second_const_reference second() const { return *this; }
175
176 void swap(compressed_pair_1& y)
177 {
178 // no need to swap empty base class:
179 using std::swap;
180 swap(_first, y._first);
181 }
182 };
183
184 // T1 != T2, T1 empty
185 template <class T1, class T2>
186 class compressed_pair_2 : T1
187 {
188 private:
189 T2 _second;
190 public:
191 typedef T1 first_type;
192 typedef T2 second_type;
193 typedef typename call_traits<first_type>::param_type first_param_type;
194 typedef typename call_traits<second_type>::param_type second_param_type;
195 typedef typename call_traits<first_type>::reference first_reference;
196 typedef typename call_traits<second_type>::reference second_reference;
197 typedef typename call_traits<first_type>::const_reference first_const_reference;
198 typedef typename call_traits<second_type>::const_reference second_const_reference;
199
200 compressed_pair_2() : T1(), _second() {}
201 compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
202 template <class A>
203 explicit compressed_pair_2(const A& val)
204 {
205 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
206 }
207 compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
208 : T1(x.first()), _second(x.second()) {}
209
210 #if 0
211 compressed_pair_2& operator=(const compressed_pair_2& x) {
212 cout << "assigning compressed pair 2" << endl;
213 T1::operator=(x);
214 _second = x._second;
215 cout << "finished assigning compressed pair 2" << endl;
216 return *this;
217 }
218 #endif
219 first_reference first() { return *this; }
220 first_const_reference first() const { return *this; }
221
222 second_reference second() { return _second; }
223 second_const_reference second() const { return _second; }
224
225 void swap(compressed_pair_2& y)
226 {
227 // no need to swap empty base class:
228 using std::swap;
229 swap(_second, y._second);
230 }
231 };
232
233 // T1 != T2, both empty
234 template <class T1, class T2>
235 class compressed_pair_3 : T1, T2
236 {
237 public:
238 typedef T1 first_type;
239 typedef T2 second_type;
240 typedef typename call_traits<first_type>::param_type first_param_type;
241 typedef typename call_traits<second_type>::param_type second_param_type;
242 typedef typename call_traits<first_type>::reference first_reference;
243 typedef typename call_traits<second_type>::reference second_reference;
244 typedef typename call_traits<first_type>::const_reference first_const_reference;
245 typedef typename call_traits<second_type>::const_reference second_const_reference;
246
247 compressed_pair_3() : T1(), T2() {}
248 compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
249 template <class A>
250 explicit compressed_pair_3(const A& val)
251 {
252 init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
253 }
254 compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
255 : T1(x.first()), T2(x.second()) {}
256
257 first_reference first() { return *this; }
258 first_const_reference first() const { return *this; }
259
260 second_reference second() { return *this; }
261 second_const_reference second() const { return *this; }
262
263 void swap(compressed_pair_3& y)
264 {
265 // no need to swap empty base classes:
266 }
267 };
268
269 // T1 == T2, and empty
270 template <class T1, class T2>
271 class compressed_pair_4 : T1
272 {
273 public:
274 typedef T1 first_type;
275 typedef T2 second_type;
276 typedef typename call_traits<first_type>::param_type first_param_type;
277 typedef typename call_traits<second_type>::param_type second_param_type;
278 typedef typename call_traits<first_type>::reference first_reference;
279 typedef typename call_traits<second_type>::reference second_reference;
280 typedef typename call_traits<first_type>::const_reference first_const_reference;
281 typedef typename call_traits<second_type>::const_reference second_const_reference;
282
283 compressed_pair_4() : T1() {}
284 compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
285 // only one single argument constructor since T1 == T2
286 explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
287 compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
288 : T1(x.first()), m_second(x.second()) {}
289
290 first_reference first() { return *this; }
291 first_const_reference first() const { return *this; }
292
293 second_reference second() { return m_second; }
294 second_const_reference second() const { return m_second; }
295
296 void swap(compressed_pair_4& y)
297 {
298 // no need to swap empty base classes:
299 }
300 private:
301 T2 m_second;
302 };
303
304 // T1 == T2, not empty
305 template <class T1, class T2>
306 class compressed_pair_5
307 {
308 private:
309 T1 _first;
310 T2 _second;
311 public:
312 typedef T1 first_type;
313 typedef T2 second_type;
314 typedef typename call_traits<first_type>::param_type first_param_type;
315 typedef typename call_traits<second_type>::param_type second_param_type;
316 typedef typename call_traits<first_type>::reference first_reference;
317 typedef typename call_traits<second_type>::reference second_reference;
318 typedef typename call_traits<first_type>::const_reference first_const_reference;
319 typedef typename call_traits<second_type>::const_reference second_const_reference;
320
321 compressed_pair_5() : _first(), _second() {}
322 compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
323 // only one single argument constructor since T1 == T2
324 explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
325 compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c)
326 : _first(c.first()), _second(c.second()) {}
327
328 first_reference first() { return _first; }
329 first_const_reference first() const { return _first; }
330
331 second_reference second() { return _second; }
332 second_const_reference second() const { return _second; }
333
334 void swap(compressed_pair_5& y)
335 {
336 using std::swap;
337 swap(_first, y._first);
338 swap(_second, y._second);
339 }
340 };
341
342 template <bool e1, bool e2, bool same>
343 struct compressed_pair_chooser
344 {
345 template <class T1, class T2>
346 struct rebind
347 {
348 typedef compressed_pair_0<T1, T2> type;
349 };
350 };
351
352 template <>
353 struct compressed_pair_chooser<false, true, false>
354 {
355 template <class T1, class T2>
356 struct rebind
357 {
358 typedef compressed_pair_1<T1, T2> type;
359 };
360 };
361
362 template <>
363 struct compressed_pair_chooser<true, false, false>
364 {
365 template <class T1, class T2>
366 struct rebind
367 {
368 typedef compressed_pair_2<T1, T2> type;
369 };
370 };
371
372 template <>
373 struct compressed_pair_chooser<true, true, false>
374 {
375 template <class T1, class T2>
376 struct rebind
377 {
378 typedef compressed_pair_3<T1, T2> type;
379 };
380 };
381
382 template <>
383 struct compressed_pair_chooser<true, true, true>
384 {
385 template <class T1, class T2>
386 struct rebind
387 {
388 typedef compressed_pair_4<T1, T2> type;
389 };
390 };
391
392 template <>
393 struct compressed_pair_chooser<false, false, true>
394 {
395 template <class T1, class T2>
396 struct rebind
397 {
398 typedef compressed_pair_5<T1, T2> type;
399 };
400 };
401
402 template <class T1, class T2>
403 struct compressed_pair_traits
404 {
405 private:
406 typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
407 typedef typename chooser::template rebind<T1, T2> bound_type;
408 public:
409 typedef typename bound_type::type type;
410 };
411
412 } // namespace detail
413
414 template <class T1, class T2>
415 class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
416 {
417 private:
418 typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
419 public:
420 typedef T1 first_type;
421 typedef T2 second_type;
422 typedef typename call_traits<first_type>::param_type first_param_type;
423 typedef typename call_traits<second_type>::param_type second_param_type;
424 typedef typename call_traits<first_type>::reference first_reference;
425 typedef typename call_traits<second_type>::reference second_reference;
426 typedef typename call_traits<first_type>::const_reference first_const_reference;
427 typedef typename call_traits<second_type>::const_reference second_const_reference;
428
429 compressed_pair() : base_type() {}
430 compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
431 template <class A>
432 explicit compressed_pair(const A& x) : base_type(x){}
433
434 first_reference first() { return base_type::first(); }
435 first_const_reference first() const { return base_type::first(); }
436
437 second_reference second() { return base_type::second(); }
438 second_const_reference second() const { return base_type::second(); }
439 };
440
441 template <class T1, class T2>
442 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
443 {
444 x.swap(y);
445 }
446
447 #else
448 // no partial specialisation, no member templates:
449
450 template <class T1, class T2>
451 class compressed_pair
452 {
453 private:
454 T1 _first;
455 T2 _second;
456 public:
457 typedef T1 first_type;
458 typedef T2 second_type;
459 typedef typename call_traits<first_type>::param_type first_param_type;
460 typedef typename call_traits<second_type>::param_type second_param_type;
461 typedef typename call_traits<first_type>::reference first_reference;
462 typedef typename call_traits<second_type>::reference second_reference;
463 typedef typename call_traits<first_type>::const_reference first_const_reference;
464 typedef typename call_traits<second_type>::const_reference second_const_reference;
465
466 compressed_pair() : _first(), _second() {}
467 compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
468 explicit compressed_pair(first_param_type x) : _first(x), _second() {}
469 // can't define this in case T1 == T2:
470 // explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
471
472 first_reference first() { return _first; }
473 first_const_reference first() const { return _first; }
474
475 second_reference second() { return _second; }
476 second_const_reference second() const { return _second; }
477
478 void swap(compressed_pair& y)
479 {
480 using std::swap;
481 swap(_first, y._first);
482 swap(_second, y._second);
483 }
484 };
485
486 template <class T1, class T2>
487 inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
488 {
489 x.swap(y);
490 }
491
492 #endif
493
494 } // boost
495
496 #endif // BOOST_OB_COMPRESSED_PAIR_HPP
497
498
499