]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/container/include/boost/container/detail/advanced_insert_int.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / container / include / boost / container / detail / advanced_insert_int.hpp
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>
34 #include <boost/container/detail/iterator_to_raw_pointer.hpp>
35 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
36 #include <boost/move/detail/fwd_macros.hpp>
37 #endif
38 // move
39 #include <boost/move/utility_core.hpp>
40 // other
41 #include <boost/assert.hpp>
42 #include <boost/core/no_exceptions_support.hpp>
43
44 namespace boost { namespace container { namespace container_detail {
45
46 template<class Allocator, class FwdIt, class Iterator>
47 struct move_insert_range_proxy
48 {
49 typedef typename allocator_traits<Allocator>::size_type size_type;
50 typedef typename allocator_traits<Allocator>::value_type value_type;
51
52 explicit move_insert_range_proxy(FwdIt first)
53 : first_(first)
54 {}
55
56 void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
57 {
58 this->first_ = ::boost::container::uninitialized_move_alloc_n_source
59 (a, this->first_, n, p);
60 }
61
62 void copy_n_and_update(Allocator &, Iterator p, size_type n)
63 {
64 this->first_ = ::boost::container::move_n_source(this->first_, n, p);
65 }
66
67 FwdIt first_;
68 };
69
70
71 template<class Allocator, class FwdIt, class Iterator>
72 struct insert_range_proxy
73 {
74 typedef typename allocator_traits<Allocator>::size_type size_type;
75 typedef typename allocator_traits<Allocator>::value_type value_type;
76
77 explicit insert_range_proxy(FwdIt first)
78 : first_(first)
79 {}
80
81 void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
82 {
83 this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p);
84 }
85
86 void copy_n_and_update(Allocator &, Iterator p, size_type n)
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 {
98 typedef typename allocator_traits<Allocator>::size_type size_type;
99 typedef typename allocator_traits<Allocator>::value_type value_type;
100
101 explicit insert_n_copies_proxy(const value_type &v)
102 : v_(v)
103 {}
104
105 void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
106 { boost::container::uninitialized_fill_alloc_n(a, v_, n, p); }
107
108 void copy_n_and_update(Allocator &, Iterator p, size_type n) const
109 {
110 for (; 0 < n; --n, ++p){
111 *p = v_;
112 }
113 }
114
115 const value_type &v_;
116 };
117
118 template<class Allocator, class Iterator>
119 struct insert_value_initialized_n_proxy
120 {
121 typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
122 typedef typename allocator_traits<Allocator>::size_type size_type;
123 typedef typename allocator_traits<Allocator>::value_type value_type;
124
125 void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
126 { boost::container::uninitialized_value_init_alloc_n(a, n, p); }
127
128 void copy_n_and_update(Allocator &, Iterator, size_type) const
129 { BOOST_ASSERT(false); }
130 };
131
132 template<class Allocator, class Iterator>
133 struct insert_default_initialized_n_proxy
134 {
135 typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
136 typedef typename allocator_traits<Allocator>::size_type size_type;
137 typedef typename allocator_traits<Allocator>::value_type value_type;
138
139 void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
140 { boost::container::uninitialized_default_init_alloc_n(a, n, p); }
141
142 void copy_n_and_update(Allocator &, Iterator, size_type) const
143 { BOOST_ASSERT(false); }
144 };
145
146 template<class Allocator, class Iterator>
147 struct insert_copy_proxy
148 {
149 typedef boost::container::allocator_traits<Allocator> alloc_traits;
150 typedef typename alloc_traits::size_type size_type;
151 typedef typename alloc_traits::value_type value_type;
152
153 explicit insert_copy_proxy(const value_type &v)
154 : v_(v)
155 {}
156
157 void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
158 {
159 BOOST_ASSERT(n == 1); (void)n;
160 alloc_traits::construct( a, iterator_to_raw_pointer(p), v_);
161 }
162
163 void copy_n_and_update(Allocator &, Iterator p, size_type n) const
164 {
165 BOOST_ASSERT(n == 1); (void)n;
166 *p =v_;
167 }
168
169 const value_type &v_;
170 };
171
172
173 template<class Allocator, class Iterator>
174 struct insert_move_proxy
175 {
176 typedef boost::container::allocator_traits<Allocator> alloc_traits;
177 typedef typename alloc_traits::size_type size_type;
178 typedef typename alloc_traits::value_type value_type;
179
180 explicit insert_move_proxy(value_type &v)
181 : v_(v)
182 {}
183
184 void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
185 {
186 BOOST_ASSERT(n == 1); (void)n;
187 alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::move(v_) );
188 }
189
190 void copy_n_and_update(Allocator &, Iterator p, size_type n) const
191 {
192 BOOST_ASSERT(n == 1); (void)n;
193 *p = ::boost::move(v_);
194 }
195
196 value_type &v_;
197 };
198
199 template<class It, class Allocator>
200 insert_move_proxy<Allocator, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v)
201 {
202 return insert_move_proxy<Allocator, It>(v);
203 }
204
205 template<class It, class Allocator>
206 insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v)
207 {
208 return insert_copy_proxy<Allocator, It>(v);
209 }
210
211 }}} //namespace boost { namespace container { namespace container_detail {
212
213 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
214
215 #include <boost/container/detail/variadic_templates_tools.hpp>
216 #include <boost/move/utility_core.hpp>
217
218 namespace boost {
219 namespace container {
220 namespace container_detail {
221
222 template<class Allocator, class Iterator, class ...Args>
223 struct insert_nonmovable_emplace_proxy
224 {
225 typedef boost::container::allocator_traits<Allocator> alloc_traits;
226 typedef typename alloc_traits::size_type size_type;
227 typedef typename alloc_traits::value_type value_type;
228
229 typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
230
231 explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
232 : args_(args...)
233 {}
234
235 void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
236 { this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); }
237
238 private:
239 template<std::size_t ...IdxPack>
240 void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
241 {
242 BOOST_ASSERT(n == 1); (void)n;
243 alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
244 }
245
246 protected:
247 tuple<Args&...> args_;
248 };
249
250 template<class Allocator, class Iterator, class ...Args>
251 struct insert_emplace_proxy
252 : public insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...>
253 {
254 typedef insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> base_t;
255 typedef boost::container::allocator_traits<Allocator> alloc_traits;
256 typedef typename base_t::value_type value_type;
257 typedef typename base_t::size_type size_type;
258 typedef typename base_t::index_tuple_t index_tuple_t;
259
260 explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
261 : base_t(::boost::forward<Args>(args)...)
262 {}
263
264 void copy_n_and_update(Allocator &a, Iterator p, size_type n)
265 { this->priv_copy_some_and_update(a, index_tuple_t(), p, n); }
266
267 private:
268
269 template<std::size_t ...IdxPack>
270 void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
271 {
272 BOOST_ASSERT(n ==1); (void)n;
273 typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
274 value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
275 alloc_traits::construct(a, vp,
276 ::boost::forward<Args>(get<IdxPack>(this->args_))...);
277 BOOST_TRY{
278 *p = ::boost::move(*vp);
279 }
280 BOOST_CATCH(...){
281 alloc_traits::destroy(a, vp);
282 BOOST_RETHROW
283 }
284 BOOST_CATCH_END
285 alloc_traits::destroy(a, vp);
286 }
287 };
288
289 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
290 template<class Allocator, class Iterator>
291 struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
292 : public insert_move_proxy<Allocator, Iterator>
293 {
294 explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v)
295 : insert_move_proxy<Allocator, Iterator>(v)
296 {}
297 };
298
299 //We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking
300 //compiler error C2752 ("more than one partial specialization matches").
301 //Any problem is solvable with an extra layer of indirection? ;-)
302 template<class Allocator, class Iterator>
303 struct insert_emplace_proxy<Allocator, Iterator
304 , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
305 >
306 : public insert_copy_proxy<Allocator, Iterator>
307 {
308 explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
309 : insert_copy_proxy<Allocator, Iterator>(v)
310 {}
311 };
312
313 template<class Allocator, class Iterator>
314 struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
315 : public insert_copy_proxy<Allocator, Iterator>
316 {
317 explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
318 : insert_copy_proxy<Allocator, Iterator>(v)
319 {}
320 };
321
322 template<class Allocator, class Iterator>
323 struct insert_emplace_proxy<Allocator, Iterator
324 , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
325 >
326 : public insert_copy_proxy<Allocator, Iterator>
327 {
328 explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
329 : insert_copy_proxy<Allocator, Iterator>(v)
330 {}
331 };
332
333 }}} //namespace boost { namespace container { namespace container_detail {
334
335 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
336
337 #include <boost/container/detail/value_init.hpp>
338
339 namespace boost {
340 namespace container {
341 namespace container_detail {
342
343 #define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \
344 template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
345 struct insert_nonmovable_emplace_proxy##N\
346 {\
347 typedef boost::container::allocator_traits<Allocator> alloc_traits;\
348 typedef typename alloc_traits::size_type size_type;\
349 typedef typename alloc_traits::value_type value_type;\
350 \
351 explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\
352 BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\
353 \
354 void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\
355 {\
356 BOOST_ASSERT(n == 1); (void)n;\
357 alloc_traits::construct(a, iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
358 }\
359 \
360 void copy_n_and_update(Allocator &, Iterator, size_type)\
361 { BOOST_ASSERT(false); }\
362 \
363 protected:\
364 BOOST_MOVE_MREF##N\
365 };\
366 \
367 template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
368 struct insert_emplace_proxy_arg##N\
369 : insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\
370 {\
371 typedef insert_nonmovable_emplace_proxy##N\
372 < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\
373 typedef typename base_t::value_type value_type;\
374 typedef typename base_t::size_type size_type;\
375 typedef boost::container::allocator_traits<Allocator> alloc_traits;\
376 \
377 explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\
378 : base_t(BOOST_MOVE_FWD##N){}\
379 \
380 void copy_n_and_update(Allocator &a, Iterator p, size_type n)\
381 {\
382 BOOST_ASSERT(n == 1); (void)n;\
383 typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
384 BOOST_ASSERT((((size_type)(&v)) % alignment_of<value_type>::value) == 0);\
385 value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));\
386 alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
387 BOOST_TRY{\
388 *p = ::boost::move(*vp);\
389 }\
390 BOOST_CATCH(...){\
391 alloc_traits::destroy(a, vp);\
392 BOOST_RETHROW\
393 }\
394 BOOST_CATCH_END\
395 alloc_traits::destroy(a, vp);\
396 }\
397 };\
398 //
399 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE)
400 #undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE
401
402 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
403
404 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
405 template<class Allocator, class Iterator>
406 struct insert_emplace_proxy_arg1<Allocator, Iterator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> >
407 : public insert_move_proxy<Allocator, Iterator>
408 {
409 explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v)
410 : insert_move_proxy<Allocator, Iterator>(v)
411 {}
412 };
413
414 template<class Allocator, class Iterator>
415 struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
416 : public insert_copy_proxy<Allocator, Iterator>
417 {
418 explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
419 : insert_copy_proxy<Allocator, Iterator>(v)
420 {}
421 };
422
423 #else //e.g. MSVC10 & MSVC11
424
425 //Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
426 template<class Allocator, class Iterator>
427 struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
428 : public insert_move_proxy<Allocator, Iterator>
429 {
430 explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v)
431 : insert_move_proxy<Allocator, Iterator>(v)
432 {}
433 };
434
435 //We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
436 //compiler error C2752 ("more than one partial specialization matches").
437 //Any problem is solvable with an extra layer of indirection? ;-)
438 template<class Allocator, class Iterator>
439 struct insert_emplace_proxy_arg1<Allocator, Iterator
440 , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
441 >
442 : public insert_copy_proxy<Allocator, Iterator>
443 {
444 explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
445 : insert_copy_proxy<Allocator, Iterator>(v)
446 {}
447 };
448
449 template<class Allocator, class Iterator>
450 struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
451 : public insert_copy_proxy<Allocator, Iterator>
452 {
453 explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
454 : insert_copy_proxy<Allocator, Iterator>(v)
455 {}
456 };
457
458 template<class Allocator, class Iterator>
459 struct insert_emplace_proxy_arg1<Allocator, Iterator
460 , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
461 >
462 : public insert_copy_proxy<Allocator, Iterator>
463 {
464 explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
465 : insert_copy_proxy<Allocator, Iterator>(v)
466 {}
467 };
468
469 #endif
470
471 }}} //namespace boost { namespace container { namespace container_detail {
472
473 #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
474
475 #include <boost/container/detail/config_end.hpp>
476
477 #endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP