14#ifndef RANGES_V3_RANGE_CONVERSION_HPP
15#define RANGES_V3_RANGE_CONVERSION_HPP
28#include <range/v3/utility/static_const.hpp>
30#include <range/v3/detail/prologue.hpp>
39 template<
typename MetaFn>
42 template<
typename MetaFn,
typename Fn>
45 template<
typename MetaFn,
typename Rng>
48 template<
typename Rng,
typename MetaFn>
49 friend auto operator|(Rng && rng,
50 closure<MetaFn, fn<MetaFn>> (*)(to_container))
51 -> CPP_broken_friend_ret(container_t<MetaFn, Rng>)(
52 requires invocable<fn<MetaFn>, Rng>)
54 return fn<MetaFn>{}(
static_cast<Rng &&
>(rng));
57 template<
typename MetaFn,
typename Pipeable>
58 friend auto operator|(closure<MetaFn, fn<MetaFn>> (*)(to_container),
60 -> CPP_broken_friend_ret(
61 closure<MetaFn, composed<Pipeable, fn<MetaFn>>>)(
62 requires (is_pipeable_v<Pipeable>))
64 return closure<MetaFn, composed<Pipeable, fn<MetaFn>>>{
65 compose(
static_cast<Pipeable &&
>(pipe), fn<MetaFn>{})};
72 template<
typename Rng,
typename Cont>
73 struct to_container_iterator
76 using I = range_cpp17_iterator_t<Rng>;
77 using ValueType = range_value_t<Cont>;
81 using difference_type =
typename std::iterator_traits<I>::difference_type;
82 using value_type = ValueType;
83 using reference = ValueType;
84 using pointer =
typename std::iterator_traits<I>::pointer;
85 using iterator_category =
typename std::iterator_traits<I>::iterator_category;
87 to_container_iterator() =
default;
88 template<
typename OtherIt>
89 to_container_iterator(OtherIt it)
92 friend bool operator==(to_container_iterator
const & a,
93 to_container_iterator
const & b)
95 return a.it_ == b.it_;
97 friend bool operator!=(to_container_iterator
const & a,
98 to_container_iterator
const & b)
104 return to_container::fn<meta::id<ValueType>>{}(*it_);
106 to_container_iterator & operator++()
111 to_container_iterator operator++(
int)
119 -> CPP_ret(to_container_iterator &)(
120 requires derived_from<iterator_category,
121 std::bidirectional_iterator_tag>)
128 -> CPP_ret(to_container_iterator &)(
129 requires derived_from<iterator_category,
130 std::bidirectional_iterator_tag>)
137 auto operator+=(difference_type n)
138 -> CPP_ret(to_container_iterator &)(
139 requires derived_from<iterator_category,
140 std::random_access_iterator_tag>)
146 auto operator-=(difference_type n)
147 -> CPP_ret(to_container_iterator &)(
148 requires derived_from<iterator_category,
149 std::random_access_iterator_tag>)
155 friend auto operator+(to_container_iterator i, difference_type n)
156 -> CPP_broken_friend_ret(to_container_iterator)(
157 requires derived_from<iterator_category,
158 std::random_access_iterator_tag>)
163 friend auto operator-(to_container_iterator i, difference_type n)
164 -> CPP_broken_friend_ret(to_container_iterator)(
165 requires derived_from<iterator_category,
166 std::random_access_iterator_tag>)
171 friend auto operator-(difference_type n, to_container_iterator i)
172 -> CPP_broken_friend_ret(to_container_iterator)(
173 requires derived_from<iterator_category,
174 std::random_access_iterator_tag>)
179 friend auto operator-(to_container_iterator
const & i,
180 to_container_iterator
const & j)
181 -> CPP_broken_friend_ret(difference_type)(
182 requires derived_from<iterator_category,
183 std::random_access_iterator_tag>)
185 return i.it_ - j.it_;
188 auto operator[](difference_type n)
const
189 -> CPP_ret(reference)(
190 requires derived_from<iterator_category,
191 std::random_access_iterator_tag>)
197 template<
typename Rng,
typename Cont>
198 using to_container_iterator_t =
199 enable_if_t<(bool)range<Rng>, to_container_iterator<Rng, Cont>>;
204 template(
typename Rng)(
205 concept (range_and_not_view_)(Rng),
206 range<Rng> AND (!view_<Rng>));
210 template<
typename Rng>
211 CPP_concept range_and_not_view =
212 CPP_concept_ref(range_and_not_view_, Rng);
216 template(
typename Rng,
typename Cont)(
217 concept (convertible_to_cont_impl_)(Rng, Cont),
218 constructible_from<range_value_t<Cont>, range_reference_t<Rng>> AND
221 range_cpp17_iterator_t<Rng>,
222 range_cpp17_iterator_t<Rng>>
226 template<
typename Rng,
typename Cont>
227 CPP_concept convertible_to_cont =
228 range_and_not_view<Cont> &&
229 move_constructible<Cont> &&
230 CPP_concept_ref(detail::convertible_to_cont_impl_, Rng, Cont);
234 template(
typename Rng,
typename Cont)(
235 concept (convertible_to_cont_cont_impl_)(Rng, Cont),
236 range_and_not_view<range_value_t<Cont>> AND
240 to_container::fn<
meta::id<range_value_t<Cont>>>,
241 range_reference_t<Rng>> AND
244 to_container_iterator_t<Rng, Cont>,
245 to_container_iterator_t<Rng, Cont>>
249 template<
typename Rng,
typename Cont>
250 CPP_concept convertible_to_cont_cont =
253 move_constructible<Cont> &&
254 CPP_concept_ref(detail::convertible_to_cont_cont_impl_, Rng, Cont);
258 template<
typename C,
typename I,
typename R>
259 CPP_concept to_container_reserve =
260 reservable_with_assign<C, I> &&
263 template<
typename MetaFn,
typename Rng>
267 struct RANGES_STRUCT_WITH_ADL_BARRIER(to_container_closure_base)
270 template(
typename Rng,
typename MetaFn,
typename Fn)(
271 requires input_range<Rng> AND
272 convertible_to_cont<Rng, container_t<MetaFn, Rng>>)
273 friend constexpr auto
274 operator|(Rng && rng, to_container::closure<MetaFn, Fn> fn)
276 return static_cast<Fn &&
>(fn)(
static_cast<Rng &&
>(rng));
279 template(
typename Rng,
typename MetaFn,
typename Fn)(
280 requires input_range<Rng> AND
281 (!convertible_to_cont<Rng, container_t<MetaFn, Rng>>) AND
282 convertible_to_cont_cont<Rng, container_t<MetaFn, Rng>>)
283 friend constexpr auto
284 operator|(Rng && rng, to_container::closure<MetaFn, Fn> fn)
286 return static_cast<Fn &&
>(fn)(
static_cast<Rng &&
>(rng));
289 template<
typename MetaFn,
typename Fn,
typename Pipeable>
290 friend constexpr auto operator|(to_container::closure<MetaFn, Fn> sh,
292 -> CPP_broken_friend_ret(
293 to_container::closure<MetaFn, composed<Pipeable, Fn>>)(
294 requires is_pipeable_v<Pipeable>)
296 return to_container::closure<MetaFn, composed<Pipeable, Fn>>{
297 compose(
static_cast<Pipeable &&
>(pipe),
static_cast<Fn &&
>(sh))};
301 template<
typename MetaFn,
typename Fn>
302 struct to_container::closure
303 : to_container_closure_base
307 constexpr explicit closure(Fn fn)
308 : Fn(static_cast<Fn &&>(fn))
312 template<
typename MetaFn>
313 struct to_container::fn
316 template<
typename Cont,
typename I,
typename Rng>
317 static Cont impl(Rng && rng, std::false_type)
319 return Cont(I{ranges::begin(rng)}, I{ranges::end(rng)});
321 template<
typename Cont,
typename I,
typename Rng>
322 static auto impl(Rng && rng, std::true_type)
325 auto const rng_size = ranges::size(rng);
326 using size_type =
decltype(c.max_size());
327 using C = common_type_t<range_size_t<Rng>, size_type>;
328 RANGES_EXPECT(
static_cast<C
>(rng_size) <=
static_cast<C
>(c.max_size()));
329 c.reserve(
static_cast<size_type
>(rng_size));
330 c.assign(I{ranges::begin(rng)}, I{ranges::end(rng)});
335 template(
typename Rng)(
336 requires input_range<Rng> AND
337 convertible_to_cont<Rng, container_t<MetaFn, Rng>>)
338 container_t<MetaFn, Rng> operator()(Rng && rng)
const
340 static_assert(!is_infinite<Rng>::value,
341 "Attempt to convert an infinite range to a container.");
342 using cont_t = container_t<MetaFn, Rng>;
343 using iter_t = range_cpp17_iterator_t<Rng>;
344 using use_reserve_t =
345 meta::bool_<(bool)to_container_reserve<cont_t, iter_t, Rng>>;
346 return impl<cont_t, iter_t>(
static_cast<Rng &&
>(rng), use_reserve_t{});
348 template(
typename Rng)(
349 requires input_range<Rng> AND
350 (!convertible_to_cont<Rng, container_t<MetaFn, Rng>>) AND
351 convertible_to_cont_cont<Rng, container_t<MetaFn, Rng>>)
352 container_t<MetaFn, Rng>
operator()(Rng && rng)
const
354 static_assert(!is_infinite<Rng>::value,
355 "Attempt to convert an infinite range to a container.");
356 using cont_t = container_t<MetaFn, Rng>;
357 using iter_t = to_container_iterator<Rng, cont_t>;
358 using use_reserve_t =
359 meta::bool_<(bool)to_container_reserve<cont_t, iter_t, Rng>>;
360 return impl<cont_t, iter_t>(
static_cast<Rng &&
>(rng), use_reserve_t{});
364 template<
typename MetaFn,
typename Fn>
365 using to_container_closure = to_container::closure<MetaFn, Fn>;
367 template<
typename MetaFn>
368 using to_container_fn = to_container_closure<MetaFn, to_container::fn<MetaFn>>;
370 template<
template<
typename...>
class ContT>
373#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
375 template<
typename Rng>
376 static auto from_rng_(
int)
377 ->
decltype(ContT(range_cpp17_iterator_t<Rng>{},
378 range_cpp17_iterator_t<Rng>{}));
381 template<
typename Rng>
382 static auto from_rng_(
long)
385 template<
typename Rng>
386 using invoke =
decltype(from_range::from_rng_<Rng>(0));
388 template<
typename Rng>
399 RANGES_INLINE_VARIABLE(detail::to_container_fn<detail::from_range<std::vector>>,
409 template<
template<
typename...>
class ContT>
410 auto to(RANGES_HIDDEN_DETAIL(detail::to_container = {}))
411 -> detail::to_container_fn<detail::from_range<ContT>>
419 detail::convertible_to_cont<Rng, C>)
420 auto to(Rng && rng) -> C
422 return detail::to_container_fn<detail::from_range<ContT>>{}(
423 static_cast<Rng &&
>(rng));
427 template<
typename Cont>
428 auto to(RANGES_HIDDEN_DETAIL(detail::to_container = {}))
429 -> detail::to_container_fn<meta::id<Cont>>
435 template(
typename Cont,
typename Rng)(
436 requires range<Rng> AND detail::convertible_to_cont<Rng, Cont>)
437 auto to(Rng && rng) -> Cont
439 return detail::to_container_fn<meta::id<Cont>>{}(
static_cast<Rng &&
>(rng));
443 template(
typename Cont,
typename Rng)(
445 (!detail::convertible_to_cont<Rng, Cont>) AND
446 detail::convertible_to_cont_cont<Rng, Cont>)
447 auto to(Rng && rng) -> Cont
449 return detail::to_container_fn<meta::id<Cont>>{}(
static_cast<Rng &&
>(rng));
454 template(
template<
typename...>
class ContT,
typename T)(
455 requires detail::convertible_to_cont<std::initializer_list<T>, ContT<T>>)
456 auto to(std::initializer_list<T> il) -> ContT<T>
458 return detail::to_container_fn<detail::from_range<ContT>>{}(il);
460 template(
typename Cont,
typename T)(
461 requires detail::convertible_to_cont<std::initializer_list<T>, Cont>)
462 auto to(std::initializer_list<T> il) -> Cont
464 return detail::to_container_fn<meta::id<Cont>>{}(il);
470 using namespace _to_;
479 template<
template<
typename...>
class ContT>
480 RANGES_DEPRECATED(
"Please use ranges::to (no underscore) instead.")
481 detail::to_container_fn<detail::from_range<ContT>> to_(detail::to_container = {})
485 template(
template<
typename...>
class ContT,
typename Rng)(
486 requires range<Rng> AND
487 detail::convertible_to_cont<Rng, ContT<range_value_t<Rng>>>)
488 RANGES_DEPRECATED(
"Please use ranges::to (no underscore) instead.")
489 ContT<range_value_t<Rng>> to_(Rng && rng)
491 return static_cast<Rng &&
>(rng) | ranges::to_<ContT>();
493 template(
template<
typename...>
class ContT,
typename T)(
494 requires detail::convertible_to_cont<std::initializer_list<T>, ContT<T>>)
495 RANGES_DEPRECATED(
"Please use ranges::to (no underscore) instead.")
496 ContT<T> to_(std::initializer_list<T> il)
498 return il | ranges::to_<ContT>();
500 template<
typename Cont>
501 RANGES_DEPRECATED(
"Please use ranges::to (no underscore) instead.")
502 detail::to_container_fn<
meta::
id<Cont>> to_(detail::to_container = {})
506 template(
typename Cont,
typename Rng)(
507 requires range<Rng> AND detail::convertible_to_cont<Rng, Cont>)
508 RANGES_DEPRECATED(
"Please use ranges::to (no underscore) instead.")
511 return static_cast<Rng &&
>(rng) | ranges::to_<Cont>();
513 template(
typename Cont,
typename T)(
514 requires detail::convertible_to_cont<std::initializer_list<T>, Cont>)
515 RANGES_DEPRECATED(
"Please use ranges::to (no underscore) instead.")
516 Cont to_(std::initializer_list<T> list)
518 return list | ranges::to_<Cont>();
523 template<
typename MetaFn,
typename Fn>
524 RANGES_INLINE_VAR
constexpr bool
525 is_pipeable_v<detail::to_container_closure<MetaFn, Fn>> =
true;
528#include <range/v3/detail/epilogue.hpp>
#define CPP_broken_friend_member
INTERNAL ONLY.
Definition concepts.hpp:447
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition meta.hpp:541
Point operator*(double s, const Point &a)
Multiply point by scalar.
Definition shapes.h:250
Point operator-(const Point &a, const Point &b)
Subtract two points_ component-wise.
Definition shapes.h:244