]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/container/detail/pair.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / container / detail / pair.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2013.
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // See http://www.boost.org/libs/container for documentation.
10 //
11 //////////////////////////////////////////////////////////////////////////////
12
13 #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
14 #define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
15
16 #ifndef BOOST_CONFIG_HPP
17 # include <boost/config.hpp>
18 #endif
19
20 #if defined(BOOST_HAS_PRAGMA_ONCE)
21 # pragma once
22 #endif
23
24 #include <boost/container/detail/config_begin.hpp>
25 #include <boost/container/detail/workaround.hpp>
26
27 #include <boost/container/detail/mpl.hpp>
28 #include <boost/container/detail/type_traits.hpp>
29 #include <boost/container/detail/mpl.hpp>
30 #include <boost/container/detail/std_fwd.hpp>
31 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
32 # include <boost/container/detail/variadic_templates_tools.hpp>
33 #endif
34 #include <boost/move/adl_move_swap.hpp> //swap
35
36 #include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
37 #include <boost/move/utility_core.hpp>
38 #include <boost/move/detail/fwd_macros.hpp>
39
40 namespace boost {
41 namespace tuples {
42
43 struct null_type;
44
45 template <
46 class T0, class T1, class T2,
47 class T3, class T4, class T5,
48 class T6, class T7, class T8,
49 class T9>
50 class tuple;
51
52 } //namespace tuples {
53 } //namespace boost {
54
55 namespace boost {
56 namespace container {
57 namespace pair_impl {
58
59 template <class TupleClass>
60 struct is_boost_tuple
61 {
62 static const bool value = false;
63 };
64
65 template <
66 class T0, class T1, class T2,
67 class T3, class T4, class T5,
68 class T6, class T7, class T8,
69 class T9>
70 struct is_boost_tuple< boost::tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
71 {
72 static const bool value = true;
73 };
74
75 template<class Tuple>
76 struct disable_if_boost_tuple
77 : boost::container::container_detail::disable_if< is_boost_tuple<Tuple> >
78 {};
79
80 template<class T>
81 struct is_tuple_null
82 {
83 static const bool value = false;
84 };
85
86 template<>
87 struct is_tuple_null<boost::tuples::null_type>
88 {
89 static const bool value = true;
90 };
91
92 }}}
93
94 #if defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
95 //MSVC 2010 tuple marker
96 namespace std { namespace tr1 { struct _Nil; }}
97 #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
98 //MSVC 2012 tuple marker
99 namespace std { struct _Nil; }
100 #endif
101
102
103 namespace boost {
104 namespace container {
105
106 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
107
108 template <int Dummy = 0>
109 struct std_piecewise_construct_holder
110 {
111 static ::std::piecewise_construct_t *dummy;
112 };
113
114 template <int Dummy>
115 ::std::piecewise_construct_t *std_piecewise_construct_holder<Dummy>::dummy =
116 reinterpret_cast< ::std::piecewise_construct_t *>(0x01234); //Avoid sanitizer errors on references to null pointers
117
118 typedef const std::piecewise_construct_t & piecewise_construct_t;
119
120 struct try_emplace_t{};
121
122 #else
123
124 //! The piecewise_construct_t struct is an empty structure type used as a unique type to
125 //! disambiguate used to disambiguate between different functions that take two tuple arguments.
126 typedef unspecified piecewise_construct_t;
127
128 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
129
130 //! A instance of type
131 //! piecewise_construct_t
132 static piecewise_construct_t piecewise_construct = BOOST_CONTAINER_DOC1ST(unspecified, *std_piecewise_construct_holder<>::dummy);
133
134 ///@cond
135
136 namespace container_detail {
137
138 struct piecewise_construct_use
139 {
140 //Avoid warnings of unused "piecewise_construct"
141 piecewise_construct_use()
142 { (void)&::boost::container::piecewise_construct; }
143 };
144
145 template <class T1, class T2>
146 struct pair;
147
148 template <class T>
149 struct is_pair
150 {
151 static const bool value = false;
152 };
153
154 template <class T1, class T2>
155 struct is_pair< pair<T1, T2> >
156 {
157 static const bool value = true;
158 };
159
160 template <class T1, class T2>
161 struct is_pair< std::pair<T1, T2> >
162 {
163 static const bool value = true;
164 };
165
166 template <class T>
167 struct is_not_pair
168 {
169 static const bool value = !is_pair<T>::value;
170 };
171
172 template <class T>
173 struct is_std_pair
174 {
175 static const bool value = false;
176 };
177
178 template <class T1, class T2>
179 struct is_std_pair< std::pair<T1, T2> >
180 {
181 static const bool value = true;
182 };
183
184 struct pair_nat;
185
186 template<typename T, typename U, typename V>
187 void get(T); //to enable ADL
188
189 ///@endcond
190
191 template <class T1, class T2>
192 struct pair
193 {
194 private:
195 BOOST_COPYABLE_AND_MOVABLE(pair)
196
197 public:
198 typedef T1 first_type;
199 typedef T2 second_type;
200
201 T1 first;
202 T2 second;
203
204 //Default constructor
205 pair()
206 : first(), second()
207 {}
208
209 //pair copy assignment
210 pair(const pair& x)
211 : first(x.first), second(x.second)
212 {}
213
214 //pair move constructor
215 pair(BOOST_RV_REF(pair) p)
216 : first(::boost::move(p.first)), second(::boost::move(p.second))
217 {}
218
219 template <class D, class S>
220 pair(const pair<D, S> &p)
221 : first(p.first), second(p.second)
222 {}
223
224 template <class D, class S>
225 pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
226 : first(::boost::move(p.first)), second(::boost::move(p.second))
227 {}
228
229 //pair from two values
230 pair(const T1 &t1, const T2 &t2)
231 : first(t1)
232 , second(t2)
233 {}
234
235 template<class U, class V>
236 pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
237 : first(::boost::forward<U>(u))
238 , second(::boost::forward<V>(v))
239 {}
240
241 //And now compatibility with std::pair
242 pair(const std::pair<T1, T2>& x)
243 : first(x.first), second(x.second)
244 {}
245
246 template <class D, class S>
247 pair(const std::pair<D, S>& p)
248 : first(p.first), second(p.second)
249 {}
250
251 pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
252 : first(::boost::move(p.first)), second(::boost::move(p.second))
253 {}
254
255 template <class D, class S>
256 pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
257 : first(::boost::move(p.first)), second(::boost::move(p.second))
258 {}
259
260 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
261 template< class KeyType, class ...Args>
262 pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args)
263 : first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\
264 {}
265 #else
266
267 //piecewise construction from boost::tuple
268 #define BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE(N)\
269 template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
270 pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\
271 : first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\
272 {}\
273 //
274 BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE)
275 #undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE
276
277 #endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
278
279 //piecewise construction from boost::tuple
280 #define BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
281 template< template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
282 BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
283 pair( piecewise_construct_t\
284 , BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
285 , BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q\
286 , typename container_detail::enable_if_c\
287 < pair_impl::is_boost_tuple< BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> >::value &&\
288 !(pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARG##N>::value || pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARGQ##M>::value) \
289 >::type* = 0\
290 )\
291 : first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\
292 { (void)p; (void)q; }\
293 //
294 BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
295 #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
296
297 //piecewise construction from variadic tuple (with delegating constructors)
298 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
299 # if !defined(BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS)
300 private:
301 template<template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
302 pair(Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
303 : first (::boost::forward<Args1>(get<Indexes1>(t1))...)
304 , second(::boost::forward<Args2>(get<Indexes2>(t2))...)
305 { (void) t1; (void)t2; }
306
307 public:
308 template< template<class ...> class Tuple, class... Args1, class... Args2
309 , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
310 pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
311 : pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type())
312 {}
313 # else
314 //piecewise construction from variadic tuple (suboptimal, without delegating constructors)
315 private:
316 template<typename T, template<class ...> class Tuple, typename... Args>
317 static T build_from_args(Tuple<Args...>&& t)
318 { return do_build_from_args<T>(::boost::move(t), typename build_number_seq<sizeof...(Args)>::type()); }
319
320 template<typename T, template<class ...> class Tuple, typename... Args, std::size_t... Indexes>
321 static T do_build_from_args(Tuple<Args...> && t, const index_tuple<Indexes...>&)
322 { (void)t; return T(::boost::forward<Args>(get<Indexes>(t))...); }
323
324 public:
325 template< template<class ...> class Tuple, class... Args1, class... Args2
326 , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
327 pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
328 : first (build_from_args<first_type> (::boost::move(t1)))
329 , second (build_from_args<second_type>(::boost::move(t2)))
330 {}
331 # endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
332 #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
333 //MSVC 2010 tuple implementation
334 #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
335 template< template<class, class, class, class, class, class, class, class, class, class> class StdTuple \
336 BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
337 pair( piecewise_construct_t\
338 , StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
339 , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
340 : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
341 { (void)p; (void)q; }\
342 //
343 BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
344 #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
345 #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
346 #if _VARIADIC_MAX >= 9
347 #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
348 #else
349 #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
350 #endif
351
352 //MSVC 2012 tuple implementation
353 #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
354 template< template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
355 BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \
356 pair( piecewise_construct_t\
357 , StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\
358 , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\
359 : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
360 { (void)p; (void)q; }\
361 //
362 BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
363 #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
364 #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
365 #endif
366
367 //pair copy assignment
368 pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
369 {
370 first = p.first;
371 second = p.second;
372 return *this;
373 }
374
375 //pair move assignment
376 pair& operator=(BOOST_RV_REF(pair) p)
377 {
378 first = ::boost::move(p.first);
379 second = ::boost::move(p.second);
380 return *this;
381 }
382
383 template <class D, class S>
384 typename ::boost::container::container_detail::disable_if_or
385 < pair &
386 , ::boost::container::container_detail::is_same<T1, D>
387 , ::boost::container::container_detail::is_same<T2, S>
388 >::type
389 operator=(const pair<D, S>&p)
390 {
391 first = p.first;
392 second = p.second;
393 return *this;
394 }
395
396 template <class D, class S>
397 typename ::boost::container::container_detail::disable_if_or
398 < pair &
399 , ::boost::container::container_detail::is_same<T1, D>
400 , ::boost::container::container_detail::is_same<T2, S>
401 >::type
402 operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
403 {
404 first = ::boost::move(p.first);
405 second = ::boost::move(p.second);
406 return *this;
407 }
408 //std::pair copy assignment
409 pair& operator=(const std::pair<T1, T2> &p)
410 {
411 first = p.first;
412 second = p.second;
413 return *this;
414 }
415
416 template <class D, class S>
417 pair& operator=(const std::pair<D, S> &p)
418 {
419 first = ::boost::move(p.first);
420 second = ::boost::move(p.second);
421 return *this;
422 }
423
424 //std::pair move assignment
425 pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
426 {
427 first = ::boost::move(p.first);
428 second = ::boost::move(p.second);
429 return *this;
430 }
431
432 template <class D, class S>
433 pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
434 {
435 first = ::boost::move(p.first);
436 second = ::boost::move(p.second);
437 return *this;
438 }
439
440 //swap
441 void swap(pair& p)
442 {
443 ::boost::adl_move_swap(this->first, p.first);
444 ::boost::adl_move_swap(this->second, p.second);
445 }
446 };
447
448 template <class T1, class T2>
449 inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
450 { return static_cast<bool>(x.first == y.first && x.second == y.second); }
451
452 template <class T1, class T2>
453 inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
454 { return static_cast<bool>(x.first < y.first ||
455 (!(y.first < x.first) && x.second < y.second)); }
456
457 template <class T1, class T2>
458 inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
459 { return static_cast<bool>(!(x == y)); }
460
461 template <class T1, class T2>
462 inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
463 { return y < x; }
464
465 template <class T1, class T2>
466 inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
467 { return static_cast<bool>(!(x < y)); }
468
469 template <class T1, class T2>
470 inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
471 { return static_cast<bool>(!(y < x)); }
472
473 template <class T1, class T2>
474 inline pair<T1, T2> make_pair(T1 x, T2 y)
475 { return pair<T1, T2>(x, y); }
476
477 template <class T1, class T2>
478 inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
479 { x.swap(y); }
480
481 } //namespace container_detail {
482 } //namespace container {
483
484 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
485
486 template<class T1, class T2>
487 struct has_move_emulation_enabled< ::boost::container::container_detail::pair<T1, T2> >
488 {
489 static const bool value = true;
490 };
491
492 #endif
493
494 namespace move_detail{
495
496 template<class T>
497 struct is_class_or_union;
498
499 template <class T1, class T2>
500 struct is_class_or_union< ::boost::container::container_detail::pair<T1, T2> >
501 //This specialization is needed to avoid instantiation of pair in
502 //is_class, and allow recursive maps.
503 {
504 static const bool value = true;
505 };
506
507 template <class T1, class T2>
508 struct is_class_or_union< std::pair<T1, T2> >
509 //This specialization is needed to avoid instantiation of pair in
510 //is_class, and allow recursive maps.
511 {
512 static const bool value = true;
513 };
514
515 template<class T>
516 struct is_union;
517
518 template <class T1, class T2>
519 struct is_union< ::boost::container::container_detail::pair<T1, T2> >
520 //This specialization is needed to avoid instantiation of pair in
521 //is_class, and allow recursive maps.
522 {
523 static const bool value = false;
524 };
525
526 template <class T1, class T2>
527 struct is_union< std::pair<T1, T2> >
528 //This specialization is needed to avoid instantiation of pair in
529 //is_class, and allow recursive maps.
530 {
531 static const bool value = false;
532 };
533
534 template<class T>
535 struct is_class;
536
537 template <class T1, class T2>
538 struct is_class< ::boost::container::container_detail::pair<T1, T2> >
539 //This specialization is needed to avoid instantiation of pair in
540 //is_class, and allow recursive maps.
541 {
542 static const bool value = true;
543 };
544
545 template <class T1, class T2>
546 struct is_class< std::pair<T1, T2> >
547 //This specialization is needed to avoid instantiation of pair in
548 //is_class, and allow recursive maps.
549 {
550 static const bool value = true;
551 };
552
553 } //namespace move_detail{
554
555 } //namespace boost {
556
557 #include <boost/container/detail/config_end.hpp>
558
559 #endif //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP