• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/static_assert.hpp>
28 #include <boost/container/detail/mpl.hpp>
29 #include <boost/container/detail/type_traits.hpp>
30 #include <boost/container/detail/mpl.hpp>
31 #include <boost/container/detail/std_fwd.hpp>
32 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
33 #  include <boost/container/detail/variadic_templates_tools.hpp>
34 #endif
35 #include <boost/move/adl_move_swap.hpp> //swap
36 
37 #include <boost/intrusive/detail/minimal_pair_header.hpp>      //pair
38 #include <boost/move/utility_core.hpp>
39 #include <boost/move/detail/fwd_macros.hpp>
40 
41 namespace boost {
42 namespace tuples {
43 
44 struct null_type;
45 
46 template <
47   class T0, class T1, class T2,
48   class T3, class T4, class T5,
49   class T6, class T7, class T8,
50   class T9>
51 class tuple;
52 
53 }  //namespace tuples {
54 }  //namespace boost {
55 
56 namespace boost {
57 namespace container {
58 namespace pair_impl {
59 
60 template <class TupleClass>
61 struct is_boost_tuple
62 {
63    static const bool value = false;
64 };
65 
66 template <
67   class T0, class T1, class T2,
68   class T3, class T4, class T5,
69   class T6, class T7, class T8,
70   class T9>
71 struct is_boost_tuple< boost::tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
72 {
73    static const bool value = true;
74 };
75 
76 template<class Tuple>
77 struct disable_if_boost_tuple
78    : boost::container::dtl::disable_if< is_boost_tuple<Tuple> >
79 {};
80 
81 template<class T>
82 struct is_tuple_null
83 {
84    static const bool value = false;
85 };
86 
87 template<>
88 struct is_tuple_null<boost::tuples::null_type>
89 {
90    static const bool value = true;
91 };
92 
93 }}}
94 
95 #if defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
96 //MSVC 2010 tuple marker
97 namespace std { namespace tr1 { struct _Nil; }}
98 #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
99 //MSVC 2012 tuple marker
100 namespace std { struct _Nil; }
101 #endif
102 
103 
104 namespace boost {
105 namespace container {
106 
107 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
108 
109    template <int Dummy = 0>
110    struct std_piecewise_construct_holder
111    {
112       static ::std::piecewise_construct_t *dummy;
113    };
114 
115    template <int Dummy>
116    ::std::piecewise_construct_t *std_piecewise_construct_holder<Dummy>::dummy =
117       reinterpret_cast< ::std::piecewise_construct_t *>(0x01234);  //Avoid sanitizer errors on references to null pointers
118 
119 typedef const std::piecewise_construct_t & piecewise_construct_t;
120 
121 struct try_emplace_t{};
122 
123 #else
124 
125 //! The piecewise_construct_t struct is an empty structure type used as a unique type to
126 //! disambiguate used to disambiguate between different functions that take two tuple arguments.
127 typedef unspecified piecewise_construct_t;
128 
129 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
130 
131 //! A instance of type
132 //! piecewise_construct_t
133 static piecewise_construct_t piecewise_construct = BOOST_CONTAINER_DOC1ST(unspecified, *std_piecewise_construct_holder<>::dummy);
134 
135 ///@cond
136 
137 namespace dtl {
138 
139 struct piecewise_construct_use
140 {
141    //Avoid warnings of unused "piecewise_construct"
piecewise_construct_useboost::container::dtl::piecewise_construct_use142    piecewise_construct_use()
143    {  (void)&::boost::container::piecewise_construct;   }
144 };
145 
146 template <class T1, class T2>
147 struct pair;
148 
149 template <class T>
150 struct is_pair
151 {
152    static const bool value = false;
153 };
154 
155 template <class T1, class T2>
156 struct is_pair< pair<T1, T2> >
157 {
158    static const bool value = true;
159 };
160 
161 template <class T1, class T2>
162 struct is_pair< std::pair<T1, T2> >
163 {
164    static const bool value = true;
165 };
166 
167 template <class T>
168 struct is_not_pair
169 {
170    static const bool value = !is_pair<T>::value;
171 };
172 
173 template <class T>
174 struct is_std_pair
175 {
176    static const bool value = false;
177 };
178 
179 template <class T1, class T2>
180 struct is_std_pair< std::pair<T1, T2> >
181 {
182    static const bool value = true;
183 };
184 
185 struct pair_nat;
186 
187 template<typename T, typename U, typename V>
188 void get(T); //to enable ADL
189 
190 ///@endcond
191 
192 #ifdef  _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
193 //Libc++, in some versions, has an ABI breakage that needs some
194 //padding in dtl::pair, as "std::pair::first" is not at offset zero.
195 //See: https://reviews.llvm.org/D56357 for more information.
196 //
197 template <class T1, class T2, std::size_t N>
198 struct pair_padding
199 {
200    char padding[N];
201 };
202 
203 template <class T1, class T2>
204 struct pair_padding<T1, T2, 0>
205 {
206 };
207 
208 template <class T1, class T2>
209 struct simple_pair
210 {
211    T1 first;
212    T2 second;
213 };
214 
215 #endif
216 
217 template <class T1, class T2>
218 struct pair
219 #ifdef  _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
220    : pair_padding<T1, T2, sizeof(std::pair<T1, T2>) - sizeof(simple_pair<T1, T2>)>
221 #endif
222 {
223    private:
224    BOOST_COPYABLE_AND_MOVABLE(pair)
225 
226    public:
227    typedef T1 first_type;
228    typedef T2 second_type;
229 
230    T1 first;
231    T2 second;
232 
233    //Default constructor
pairboost::container::dtl::pair234    pair()
235       : first(), second()
236    {
237       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
238    }
239 
240    //pair copy assignment
pairboost::container::dtl::pair241    pair(const pair& x)
242       : first(x.first), second(x.second)
243    {
244       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
245    }
246 
247    //pair move constructor
pairboost::container::dtl::pair248    pair(BOOST_RV_REF(pair) p)
249       : first(::boost::move(p.first)), second(::boost::move(p.second))
250    {
251       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
252    }
253 
254    template <class D, class S>
pairboost::container::dtl::pair255    pair(const pair<D, S> &p)
256       : first(p.first), second(p.second)
257    {
258       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
259    }
260 
261    template <class D, class S>
pairboost::container::dtl::pair262    pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
263       : first(::boost::move(p.first)), second(::boost::move(p.second))
264    {
265       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
266    }
267 
268    //pair from two values
pairboost::container::dtl::pair269    pair(const T1 &t1, const T2 &t2)
270       : first(t1)
271       , second(t2)
272    {
273       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
274    }
275 
276    template<class U, class V>
pairboost::container::dtl::pair277    pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
278       : first(::boost::forward<U>(u))
279       , second(::boost::forward<V>(v))
280    {
281       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
282    }
283 
284    //And now compatibility with std::pair
pairboost::container::dtl::pair285    pair(const std::pair<T1, T2>& x)
286       : first(x.first), second(x.second)
287    {
288       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
289    }
290 
291    template <class D, class S>
pairboost::container::dtl::pair292    pair(const std::pair<D, S>& p)
293       : first(p.first), second(p.second)
294    {
295       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
296    }
297 
pairboost::container::dtl::pair298    pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
299       : first(::boost::move(p.first)), second(::boost::move(p.second))
300    {
301       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
302    }
303 
304    template <class D, class S>
pairboost::container::dtl::pair305    pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
306       : first(::boost::move(p.first)), second(::boost::move(p.second))
307    {
308       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
309    }
310 
311    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
312    template< class KeyType, class ...Args>
pairboost::container::dtl::pair313    pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args)
314       : first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\
315    {
316       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
317    }
318    #else
319 
320    //piecewise construction from boost::tuple
321    #define BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE(N)\
322    template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
323    pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\
324       : first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\
325    {\
326       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
327    }\
328    //
329    BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE)
330    #undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE
331 
332    #endif   //BOOST_NO_CXX11_VARIADIC_TEMPLATES
333 
334    //piecewise construction from boost::tuple
335    #define BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
336    template< template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
337             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 > \
338    pair( piecewise_construct_t\
339        , BoostTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
340        , BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q\
341        , typename dtl::enable_if_c\
342          < 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 &&\
343            !(pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARG##N>::value || pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARGQ##M>::value) \
344          >::type* = 0\
345        )\
346       : first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\
347    { (void)p; (void)q;\
348       BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
349    }\
350    //
351    BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
352    #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
353 
354    //piecewise construction from variadic tuple (with delegating constructors)
355    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
356    #  if !defined(BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS)
357       private:
358       template<template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
pairboost::container::dtl::pair359       pair(Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
360          : first (::boost::forward<Args1>(get<Indexes1>(t1))...)
361          , second(::boost::forward<Args2>(get<Indexes2>(t2))...)
362       {  (void) t1; (void)t2; }
363 
364       public:
365       template< template<class ...> class Tuple, class... Args1, class... Args2
366               , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
pairboost::container::dtl::pair367       pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
368          : pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type())
369       {
370          BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
371       }
372    #  else
373       //piecewise construction from variadic tuple (suboptimal, without delegating constructors)
374       private:
375       template<typename T, template<class ...> class Tuple, typename... Args>
376       static T build_from_args(Tuple<Args...>&& t)
377       {  return do_build_from_args<T>(::boost::move(t), typename build_number_seq<sizeof...(Args)>::type());   }
378 
379       template<typename T, template<class ...> class Tuple, typename... Args, std::size_t... Indexes>
380       static T do_build_from_args(Tuple<Args...> && t, const index_tuple<Indexes...>&)
381       {  (void)t; return T(::boost::forward<Args>(get<Indexes>(t))...);  }
382 
383       public:
384       template< template<class ...> class Tuple, class... Args1, class... Args2
385               , class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type>
386       pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2)
387          : first  (build_from_args<first_type> (::boost::move(t1)))
388          , second (build_from_args<second_type>(::boost::move(t2)))
389       {
390          BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));
391       }
392    #  endif   //BOOST_NO_CXX11_VARIADIC_TEMPLATES
393    #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
394       //MSVC 2010 tuple implementation
395       #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
396       template< template<class, class, class, class, class, class, class, class, class, class> class StdTuple \
397                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 > \
398       pair( piecewise_construct_t\
399           , StdTuple<BOOST_MOVE_TARG##N  BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
400           , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
401          : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
402       { (void)p; (void)q;\
403          BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
404       }\
405       //
406       BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
407       #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
408    #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
409       #if _VARIADIC_MAX >= 9
410       #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
411       #else
412       #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
413       #endif
414 
415       //MSVC 2012 tuple implementation
416       #define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
417       template< template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
418                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 > \
419       pair( piecewise_construct_t\
420           , 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\
421           , 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)\
422          : first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\
423       { (void)p; (void)q;\
424          BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\
425       }\
426       //
427       BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
428       #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
429       #undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
430    #endif
431 
432    //pair copy assignment
operator =boost::container::dtl::pair433    pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
434    {
435       first  = p.first;
436       second = p.second;
437       return *this;
438    }
439 
440    //pair move assignment
operator =boost::container::dtl::pair441    pair& operator=(BOOST_RV_REF(pair) p)
442    {
443       first  = ::boost::move(p.first);
444       second = ::boost::move(p.second);
445       return *this;
446    }
447 
448    template <class D, class S>
449    typename ::boost::container::dtl::disable_if_or
450       < pair &
451       , ::boost::container::dtl::is_same<T1, D>
452       , ::boost::container::dtl::is_same<T2, S>
453       >::type
operator =boost::container::dtl::pair454       operator=(const pair<D, S>&p)
455    {
456       first  = p.first;
457       second = p.second;
458       return *this;
459    }
460 
461    template <class D, class S>
462    typename ::boost::container::dtl::disable_if_or
463       < pair &
464       , ::boost::container::dtl::is_same<T1, D>
465       , ::boost::container::dtl::is_same<T2, S>
466       >::type
operator =boost::container::dtl::pair467       operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
468    {
469       first  = ::boost::move(p.first);
470       second = ::boost::move(p.second);
471       return *this;
472    }
473 //std::pair copy assignment
operator =boost::container::dtl::pair474    pair& operator=(const std::pair<T1, T2> &p)
475    {
476       first  = p.first;
477       second = p.second;
478       return *this;
479    }
480 
481    template <class D, class S>
operator =boost::container::dtl::pair482    pair& operator=(const std::pair<D, S> &p)
483    {
484       first  = ::boost::move(p.first);
485       second = ::boost::move(p.second);
486       return *this;
487    }
488 
489    //std::pair move assignment
operator =boost::container::dtl::pair490    pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
491    {
492       first  = ::boost::move(p.first);
493       second = ::boost::move(p.second);
494       return *this;
495    }
496 
497    template <class D, class S>
operator =boost::container::dtl::pair498    pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
499    {
500       first  = ::boost::move(p.first);
501       second = ::boost::move(p.second);
502       return *this;
503    }
504 
505    //swap
swapboost::container::dtl::pair506    void swap(pair& p)
507    {
508       ::boost::adl_move_swap(this->first, p.first);
509       ::boost::adl_move_swap(this->second, p.second);
510    }
511 };
512 
513 template <class T1, class T2>
operator ==(const pair<T1,T2> & x,const pair<T1,T2> & y)514 inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
515 {  return static_cast<bool>(x.first == y.first && x.second == y.second);  }
516 
517 template <class T1, class T2>
operator <(const pair<T1,T2> & x,const pair<T1,T2> & y)518 inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
519 {  return static_cast<bool>(x.first < y.first ||
520                          (!(y.first < x.first) && x.second < y.second)); }
521 
522 template <class T1, class T2>
operator !=(const pair<T1,T2> & x,const pair<T1,T2> & y)523 inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
524 {  return static_cast<bool>(!(x == y));  }
525 
526 template <class T1, class T2>
operator >(const pair<T1,T2> & x,const pair<T1,T2> & y)527 inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
528 {  return y < x;  }
529 
530 template <class T1, class T2>
operator >=(const pair<T1,T2> & x,const pair<T1,T2> & y)531 inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
532 {  return static_cast<bool>(!(x < y)); }
533 
534 template <class T1, class T2>
operator <=(const pair<T1,T2> & x,const pair<T1,T2> & y)535 inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
536 {  return static_cast<bool>(!(y < x)); }
537 
538 template <class T1, class T2>
make_pair(T1 x,T2 y)539 inline pair<T1, T2> make_pair(T1 x, T2 y)
540 {  return pair<T1, T2>(x, y); }
541 
542 template <class T1, class T2>
swap(pair<T1,T2> & x,pair<T1,T2> & y)543 inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
544 {  x.swap(y);  }
545 
546 }  //namespace dtl {
547 }  //namespace container {
548 
549 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
550 
551 template<class T1, class T2>
552 struct has_move_emulation_enabled< ::boost::container::dtl::pair<T1, T2> >
553 {
554    static const bool value = true;
555 };
556 
557 #endif
558 
559 namespace move_detail{
560 
561 template<class T>
562 struct is_class_or_union;
563 
564 template <class T1, class T2>
565 struct is_class_or_union< ::boost::container::dtl::pair<T1, T2> >
566 //This specialization is needed to avoid instantiation of pair in
567 //is_class, and allow recursive maps.
568 {
569    static const bool value = true;
570 };
571 
572 template <class T1, class T2>
573 struct is_class_or_union< std::pair<T1, T2> >
574 //This specialization is needed to avoid instantiation of pair in
575 //is_class, and allow recursive maps.
576 {
577    static const bool value = true;
578 };
579 
580 template<class T>
581 struct is_union;
582 
583 template <class T1, class T2>
584 struct is_union< ::boost::container::dtl::pair<T1, T2> >
585 //This specialization is needed to avoid instantiation of pair in
586 //is_class, and allow recursive maps.
587 {
588    static const bool value = false;
589 };
590 
591 template <class T1, class T2>
592 struct is_union< std::pair<T1, T2> >
593 //This specialization is needed to avoid instantiation of pair in
594 //is_class, and allow recursive maps.
595 {
596    static const bool value = false;
597 };
598 
599 template<class T>
600 struct is_class;
601 
602 template <class T1, class T2>
603 struct is_class< ::boost::container::dtl::pair<T1, T2> >
604 //This specialization is needed to avoid instantiation of pair in
605 //is_class, and allow recursive maps.
606 {
607    static const bool value = true;
608 };
609 
610 template <class T1, class T2>
611 struct is_class< std::pair<T1, T2> >
612 //This specialization is needed to avoid instantiation of pair in
613 //is_class, and allow recursive maps.
614 {
615    static const bool value = true;
616 };
617 
618 
619 //Triviality of pair
620 template<class T>
621 struct is_trivially_copy_constructible;
622 
623 template<class A, class B>
624 struct is_trivially_copy_assignable
625    <boost::container::dtl::pair<A,B> >
626 {
627    static const bool value = boost::move_detail::is_trivially_copy_assignable<A>::value &&
628                              boost::move_detail::is_trivially_copy_assignable<B>::value ;
629 };
630 
631 template<class T>
632 struct is_trivially_move_constructible;
633 
634 template<class A, class B>
635 struct is_trivially_move_assignable
636    <boost::container::dtl::pair<A,B> >
637 {
638    static const bool value = boost::move_detail::is_trivially_move_assignable<A>::value &&
639                              boost::move_detail::is_trivially_move_assignable<B>::value ;
640 };
641 
642 template<class T>
643 struct is_trivially_copy_assignable;
644 
645 template<class A, class B>
646 struct is_trivially_copy_constructible<boost::container::dtl::pair<A,B> >
647 {
648    static const bool value = boost::move_detail::is_trivially_copy_constructible<A>::value &&
649                              boost::move_detail::is_trivially_copy_constructible<B>::value ;
650 };
651 
652 template<class T>
653 struct is_trivially_move_assignable;
654 
655 template<class A, class B>
656 struct is_trivially_move_constructible<boost::container::dtl::pair<A,B> >
657 {
658    static const bool value = boost::move_detail::is_trivially_move_constructible<A>::value &&
659                              boost::move_detail::is_trivially_move_constructible<B>::value ;
660 };
661 
662 template<class T>
663 struct is_trivially_destructible;
664 
665 template<class A, class B>
666 struct is_trivially_destructible<boost::container::dtl::pair<A,B> >
667 {
668    static const bool value = boost::move_detail::is_trivially_destructible<A>::value &&
669                              boost::move_detail::is_trivially_destructible<B>::value ;
670 };
671 
672 
673 }  //namespace move_detail{
674 
675 }  //namespace boost {
676 
677 #include <boost/container/detail/config_end.hpp>
678 
679 #endif   //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP
680