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