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