pair.hpp 21 KB

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