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