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