pair.hpp 19 KB

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