]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/container/detail/dispatch_uses_allocator.hpp
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / boost / boost / container / detail / dispatch_uses_allocator.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/container for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10
11 #ifndef BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP
12 #define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP
13
14 #if defined (_MSC_VER)
15 # pragma once
16 #endif
17
18 #include <boost/container/detail/config_begin.hpp>
19 #include <boost/container/detail/workaround.hpp>
20
21 #include <boost/container/allocator_traits.hpp>
22 #include <boost/container/uses_allocator.hpp>
23
24 #include <boost/container/detail/addressof.hpp>
25 #include <boost/container/detail/mpl.hpp>
26 #include <boost/container/detail/is_pair.hpp>
27 #include <boost/container/detail/type_traits.hpp>
28
29 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
30 #include <boost/move/detail/fwd_macros.hpp>
31 #else
32 #include <boost/container/detail/variadic_templates_tools.hpp>
33 #endif
34 #include <boost/move/utility_core.hpp>
35
36 #include <boost/core/no_exceptions_support.hpp>
37
38 namespace boost { namespace container {
39
40 namespace dtl {
41
42
43 // Check if we can detect is_convertible using advanced SFINAE expressions
44 #if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
45
46 //! Code inspired by Mathias Gaunard's is_convertible.cpp found in the Boost mailing list
47 //! http://boost.2283326.n4.nabble.com/type-traits-is-constructible-when-decltype-is-supported-td3575452.html
48 //! Thanks Mathias!
49
50 //With variadic templates, we need a single class to implement the trait
51 template<class T, class ...Args>
52 struct is_constructible
53 {
54 typedef char yes_type;
55 struct no_type
56 { char padding[2]; };
57
58 template<std::size_t N>
59 struct dummy;
60
61 template<class X>
62 static decltype(X(boost::move_detail::declval<Args>()...), true_type()) test(int);
63
64 template<class X>
65 static no_type test(...);
66
67 static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
68 };
69
70 template <class T, class InnerAlloc, class ...Args>
71 struct is_constructible_with_allocator_prefix
72 : is_constructible<T, allocator_arg_t, InnerAlloc, Args...>
73 {};
74
75 #else // #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
76
77 //Without advanced SFINAE expressions, we can't use is_constructible
78 //so backup to constructible_with_allocator_xxx
79
80 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
81
82 template <class T, class InnerAlloc, class ...Args>
83 struct is_constructible_with_allocator_prefix
84 : constructible_with_allocator_prefix<T>
85 {};
86
87 template <class T, class InnerAlloc, class ...Args>
88 struct is_constructible_with_allocator_suffix
89 : constructible_with_allocator_suffix<T>
90 {};
91
92 #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
93
94 template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
95 struct is_constructible_with_allocator_prefix
96 : constructible_with_allocator_prefix<T>
97 {};
98
99 template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
100 struct is_constructible_with_allocator_suffix
101 : constructible_with_allocator_suffix<T>
102 {};
103
104 #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
105
106 #endif // #if !defined(BOOST_NO_SFINAE_EXPR)
107
108 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
109
110 template < typename ConstructAlloc
111 , typename ArgAlloc
112 , typename T
113 , class ...Args
114 >
115 BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
116 < void
117 , dtl::is_not_pair<T>
118 , dtl::not_< uses_allocator<T, typename remove_cvref<ArgAlloc>::type > >
119 >::type dispatch_uses_allocator
120 ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
121 {
122 (void)arg_alloc;
123 allocator_traits<ConstructAlloc>::construct(construct_alloc, p, ::boost::forward<Args>(args)...);
124 }
125
126 // allocator_arg_t
127 template < typename ConstructAlloc
128 , typename ArgAlloc
129 , typename T
130 , class ...Args
131 >
132 BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
133 < void
134 , dtl::is_not_pair<T>
135 , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>
136 , is_constructible_with_allocator_prefix<T, ArgAlloc, Args...>
137 >::type dispatch_uses_allocator
138 ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args) ...args)
139 {
140 allocator_traits<ConstructAlloc>::construct
141 ( construct_alloc, p, allocator_arg
142 , ::boost::forward<ArgAlloc>(arg_alloc), ::boost::forward<Args>(args)...);
143 }
144
145 // allocator suffix
146 template < typename ConstructAlloc
147 , typename ArgAlloc
148 , typename T
149 , class ...Args
150 >
151 BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
152 < void
153 , dtl::is_not_pair<T>
154 , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>
155 , dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc, Args...> >
156 >::type dispatch_uses_allocator
157 ( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
158 {
159 allocator_traits<ConstructAlloc>::construct
160 (construct_alloc, p, ::boost::forward<Args>(args)..., ::boost::forward<ArgAlloc>(arg_alloc));
161 }
162
163 #else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
164
165 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
166 template <typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
167 BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
168 < void\
169 , dtl::is_not_pair<T>\
170 , dtl::not_<uses_allocator<T, typename remove_cvref<ArgAlloc>::type> >\
171 >::type\
172 dispatch_uses_allocator\
173 (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
174 {\
175 (void)arg_alloc;\
176 allocator_traits<ConstructAlloc>::construct(construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
177 }\
178 //
179 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
180 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
181
182 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
183 template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
184 BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
185 < void\
186 , dtl::is_not_pair<T>\
187 , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\
188 , is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>\
189 >::type\
190 dispatch_uses_allocator\
191 (ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
192 {\
193 allocator_traits<ConstructAlloc>::construct\
194 (construct_alloc, p, allocator_arg, ::boost::forward<ArgAlloc>(arg_alloc) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
195 }\
196 //
197 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
198 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
199
200 #define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
201 template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
202 BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
203 < void\
204 , dtl::is_not_pair<T>\
205 , uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\
206 , dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N> >\
207 >::type\
208 dispatch_uses_allocator\
209 (ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
210 {\
211 allocator_traits<ConstructAlloc>::construct\
212 (construct_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N, ::boost::forward<ArgAlloc>(arg_alloc));\
213 }\
214 //
215 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
216 #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
217
218 #endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
219
220 template < typename ConstructAlloc
221 , typename ArgAlloc
222 , typename Pair
223 > inline
224 BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> BOOST_MOVE_I void >::type)
225 dispatch_uses_allocator
226 ( ConstructAlloc & construct_alloc
227 , BOOST_FWD_REF(ArgAlloc) arg_alloc
228 , Pair* p)
229 {
230 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first));
231 BOOST_TRY{
232 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second));
233 }
234 BOOST_CATCH(...) {
235 allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
236 BOOST_RETHROW
237 }
238 BOOST_CATCH_END
239 }
240
241
242 template < typename ConstructAlloc
243 , typename ArgAlloc
244 , class Pair, class U, class V>
245 BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if<dtl::is_pair<Pair> BOOST_MOVE_I void>::type)
246 dispatch_uses_allocator
247 ( ConstructAlloc & construct_alloc
248 , BOOST_FWD_REF(ArgAlloc) arg_alloc
249 , Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
250 {
251 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<U>(x));
252 BOOST_TRY{
253 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<V>(y));
254 }
255 BOOST_CATCH(...){
256 allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
257 BOOST_RETHROW
258 }
259 BOOST_CATCH_END
260 }
261
262 template < typename ConstructAlloc
263 , typename ArgAlloc
264 , class Pair, class Pair2>
265 BOOST_CONTAINER_DOC1ST(void, typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void >::type)
266 dispatch_uses_allocator
267 (ConstructAlloc & construct_alloc
268 , BOOST_FWD_REF(ArgAlloc) arg_alloc
269 , Pair* p, Pair2& x)
270 { dispatch_uses_allocator(construct_alloc, arg_alloc, p, x.first, x.second); }
271
272 template < typename ConstructAlloc
273 , typename ArgAlloc
274 , class Pair, class Pair2>
275 typename dtl::enable_if_and
276 < void
277 , dtl::is_pair<Pair>
278 , dtl::not_<boost::move_detail::is_reference<Pair2> > >::type //This is needed for MSVC10 and ambiguous overloads
279 dispatch_uses_allocator
280 (ConstructAlloc & construct_alloc
281 , BOOST_FWD_REF(ArgAlloc) arg_alloc
282 , Pair* p, BOOST_RV_REF_BEG Pair2 BOOST_RV_REF_END x)
283 { dispatch_uses_allocator(construct_alloc, arg_alloc, p, ::boost::move(x.first), ::boost::move(x.second)); }
284
285
286 //piecewise construction from boost::tuple
287 #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
288 template< typename ConstructAlloc, typename ArgAlloc, class Pair \
289 , template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \
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 typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\
292 dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
293 , BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\
294 , BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q)\
295 {\
296 (void)p; (void)q;\
297 dispatch_uses_allocator\
298 (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_TMPL_GET##N);\
299 BOOST_TRY{\
300 dispatch_uses_allocator\
301 (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_TMPL_GETQ##M);\
302 }\
303 BOOST_CATCH(...) {\
304 allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
305 BOOST_RETHROW\
306 }\
307 BOOST_CATCH_END\
308 }\
309 //
310 BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE)
311 #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
312
313 //piecewise construction from Std Tuple
314 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
315
316 template< typename ConstructAlloc, typename ArgAlloc, class Pair
317 , template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2>
318 void dispatch_uses_allocator_index( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair
319 , Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>)
320 {
321 (void)t1; (void)t2;
322 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(pair->first), ::boost::forward<Args1>(get<Indexes1>(t1))...);
323 BOOST_TRY{
324 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(pair->second), ::boost::forward<Args2>(get<Indexes2>(t2))...);
325 }
326 BOOST_CATCH(...){
327 allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));
328 BOOST_RETHROW
329 }
330 BOOST_CATCH_END
331 }
332
333 template< typename ConstructAlloc, typename ArgAlloc, class Pair
334 , template<class ...> class Tuple, class... Args1, class... Args2>
335 typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
336 dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t
337 , Tuple<Args1...> t1, Tuple<Args2...> t2)
338 {
339 (dispatch_uses_allocator_index)( construct_alloc, arg_alloc, pair, t1, t2
340 , typename build_number_seq<sizeof...(Args1)>::type()
341 , typename build_number_seq<sizeof...(Args2)>::type());
342 }
343
344 #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
345
346 //MSVC 2010 tuple implementation
347 #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
348 template< typename ConstructAlloc, typename ArgAlloc, class Pair\
349 , template<class, class, class, class, class, class, class, class, class, class> class StdTuple\
350 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 > \
351 typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\
352 dispatch_uses_allocator(ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
353 , StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\
354 , StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\
355 {\
356 (void)p; (void)q;\
357 dispatch_uses_allocator\
358 (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
359 BOOST_TRY{\
360 dispatch_uses_allocator\
361 (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
362 }\
363 BOOST_CATCH(...) {\
364 allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
365 BOOST_RETHROW\
366 }\
367 BOOST_CATCH_END\
368 }\
369 //
370 BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE)
371 #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
372
373 #elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
374 #if _VARIADIC_MAX >= 9
375 #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
376 #else
377 #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
378 #endif
379
380 //MSVC 2012 tuple implementation
381 #define BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
382 template< typename ConstructAlloc, typename ArgAlloc, class Pair\
383 , template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \
384 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 > \
385 typename dtl::enable_if< dtl::is_pair<Pair> BOOST_MOVE_I void>::type\
386 dispatch_uses_allocator\
387 ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\
388 , 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\
389 , 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)\
390 {\
391 (void)p; (void)q;\
392 dispatch_uses_allocator\
393 (construct_alloc, arg_alloc, dtl::addressof(pair->first) BOOST_MOVE_I_IF(N) BOOST_MOVE_GET_IDX##N);\
394 BOOST_TRY{\
395 dispatch_uses_allocator\
396 (construct_alloc, arg_alloc, dtl::addressof(pair->second) BOOST_MOVE_I_IF(M) BOOST_MOVE_GET_IDXQ##M);\
397 }\
398 BOOST_CATCH(...) {\
399 allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(pair->first));\
400 BOOST_RETHROW\
401 }\
402 BOOST_CATCH_END\
403 }\
404 //
405 BOOST_MOVE_ITER2D_0TOMAX(BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE)
406 #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
407 #undef BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
408
409 #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
410
411 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
412
413 template < typename ConstructAlloc
414 , typename ArgAlloc
415 , class Pair, class KeyType, class ... Args>
416 typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
417 dispatch_uses_allocator
418 (ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args)
419 {
420 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));
421 BOOST_TRY{
422 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second), ::boost::forward<Args>(args)...);
423 }
424 BOOST_CATCH(...) {
425 allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));
426 BOOST_RETHROW
427 }
428 BOOST_CATCH_END
429 }
430
431 #else
432
433 #define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE(N) \
434 template <typename ConstructAlloc, typename ArgAlloc, class Pair, class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
435 inline typename dtl::enable_if\
436 < dtl::is_pair<Pair> BOOST_MOVE_I void >::type\
437 dispatch_uses_allocator\
438 (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, \
439 BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
440 {\
441 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->first), ::boost::forward<KeyType>(k));\
442 BOOST_TRY{\
443 dispatch_uses_allocator(construct_alloc, arg_alloc, dtl::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
444 }\
445 BOOST_CATCH(...) {\
446 allocator_traits<ConstructAlloc>::destroy(construct_alloc, dtl::addressof(p->first));\
447 BOOST_RETHROW\
448 }\
449 BOOST_CATCH_END\
450 }\
451 //
452 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE)
453 #undef BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE
454
455 #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
456
457 } //namespace dtl
458
459 }} // namespace boost { namespace container {
460
461 #include <boost/container/detail/config_end.hpp>
462
463 #endif // BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_HPP