]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // (C) Copyright Ion Gaztanaga 2008-2013. 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_ADVANCED_INSERT_INT_HPP | |
12 | #define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP | |
13 | ||
14 | #ifndef BOOST_CONFIG_HPP | |
15 | # include <boost/config.hpp> | |
16 | #endif | |
17 | ||
18 | #if defined(BOOST_HAS_PRAGMA_ONCE) | |
19 | # pragma once | |
20 | #endif | |
21 | ||
22 | #include <boost/container/detail/config_begin.hpp> | |
23 | #include <boost/container/detail/workaround.hpp> | |
24 | ||
25 | // container | |
26 | #include <boost/container/allocator_traits.hpp> | |
27 | // container/detail | |
28 | #include <boost/container/detail/copy_move_algo.hpp> | |
29 | #include <boost/container/detail/destroyers.hpp> | |
30 | #include <boost/container/detail/mpl.hpp> | |
31 | #include <boost/container/detail/type_traits.hpp> | |
32 | #include <boost/container/detail/iterator.hpp> | |
33 | #include <boost/container/detail/iterators.hpp> | |
b32b8144 | 34 | #include <boost/move/detail/iterator_to_raw_pointer.hpp> |
7c673cae FG |
35 | #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) |
36 | #include <boost/move/detail/fwd_macros.hpp> | |
37 | #endif | |
38 | // move | |
1e59de90 | 39 | |
7c673cae | 40 | #include <boost/move/utility_core.hpp> |
1e59de90 | 41 | #include <boost/move/detail/force_ptr.hpp> |
7c673cae FG |
42 | // other |
43 | #include <boost/assert.hpp> | |
44 | #include <boost/core/no_exceptions_support.hpp> | |
45 | ||
11fdf7f2 | 46 | namespace boost { namespace container { namespace dtl { |
7c673cae FG |
47 | |
48 | template<class Allocator, class FwdIt, class Iterator> | |
49 | struct move_insert_range_proxy | |
50 | { | |
7c673cae FG |
51 | typedef typename allocator_traits<Allocator>::value_type value_type; |
52 | ||
20effc67 | 53 | BOOST_CONTAINER_FORCEINLINE explicit move_insert_range_proxy(FwdIt first) |
7c673cae FG |
54 | : first_(first) |
55 | {} | |
56 | ||
1e59de90 | 57 | BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) |
7c673cae FG |
58 | { |
59 | this->first_ = ::boost::container::uninitialized_move_alloc_n_source | |
60 | (a, this->first_, n, p); | |
61 | } | |
62 | ||
1e59de90 | 63 | BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) |
7c673cae FG |
64 | { |
65 | this->first_ = ::boost::container::move_n_source(this->first_, n, p); | |
66 | } | |
67 | ||
68 | FwdIt first_; | |
69 | }; | |
70 | ||
71 | ||
72 | template<class Allocator, class FwdIt, class Iterator> | |
73 | struct insert_range_proxy | |
74 | { | |
7c673cae FG |
75 | typedef typename allocator_traits<Allocator>::value_type value_type; |
76 | ||
20effc67 | 77 | BOOST_CONTAINER_FORCEINLINE explicit insert_range_proxy(FwdIt first) |
7c673cae FG |
78 | : first_(first) |
79 | {} | |
80 | ||
1e59de90 | 81 | BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) |
7c673cae FG |
82 | { |
83 | this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p); | |
84 | } | |
85 | ||
1e59de90 | 86 | BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) |
7c673cae FG |
87 | { |
88 | this->first_ = ::boost::container::copy_n_source(this->first_, n, p); | |
89 | } | |
90 | ||
91 | FwdIt first_; | |
92 | }; | |
93 | ||
94 | ||
95 | template<class Allocator, class Iterator> | |
96 | struct insert_n_copies_proxy | |
97 | { | |
7c673cae FG |
98 | typedef typename allocator_traits<Allocator>::value_type value_type; |
99 | ||
20effc67 | 100 | BOOST_CONTAINER_FORCEINLINE explicit insert_n_copies_proxy(const value_type &v) |
7c673cae FG |
101 | : v_(v) |
102 | {} | |
103 | ||
1e59de90 | 104 | BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
7c673cae FG |
105 | { boost::container::uninitialized_fill_alloc_n(a, v_, n, p); } |
106 | ||
1e59de90 | 107 | BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const |
7c673cae | 108 | { |
20effc67 TL |
109 | while (n){ |
110 | --n; | |
b32b8144 | 111 | *p = v_; |
20effc67 | 112 | ++p; |
7c673cae FG |
113 | } |
114 | } | |
115 | ||
116 | const value_type &v_; | |
117 | }; | |
118 | ||
119 | template<class Allocator, class Iterator> | |
120 | struct insert_value_initialized_n_proxy | |
121 | { | |
122 | typedef ::boost::container::allocator_traits<Allocator> alloc_traits; | |
7c673cae | 123 | typedef typename allocator_traits<Allocator>::value_type value_type; |
20effc67 | 124 | typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t; |
7c673cae | 125 | |
1e59de90 | 126 | BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
7c673cae FG |
127 | { boost::container::uninitialized_value_init_alloc_n(a, n, p); } |
128 | ||
1e59de90 | 129 | void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
92f5a8d4 | 130 | { |
20effc67 TL |
131 | while (n){ |
132 | --n; | |
133 | storage_t v; | |
1e59de90 TL |
134 | alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v)); |
135 | value_type *vp = move_detail::force_ptr<value_type *>(&v); | |
92f5a8d4 TL |
136 | value_destructor<Allocator> on_exit(a, *vp); (void)on_exit; |
137 | *p = ::boost::move(*vp); | |
20effc67 | 138 | ++p; |
92f5a8d4 TL |
139 | } |
140 | } | |
7c673cae FG |
141 | }; |
142 | ||
143 | template<class Allocator, class Iterator> | |
144 | struct insert_default_initialized_n_proxy | |
145 | { | |
146 | typedef ::boost::container::allocator_traits<Allocator> alloc_traits; | |
7c673cae | 147 | typedef typename allocator_traits<Allocator>::value_type value_type; |
20effc67 | 148 | typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t; |
7c673cae | 149 | |
1e59de90 | 150 | BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
7c673cae FG |
151 | { boost::container::uninitialized_default_init_alloc_n(a, n, p); } |
152 | ||
1e59de90 | 153 | void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
92f5a8d4 TL |
154 | { |
155 | if(!is_pod<value_type>::value){ | |
20effc67 TL |
156 | while (n){ |
157 | --n; | |
92f5a8d4 | 158 | typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; |
1e59de90 TL |
159 | alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v), default_init); |
160 | value_type *vp = move_detail::force_ptr<value_type *>(&v); | |
92f5a8d4 TL |
161 | value_destructor<Allocator> on_exit(a, *vp); (void)on_exit; |
162 | *p = ::boost::move(*vp); | |
20effc67 | 163 | ++p; |
92f5a8d4 TL |
164 | } |
165 | } | |
166 | } | |
7c673cae FG |
167 | }; |
168 | ||
169 | template<class Allocator, class Iterator> | |
170 | struct insert_copy_proxy | |
171 | { | |
172 | typedef boost::container::allocator_traits<Allocator> alloc_traits; | |
7c673cae FG |
173 | typedef typename alloc_traits::value_type value_type; |
174 | ||
20effc67 TL |
175 | static const bool single_value = true; |
176 | ||
177 | BOOST_CONTAINER_FORCEINLINE explicit insert_copy_proxy(const value_type &v) | |
7c673cae FG |
178 | : v_(v) |
179 | {} | |
180 | ||
1e59de90 | 181 | BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
7c673cae FG |
182 | { |
183 | BOOST_ASSERT(n == 1); (void)n; | |
b32b8144 | 184 | alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_); |
7c673cae FG |
185 | } |
186 | ||
1e59de90 | 187 | BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const |
7c673cae FG |
188 | { |
189 | BOOST_ASSERT(n == 1); (void)n; | |
b32b8144 | 190 | *p = v_; |
7c673cae FG |
191 | } |
192 | ||
193 | const value_type &v_; | |
194 | }; | |
195 | ||
196 | ||
197 | template<class Allocator, class Iterator> | |
198 | struct insert_move_proxy | |
199 | { | |
200 | typedef boost::container::allocator_traits<Allocator> alloc_traits; | |
7c673cae FG |
201 | typedef typename alloc_traits::value_type value_type; |
202 | ||
20effc67 TL |
203 | static const bool single_value = true; |
204 | ||
92f5a8d4 | 205 | BOOST_CONTAINER_FORCEINLINE explicit insert_move_proxy(value_type &v) |
7c673cae FG |
206 | : v_(v) |
207 | {} | |
208 | ||
1e59de90 | 209 | BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
7c673cae FG |
210 | { |
211 | BOOST_ASSERT(n == 1); (void)n; | |
b32b8144 | 212 | alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) ); |
7c673cae FG |
213 | } |
214 | ||
1e59de90 | 215 | BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const |
7c673cae FG |
216 | { |
217 | BOOST_ASSERT(n == 1); (void)n; | |
218 | *p = ::boost::move(v_); | |
219 | } | |
220 | ||
221 | value_type &v_; | |
222 | }; | |
223 | ||
224 | template<class It, class Allocator> | |
20effc67 | 225 | BOOST_CONTAINER_FORCEINLINE insert_move_proxy<Allocator, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v) |
7c673cae FG |
226 | { |
227 | return insert_move_proxy<Allocator, It>(v); | |
228 | } | |
229 | ||
230 | template<class It, class Allocator> | |
20effc67 | 231 | BOOST_CONTAINER_FORCEINLINE insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v) |
7c673cae FG |
232 | { |
233 | return insert_copy_proxy<Allocator, It>(v); | |
234 | } | |
235 | ||
11fdf7f2 | 236 | }}} //namespace boost { namespace container { namespace dtl { |
7c673cae FG |
237 | |
238 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
239 | ||
240 | #include <boost/container/detail/variadic_templates_tools.hpp> | |
241 | #include <boost/move/utility_core.hpp> | |
242 | ||
243 | namespace boost { | |
244 | namespace container { | |
11fdf7f2 | 245 | namespace dtl { |
7c673cae FG |
246 | |
247 | template<class Allocator, class Iterator, class ...Args> | |
248 | struct insert_nonmovable_emplace_proxy | |
249 | { | |
250 | typedef boost::container::allocator_traits<Allocator> alloc_traits; | |
7c673cae | 251 | typedef typename alloc_traits::value_type value_type; |
7c673cae FG |
252 | typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t; |
253 | ||
20effc67 TL |
254 | static const bool single_value = true; |
255 | ||
256 | BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args) | |
7c673cae FG |
257 | : args_(args...) |
258 | {} | |
259 | ||
1e59de90 | 260 | BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) |
7c673cae FG |
261 | { this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); } |
262 | ||
263 | private: | |
264 | template<std::size_t ...IdxPack> | |
1e59de90 | 265 | BOOST_CONTAINER_FORCEINLINE void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, std::size_t n) |
7c673cae FG |
266 | { |
267 | BOOST_ASSERT(n == 1); (void)n; | |
b32b8144 | 268 | alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... ); |
7c673cae FG |
269 | } |
270 | ||
271 | protected: | |
272 | tuple<Args&...> args_; | |
273 | }; | |
274 | ||
275 | template<class Allocator, class Iterator, class ...Args> | |
276 | struct insert_emplace_proxy | |
277 | : public insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> | |
278 | { | |
279 | typedef insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> base_t; | |
280 | typedef boost::container::allocator_traits<Allocator> alloc_traits; | |
281 | typedef typename base_t::value_type value_type; | |
7c673cae FG |
282 | typedef typename base_t::index_tuple_t index_tuple_t; |
283 | ||
20effc67 TL |
284 | static const bool single_value = true; |
285 | ||
286 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args) | |
7c673cae FG |
287 | : base_t(::boost::forward<Args>(args)...) |
288 | {} | |
289 | ||
1e59de90 | 290 | BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) |
7c673cae FG |
291 | { this->priv_copy_some_and_update(a, index_tuple_t(), p, n); } |
292 | ||
293 | private: | |
294 | ||
295 | template<std::size_t ...IdxPack> | |
1e59de90 | 296 | BOOST_CONTAINER_FORCEINLINE void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, std::size_t n) |
7c673cae FG |
297 | { |
298 | BOOST_ASSERT(n ==1); (void)n; | |
92f5a8d4 | 299 | typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; |
1e59de90 TL |
300 | alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v), ::boost::forward<Args>(get<IdxPack>(this->args_))...); |
301 | value_type *vp = move_detail::force_ptr<value_type *>(&v); | |
7c673cae FG |
302 | BOOST_TRY{ |
303 | *p = ::boost::move(*vp); | |
304 | } | |
305 | BOOST_CATCH(...){ | |
306 | alloc_traits::destroy(a, vp); | |
307 | BOOST_RETHROW | |
308 | } | |
309 | BOOST_CATCH_END | |
310 | alloc_traits::destroy(a, vp); | |
311 | } | |
312 | }; | |
313 | ||
314 | //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type | |
315 | template<class Allocator, class Iterator> | |
316 | struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type> | |
317 | : public insert_move_proxy<Allocator, Iterator> | |
318 | { | |
20effc67 TL |
319 | static const bool single_value = true; |
320 | ||
321 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v) | |
7c673cae FG |
322 | : insert_move_proxy<Allocator, Iterator>(v) |
323 | {} | |
324 | }; | |
325 | ||
326 | //We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking | |
327 | //compiler error C2752 ("more than one partial specialization matches"). | |
328 | //Any problem is solvable with an extra layer of indirection? ;-) | |
329 | template<class Allocator, class Iterator> | |
330 | struct insert_emplace_proxy<Allocator, Iterator | |
11fdf7f2 | 331 | , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type |
7c673cae FG |
332 | > |
333 | : public insert_copy_proxy<Allocator, Iterator> | |
334 | { | |
20effc67 TL |
335 | |
336 | static const bool single_value = true; | |
337 | ||
338 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) | |
7c673cae FG |
339 | : insert_copy_proxy<Allocator, Iterator>(v) |
340 | {} | |
341 | }; | |
342 | ||
343 | template<class Allocator, class Iterator> | |
344 | struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &> | |
345 | : public insert_copy_proxy<Allocator, Iterator> | |
346 | { | |
20effc67 TL |
347 | static const bool single_value = true; |
348 | ||
349 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) | |
7c673cae FG |
350 | : insert_copy_proxy<Allocator, Iterator>(v) |
351 | {} | |
352 | }; | |
353 | ||
354 | template<class Allocator, class Iterator> | |
355 | struct insert_emplace_proxy<Allocator, Iterator | |
11fdf7f2 | 356 | , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type & |
7c673cae FG |
357 | > |
358 | : public insert_copy_proxy<Allocator, Iterator> | |
359 | { | |
20effc67 TL |
360 | static const bool single_value = true; |
361 | ||
362 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) | |
7c673cae FG |
363 | : insert_copy_proxy<Allocator, Iterator>(v) |
364 | {} | |
365 | }; | |
366 | ||
11fdf7f2 | 367 | }}} //namespace boost { namespace container { namespace dtl { |
7c673cae FG |
368 | |
369 | #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
370 | ||
371 | #include <boost/container/detail/value_init.hpp> | |
372 | ||
373 | namespace boost { | |
374 | namespace container { | |
11fdf7f2 | 375 | namespace dtl { |
7c673cae FG |
376 | |
377 | #define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \ | |
378 | template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ | |
379 | struct insert_nonmovable_emplace_proxy##N\ | |
380 | {\ | |
381 | typedef boost::container::allocator_traits<Allocator> alloc_traits;\ | |
7c673cae FG |
382 | typedef typename alloc_traits::value_type value_type;\ |
383 | \ | |
20effc67 TL |
384 | static const bool single_value = true;\ |
385 | \ | |
386 | BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\ | |
7c673cae FG |
387 | BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\ |
388 | \ | |
1e59de90 | 389 | BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n)\ |
7c673cae FG |
390 | {\ |
391 | BOOST_ASSERT(n == 1); (void)n;\ | |
b32b8144 | 392 | alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ |
7c673cae FG |
393 | }\ |
394 | \ | |
1e59de90 | 395 | BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator, std::size_t)\ |
7c673cae FG |
396 | { BOOST_ASSERT(false); }\ |
397 | \ | |
398 | protected:\ | |
399 | BOOST_MOVE_MREF##N\ | |
400 | };\ | |
401 | \ | |
402 | template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ | |
403 | struct insert_emplace_proxy_arg##N\ | |
404 | : insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\ | |
405 | {\ | |
406 | typedef insert_nonmovable_emplace_proxy##N\ | |
407 | < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\ | |
408 | typedef typename base_t::value_type value_type;\ | |
7c673cae FG |
409 | typedef boost::container::allocator_traits<Allocator> alloc_traits;\ |
410 | \ | |
20effc67 TL |
411 | static const bool single_value = true;\ |
412 | \ | |
413 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\ | |
7c673cae FG |
414 | : base_t(BOOST_MOVE_FWD##N){}\ |
415 | \ | |
1e59de90 | 416 | BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, std::size_t n)\ |
7c673cae FG |
417 | {\ |
418 | BOOST_ASSERT(n == 1); (void)n;\ | |
92f5a8d4 | 419 | typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\ |
1e59de90 TL |
420 | alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ |
421 | value_type *vp = move_detail::force_ptr<value_type *>(&v);\ | |
7c673cae FG |
422 | BOOST_TRY{\ |
423 | *p = ::boost::move(*vp);\ | |
424 | }\ | |
425 | BOOST_CATCH(...){\ | |
426 | alloc_traits::destroy(a, vp);\ | |
427 | BOOST_RETHROW\ | |
428 | }\ | |
429 | BOOST_CATCH_END\ | |
430 | alloc_traits::destroy(a, vp);\ | |
431 | }\ | |
432 | };\ | |
433 | // | |
434 | BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE) | |
435 | #undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE | |
436 | ||
437 | #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
438 | ||
439 | //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type | |
440 | template<class Allocator, class Iterator> | |
441 | struct insert_emplace_proxy_arg1<Allocator, Iterator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> > | |
442 | : public insert_move_proxy<Allocator, Iterator> | |
443 | { | |
20effc67 TL |
444 | static const bool single_value = true; |
445 | ||
446 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v) | |
7c673cae FG |
447 | : insert_move_proxy<Allocator, Iterator>(v) |
448 | {} | |
449 | }; | |
450 | ||
451 | template<class Allocator, class Iterator> | |
452 | struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type> | |
453 | : public insert_copy_proxy<Allocator, Iterator> | |
454 | { | |
20effc67 TL |
455 | static const bool single_value = true; |
456 | ||
457 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) | |
7c673cae FG |
458 | : insert_copy_proxy<Allocator, Iterator>(v) |
459 | {} | |
460 | }; | |
461 | ||
462 | #else //e.g. MSVC10 & MSVC11 | |
463 | ||
464 | //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type | |
465 | template<class Allocator, class Iterator> | |
466 | struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type> | |
467 | : public insert_move_proxy<Allocator, Iterator> | |
468 | { | |
20effc67 TL |
469 | static const bool single_value = true; |
470 | ||
471 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v) | |
7c673cae FG |
472 | : insert_move_proxy<Allocator, Iterator>(v) |
473 | {} | |
474 | }; | |
475 | ||
476 | //We use "add_const" here as adding "const" only confuses MSVC10&11 provoking | |
477 | //compiler error C2752 ("more than one partial specialization matches"). | |
478 | //Any problem is solvable with an extra layer of indirection? ;-) | |
479 | template<class Allocator, class Iterator> | |
480 | struct insert_emplace_proxy_arg1<Allocator, Iterator | |
11fdf7f2 | 481 | , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type |
7c673cae FG |
482 | > |
483 | : public insert_copy_proxy<Allocator, Iterator> | |
484 | { | |
20effc67 TL |
485 | static const bool single_value = true; |
486 | ||
487 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) | |
7c673cae FG |
488 | : insert_copy_proxy<Allocator, Iterator>(v) |
489 | {} | |
490 | }; | |
491 | ||
492 | template<class Allocator, class Iterator> | |
493 | struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &> | |
494 | : public insert_copy_proxy<Allocator, Iterator> | |
495 | { | |
20effc67 TL |
496 | static const bool single_value = true; |
497 | ||
498 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) | |
7c673cae FG |
499 | : insert_copy_proxy<Allocator, Iterator>(v) |
500 | {} | |
501 | }; | |
502 | ||
503 | template<class Allocator, class Iterator> | |
504 | struct insert_emplace_proxy_arg1<Allocator, Iterator | |
11fdf7f2 | 505 | , typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type & |
7c673cae FG |
506 | > |
507 | : public insert_copy_proxy<Allocator, Iterator> | |
508 | { | |
20effc67 TL |
509 | static const bool single_value = true; |
510 | ||
511 | BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) | |
7c673cae FG |
512 | : insert_copy_proxy<Allocator, Iterator>(v) |
513 | {} | |
514 | }; | |
515 | ||
516 | #endif | |
517 | ||
11fdf7f2 | 518 | }}} //namespace boost { namespace container { namespace dtl { |
7c673cae FG |
519 | |
520 | #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
521 | ||
20effc67 TL |
522 | namespace boost { namespace container { namespace dtl { |
523 | ||
524 | template <class T> | |
525 | struct has_single_value | |
526 | { | |
527 | private: | |
528 | struct two {char array_[2];}; | |
529 | template<bool Arg> struct wrapper; | |
530 | template <class U> static two test(int, ...); | |
531 | template <class U> static char test(int, const wrapper<U::single_value>*); | |
532 | public: | |
533 | static const bool value = sizeof(test<T>(0, 0)) == 1; | |
534 | void dummy(){} | |
535 | }; | |
536 | ||
537 | template<class InsertionProxy, bool = has_single_value<InsertionProxy>::value> | |
538 | struct is_single_value_proxy_impl | |
539 | { | |
540 | static const bool value = InsertionProxy::single_value; | |
541 | }; | |
542 | ||
543 | template<class InsertionProxy> | |
544 | struct is_single_value_proxy_impl<InsertionProxy, false> | |
545 | { | |
546 | static const bool value = false; | |
547 | }; | |
548 | ||
549 | template<class InsertionProxy> | |
550 | struct is_single_value_proxy | |
551 | : is_single_value_proxy_impl<InsertionProxy> | |
552 | {}; | |
553 | ||
554 | }}} //namespace boost { namespace container { namespace dtl { | |
555 | ||
7c673cae FG |
556 | #include <boost/container/detail/config_end.hpp> |
557 | ||
558 | #endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP |