pair.hpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. #include <boost/move/adl_move_swap.hpp> //swap
  27. #include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
  28. #include <boost/move/utility_core.hpp>
  29. namespace boost {
  30. namespace container {
  31. namespace container_detail {
  32. template <class T1, class T2>
  33. struct pair;
  34. template <class T>
  35. struct is_pair
  36. {
  37. static const bool value = false;
  38. };
  39. template <class T1, class T2>
  40. struct is_pair< pair<T1, T2> >
  41. {
  42. static const bool value = true;
  43. };
  44. template <class T1, class T2>
  45. struct is_pair< std::pair<T1, T2> >
  46. {
  47. static const bool value = true;
  48. };
  49. template <class T>
  50. struct is_not_pair
  51. {
  52. static const bool value = !is_pair<T>::value;
  53. };
  54. template <class T>
  55. struct is_std_pair
  56. {
  57. static const bool value = false;
  58. };
  59. template <class T1, class T2>
  60. struct is_std_pair< std::pair<T1, T2> >
  61. {
  62. static const bool value = true;
  63. };
  64. struct pair_nat;
  65. template <class T1, class T2>
  66. struct pair
  67. {
  68. private:
  69. BOOST_COPYABLE_AND_MOVABLE(pair)
  70. public:
  71. typedef T1 first_type;
  72. typedef T2 second_type;
  73. T1 first;
  74. T2 second;
  75. //Default constructor
  76. pair()
  77. : first(), second()
  78. {}
  79. //pair copy assignment
  80. pair(const pair& x)
  81. : first(x.first), second(x.second)
  82. {}
  83. //pair move constructor
  84. pair(BOOST_RV_REF(pair) p)
  85. : first(::boost::move(p.first)), second(::boost::move(p.second))
  86. {}
  87. template <class D, class S>
  88. pair(const pair<D, S> &p)
  89. : first(p.first), second(p.second)
  90. {}
  91. template <class D, class S>
  92. pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
  93. : first(::boost::move(p.first)), second(::boost::move(p.second))
  94. {}
  95. //pair from two values
  96. pair(const T1 &t1, const T2 &t2)
  97. : first(t1)
  98. , second(t2)
  99. {}
  100. template<class U, class V>
  101. pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
  102. : first(::boost::forward<U>(u))
  103. , second(::boost::forward<V>(v))
  104. {}
  105. //And now compatibility with std::pair
  106. pair(const std::pair<T1, T2>& x)
  107. : first(x.first), second(x.second)
  108. {}
  109. template <class D, class S>
  110. pair(const std::pair<D, S>& p)
  111. : first(p.first), second(p.second)
  112. {}
  113. pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
  114. : first(::boost::move(p.first)), second(::boost::move(p.second))
  115. {}
  116. template <class D, class S>
  117. pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
  118. : first(::boost::move(p.first)), second(::boost::move(p.second))
  119. {}
  120. //piecewise_construct missing
  121. //template <class U, class V> pair(pair<U, V>&& p);
  122. //template <class... Args1, class... Args2>
  123. // pair(piecewise_construct_t, tuple<Args1...> first_args,
  124. // tuple<Args2...> second_args);
  125. //pair copy assignment
  126. pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
  127. {
  128. first = p.first;
  129. second = p.second;
  130. return *this;
  131. }
  132. //pair move assignment
  133. pair& operator=(BOOST_RV_REF(pair) p)
  134. {
  135. first = ::boost::move(p.first);
  136. second = ::boost::move(p.second);
  137. return *this;
  138. }
  139. template <class D, class S>
  140. typename ::boost::container::container_detail::disable_if_or
  141. < pair &
  142. , ::boost::container::container_detail::is_same<T1, D>
  143. , ::boost::container::container_detail::is_same<T2, S>
  144. >::type
  145. operator=(const pair<D, S>&p)
  146. {
  147. first = p.first;
  148. second = p.second;
  149. return *this;
  150. }
  151. template <class D, class S>
  152. typename ::boost::container::container_detail::disable_if_or
  153. < pair &
  154. , ::boost::container::container_detail::is_same<T1, D>
  155. , ::boost::container::container_detail::is_same<T2, S>
  156. >::type
  157. operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
  158. {
  159. first = ::boost::move(p.first);
  160. second = ::boost::move(p.second);
  161. return *this;
  162. }
  163. //std::pair copy assignment
  164. pair& operator=(const std::pair<T1, T2> &p)
  165. {
  166. first = p.first;
  167. second = p.second;
  168. return *this;
  169. }
  170. template <class D, class S>
  171. pair& operator=(const std::pair<D, S> &p)
  172. {
  173. first = ::boost::move(p.first);
  174. second = ::boost::move(p.second);
  175. return *this;
  176. }
  177. //std::pair move assignment
  178. pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
  179. {
  180. first = ::boost::move(p.first);
  181. second = ::boost::move(p.second);
  182. return *this;
  183. }
  184. template <class D, class S>
  185. pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
  186. {
  187. first = ::boost::move(p.first);
  188. second = ::boost::move(p.second);
  189. return *this;
  190. }
  191. //swap
  192. void swap(pair& p)
  193. {
  194. ::boost::adl_move_swap(this->first, p.first);
  195. ::boost::adl_move_swap(this->second, p.second);
  196. }
  197. };
  198. template <class T1, class T2>
  199. inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
  200. { return static_cast<bool>(x.first == y.first && x.second == y.second); }
  201. template <class T1, class T2>
  202. inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
  203. { return static_cast<bool>(x.first < y.first ||
  204. (!(y.first < x.first) && x.second < y.second)); }
  205. template <class T1, class T2>
  206. inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
  207. { return static_cast<bool>(!(x == y)); }
  208. template <class T1, class T2>
  209. inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
  210. { return y < x; }
  211. template <class T1, class T2>
  212. inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
  213. { return static_cast<bool>(!(x < y)); }
  214. template <class T1, class T2>
  215. inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
  216. { return static_cast<bool>(!(y < x)); }
  217. template <class T1, class T2>
  218. inline pair<T1, T2> make_pair(T1 x, T2 y)
  219. { return pair<T1, T2>(x, y); }
  220. template <class T1, class T2>
  221. inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
  222. { x.swap(y); }
  223. } //namespace container_detail {
  224. } //namespace container {
  225. //Without this specialization recursive flat_(multi)map instantiation fails
  226. //because is_enum needs to instantiate the recursive pair, leading to a compilation error).
  227. //This breaks the cycle clearly stating that pair is not an enum avoiding any instantiation.
  228. template<class T>
  229. struct is_enum;
  230. template<class T, class U>
  231. struct is_enum< ::boost::container::container_detail::pair<T, U> >
  232. {
  233. static const bool value = false;
  234. };
  235. template <class T>
  236. struct is_class;
  237. //This specialization is needed to avoid instantiation of pair in
  238. //is_class, and allow recursive maps.
  239. template <class T1, class T2>
  240. struct is_class< ::boost::container::container_detail::pair<T1, T2> >
  241. {
  242. static const bool value = true;
  243. };
  244. #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
  245. template<class T1, class T2>
  246. struct has_move_emulation_enabled< ::boost::container::container_detail::pair<T1, T2> >
  247. {
  248. static const bool value = true;
  249. };
  250. #endif
  251. namespace move_detail{
  252. template<class T>
  253. struct is_class_or_union;
  254. template <class T1, class T2>
  255. struct is_class_or_union< ::boost::container::container_detail::pair<T1, T2> >
  256. //This specialization is needed to avoid instantiation of pair in
  257. //is_class, and allow recursive maps.
  258. {
  259. static const bool value = true;
  260. };
  261. template <class T1, class T2>
  262. struct is_class_or_union< std::pair<T1, T2> >
  263. //This specialization is needed to avoid instantiation of pair in
  264. //is_class, and allow recursive maps.
  265. {
  266. static const bool value = true;
  267. };
  268. } //namespace move_detail{
  269. } //namespace boost {
  270. #include <boost/container/detail/config_end.hpp>
  271. #endif //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP