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