14#ifndef RANGES_V3_ACTION_INSERT_HPP
15#define RANGES_V3_ACTION_INSERT_HPP
17#include <initializer_list>
26#include <range/v3/utility/static_const.hpp>
28#include <range/v3/detail/prologue.hpp>
33 namespace adl_insert_detail
35 template<
typename Cont,
typename... Args>
36 using insert_result_t =
decltype(
37 unwrap_reference(std::declval<Cont>()).insert(std::declval<Args>()...));
39 template(
typename Cont,
typename T)(
40 requires lvalue_container_like<Cont> AND
41 (!range<T> && constructible_from<range_value_t<Cont>, T>))
42 insert_result_t<Cont &, T> insert(Cont && cont, T && t)
44 return unwrap_reference(cont).insert(
static_cast<T &&
>(t));
47 template(
typename Cont,
typename I,
typename S)(
48 requires lvalue_container_like<Cont> AND sentinel_for<S, I> AND (!range<S>))
49 insert_result_t<Cont &, detail::cpp17_iterator_t<I, S>,
50 detail::cpp17_iterator_t<I, S>>
51 insert(Cont && cont, I i, S j)
53 return unwrap_reference(cont).insert(detail::cpp17_iterator_t<I, S>{i},
54 detail::cpp17_iterator_t<I, S>{j});
57 template(
typename Cont,
typename Rng)(
58 requires lvalue_container_like<Cont> AND range<Rng>)
59 insert_result_t<Cont &, detail::range_cpp17_iterator_t<Rng>,
60 detail::range_cpp17_iterator_t<Rng>>
61 insert(Cont && cont, Rng && rng)
63 return unwrap_reference(cont).insert(
64 detail::range_cpp17_iterator_t<Rng>{ranges::begin(rng)},
65 detail::range_cpp17_iterator_t<Rng>{ranges::end(rng)});
68 template(
typename Cont,
typename I,
typename T)(
69 requires lvalue_container_like<Cont> AND input_iterator<I> AND
70 (!range<T> && constructible_from<range_value_t<Cont>, T>))
71 insert_result_t<Cont &, I, T> insert(Cont && cont, I p, T && t)
73 return unwrap_reference(cont).insert(p,
static_cast<T &&
>(t));
76 template(
typename Cont,
typename I,
typename N,
typename T)(
77 requires lvalue_container_like<Cont> AND input_iterator<I> AND
78 integral<N> AND constructible_from<range_value_t<Cont>, T>)
79 insert_result_t<Cont &, I, N, T> insert(Cont && cont, I p, N n, T && t)
81 return unwrap_reference(cont).insert(p, n,
static_cast<T &&
>(t));
87 using ranges::detail::cpp17_iterator_t;
88 using ranges::detail::range_cpp17_iterator_t;
90 template(
typename Cont,
typename P)(
91 requires container<Cont> AND input_iterator<P> AND
92 random_access_reservable<Cont>)
93 iterator_t<Cont> insert_reserve_helper(
94 Cont & cont, P
const p, range_size_t<Cont>
const delta)
96 auto const old_size = ranges::size(cont);
97 auto const max_size = cont.max_size();
98 RANGES_EXPECT(delta <= max_size - old_size);
99 auto const new_size = old_size + delta;
100 auto const old_capacity = cont.capacity();
101 auto const index = p - ranges::begin(cont);
102 if(old_capacity < new_size)
104 auto const new_capacity =
105 (old_capacity <= max_size / 3 * 2)
106 ? ranges::max(old_capacity + old_capacity / 2, new_size)
108 cont.reserve(new_capacity);
110 return ranges::begin(cont) + index;
113 template(
typename Cont,
typename P,
typename I,
typename S)(
114 requires sentinel_for<S, I> AND (!range<S>))
115 auto insert_impl(Cont && cont, P p, I i, S j, std::false_type)
116 ->
decltype(unwrap_reference(cont).insert(
117 p, cpp17_iterator_t<I, S>{i}, cpp17_iterator_t<I, S>{j}))
119 using C = cpp17_iterator_t<I, S>;
120 return unwrap_reference(cont).insert(p, C{i}, C{j});
123 template(
typename Cont,
typename P,
typename I,
typename S)(
124 requires sized_sentinel_for<S, I> AND random_access_reservable<Cont> AND
126 auto insert_impl(Cont && cont_, P p, I i, S j, std::true_type)
127 ->
decltype(unwrap_reference(cont_).insert(
128 ranges::begin(unwrap_reference(cont_)), cpp17_iterator_t<I, S>{i},
129 cpp17_iterator_t<I, S>{j}))
131 using C = cpp17_iterator_t<I, S>;
132 auto && cont = unwrap_reference(cont_);
133 auto const delta =
static_cast<range_size_t<Cont>
>(j - i);
134 auto pos = insert_reserve_helper(cont, std::move(p), delta);
135 return cont.insert(pos, C{std::move(i)}, C{std::move(j)});
138 template(
typename Cont,
typename I,
typename Rng)(
140 auto insert_impl(Cont && cont, I p, Rng && rng, std::false_type)
141 ->
decltype(unwrap_reference(cont).insert(
142 p, range_cpp17_iterator_t<Rng>{ranges::begin(rng)},
143 range_cpp17_iterator_t<Rng>{ranges::end(rng)}))
145 using C = range_cpp17_iterator_t<Rng>;
146 return unwrap_reference(cont).insert(
147 p, C{ranges::begin(rng)}, C{ranges::end(rng)});
150 template(
typename Cont,
typename I,
typename Rng)(
151 requires random_access_reservable<Cont> AND sized_range<Rng>)
152 auto insert_impl(Cont && cont_, I p, Rng && rng, std::true_type)
153 ->
decltype(unwrap_reference(cont_).insert(
154 begin(unwrap_reference(cont_)),
155 range_cpp17_iterator_t<Rng>{ranges::begin(rng)},
156 range_cpp17_iterator_t<Rng>{ranges::end(rng)}))
158 using C = range_cpp17_iterator_t<Rng>;
159 auto && cont = unwrap_reference(cont_);
160 auto const delta =
static_cast<range_size_t<Cont>
>(ranges::size(rng));
161 auto pos = insert_reserve_helper(cont, std::move(p), delta);
162 return cont.insert(pos, C{ranges::begin(rng)}, C{ranges::end(rng)});
167 template(
typename Cont,
typename P,
typename I,
typename S)(
168 requires lvalue_container_like<Cont> AND input_iterator<P> AND
169 sentinel_for<S, I> AND
171 auto insert(Cont && cont, P p, I i, S j)
172 ->
decltype(detail::insert_impl(
173 static_cast<Cont &&
>(cont),
174 static_cast<P &&
>(p),
175 static_cast<I &&
>(i),
176 static_cast<S &&
>(j),
178 sized_sentinel_for<S, I>>{}))
180 return detail::insert_impl(
static_cast<Cont &&
>(cont),
181 static_cast<P &&
>(p),
182 static_cast<I &&
>(i),
183 static_cast<S &&
>(j),
185 sized_sentinel_for<S, I>>{});
188 template(
typename Cont,
typename I,
typename Rng)(
189 requires lvalue_container_like<Cont> AND input_iterator<I> AND range<Rng>)
190 auto insert(Cont && cont, I p, Rng && rng)
191 ->
decltype(detail::insert_impl(
192 static_cast<Cont &&
>(cont), std::move(p),
static_cast<Rng &&
>(rng),
193 meta::bool_<random_access_reservable<Cont> && sized_range<Rng>>{}))
195 return detail::insert_impl(
static_cast<Cont &&
>(cont),
197 static_cast<Rng &&
>(rng),
199 sized_range<Rng>>{});
204 template<
typename Rng,
typename... Args>
205 using insert_result_t =
206 decltype(insert(std::declval<Rng>(), std::declval<Args>()...));
208 template(
typename Rng,
typename T)(
210 (!
range<T>) AND constructible_from<range_value_t<Rng>, T>)
211 insert_result_t<Rng, T>
operator()(Rng && rng, T && t)
const
213 return insert(
static_cast<Rng &&
>(rng),
static_cast<T &&
>(t));
216 template(
typename Rng,
typename Rng2)(
218 insert_result_t<Rng, Rng2> operator()(Rng && rng, Rng2 && rng2)
const
220 static_assert(!is_infinite<Rng>::value,
221 "Attempting to insert an infinite range into a container");
222 return insert(
static_cast<Rng &&
>(rng),
static_cast<Rng2 &&
>(rng2));
225 template(
typename Rng,
typename T)(
227 insert_result_t<Rng, std::initializer_list<T> &>
228 operator()(Rng && rng, std::initializer_list<T> rng2)
const
230 return insert(
static_cast<Rng &&
>(rng), rng2);
233 template(
typename Rng,
typename I,
typename S)(
235 insert_result_t<Rng, I, S>
operator()(Rng && rng, I i, S j)
const
237 return insert(
static_cast<Rng &&
>(rng), std::move(i), std::move(j));
240 template(
typename Rng,
typename I,
typename T)(
242 (!
range<T>) AND constructible_from<range_value_t<Rng>, T>)
243 insert_result_t<Rng, I, T>
operator()(Rng && rng, I p, T && t)
const
246 static_cast<Rng &&
>(rng), std::move(p),
static_cast<T &&
>(t));
249 template(
typename Rng,
typename I,
typename Rng2)(
251 insert_result_t<Rng, I, Rng2> operator()(Rng && rng, I p, Rng2 && rng2)
const
253 static_assert(!is_infinite<Rng>::value,
254 "Attempting to insert an infinite range into a container");
256 static_cast<Rng &&
>(rng), std::move(p),
static_cast<Rng2 &&
>(rng2));
259 template(
typename Rng,
typename I,
typename T)(
261 insert_result_t<Rng, I, std::initializer_list<T> &>
262 operator()(Rng && rng, I p, std::initializer_list<T> rng2)
const
264 return insert(
static_cast<Rng &&
>(rng), std::move(p), rng2);
267 template(
typename Rng,
typename I,
typename N,
typename T)(
269 (!
range<T>) AND constructible_from<range_value_t<Rng>, T>)
270 insert_result_t<Rng, I, N, T>
operator()(Rng && rng, I p, N n, T && t)
const
273 static_cast<Rng &&
>(rng), std::move(p), n,
static_cast<T &&
>(t));
276 template(
typename Rng,
typename P,
typename I,
typename S)(
279 insert_result_t<Rng, P, I, S>
operator()(Rng && rng, P p, I i, S j)
const
282 static_cast<Rng &&
>(rng), std::move(p), std::move(i), std::move(j));
289 RANGES_INLINE_VARIABLE(adl_insert_detail::insert_fn, insert)
293 using ranges::insert;
297#include <range/v3/detail/epilogue.hpp>
The sentinel_for concept.
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
Definition insert.hpp:203