pair.hpp 20 KB

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