Horizon
Loading...
Searching...
No Matches
insert.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2013-present
5//
6// Use, modification and distribution is subject to the
7// Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//
11// Project home: https://github.com/ericniebler/range-v3
12//
13
14#ifndef RANGES_V3_ACTION_INSERT_HPP
15#define RANGES_V3_ACTION_INSERT_HPP
16
17#include <initializer_list>
18#include <utility>
19
21
26#include <range/v3/utility/static_const.hpp>
27
28#include <range/v3/detail/prologue.hpp>
29
30namespace ranges
31{
33 namespace adl_insert_detail
34 {
35 template<typename Cont, typename... Args>
36 using insert_result_t = decltype(
37 unwrap_reference(std::declval<Cont>()).insert(std::declval<Args>()...));
38
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)
43 {
44 return unwrap_reference(cont).insert(static_cast<T &&>(t));
45 }
46
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)
52 {
53 return unwrap_reference(cont).insert(detail::cpp17_iterator_t<I, S>{i},
54 detail::cpp17_iterator_t<I, S>{j});
55 }
56
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)
62 {
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)});
66 }
67
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)
72 {
73 return unwrap_reference(cont).insert(p, static_cast<T &&>(t));
74 }
75
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)
80 {
81 return unwrap_reference(cont).insert(p, n, static_cast<T &&>(t));
82 }
83
85 namespace detail
86 {
87 using ranges::detail::cpp17_iterator_t;
88 using ranges::detail::range_cpp17_iterator_t;
89
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)
95 {
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)
103 {
104 auto const new_capacity =
105 (old_capacity <= max_size / 3 * 2)
106 ? ranges::max(old_capacity + old_capacity / 2, new_size)
107 : max_size;
108 cont.reserve(new_capacity);
109 }
110 return ranges::begin(cont) + index;
111 }
112
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}))
118 {
119 using C = cpp17_iterator_t<I, S>;
120 return unwrap_reference(cont).insert(p, C{i}, C{j});
121 }
122
123 template(typename Cont, typename P, typename I, typename S)(
124 requires sized_sentinel_for<S, I> AND random_access_reservable<Cont> AND
125 (!range<S>)) //
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}))
130 {
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)});
136 }
137
138 template(typename Cont, typename I, typename Rng)(
139 requires range<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)}))
144 {
145 using C = range_cpp17_iterator_t<Rng>;
146 return unwrap_reference(cont).insert(
147 p, C{ranges::begin(rng)}, C{ranges::end(rng)});
148 }
149
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)}))
157 {
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)});
163 }
164 } // namespace detail
166
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
170 (!range<S>)) //
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),
177 meta::bool_<random_access_reservable<Cont> && //
178 sized_sentinel_for<S, I>>{}))
179 {
180 return detail::insert_impl(static_cast<Cont &&>(cont),
181 static_cast<P &&>(p),
182 static_cast<I &&>(i),
183 static_cast<S &&>(j),
184 meta::bool_<random_access_reservable<Cont> &&
185 sized_sentinel_for<S, I>>{});
186 }
187
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>>{}))
194 {
195 return detail::insert_impl(static_cast<Cont &&>(cont),
196 std::move(p),
197 static_cast<Rng &&>(rng),
198 meta::bool_<random_access_reservable<Cont> &&
199 sized_range<Rng>>{});
200 }
201
203 {
204 template<typename Rng, typename... Args>
205 using insert_result_t =
206 decltype(insert(std::declval<Rng>(), std::declval<Args>()...));
207
208 template(typename Rng, typename T)(
209 requires range<Rng> AND
210 (!range<T>) AND constructible_from<range_value_t<Rng>, T>)
211 insert_result_t<Rng, T> operator()(Rng && rng, T && t) const
212 {
213 return insert(static_cast<Rng &&>(rng), static_cast<T &&>(t));
214 }
215
216 template(typename Rng, typename Rng2)(
217 requires range<Rng> AND range<Rng2>)
218 insert_result_t<Rng, Rng2> operator()(Rng && rng, Rng2 && rng2) const
219 {
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));
223 }
224
225 template(typename Rng, typename T)(
226 requires range<Rng>)
227 insert_result_t<Rng, std::initializer_list<T> &> //
228 operator()(Rng && rng, std::initializer_list<T> rng2) const
229 {
230 return insert(static_cast<Rng &&>(rng), rng2);
231 }
232
233 template(typename Rng, typename I, typename S)(
234 requires range<Rng> AND sentinel_for<S, I> AND (!range<S>)) //
235 insert_result_t<Rng, I, S> operator()(Rng && rng, I i, S j) const
236 {
237 return insert(static_cast<Rng &&>(rng), std::move(i), std::move(j));
238 }
239
240 template(typename Rng, typename I, typename T)(
241 requires range<Rng> AND input_iterator<I> AND
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
244 {
245 return insert(
246 static_cast<Rng &&>(rng), std::move(p), static_cast<T &&>(t));
247 }
248
249 template(typename Rng, typename I, typename Rng2)(
251 insert_result_t<Rng, I, Rng2> operator()(Rng && rng, I p, Rng2 && rng2) const
252 {
253 static_assert(!is_infinite<Rng>::value,
254 "Attempting to insert an infinite range into a container");
255 return insert(
256 static_cast<Rng &&>(rng), std::move(p), static_cast<Rng2 &&>(rng2));
257 }
258
259 template(typename Rng, typename I, typename T)(
260 requires range<Rng> AND input_iterator<I>)
261 insert_result_t<Rng, I, std::initializer_list<T> &> //
262 operator()(Rng && rng, I p, std::initializer_list<T> rng2) const
263 {
264 return insert(static_cast<Rng &&>(rng), std::move(p), rng2);
265 }
266
267 template(typename Rng, typename I, typename N, typename T)(
268 requires range<Rng> AND input_iterator<I> AND integral<N> AND
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
271 {
272 return insert(
273 static_cast<Rng &&>(rng), std::move(p), n, static_cast<T &&>(t));
274 }
275
276 template(typename Rng, typename P, typename I, typename S)(
278 (!range<S>)) //
279 insert_result_t<Rng, P, I, S> operator()(Rng && rng, P p, I i, S j) const
280 {
281 return insert(
282 static_cast<Rng &&>(rng), std::move(p), std::move(i), std::move(j));
283 }
284 };
285 } // namespace adl_insert_detail
287
289 RANGES_INLINE_VARIABLE(adl_insert_detail::insert_fn, insert)
290
291 namespace actions
292 {
293 using ranges::insert;
294 }
295} // namespace ranges
296
297#include <range/v3/detail/epilogue.hpp>
298
299#endif
The input_iterator concept.
The range concept.
The sentinel_for concept.
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
Definition insert.hpp:203