1
//////////////////////////////////////////////////////////////////////////////
3
// (C) Copyright Ion Gaztanaga 2008-2012. 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)
7
// See http://www.boost.org/libs/container for documentation.
9
//////////////////////////////////////////////////////////////////////////////
11
#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
12
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
18
#include "config_begin.hpp"
19
#include <boost/container/detail/workaround.hpp>
20
#include <boost/container/allocator_traits.hpp>
21
#include <boost/container/detail/destroyers.hpp>
22
#include <boost/aligned_storage.hpp>
23
#include <boost/move/utility.hpp>
24
#include <iterator> //std::iterator_traits
25
#include <boost/assert.hpp>
26
#include <boost/detail/no_exceptions_support.hpp>
28
namespace boost { namespace container { namespace container_detail {
30
template<class A, class FwdIt, class Iterator>
31
struct move_insert_range_proxy
33
typedef typename allocator_traits<A>::size_type size_type;
34
typedef typename allocator_traits<A>::value_type value_type;
36
move_insert_range_proxy(A& a, FwdIt first)
37
: a_(a), first_(first)
40
void uninitialized_copy_n_and_update(Iterator p, size_type n)
42
this->first_ = ::boost::container::uninitialized_move_alloc_n_source
43
(this->a_, this->first_, n, p);
46
void copy_n_and_update(Iterator p, size_type n)
48
this->first_ = ::boost::container::move_n_source(this->first_, n, p);
56
template<class A, class FwdIt, class Iterator>
57
struct insert_range_proxy
59
typedef typename allocator_traits<A>::size_type size_type;
60
typedef typename allocator_traits<A>::value_type value_type;
62
insert_range_proxy(A& a, FwdIt first)
63
: a_(a), first_(first)
66
void uninitialized_copy_n_and_update(Iterator p, size_type n)
68
this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(this->a_, this->first_, n, p);
71
void copy_n_and_update(Iterator p, size_type n)
73
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
81
template<class A, class Iterator>
82
struct insert_n_copies_proxy
84
typedef typename allocator_traits<A>::size_type size_type;
85
typedef typename allocator_traits<A>::value_type value_type;
87
insert_n_copies_proxy(A& a, const value_type &v)
91
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
92
{ boost::container::uninitialized_fill_alloc_n(this->a_, v_, n, p); }
94
void copy_n_and_update(Iterator p, size_type n) const
95
{ std::fill_n(p, n, v_); }
101
template<class A, class Iterator>
102
struct insert_value_initialized_n_proxy
104
typedef ::boost::container::allocator_traits<A> alloc_traits;
105
typedef typename allocator_traits<A>::size_type size_type;
106
typedef typename allocator_traits<A>::value_type value_type;
109
explicit insert_value_initialized_n_proxy(A &a)
113
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
114
{ boost::container::uninitialized_value_init_alloc_n(this->a_, n, p); }
116
void copy_n_and_update(Iterator, size_type) const
125
template<class A, class Iterator>
126
struct insert_default_initialized_n_proxy
128
typedef ::boost::container::allocator_traits<A> alloc_traits;
129
typedef typename allocator_traits<A>::size_type size_type;
130
typedef typename allocator_traits<A>::value_type value_type;
133
explicit insert_default_initialized_n_proxy(A &a)
137
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
138
{ boost::container::uninitialized_default_init_alloc_n(this->a_, n, p); }
140
void copy_n_and_update(Iterator, size_type) const
149
template<class A, class Iterator>
150
struct insert_copy_proxy
152
typedef boost::container::allocator_traits<A> alloc_traits;
153
typedef typename alloc_traits::size_type size_type;
154
typedef typename alloc_traits::value_type value_type;
156
insert_copy_proxy(A& a, const value_type &v)
160
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
162
BOOST_ASSERT(n == 1); (void)n;
163
alloc_traits::construct( this->a_
164
, container_detail::to_raw_pointer(&*p)
169
void copy_n_and_update(Iterator p, size_type n) const
171
BOOST_ASSERT(n == 1); (void)n;
176
const value_type &v_;
180
template<class A, class Iterator>
181
struct insert_move_proxy
183
typedef boost::container::allocator_traits<A> alloc_traits;
184
typedef typename alloc_traits::size_type size_type;
185
typedef typename alloc_traits::value_type value_type;
187
insert_move_proxy(A& a, value_type &v)
191
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
193
BOOST_ASSERT(n == 1); (void)n;
194
alloc_traits::construct( this->a_
195
, container_detail::to_raw_pointer(&*p)
200
void copy_n_and_update(Iterator p, size_type n) const
202
BOOST_ASSERT(n == 1); (void)n;
203
*p = ::boost::move(v_);
210
template<class It, class A>
211
insert_move_proxy<A, It> get_insert_value_proxy(A& a, BOOST_RV_REF(typename std::iterator_traits<It>::value_type) v)
213
return insert_move_proxy<A, It>(a, v);
216
template<class It, class A>
217
insert_copy_proxy<A, It> get_insert_value_proxy(A& a, const typename std::iterator_traits<It>::value_type &v)
219
return insert_copy_proxy<A, It>(a, v);
222
}}} //namespace boost { namespace container { namespace container_detail {
224
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
226
#include <boost/container/detail/variadic_templates_tools.hpp>
227
#include <boost/move/utility.hpp>
229
//#include <iostream> //For debugging purposes
232
namespace container {
233
namespace container_detail {
235
template<class A, class Iterator, class ...Args>
236
struct insert_non_movable_emplace_proxy
238
typedef boost::container::allocator_traits<A> alloc_traits;
239
typedef typename alloc_traits::size_type size_type;
240
typedef typename alloc_traits::value_type value_type;
242
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
244
explicit insert_non_movable_emplace_proxy(A &a, Args&&... args)
245
: a_(a), args_(args...)
248
void uninitialized_copy_n_and_update(Iterator p, size_type n)
249
{ this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, n); }
252
template<int ...IdxPack>
253
void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, size_type n)
255
BOOST_ASSERT(n == 1); (void)n;
256
alloc_traits::construct( this->a_
257
, container_detail::to_raw_pointer(&*p)
258
, ::boost::forward<Args>(get<IdxPack>(this->args_))...
264
tuple<Args&...> args_;
267
template<class A, class Iterator, class ...Args>
268
struct insert_emplace_proxy
269
: public insert_non_movable_emplace_proxy<A, Iterator, Args...>
271
typedef insert_non_movable_emplace_proxy<A, Iterator, Args...> base_t;
272
typedef boost::container::allocator_traits<A> alloc_traits;
273
typedef typename base_t::value_type value_type;
274
typedef typename base_t::size_type size_type;
275
typedef typename base_t::index_tuple_t index_tuple_t;
277
explicit insert_emplace_proxy(A &a, Args&&... args)
278
: base_t(a, ::boost::forward<Args>(args)...)
281
void copy_n_and_update(Iterator p, size_type n)
282
{ this->priv_copy_some_and_update(index_tuple_t(), p, n); }
286
template<int ...IdxPack>
287
void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, size_type n)
289
BOOST_ASSERT(n ==1); (void)n;
290
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
291
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
292
alloc_traits::construct(this->a_, vp,
293
::boost::forward<Args>(get<IdxPack>(this->args_))...);
295
*p = ::boost::move(*vp);
298
alloc_traits::destroy(this->a_, vp);
302
alloc_traits::destroy(this->a_, vp);
306
}}} //namespace boost { namespace container { namespace container_detail {
308
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
310
#include <boost/container/detail/preprocessor.hpp>
311
#include <boost/container/detail/value_init.hpp>
314
namespace container {
315
namespace container_detail {
317
#define BOOST_PP_LOCAL_MACRO(N) \
318
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
319
struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
321
typedef boost::container::allocator_traits<A> alloc_traits; \
322
typedef typename alloc_traits::size_type size_type; \
323
typedef typename alloc_traits::value_type value_type; \
325
BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
326
( A &a BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
328
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \
331
void uninitialized_copy_n_and_update(Iterator p, size_type n) \
333
BOOST_ASSERT(n == 1); (void)n; \
334
alloc_traits::construct \
336
, container_detail::to_raw_pointer(&*p) \
337
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
341
void copy_n_and_update(Iterator, size_type) \
342
{ BOOST_ASSERT(false); } \
346
BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
349
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
350
struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
351
: BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
352
< A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \
354
typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
355
<A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > base_t; \
356
typedef typename base_t::value_type value_type; \
357
typedef typename base_t::size_type size_type; \
358
typedef boost::container::allocator_traits<A> alloc_traits; \
360
BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
361
( A &a BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
362
: base_t(a BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
365
void copy_n_and_update(Iterator p, size_type n) \
367
BOOST_ASSERT(n == 1); (void)n; \
368
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
369
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
370
alloc_traits::construct(this->a_, vp \
371
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
373
*p = ::boost::move(*vp); \
376
alloc_traits::destroy(this->a_, vp); \
380
alloc_traits::destroy(this->a_, vp); \
384
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
385
#include BOOST_PP_LOCAL_ITERATE()
387
}}} //namespace boost { namespace container { namespace container_detail {
389
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
391
#include <boost/container/detail/config_end.hpp>
393
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP