5 #ifndef VCCC_RANGES_TO_HPP_
6 #define VCCC_RANGES_TO_HPP_
10 #include <type_traits>
53 template<
typename T,
typename N,
typename =
void>
54 struct has_mf_reserve : std::false_type {};
55 template<
typename T,
typename N>
56 struct has_mf_reserve<T, N,
void_t<decltype(
std::declval<T&>().reserve(std::declval<N>()) )>> : std::true_type {};
58 template<
typename T,
typename N,
typename =
void>
59 struct has_mf_capacity : std::false_type {};
60 template<
typename T,
typename N>
61 struct has_mf_capacity<T, N,
void_t<decltype(
std::declval<T&>().capacity() )>>
62 : same_as<decltype(std::declval<T&>().capacity()), N> {};
64 template<
typename T,
typename N,
typename =
void>
65 struct has_mf_max_size : std::false_type {};
66 template<
typename T,
typename N>
67 struct has_mf_max_size<T, N,
void_t<decltype(
std::declval<T&>().max_size() )>>
68 : same_as<decltype(std::declval<T&>().max_size()), N> {};
71 struct reservable_container
73 has_mf_reserve<Container, range_size_t<Container>>,
74 has_mf_reserve<Container, range_size_t<Container>>,
75 has_mf_reserve<Container, range_size_t<Container>>
77 template<
typename Container>
78 struct reservable_container<Container, false> : std::false_type {};
80 template<
typename C,
typename R, std::enable_if_t<conjunction<sized_range<R>, reservable_container<C>>::value,
int> = 0>
81 constexpr
void try_reserve(C& c, R&& r) {
82 c.reserve(
static_cast<range_size_t<C>
>(
ranges::size(r)));
84 template<
typename C,
typename R, std::enable_if_t<conjunction<sized_range<R>, reservable_container<C>>::value == false,
int> = 0>
85 constexpr
void try_reserve(C&, R&&) {}
87 template<
typename T,
typename U,
typename =
void>
88 struct has_mf_push_back : std::false_type {};
89 template<
typename T,
typename U>
90 struct has_mf_push_back<T, U,
void_t<decltype(
std::declval<T&>().push_back(std::declval<U>()) )>>
93 template<
typename T,
typename =
void>
94 struct has_mf_end : std::false_type {};
96 struct has_mf_end<T,
void_t<decltype(
std::declval<T&>().
end() )>>
97 : is_referencable<decltype( std::declval<T&>().end() )> {};
100 struct has_mf_insert : std::false_type {};
101 template<
typename T,
typename U>
102 struct has_mf_insert<T, U, true,
void_t<decltype(
std::declval<T&>().insert(std::declval<T&>().end(), std::declval<U>()) )>>
105 template<
typename Container,
typename Reference,
bool = conjunction<is_referencable<Container>, is_referencable<Reference>>::value>
106 struct container_insertable
108 has_mf_push_back<Container, Reference>,
109 has_mf_insert<Container, Reference>
113 constexpr
auto container_inserter(C& c) {
114 return std::back_inserter(c);
118 constexpr
auto container_inserter(C& c) {
119 return std::inserter(c, c.end());
123 struct container_compatible_range : convertible_to<range_reference_t<R>, T> {};
124 template<
typename R,
typename T>
125 struct container_compatible_range<R, T, false> : std::false_type {};
127 using vccc::detail::tag_1;
128 using vccc::detail::tag_2;
129 using vccc::detail::tag_3;
130 using vccc::detail::tag_4;
131 using vccc::detail::tag_5;
133 template<
bool ,
typename C,
typename R,
typename... Args>
134 struct ranges_to_1_a_3_impl : std::false_type {};
135 template<
typename C,
typename R,
typename... Args>
136 struct ranges_to_1_a_3_impl<true, C, R, Args...>
138 derived_from<typename cxx20_iterator_traits<iterator_t<R>>::iterator_category, input_iterator_tag>,
139 constructible_from<C, iterator_t<R>, sentinel_t<R>, Args...>
142 template<
bool ,
typename C,
typename R,
typename... Args>
143 struct ranges_to_1_a_3 : std::false_type {};
144 template<
typename C,
typename R,
typename... Args>
145 struct ranges_to_1_a_3<true, C, R, Args...>
146 : ranges_to_1_a_3_impl<
147 vccc::detail::has_typename_iterator_category< cxx20_iterator_traits<iterator_t<R>> >::value,
152 template<
typename C,
typename R,
typename... Args>
153 struct ranges_to_1_a_4
155 constructible_from<C, Args...>,
156 container_insertable<C, range_reference_t<R>>
159 template<
typename C,
typename R,
typename... Args>
160 struct ranges_to_1_a {
163 constructible_from<C, R, Args...>
::value, tag_1,
165 constructible_from<C, from_range_t, R, Args...>
::value, tag_2,
169 ranges_to_1_a_4<C, R, Args...>
::value, tag_4,
174 template<
typename C,
bool = has_
typename_type<range_reference<C>>::value>
175 struct ranges_to_1_b {
176 using tag = tag_else;
179 struct ranges_to_1_b<C, true> {
180 using tag = std::conditional_t<input_range<range_reference_t<C>>
::value, tag_5, tag_else>;
184 template<
typename T,
typename U>
185 struct tuple_convertible_to : convertible_to<T, U> {};
186 #if __cplusplus < 202302L
187 template<
typename T1,
typename T2,
typename U1,
typename U2>
188 struct tuple_convertible_to<
std::tuple<T1, T2>, std::pair<U1, U2>>
189 : conjunction<convertible_to<T1, U1>, convertible_to<T2, U2>> {};
192 template<
typename C,
typename R,
typename... Args>
194 : std::conditional_t<
196 negation<input_range<C>>,
197 tuple_convertible_to<range_reference_t<R>, range_value_t<C>>
199 ranges_to_1_a<C, R, Args...>,
203 template<
typename C,
typename R,
typename... Args>
204 using ranges_to_1_tag =
typename ranges_to_1<C, R, Args...>::tag;
206 template<
typename C,
typename R,
typename... Args>
207 constexpr C to_1(tag_1, R&& r, Args&&... args) {
208 return C(std::forward<R>(r), std::forward<Args>(args)...);
211 template<
typename C,
typename R,
typename... Args>
212 constexpr C to_1(tag_2, R&& r, Args&&... args) {
213 return C(
from_range, std::forward<R>(r), std::forward<Args>(args)...);
216 template<
typename C,
typename R,
typename... Args>
217 constexpr C to_1_kv(std::false_type, R&& r, Args&&... args) {
221 template<
typename C,
typename R,
typename... Args>
222 constexpr C to_1_kv(std::true_type, R&& r, Args&&... args) {
223 return to_1_kv<C>(std::false_type{}, std::forward<R>(r) |
views::transform([](
auto&& tup) {
224 return range_value_t<C>(std::get<0>(std::forward<decltype(tup)>(tup)), std::get<1>(std::forward<decltype(tup)>(tup)));
225 }), std::forward<Args>(args)...);
228 template<
typename C,
typename R,
typename... Args>
229 constexpr C to_1(tag_3, R&& r, Args&&... args) {
230 #if __cplusplus < 202302L
231 return to_1_kv<C>(is_specialization<range_reference_t<R>, std::tuple>{}, std::forward<R>(r), std::forward<Args>(args)...);
237 template<
typename C,
typename R,
typename... Args>
238 constexpr C to_1(tag_4, R&& r, Args&&... args) {
239 C c(std::forward<Args>(args)...);
240 detail::try_reserve(c, std::forward<R>(r));
241 ranges::copy(std::forward<R>(r), detail::container_inserter<range_reference_t<R>>(c));
245 template<
typename C,
typename R,
typename... Args>
246 constexpr C to_1(tag_5, R&& r, Args&&... args);
252 struct ranges_to_input_iterator {
254 using value_type = range_value_t<R>;
255 using difference_type = std::ptrdiff_t;
256 using pointer = std::add_pointer_t<range_reference_t<R>>;
257 using reference = range_reference_t<R>;
260 pointer operator->()
const;
261 ranges_to_input_iterator& operator++();
262 ranges_to_input_iterator operator++(
int);
263 bool operator==(
const ranges_to_input_iterator&)
const;
285 struct is_key_value_range
288 has_typename_type<range_key<R>>,
289 has_typename_type<range_mapped<R>>
292 template<
template<
typename...>
class C>
293 struct maybe_key_value_container
295 bool_constant<(mandatory_template_arity<C>::value == 2)>,
296 bool_constant<(template_arity<C>::value > 2)>
300 template<
typename...>
class C,
305 has_typename_type<iter_val<R>>,
306 has_typename_type<iter_key<R>>
309 struct iter_key_val_category {
310 using category = return_category<0>;
312 template<
template<
typename...>
class C,
typename R,
typename... Args>
313 struct iter_key_val_category<C, R, type_sequence<Args...>, true> {
316 std::is_constructible<
317 C<iter_key_t<R>, iter_val_t<R>, Args...>,
318 ranges_to_input_iterator<R>&&, ranges_to_input_iterator<R>&&
320 return_category<2, C<iter_key_t<R>, iter_val_t<R>, Args...>>,
325 template<
template<
typename...>
class C,
typename R,
typename ArgSeq>
326 struct DEDUCE_EXPR_IMPL_KV;
327 template<
template<
typename...>
class C,
typename R,
typename... Args>
328 struct DEDUCE_EXPR_IMPL_KV<C, R, type_sequence<Args...>> {
331 std::is_constructible<
332 C<range_key_t<R>, range_mapped_t<R>, Args...>,
334 return_category<1, C<range_key_t<R>, range_mapped_t<R>, Args...>>,
336 std::is_constructible<
337 C<range_key_t<R>, range_mapped_t<R>, Args...>,
338 from_range_t, R&&, Args&&...>
::value,
339 return_category<1, C<range_key_t<R>, range_mapped_t<R>, Args...>>,
341 std::is_constructible<
342 C<range_key_t<R>, range_mapped_t<R>, Args...>,
343 ranges_to_input_iterator<R>&&, ranges_to_input_iterator<R>&&>
::value,
344 return_category<1, C<range_key_t<R>, range_mapped_t<R>, Args...>>,
345 typename iter_key_val_category<C, R, type_sequence<Args...>>::category
349 template<
template<
typename...>
class C,
typename R,
typename ArgSeq,
bool = has_typename_type<iter_val<R>>
::value>
350 struct iter_val_category {
351 using category = return_category<0>;
353 template<
template<
typename...>
class C,
typename R,
typename... Args>
354 struct iter_val_category<C, R, type_sequence<Args...>, true> {
357 std::is_constructible<
358 C<iter_val_t<std::decay_t<R>>, Args...>,
359 ranges_to_input_iterator<R>&&, ranges_to_input_iterator<R>&&
361 return_category<2, C<iter_val_t<R>, Args...>>,
365 template<
template<
typename...>
class C,
typename R,
typename ArgSeq>
366 struct DEDUCE_EXPR_IMPL_T;
367 template<
template<
typename...>
class C,
typename R,
typename... Args>
368 struct DEDUCE_EXPR_IMPL_T<C, R, type_sequence<Args...>> {
371 std::is_constructible<
372 C<range_value_t<R>, Args...>,
374 return_category<1, C<range_value_t<R>, Args...>>,
376 std::is_constructible<
377 C<range_value_t<R>, Args...>,
378 from_range_t, R&&, Args&&... >
::value,
379 return_category<1, C<range_value_t<R>, Args...>>,
381 std::is_constructible<
382 C<range_value_t<R>, Args...>,
383 ranges_to_input_iterator<R>&&, ranges_to_input_iterator<R>&& >
::value,
384 return_category<1, C<range_value_t<R>, Args...>>,
385 typename iter_val_category<C, R, type_sequence<Args...>>::category
390 template<
typename...>
class C,
395 maybe_key_value_container<C>,
396 is_key_value_range<R>
399 struct DEDUCE_EXPR_IMPL;
401 template<
template<
typename...>
class C,
typename R,
typename ArgSeq>
402 struct DEDUCE_EXPR_IMPL<C, R, ArgSeq, true> : DEDUCE_EXPR_IMPL_KV<C, R, ArgSeq> {};
403 template<
template<
typename...>
class C,
typename R,
typename ArgSeq>
404 struct DEDUCE_EXPR_IMPL<C, R, ArgSeq, false> : DEDUCE_EXPR_IMPL_T<C, R, ArgSeq> {};
406 template<
template<
typename...>
class C,
typename R,
typename... Args>
407 using DEDUCE_EXPR_CATEGORY =
typename DEDUCE_EXPR_IMPL<C, R, type_sequence<Args...>>::category;
441 template<
typename C,
typename R,
typename... Args, std::enable_if_t<conjunction<
445 constexpr std::enable_if_t<(detail::ranges_to_1_tag<C, R, Args...>
::value > 0), C>
446 to(R&& r, Args&&... args) {
447 return detail::to_1<C>(detail::ranges_to_1_tag<C, R, Args...>{}, std::forward<R>(r), std::forward<Args>(args)...);
451 template<
template<
typename...>
class C,
typename R,
typename... Args, std::enable_if_t<
453 constexpr
typename detail::DEDUCE_EXPR_CATEGORY<C, R, Args...>::return_type
454 to(R&& r, Args&&... args) {
455 using DEDUCE_EXPR =
typename detail::DEDUCE_EXPR_CATEGORY<C, R, Args...>::return_type;
456 return vccc::ranges::to<DEDUCE_EXPR>(std::forward<R>(r), std::forward<Args>(args)...);
461 template<
typename C,
typename R,
typename... Args>
462 constexpr C to_1(tag_5, R&& r, Args&&... args) {
464 return to<range_value_t<C>>(std::forward<decltype(elem)>(elem));
465 }), std::forward<Args>(args)...);
468 template<
typename C,
typename... Args>
469 class to_adaptor_closure :
public range_adaptor_closure<to_adaptor_closure<C, Args...>> {
471 template<
typename... T>
472 constexpr
explicit to_adaptor_closure(in_place_t, T&&... arg)
473 : tup_(
std::forward<T>(arg)...) {}
476 constexpr
auto operator()(R&& r)
const& {
477 return call(std::forward<R>(r), std::index_sequence_for<Args...>{});
481 constexpr
auto operator()(R&& r) && {
482 return std::move(*this).call(std::forward<R>(r), std::index_sequence_for<Args...>{});
486 template<
typename R, std::size_t... I>
487 constexpr
auto call(R&& r, std::index_sequence<I...>)
const& {
488 return vccc::ranges::to<C>(std::forward<R>(r), std::get<I>(tup_)...);
490 template<
typename R, std::size_t... I>
491 constexpr
auto call(R&& r, std::index_sequence<I...>) && {
492 return vccc::ranges::to<C>(std::forward<R>(r), std::get<I>(std::move(tup_))...);
495 std::tuple<Args...> tup_;
498 template<
template<
typename...>
class>
499 struct template_type_holder;
501 template<
template<
typename...>
class C,
typename... Args>
502 class to_adaptor_closure<template_type_holder<C>, Args...>
503 :
public range_adaptor_closure<to_adaptor_closure<template_type_holder<C>, Args...>>
506 template<
typename... T>
507 constexpr
explicit to_adaptor_closure(in_place_t, T&&... arg)
508 : tup_(
std::forward<T>(arg)...) {}
511 constexpr
auto operator()(R&& r)
const& {
512 return call(std::forward<R>(r), std::index_sequence_for<Args...>{});
516 constexpr
auto operator()(R&& r) && {
517 return std::move(*this).call(std::forward<R>(r), std::index_sequence_for<Args...>{});
521 template<
typename R, std::size_t... I>
522 constexpr
auto call(R&& r, std::index_sequence<I...>)
const& {
523 return vccc::ranges::to<C>(std::forward<R>(r), std::get<I>(tup_)...);
525 template<
typename R, std::size_t... I>
526 constexpr
auto call(R&& r, std::index_sequence<I...>) && {
527 return vccc::ranges::to<C>(std::forward<R>(r), std::get<I>(std::move(tup_))...);
530 std::tuple<Args...> tup_;
533 template<
typename...>
536 struct to_check_arg<> : std::true_type {};
537 template<
typename T,
typename... U>
538 struct to_check_arg<T, U...> : negation<input_range<T>> {};
544 template<
typename C,
typename... Args, std::enable_if_t<conjunction<
545 detail::to_check_arg<Args...>,
548 constexpr detail::to_adaptor_closure<C, std::decay_t<Args>...>
to(Args&&... args) {
549 return detail::to_adaptor_closure<C, std::decay_t<Args>...>(
in_place, std::forward<Args>(args)...);
554 template<
template<
typename...>
class C,
typename... Args, std::enable_if_t<
555 detail::to_check_arg<Args...>
::value,
int> = 0>
556 constexpr detail::to_adaptor_closure<detail::template_type_holder<C>, std::decay_t<Args>...>
558 return detail::to_adaptor_closure<detail::template_type_holder<C>, std::decay_t<Args>...>(
in_place, std::forward<Args>(args)...);
constexpr VCCC_INLINE_OR_STATIC detail::copy_niebloid copy
Definition: copy.hpp:69
std::input_iterator_tag input_iterator_tag
Definition: iterator_tag.hpp:15
constexpr MatrixMulMatrix< E1, E2 > operator*(const MatrixBase< E1 > &lhs, const MatrixBase< E2 > &rhs)
Definition: matrix_mul_matrix.hpp:77
constexpr std::enable_if_t<(detail::ranges_to_1_tag< C, R, Args... >::value > 0), C > to(R &&r, Args &&... args)
Constructs an object of type C from the elements of r
Definition: to.hpp:446
constexpr VCCC_INLINE_OR_STATIC detail::transform_niebloid transform
Definition: transform.hpp:61
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
constexpr VCCC_INLINE_OR_STATIC detail::size_niebloid size
returns the size of a container or array
Definition: size.hpp:145
constexpr VCCC_INLINE_OR_STATIC from_range_t from_range
Definition: from_range.hpp:28
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
constexpr VCCC_INLINE_OR_STATIC in_place_t in_place
Definition: in_place.hpp:47
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
constexpr bool operator==(const MatrixBase< E1 > &lhs, const MatrixBase< E2 > &rhs)
Definition: mat_expr_operations.hpp:15