]> git.proxmox.com Git - ceph.git/blame - 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
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
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
38namespace 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
50template <class T1, class T2>
51class compressed_pair;
52
53namespace detail{
54
55template <class A, class T1, class T2>
56struct 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
67template <int>
68struct init_one;
69
70template <>
71struct 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
80template <>
81struct 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
92template <class T1, class T2>
93class compressed_pair_0
94{
95private:
96 T1 _first;
97 T2 _second;
98public:
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
143template <class T1, class T2>
144class compressed_pair_1 : T2
145{
146private:
147 T1 _first;
148public:
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
185template <class T1, class T2>
186class compressed_pair_2 : T1
187{
188private:
189 T2 _second;
190public:
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
234template <class T1, class T2>
235class compressed_pair_3 : T1, T2
236{
237public:
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
270template <class T1, class T2>
271class compressed_pair_4 : T1
272{
273public:
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 }
300private:
301 T2 m_second;
302};
303
304// T1 == T2, not empty
305template <class T1, class T2>
306class compressed_pair_5
307{
308private:
309 T1 _first;
310 T2 _second;
311public:
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
342template <bool e1, bool e2, bool same>
343struct 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
352template <>
353struct 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
362template <>
363struct 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
372template <>
373struct 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
382template <>
383struct 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
392template <>
393struct 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
402template <class T1, class T2>
403struct compressed_pair_traits
404{
405private:
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;
408public:
409 typedef typename bound_type::type type;
410};
411
412} // namespace detail
413
414template <class T1, class T2>
415class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
416{
417private:
418 typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
419public:
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
441template <class T1, class T2>
442inline 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
450template <class T1, class T2>
451class compressed_pair
452{
453private:
454 T1 _first;
455 T2 _second;
456public:
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
486template <class T1, class T2>
487inline 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