31#ifndef ETL_RANGES_INCLUDED
32#define ETL_RANGES_INCLUDED
54 namespace private_ranges
56 template <
typename T,
typename Enable =
void>
57 struct iterator_trait;
60 struct iterator_trait<T, etl::enable_if_t<etl::is_class_v<T>>>
62 using iterator =
typename etl::conditional_t< etl::is_const_v<T>,
typename T::const_iterator,
typename T::iterator>;
63 using const_iterator =
typename T::const_iterator;
65 using value_type =
typename etl::iterator_traits<const_iterator>::value_type;
66 using difference_type =
typename etl::iterator_traits<const_iterator>::difference_type;
67 using pointer =
typename etl::iterator_traits<const_iterator>::pointer;
68 using reference =
typename etl::iterator_traits<const_iterator>::reference;
72 struct iterator_trait< T, etl::enable_if_t<etl::is_reference_v<T> && !etl::is_array_v<etl::remove_reference_t<T>>>>
75 typename etl::conditional_t< etl::is_const_v<etl::remove_reference_t<T>>,
typename etl::remove_reference<T>::type::const_iterator,
76 typename etl::remove_reference<T>::type::iterator>;
77 using const_iterator =
typename etl::remove_reference<T>::type::const_iterator;
79 using value_type =
typename etl::iterator_traits<iterator>::value_type;
80 using difference_type =
typename etl::iterator_traits<iterator>::difference_type;
81 using pointer =
typename etl::iterator_traits<iterator>::pointer;
82 using reference =
typename etl::iterator_traits<iterator>::reference;
86 struct iterator_trait< T, etl::enable_if_t<etl::is_array_v<etl::remove_reference_t<T>>>>
88 using value_type =
typename etl::remove_all_extents<etl::remove_reference_t<T>>::type;
89 using iterator = value_type*;
90 using const_iterator =
const value_type*;
91 using difference_type = ptrdiff_t;
92 using pointer =
const value_type*;
93 using reference =
const value_type&;
102 view_interface() =
default;
104 constexpr bool empty()
const
111 return static_cast<const D*
>(
this)->
begin();
116 return static_cast<const D*
>(
this)->
end();
119 operator bool()
const
126 return static_cast<size_t>(etl::distance(
cbegin(),
cend()));
129 constexpr decltype(
auto) front()
131 return *(
static_cast<D*
>(
this)->begin());
134 constexpr decltype(
auto) front()
const
139 template <
typename D2 = D,
140 etl::enable_if_t< etl::is_bidirectional_iterator_concept< decltype(etl::declval<const D2&>().begin())>::value,
int> = 0>
141 constexpr decltype(
auto) back()
143 return *(
static_cast<D*
>(
this)->end() - 1);
146 template <
typename D2 = D,
147 etl::enable_if_t< etl::is_bidirectional_iterator_concept< decltype(etl::declval<const D2&>().begin())>::value,
int> = 0>
148 constexpr decltype(
auto) back()
const
150 return *etl::prev(
cend());
153 constexpr decltype(
auto)
operator[](
size_t i)
155 auto it{
static_cast<D*
>(
this)->
begin()};
160 template < typename D2 = D, etl::enable_if_t<etl::is_random_access_iterator< decltype(etl::declval<const D2&>().begin())>::value,
int> = 0>
161 constexpr decltype(
auto) operator[](
size_t i)
163 return static_cast<D*
>(
this)->
begin()[i];
166 template < typename D2 = D, etl::enable_if_t<etl::is_random_access_iterator< decltype(etl::declval<const D2&>().begin())>::value,
int> = 0>
167 constexpr decltype(
auto) operator[](
size_t i)
const
180 return **(
static_cast<const I*
>(
this));
184 template <
class I,
class S = I>
185 class subrange :
public etl::ranges::view_interface<subrange<I, S>>
195 constexpr I
begin()
const
200 constexpr S
end()
const
205 constexpr subrange& advance(etl::iter_difference_t<I> n)
207 etl::advance(_begin, n);
211 constexpr subrange prev(etl::iter_difference_t<I> n = 1)
213 auto result = subrange{_begin, _end};
218 constexpr subrange next(etl::iter_difference_t<I> n = 1)
220 auto result = subrange{_begin, _end};
231 template <
class I,
class S>
232 subrange(I, S) -> subrange<I, S>;
235 class empty_view :
public etl::ranges::view_interface<empty_view<T>>
241 constexpr empty_view() =
default;
243 static constexpr iterator
begin() noexcept
248 static constexpr iterator
end() noexcept
253 static constexpr T*
data() noexcept
258 static constexpr size_t size() noexcept
263 static constexpr bool empty() noexcept
271 constexpr dangling() noexcept = default;
273 template <class... Args>
274 constexpr dangling(Args&&...) noexcept
280 constexpr bool enable_borrowed_range =
false;
283 struct is_borrowed_range
285 static constexpr bool value = etl::is_range_v<T> || etl::ranges::enable_borrowed_range<T>;
288 template <
typename T>
289 inline constexpr bool is_borrowed_range_v = is_borrowed_range<T>::value;
292 using borrowed_iterator_t = etl::conditional_t<etl::ranges::is_borrowed_range_v<T>, etl::ranges::iterator_t<T>, etl::ranges::dangling>;
295 using borrowed_subrange_t =
296 etl::conditional_t<etl::ranges::is_borrowed_range_v<T>, etl::ranges::subrange<etl::ranges::iterator_t<T>>, etl::ranges::dangling>;
301 constexpr empty_view<T> empty{};
305 class single_view :
public etl::ranges::view_interface<single_view<T>>
309 using value_type = T;
310 using iterator = value_type*;
311 using const_iterator =
const value_type*;
313 constexpr single_view(
const T& t) noexcept
318 constexpr single_view(T&& t) noexcept
319 : _value(etl::move(t))
323 constexpr single_view(
const single_view<T>& other)
324 : _value(other._value)
328 constexpr single_view(single_view<T>&& other)
329 : _value(etl::move(other._value))
333 constexpr single_view& operator=(
const single_view<T>& other)
335 _value = other._value;
339 constexpr single_view& operator=(single_view<T>&& other)
341 _value = etl::move(other._value);
345 constexpr iterator
begin() noexcept
350 constexpr const_iterator
begin() const noexcept
355 constexpr iterator
end() noexcept
360 constexpr const_iterator
end() const noexcept
365 constexpr const T*
data() const noexcept
370 constexpr T*
data() noexcept
375 constexpr size_t size() const noexcept
380 constexpr bool empty() const noexcept
391 single_view(T) -> single_view<T>;
395 namespace private_views
399 template <
typename T>
400 constexpr auto operator()(T&& t)
const
402 return etl::ranges::single_view(t);
407 inline constexpr private_views::single single;
410 template <
typename T>
411 struct iota_iterator :
public range_iterator<iota_iterator<T>>
415 using value_type = T;
416 using difference_type = ptrdiff_t;
418 using reference = T&;
420 using iterator_category = ETL_OR_STD::random_access_iterator_tag;
422 constexpr explicit iota_iterator(T i)
427 constexpr iota_iterator(
const iota_iterator& other)
432 iota_iterator& operator++()
438 iota_iterator operator++(
int)
440 iota_iterator tmp = *
this;
445 iota_iterator& operator--()
451 iota_iterator operator--(
int)
453 iota_iterator tmp = *
this;
458 iota_iterator& operator+=(difference_type n)
464 iota_iterator
operator+(difference_type n)
const
466 return iota_iterator{
static_cast<value_type
>(_i + n)};
469 iota_iterator
operator-(difference_type n)
const
471 return iota_iterator{
static_cast<value_type
>(_i - n)};
474 difference_type
operator-(iota_iterator other)
const
476 return _i - other._i;
479 iota_iterator& operator=(
const iota_iterator& other)
485 constexpr bool operator==(
const iota_iterator& other)
const
487 return _i == other._i;
490 constexpr bool operator!=(
const iota_iterator& other)
const
492 return _i != other._i;
511 class iota_view :
public etl::ranges::view_interface<iota_view<T>>
515 using iterator = iota_iterator<T>;
516 using const_iterator = iota_iterator<T>;
518 iota_view() =
default;
520 constexpr explicit iota_view(T value, T bound = etl::numeric_limits<T>::max())
526 constexpr iterator
begin() const noexcept
528 return iterator(_value);
531 constexpr iterator
end() const noexcept
533 return iterator(_bound);
536 constexpr size_t size() const noexcept
538 if (_bound == etl::numeric_limits<T>::max())
540 return etl::numeric_limits<T>::max();
542 return static_cast<size_t>(_bound - _value);
545 constexpr bool empty() const noexcept
547 return _value == _bound;
557 iota_view(T) -> iota_view<T>;
561 namespace private_views
565 template <
typename T,
typename B>
566 constexpr auto operator()(T&& t, B&& b)
const
568 return etl::ranges::iota_view(t, b);
573 inline constexpr private_views::iota
iota;
576 template <
typename T,
typename B = T>
577 struct repeat_iterator :
public range_iterator<repeat_iterator<T, B>>
581 using value_type = T;
582 using difference_type = ptrdiff_t;
584 using reference = T&;
586 using iterator_category = ETL_OR_STD::random_access_iterator_tag;
588 constexpr repeat_iterator()
594 constexpr explicit repeat_iterator(T value, B i = etl::numeric_limits<B>::max())
600 constexpr repeat_iterator(
const repeat_iterator& other) =
default;
602 repeat_iterator& operator++()
608 repeat_iterator operator++(
int)
610 repeat_iterator tmp(*
this);
615 repeat_iterator& operator--()
621 repeat_iterator operator--(
int)
623 repeat_iterator tmp(*
this);
628 repeat_iterator& operator+=(difference_type n)
630 _i -=
static_cast<B
>(n);
634 repeat_iterator
operator+(difference_type n)
const
636 return repeat_iterator{_value,
static_cast<B
>(_i -
static_cast<B
>(n))};
639 repeat_iterator
operator-(difference_type n)
const
641 return repeat_iterator{_value,
static_cast<B
>(_i +
static_cast<B
>(n))};
644 difference_type
operator-(repeat_iterator other)
const
646 return other._i - _i;
649 repeat_iterator& operator=(
const repeat_iterator& other)
652 _value = other._value;
656 constexpr bool operator==(
const repeat_iterator& other)
const
658 return _i == other._i;
661 constexpr bool operator!=(
const repeat_iterator& other)
const
663 return _i != other._i;
682 template <
class T,
class B = T>
683 class repeat_view :
public etl::ranges::view_interface<repeat_view<T>>
687 using iterator = repeat_iterator<T, B>;
688 using const_iterator = repeat_iterator<T, B>;
690 repeat_view() =
default;
692 constexpr explicit repeat_view(T value, B bound = etl::numeric_limits<B>::max())
698 constexpr iterator
begin() const noexcept
700 return iterator(_value, _bound);
703 constexpr iterator
end() const noexcept
705 return iterator(_value, 0);
708 constexpr size_t size() const noexcept
710 return static_cast<size_t>(_bound);
713 constexpr bool empty() const noexcept
724 template <
class T,
class B = T>
725 repeat_view(T, B = B()) -> repeat_view<T, B>;
729 namespace private_views
733 template <
typename T,
typename B>
734 constexpr auto operator()(T&& t, B&& b)
const
736 return etl::ranges::repeat_view(t, b);
741 inline constexpr private_views::repeat repeat;
745 class range_adapter_closure_base
750 template <
class Range,
class Closure,
751 typename = etl::enable_if_t< etl::is_base_of_v<range_adapter_closure_base, etl::decay_t<Closure>>
752 && etl::is_invocable_v<etl::decay_t<Closure>, Range>>>
753 friend auto operator|(Range&& r, Closure&& c)
755 return etl::forward<Closure>(c)(etl::forward<Range>(r));
759 template <
class Derived>
760 class range_adapter_closure :
public range_adapter_closure_base
764 template <
class Range>
765 class ref_view :
public etl::ranges::view_interface<ref_view<Range>>
769 using iterator =
typename etl::ranges::private_ranges::iterator_trait<Range>::iterator;
770 using const_iterator =
typename etl::ranges::private_ranges::iterator_trait< Range>::const_iterator;
771 using pointer =
typename etl::ranges::private_ranges::iterator_trait<Range>::pointer;
778 constexpr Range& base()
const
783 constexpr iterator
begin()
const
785 return iterator(ETL_OR_STD::begin(*_r));
788 constexpr iterator
end()
const
790 return iterator(ETL_OR_STD::end(*_r));
793 constexpr bool empty()
const
798 constexpr size_t size()
const
800 return static_cast<size_t>(etl::distance(
begin(),
end()));
803 constexpr pointer
data()
const
813 template <
class Range>
814 ref_view(Range&) -> ref_view<Range>;
816 struct ref_range_adapter_closure :
public range_adapter_closure<ref_range_adapter_closure>
818 template <
typename Range>
819 using target_view_type = ref_view<Range>;
821 ref_range_adapter_closure() =
default;
823 template <
typename Range>
824 ref_view<Range> operator()(Range& r)
826 return ref_view<Range>(r);
832 namespace private_views
836 template <
class Range>
837 constexpr auto operator()(Range& r)
const
839 return ranges::ref_view(r);
842 constexpr auto operator()()
const
844 return ranges::ref_range_adapter_closure();
849 inline constexpr private_views::ref ref;
852 template <
class Range>
853 class owning_view :
public etl::ranges::view_interface<owning_view<Range>>
857 using iterator =
typename etl::ranges::private_ranges::iterator_trait<Range>::iterator;
858 using const_iterator =
typename etl::ranges::private_ranges::iterator_trait< Range>::const_iterator;
859 using pointer =
typename etl::ranges::private_ranges::iterator_trait<Range>::pointer;
861 owning_view() =
default;
863 owning_view(owning_view&& other) =
default;
865 constexpr owning_view(Range&& r)
870 owning_view& operator=(
const owning_view&) =
delete;
872 owning_view& operator=(owning_view&& other)
874 _r = etl::move(other._r);
878 constexpr Range& base() noexcept
883 constexpr iterator
begin()
const
885 return iterator(ETL_OR_STD::begin(_r));
888 constexpr iterator
end()
const
890 return iterator(ETL_OR_STD::end(_r));
893 constexpr bool empty()
const
898 constexpr size_t size()
const
900 return static_cast<size_t>(etl::distance(
begin(),
end()));
903 constexpr pointer
data()
917 template <
class Range>
918 owning_view(Range&&) -> owning_view<Range>;
920 struct owning_range_adapter_closure :
public range_adapter_closure<owning_range_adapter_closure>
922 template <
typename Range,
typename CleanRange = etl::remove_reference_t<Range>>
923 using target_view_type = owning_view<CleanRange>;
925 owning_range_adapter_closure() =
default;
927 template <
typename Range,
typename CleanRange = etl::remove_reference_t<Range>>
928 owning_view<CleanRange> operator()(Range&& r)
930 return owning_view<CleanRange>(etl::move(r));
936 namespace private_views
940 template <
class Range>
941 constexpr auto operator()(Range&& r)
const
943 return ranges::owning_view(etl::forward<Range>(r));
946 constexpr auto operator()()
const
948 return ranges::owning_range_adapter_closure();
953 inline constexpr private_views::owning owning;
958 namespace private_views
960 struct all :
public range_adapter_closure_base
962 template <
class Range,
963 etl::enable_if_t<etl::is_base_of_v< etl::ranges::view_interface<etl::decay_t<Range>>, etl::decay_t<Range>>,
int> = 0>
964 constexpr etl::decay_t<Range> operator()(Range&& r)
const
969 template <
class Range,
970 etl::enable_if_t<!etl::is_base_of_v< etl::ranges::view_interface<etl::decay_t<Range>>, etl::decay_t<Range>>,
int> = 0>
971 constexpr auto operator()(Range&& r)
const
973 if constexpr (etl::is_lvalue_reference_v<Range>)
975 return etl::ranges::ref_view(etl::forward<Range>(r));
979 return etl::ranges::owning_view(etl::forward<Range>(r));
985 inline constexpr private_views::all all;
987 template <
typename R>
988 using all_t =
decltype(views::all(etl::declval<R>()));
991 template <
class Range,
class Pred>
992 class filter_iterator
996 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
998 using iterator =
typename trait::iterator;
999 using const_iterator =
typename trait::const_iterator;
1000 using value_type =
typename trait::value_type;
1001 using difference_type =
typename trait::difference_type;
1005 using reference =
decltype(*etl::declval<iterator&>());
1006 using pointer = etl::remove_reference_t<reference>*;
1008 using iterator_category = ETL_OR_STD::bidirectional_iterator_tag;
1010 filter_iterator(iterator it, iterator it_end,
const Pred& p)
1016 while (_it != _it_end && !_p(*_it))
1022 filter_iterator(
const filter_iterator& other)
1024 , _it_begin{other._it_begin}
1025 , _it_end{other._it_end}
1028 while (_it != _it_end && !_p(*_it))
1034 filter_iterator& operator++()
1037 while (_it != _it_end && !_p(*_it))
1044 filter_iterator operator++(
int)
1046 filter_iterator tmp = *
this;
1049 while (_it != _it_end && !_p(*_it))
1057 filter_iterator& operator--()
1060 while (_it != _it_begin && !_p(*_it))
1067 filter_iterator operator--(
int)
1069 filter_iterator tmp = *
this;
1072 while (_it != _it_begin && !_p(*_it))
1080 filter_iterator& operator+=(
size_t n)
1082 for (
size_t i = 0; i < n; i++)
1093 filter_iterator& operator-=(
size_t n)
1095 for (
size_t i = 0; i < n; i++)
1097 if (_it != _it_begin)
1106 filter_iterator& operator=(
const filter_iterator& other)
1109 _it_begin = other._it_begin;
1110 _it_end = other._it_end;
1111 ETL_ASSERT(&_p == &other._p, ETL_ERROR_GENERIC(
"Predicates need to be the same"));
1120 bool operator==(
const filter_iterator& other)
const
1122 return other._it == _it;
1125 bool operator!=(
const filter_iterator& other)
const
1127 return !(*
this == other);
1138 template <
class Range,
class Pred>
1139 constexpr typename filter_iterator<Range, Pred>::difference_type
operator-(
const filter_iterator<Range, Pred>& lhs,
1140 const filter_iterator<Range, Pred>& rhs)
1142 typename filter_iterator<Range, Pred>::difference_type result{0};
1143 filter_iterator<Range, Pred> it_up{rhs};
1144 while (it_up != lhs)
1152 template <
class Range,
typename Pred>
1153 class filter_view :
public etl::ranges::view_interface<filter_view<Range, Pred>>
1157 using iterator = filter_iterator<Range, Pred>;
1158 using const_iterator = filter_iterator<Range, Pred>;
1160 filter_view(Range&& r,
const Pred& pred)
1166 constexpr Range& base() const&
1171 constexpr const Pred& pred()
const
1176 constexpr const_iterator
begin()
const
1178 return const_iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), _pred);
1181 constexpr const_iterator
end()
const
1183 return const_iterator(ETL_OR_STD::end(_r), ETL_OR_STD::end(_r), _pred);
1192 template <
class Range,
typename Pred>
1193 filter_view(Range&&, Pred) -> filter_view<views::all_t<Range>, Pred>;
1195 template <
typename Pred>
1196 struct filter_range_adapter_closure :
public range_adapter_closure<filter_range_adapter_closure<Pred>>
1198 template <
typename Range>
1199 using target_view_type = filter_view<Range, Pred>;
1201 filter_range_adapter_closure(
const Pred& p)
1206 template <
typename Range>
1207 constexpr auto operator()(Range&& r)
1209 return filter_view(views::all(etl::forward<Range>(r)), _p);
1217 namespace private_views
1221 template <
class Range,
typename Pred>
1222 constexpr auto operator()(Range&& r,
const Pred& p)
const
1224 return filter_view(views::all(etl::forward<Range>(r)), p);
1227 template <
typename Pred>
1228 constexpr auto operator()(
const Pred& p)
const
1230 return ranges::filter_range_adapter_closure<Pred>(p);
1235 inline constexpr private_views::filter filter;
1238 template <
class Range,
class Fun>
1239 class transform_iterator
1243 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
1245 using iterator =
typename trait::iterator;
1246 using const_iterator =
typename trait::const_iterator;
1247 using difference_type =
typename trait::difference_type;
1252 using reference =
decltype(etl::declval<const Fun&>()(*etl::declval<const_iterator&>()));
1253 using value_type = etl::remove_cvref_t<reference>;
1254 using pointer = void;
1256 using iterator_category = ETL_OR_STD::forward_iterator_tag;
1258 transform_iterator(const_iterator it,
const Fun& f)
1264 transform_iterator(
const transform_iterator& other)
1270 transform_iterator& operator++()
1276 transform_iterator operator++(
int)
1278 transform_iterator tmp = *
this;
1283 transform_iterator& operator=(
const transform_iterator& other)
1286 ETL_ASSERT(&_f == &other._f, ETL_ERROR_GENERIC(
"Transform functions need to be the same"));
1295 bool operator==(
const transform_iterator& other)
const
1297 return other._it == _it;
1300 bool operator!=(
const transform_iterator& other)
const
1302 return !(*
this == other);
1311 template <
class Range,
typename Fun>
1312 class transform_view :
public etl::ranges::view_interface<transform_view<Range, Fun>>
1316 using iterator = transform_iterator<Range, Fun>;
1317 using const_iterator = transform_iterator<Range, Fun>;
1319 transform_view(Range&& r,
const Fun& fun)
1325 constexpr Range& base() const&
1330 constexpr const_iterator
begin()
const
1332 return const_iterator(ETL_OR_STD::begin(_r), _fun);
1335 constexpr const_iterator
end()
const
1337 return const_iterator(ETL_OR_STD::end(_r), _fun);
1340 constexpr size_t size()
const
1342 return static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
1351 template <
class Range,
typename Fun>
1352 transform_view(Range&&, Fun) -> transform_view<views::all_t<Range>, Fun>;
1354 template <
typename Fun>
1355 struct transform_range_adapter_closure :
public range_adapter_closure<transform_range_adapter_closure<Fun>>
1357 template <
typename Range>
1358 using target_view_type = transform_view<Range, Fun>;
1360 transform_range_adapter_closure(
const Fun& f)
1365 template <
typename Range>
1366 constexpr auto operator()(Range&& r)
1368 return transform_view(views::all(etl::forward<Range>(r)), _f);
1376 namespace private_views
1380 template <
class Range,
typename Fun>
1381 constexpr auto operator()(Range&& r,
const Fun& f)
const
1383 return transform_view(views::all(etl::forward<Range>(r)), f);
1386 template <
typename Fun>
1387 constexpr auto operator()(
const Fun& f)
const
1389 return ranges::transform_range_adapter_closure<Fun>(f);
1394 inline constexpr private_views::transform transform;
1397 template <
class Range>
1398 class as_rvalue_view :
public etl::ranges::view_interface<as_rvalue_view<Range>>
1402 using iterator =
typename etl::move_iterator< typename etl::ranges::private_ranges::iterator_trait<Range>::iterator>;
1404 as_rvalue_view(
const as_rvalue_view& other) =
default;
1406 as_rvalue_view(Range&& r)
1411 constexpr Range& base()
const
1416 constexpr iterator
begin()
const
1418 return iterator(ETL_OR_STD::begin(_r));
1421 constexpr iterator
end()
const
1423 return iterator(ETL_OR_STD::end(_r));
1426 constexpr size_t size()
const
1428 return static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
1436 template <
class Range>
1437 as_rvalue_view(Range&&) -> as_rvalue_view<views::all_t<Range>>;
1439 struct as_rvalue_range_adapter_closure :
public range_adapter_closure<as_rvalue_range_adapter_closure>
1441 template <
typename Range>
1442 using target_view_type = as_rvalue_view<Range>;
1444 as_rvalue_range_adapter_closure() =
default;
1446 template <
typename Range>
1447 constexpr auto operator()(Range&& r)
1449 return as_rvalue_view(views::all(etl::forward<Range>(r)));
1455 namespace private_views
1457 struct as_rvalue :
public range_adapter_closure_base
1459 template <
class Range>
1460 constexpr auto operator()(Range&& r)
const
1462 return as_rvalue_view(views::all(etl::forward<Range>(r)));
1465 constexpr auto operator()()
const
1467 return ranges::as_rvalue_range_adapter_closure();
1472 inline constexpr private_views::as_rvalue as_rvalue;
1475 template <
class Range>
1476 class as_const_view :
public etl::ranges::view_interface<as_const_view<Range>>
1480 using iterator =
typename etl::ranges::private_ranges::iterator_trait< Range>::const_iterator;
1481 using const_iterator = iterator;
1483 as_const_view(
const as_const_view& other) =
default;
1485 as_const_view(Range&& r)
1490 constexpr Range& base()
const
1495 constexpr iterator
begin()
const
1497 return ETL_OR_STD::cbegin(_r);
1500 constexpr iterator
end()
const
1502 return ETL_OR_STD::cend(_r);
1505 constexpr size_t size()
const
1507 return static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
1515 template <
class Range>
1516 as_const_view(Range&&) -> as_const_view<views::all_t<Range>>;
1518 struct as_const_range_adapter_closure :
public range_adapter_closure<as_const_range_adapter_closure>
1520 template <
typename Range>
1521 using target_view_type = as_const_view<Range>;
1523 as_const_range_adapter_closure() =
default;
1525 template <
typename Range>
1526 constexpr auto operator()(Range&& r)
1528 return as_const_view(views::all(etl::forward<Range>(r)));
1534 namespace private_views
1536 struct as_const :
public range_adapter_closure_base
1538 template <
class Range>
1539 constexpr auto operator()(Range&& r)
const
1541 return as_const_view(views::all(etl::forward<Range>(r)));
1544 constexpr auto operator()()
const
1546 return ranges::as_const_range_adapter_closure();
1551 inline constexpr private_views::as_const
as_const;
1559 namespace private_ranges
1561 template <
typename T>
1562 struct cache_latest_cache
1564 cache_latest_cache()
1570 cache_latest_cache(
const cache_latest_cache&) =
delete;
1571 cache_latest_cache& operator=(
const cache_latest_cache&) =
delete;
1573 bool has_value()
const
1578 void set(
const T& v)
1602 template <
class Range>
1603 class cache_latest_iterator
1607 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
1609 using iterator =
typename trait::iterator;
1610 using const_iterator =
typename trait::const_iterator;
1611 using value_type =
typename trait::value_type;
1612 using difference_type =
typename trait::difference_type;
1613 using pointer = value_type*;
1614 using reference = value_type&;
1616 using iterator_category = ETL_OR_STD::forward_iterator_tag;
1618 cache_latest_iterator() =
default;
1620 cache_latest_iterator(const_iterator it, private_ranges::cache_latest_cache<value_type>* cache)
1626 cache_latest_iterator(
const cache_latest_iterator& other)
1628 , _cache(other._cache)
1632 cache_latest_iterator& operator++()
1642 cache_latest_iterator operator++(
int)
1644 cache_latest_iterator tmp = *
this;
1649 cache_latest_iterator& operator=(
const cache_latest_iterator& other)
1652 _cache = other._cache;
1658 if (_cache && !_cache->has_value())
1662 return _cache->value();
1665 pointer operator->()
const
1670 bool operator==(
const cache_latest_iterator& other)
const
1672 return other._it == _it;
1675 bool operator!=(
const cache_latest_iterator& other)
const
1677 return !(*
this == other);
1682 mutable const_iterator _it;
1683 private_ranges::cache_latest_cache<value_type>* _cache;
1692 template <
class Range>
1693 class cache_latest_view :
public etl::ranges::view_interface<cache_latest_view<Range>>
1697 using iterator = cache_latest_iterator<Range>;
1698 using const_iterator = cache_latest_iterator<Range>;
1699 using value_type =
typename etl::ranges::private_ranges::iterator_trait<Range>::value_type;
1701 cache_latest_view(Range&& r)
1707 cache_latest_view(
const cache_latest_view& other)
1713 constexpr Range& base() const&
1718 constexpr iterator
begin()
const
1721 return iterator(ETL_OR_STD::begin(_r), &_cache);
1724 constexpr iterator
end()
const
1726 return iterator(ETL_OR_STD::end(_r), &_cache);
1729 constexpr size_t size()
const
1731 return static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
1737 mutable private_ranges::cache_latest_cache<value_type> _cache;
1740 template <
class Range>
1741 cache_latest_view(Range&&) -> cache_latest_view<views::all_t<Range>>;
1743 struct cache_latest_range_adapter_closure :
public range_adapter_closure<cache_latest_range_adapter_closure>
1745 template <
typename Range>
1746 using target_view_type = cache_latest_view<Range>;
1748 cache_latest_range_adapter_closure() =
default;
1750 template <
typename Range>
1751 constexpr auto operator()(Range&& r)
1753 return cache_latest_view(views::all(etl::forward<Range>(r)));
1759 namespace private_views
1761 struct cache_latest :
public range_adapter_closure_base
1763 template <
class Range>
1764 constexpr auto operator()(Range&& r)
const
1766 return cache_latest_view(views::all(etl::forward<Range>(r)));
1769 constexpr auto operator()()
const
1771 return ranges::cache_latest_range_adapter_closure();
1776 inline constexpr private_views::cache_latest cache_latest;
1779 template <
class Range>
1780 class reverse_view :
public etl::ranges::view_interface<reverse_view<Range>>
1784 using iterator = ETL_OR_STD::reverse_iterator< typename etl::ranges::private_ranges::iterator_trait<Range>::iterator>;
1785 using const_iterator = ETL_OR_STD::reverse_iterator< typename etl::ranges::private_ranges::iterator_trait<Range>::const_iterator>;
1786 using difference_type =
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type;
1788 constexpr reverse_view(Range&& r)
1793 reverse_view(
const reverse_view& other) =
default;
1795 constexpr Range base() const&
1800 constexpr iterator
begin()
const
1802 return iterator(ETL_OR_STD::end(_r));
1805 constexpr iterator
end()
const
1807 return iterator(ETL_OR_STD::begin(_r));
1810 constexpr size_t size()
const
1812 return static_cast<size_t>(etl::distance(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r)));
1820 template <
class Range>
1821 reverse_view(Range&&) -> reverse_view<views::all_t<Range>>;
1823 template <
typename T>
1828 template <
typename Range>
1829 struct is_reverse_view<reverse_view<Range>> : etl::true_type
1835 namespace private_views
1837 struct reverse :
public range_adapter_closure_base
1839 template <
class Range>
1840 constexpr auto operator()(Range&& r)
const
1842 if constexpr (is_reverse_view<etl::remove_cv_t< etl::remove_reference_t<Range>>>::value)
1848 return reverse_view(views::all(etl::forward<Range>(r)));
1854 inline constexpr private_views::reverse reverse;
1857 template <
class Range>
1858 class drop_view :
public etl::ranges::view_interface<drop_view<Range>>
1862 using iterator =
typename etl::ranges::private_ranges::iterator_trait<Range>::iterator;
1863 using const_iterator =
typename etl::ranges::private_ranges::iterator_trait< Range>::const_iterator;
1864 using difference_type =
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type;
1866 constexpr drop_view(Range&& r,
size_t drop_n)
1869 , _begin_cache{ETL_OR_STD::
end(_r)}
1870 , _begin_cache_valid{false}
1874 drop_view(
const drop_view& other) =
default;
1876 constexpr Range base() const&
1881 constexpr iterator
begin()
const
1883 if (!_begin_cache_valid)
1885 _begin_cache = drop_begin();
1886 _begin_cache_valid =
true;
1888 return _begin_cache;
1891 constexpr iterator
end()
const
1893 return iterator(ETL_OR_STD::end(_r));
1896 constexpr size_t size()
const
1898 if (!_begin_cache_valid)
1900 _begin_cache = drop_begin();
1901 _begin_cache_valid =
true;
1903 return static_cast<size_t>(etl::distance(_begin_cache, ETL_OR_STD::end(_r)));
1908 constexpr iterator drop_begin()
const
1910 iterator result{ETL_OR_STD::end(_r)};
1911 if (
static_cast<difference_type
>(_drop_n) < etl::distance(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r)))
1913 result = ETL_OR_STD::begin(_r);
1914 etl::advance(result, _drop_n);
1921 mutable iterator _begin_cache;
1922 mutable bool _begin_cache_valid;
1925 template <
class Range>
1926 drop_view(Range&&) -> drop_view<views::all_t<Range>>;
1928 struct drop_range_adapter_closure :
public range_adapter_closure<drop_range_adapter_closure>
1930 template <
typename Range>
1931 using target_view_type = drop_view<Range>;
1933 constexpr drop_range_adapter_closure(
size_t drop_n)
1938 template <
typename Range>
1939 constexpr auto operator()(Range&& r)
const
1941 return drop_view(views::all(etl::forward<Range>(r)), _drop_n);
1944 const size_t _drop_n;
1949 namespace private_views
1953 template <
class Range>
1954 constexpr auto operator()(Range&& r,
size_t drop_n)
const
1956 return drop_view(views::all(etl::forward<Range>(r)), drop_n);
1959 constexpr auto operator()(
size_t drop_n)
const
1961 return ranges::drop_range_adapter_closure(drop_n);
1966 inline constexpr private_views::drop drop;
1969 template <
class Range,
class Pred>
1970 class drop_while_view :
public etl::ranges::view_interface<drop_while_view<Range, Pred>>
1974 using const_iterator =
typename etl::ranges::private_ranges::iterator_trait< Range>::const_iterator;
1975 using difference_type =
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type;
1977 constexpr drop_while_view(Range&& r, Pred pred)
1981 , _begin_cache_valid{false}
1985 constexpr const Range base() const&
1990 constexpr const Pred& pred()
const
1995 constexpr const_iterator
begin()
const
1997 if (!_begin_cache_valid)
1999 const_iterator result{ETL_OR_STD::cbegin(_r)};
2000 while (result != ETL_OR_STD::cend(_r) && _pred(*result))
2004 _begin_cache = result;
2005 _begin_cache_valid =
true;
2007 return _begin_cache;
2010 constexpr const_iterator
end()
const
2012 return const_iterator(ETL_OR_STD::cend(_r));
2019 mutable const_iterator _begin_cache;
2020 mutable bool _begin_cache_valid;
2023 template <
class Range,
class Pred>
2024 drop_while_view(Range&&, Pred) -> drop_while_view<views::all_t<Range>, Pred>;
2026 template <
typename Pred>
2027 struct drop_while_range_adapter_closure :
public range_adapter_closure<drop_while_range_adapter_closure<Pred>>
2029 template <
typename Range>
2030 using target_view_type = drop_while_view<Range, Pred>;
2032 constexpr drop_while_range_adapter_closure(Pred& pred)
2037 template <
typename Range>
2038 constexpr auto operator()(Range&& r)
const
2040 return drop_while_view(views::all(etl::forward<Range>(r)), _pred);
2048 namespace private_views
2052 template <
class Range,
class Pred>
2053 constexpr auto operator()(Range&& r, Pred pred)
const
2055 return drop_while_view(views::all(etl::forward<Range>(r)), pred);
2058 template <
class Pred>
2059 constexpr auto operator()(Pred pred)
const
2061 return ranges::drop_while_range_adapter_closure(pred);
2066 inline constexpr private_views::drop_while drop_while;
2071 namespace private_views
2073 template <
typename T>
2074 constexpr T min(T a, T b)
2076 return a < b ? a : b;
2080 template <
class Range>
2081 class take_view :
public etl::ranges::view_interface<take_view<Range>>
2085 using iterator =
typename etl::ranges::private_ranges::iterator_trait<Range>::iterator;
2086 using const_iterator =
typename etl::ranges::private_ranges::iterator_trait< Range>::const_iterator;
2087 using difference_type =
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type;
2089 constexpr take_view(Range&& r, ranges::range_difference_t<Range> take_n)
2091 , _take_n{private_views::min<ranges::range_difference_t<Range>>(take_n, etl::distance(ETL_OR_STD::
cbegin(r), ETL_OR_STD::
cend(r)))}
2095 take_view(
const take_view& other) =
default;
2097 constexpr Range base() const&
2102 constexpr iterator
begin()
const
2104 return iterator(ETL_OR_STD::begin(_r));
2107 constexpr iterator
end()
const
2109 iterator result{
begin()};
2110 etl::advance(result, _take_n);
2114 constexpr ranges::range_difference_t<Range>
size()
const
2122 ranges::range_difference_t<Range> _take_n;
2125 template <
class Range>
2126 take_view(Range&&, ranges::range_difference_t<Range>) -> take_view<views::all_t<Range>>;
2128 struct take_range_adapter_closure :
public range_adapter_closure<take_range_adapter_closure>
2130 template <
typename Range>
2131 using target_view_type = take_view<Range>;
2133 template <
class DifferenceType>
2134 constexpr take_range_adapter_closure(DifferenceType take_n)
2135 : _take_n{static_cast<size_t>(take_n)}
2139 template <
typename Range>
2140 constexpr auto operator()(Range&& r)
const
2142 return take_view(views::all(etl::forward<Range>(r)),
static_cast<ranges::range_difference_t<Range>
>(_take_n));
2145 const size_t _take_n;
2150 namespace private_views
2154 template <
class Range>
2155 constexpr auto operator()(Range&& r, ranges::range_difference_t<Range> take_n)
const
2157 return take_view(views::all(etl::forward<Range>(r)), take_n);
2160 template <
class DifferenceType>
2161 constexpr auto operator()(DifferenceType take_n)
const
2163 return ranges::take_range_adapter_closure(take_n);
2168 inline constexpr private_views::take take;
2171 template <
class Range,
class Pred>
2172 class take_while_view :
public etl::ranges::view_interface<take_while_view<Range, Pred>>
2176 using iterator =
typename etl::ranges::private_ranges::iterator_trait<Range>::iterator;
2177 using const_iterator =
typename etl::ranges::private_ranges::iterator_trait< Range>::const_iterator;
2178 using difference_type =
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type;
2180 constexpr take_while_view(Range&& r, Pred pred)
2182 , _pred{etl::move(pred)}
2184 , _end_cache_valid{false}
2188 constexpr const Range base() const&
2193 constexpr const Pred& pred()
const
2198 constexpr auto begin()
const
2200 return ETL_OR_STD::begin(_r);
2203 constexpr auto end()
const
2205 if (!_end_cache_valid)
2207 iterator result{ETL_OR_STD::begin(_r)};
2208 while (result != ETL_OR_STD::end(_r) && _pred(*result))
2212 _end_cache = result;
2213 _end_cache_valid =
true;
2222 mutable iterator _end_cache;
2223 mutable bool _end_cache_valid;
2226 template <
class Range,
class Pred>
2227 take_while_view(Range&&, Pred) -> take_while_view<views::all_t<Range>, Pred>;
2229 template <
typename Pred>
2230 struct take_while_range_adapter_closure :
public range_adapter_closure<take_while_range_adapter_closure<Pred>>
2232 template <
typename Range>
2233 using target_view_type = take_while_view<Range, Pred>;
2235 constexpr take_while_range_adapter_closure(Pred pred)
2236 : _pred{etl::move(pred)}
2240 template <
typename Range>
2241 constexpr auto operator()(Range&& r)
const
2243 return take_while_view(views::all(etl::forward<Range>(r)), _pred);
2251 namespace private_views
2255 template <
class Range,
class Pred>
2256 constexpr auto operator()(Range&& r, Pred&& pred)
const
2258 return take_while_view(views::all(etl::forward<Range>(r)), etl::forward<Pred>(pred));
2261 template <
class Pred>
2262 constexpr auto operator()(Pred&& pred)
const
2264 return ranges::take_while_range_adapter_closure(etl::forward<Pred>(pred));
2269 inline constexpr private_views::take_while take_while;
2272 template <
class Range>
2277 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
2279 using iterator =
typename trait::iterator;
2280 using const_iterator =
typename trait::const_iterator;
2281 using difference_type =
typename trait::difference_type;
2283 using iterator_category = ETL_OR_STD::forward_iterator_tag;
2285 using InnerRange =
decltype(*(ETL_OR_STD::begin(etl::declval<Range>())));
2286 using inner_trait =
typename etl::ranges::private_ranges::iterator_trait<InnerRange>;
2287 using inner_iterator =
typename inner_trait::iterator;
2292 using reference =
decltype(*etl::declval<const inner_iterator&>());
2293 using value_type = etl::remove_cvref_t<reference>;
2294 using pointer =
typename inner_trait::pointer;
2296 join_iterator(iterator it, iterator it_end)
2299 , _inner_it(it != it_end ? ETL_OR_STD::
begin(*it) : inner_iterator{})
2300 , _inner_it_end(it != it_end ? ETL_OR_STD::
end(*it) : inner_iterator{})
2305 join_iterator(
const join_iterator& other) =
default;
2307 join_iterator& operator++()
2309 if (_inner_it != _inner_it_end)
2319 join_iterator operator++(
int)
2321 join_iterator tmp{*
this};
2323 if (_inner_it != _inner_it_end)
2333 join_iterator& operator=(
const join_iterator& other)
2336 _it_end = other._it_end;
2337 _inner_it = other._inner_it;
2338 _inner_it_end = other._inner_it_end;
2350 constexpr bool operator==(
const join_iterator& other)
const
2352 return (_it == other._it && _inner_it == other._inner_it) || (_it == _it_end && other._it == other._it_end);
2355 constexpr bool operator!=(
const join_iterator& other)
const
2357 return !(*
this == other);
2362 void adjust_iterator()
2364 while (_it != _it_end && _inner_it == _inner_it_end)
2369 _inner_it = ETL_OR_STD::begin((*_it));
2370 _inner_it_end = ETL_OR_STD::end((*_it));
2377 inner_iterator _inner_it;
2378 inner_iterator _inner_it_end;
2381 template <
class Range>
2382 class join_view :
public etl::ranges::view_interface<join_view<Range>>
2386 using iterator = join_iterator<Range>;
2387 using const_iterator = join_iterator<Range>;
2389 join_view(Range&& r)
2394 constexpr Range base() const&
2399 constexpr iterator
begin()
const
2401 return iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r));
2404 constexpr iterator
end()
const
2406 return iterator(ETL_OR_STD::end(_r), ETL_OR_STD::end(_r));
2414 struct join_range_adapter_closure :
public range_adapter_closure<join_range_adapter_closure>
2416 template <
typename Range>
2417 using target_view_type = join_view<Range>;
2419 join_range_adapter_closure() =
default;
2421 template <
typename Range>
2422 constexpr auto operator()(Range&& r)
2424 return join_view(views::all(etl::forward<Range>(r)));
2428 template <
class Range>
2429 explicit join_view(Range&&) -> join_view<views::all_t<Range>>;
2433 namespace private_views
2435 struct join :
public range_adapter_closure_base
2437 template <
class Range>
2438 constexpr auto operator()(Range&& r)
const
2440 return join_view(views::all(etl::forward<Range>(r)));
2443 constexpr auto operator()()
const
2445 return ranges::join_range_adapter_closure();
2450 inline constexpr private_views::join join;
2453 namespace private_ranges
2464 template <
typename InnerRef,
typename PatternRef>
2465 struct join_with_reference
2467 using value_type = etl::common_type_t<etl::remove_cvref_t<InnerRef>, etl::remove_cvref_t<PatternRef>>;
2469 static constexpr bool same_underlying = etl::is_same<etl::remove_cvref_t<InnerRef>, etl::remove_cvref_t<PatternRef>>::value;
2470 static constexpr bool both_lvalue = etl::is_lvalue_reference<InnerRef>::value && etl::is_lvalue_reference<PatternRef>::value;
2471 static constexpr bool any_const =
2472 etl::is_const<etl::remove_reference_t<InnerRef>>::value || etl::is_const<etl::remove_reference_t<PatternRef>>::value;
2474 using type = etl::conditional_t<same_underlying && both_lvalue, etl::conditional_t<any_const, const value_type&, value_type&>, value_type>;
2478 template <
class Range,
class Pattern>
2479 class join_with_iterator
2483 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
2485 using iterator =
typename trait::iterator;
2486 using const_iterator =
typename trait::const_iterator;
2487 using difference_type =
typename trait::difference_type;
2489 using iterator_category = ETL_OR_STD::forward_iterator_tag;
2491 using InnerRange =
decltype(*(ETL_OR_STD::begin(etl::declval<Range>())));
2492 using inner_trait =
typename etl::ranges::private_ranges::iterator_trait<InnerRange>;
2493 using inner_iterator =
typename inner_trait::iterator;
2498 using pattern_iterator =
decltype(ETL_OR_STD::begin(etl::declval<const Pattern&>()));
2504 using inner_reference =
decltype(*etl::declval<const inner_iterator&>());
2505 using pattern_reference =
decltype(*etl::declval<const pattern_iterator&>());
2507 using value_type = etl::common_type_t<etl::remove_cvref_t<inner_reference>, etl::remove_cvref_t<pattern_reference>>;
2508 using reference =
typename etl::ranges::private_ranges::join_with_reference<inner_reference, pattern_reference>::type;
2509 using pointer =
typename inner_trait::pointer;
2511 join_with_iterator(iterator it, iterator it_end,
const Pattern& pattern)
2514 , _inner_it(it != it_end ? ETL_OR_STD::
begin(*it) : inner_iterator{})
2515 , _inner_it_end(it != it_end ? ETL_OR_STD::
end(*it) : inner_iterator{})
2517 , _pattern_it(ETL_OR_STD::
end(pattern))
2518 , _pattern_it_end(ETL_OR_STD::
end(pattern))
2523 join_with_iterator(
const join_with_iterator& other) =
default;
2525 join_with_iterator& operator++()
2527 if (_pattern_it != _pattern_it_end)
2531 else if (_inner_it != _inner_it_end)
2541 join_with_iterator operator++(
int)
2543 join_with_iterator tmp{*
this};
2545 if (_pattern_it != _pattern_it_end)
2549 else if (_inner_it != _inner_it_end)
2559 join_with_iterator& operator=(
const join_with_iterator& other)
2562 _it_end = other._it_end;
2563 _inner_it = other._inner_it;
2564 _inner_it_end = other._inner_it_end;
2565 _pattern_it = other._pattern_it;
2566 _pattern_it_end = other._pattern_it_end;
2575 if (_pattern_it != _pattern_it_end)
2577 return *_pattern_it;
2582 constexpr bool operator==(
const join_with_iterator& other)
const
2584 return (_it == other._it && _inner_it == other._inner_it && _pattern_it == other._pattern_it) || (_it == _it_end);
2587 constexpr bool operator!=(
const join_with_iterator& other)
const
2589 return !(*
this == other);
2594 void adjust_iterator()
2596 if (_it != _it_end && _inner_it == _inner_it_end && _pattern_it == _pattern_it_end)
2601 _pattern_it = ETL_OR_STD::begin(_pattern);
2602 _pattern_it_end = ETL_OR_STD::end(_pattern);
2603 _inner_it = ETL_OR_STD::begin(*_it);
2604 _inner_it_end = ETL_OR_STD::end(*_it);
2611 inner_iterator _inner_it;
2612 inner_iterator _inner_it_end;
2613 const Pattern& _pattern;
2614 pattern_iterator _pattern_it;
2615 pattern_iterator _pattern_it_end;
2618 template <
class Range,
class Pattern>
2619 class join_with_view :
public etl::ranges::view_interface<join_with_view<Range, Pattern>>
2623 using iterator = join_with_iterator<Range, Pattern>;
2624 using const_iterator = join_with_iterator<Range, Pattern>;
2626 join_with_view(Range&& r, Pattern&& pattern)
2628 , _pattern{etl::move(pattern)}
2632 constexpr Range base() const&
2637 constexpr iterator
begin()
const
2639 return iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), _pattern);
2642 constexpr iterator
end()
const
2644 return iterator(ETL_OR_STD::end(_r), ETL_OR_STD::end(_r), _pattern);
2654 template <
class Range,
class Pattern>
2655 join_with_view(Range&&, Pattern&&) -> join_with_view<views::all_t<Range>, views::all_t<Pattern>>;
2658 template <
class Range>
2659 join_with_view(Range&&, etl::ranges::range_value_t<etl::ranges::range_reference_t<Range>>)
2660 -> join_with_view<views::all_t<Range>, etl::ranges::single_view<etl::ranges::range_value_t< etl::ranges::range_reference_t<Range>>>>;
2662 namespace private_ranges
2664 template <
class Pattern>
2665 constexpr auto make_pattern(Pattern&& pattern)
2667 if constexpr (etl::is_base_of_v<etl::ranges::view_interface<Pattern>, Pattern>)
2669 return etl::forward<Pattern>(pattern);
2673 return etl::ranges::single_view<Pattern>(etl::forward<Pattern>(pattern));
2677 template <
class Pattern>
2678 constexpr auto make_pattern(
const Pattern& pattern)
2680 if constexpr (etl::is_array_v<etl::remove_reference_t<Pattern>> || etl::is_range_v<etl::remove_reference_t<Pattern>>)
2682 return views::all(pattern);
2686 return etl::ranges::single_view<etl::remove_reference_t<Pattern>>(pattern);
2691 template <
class Pattern>
2692 struct join_with_range_adapter_closure :
public range_adapter_closure<join_with_range_adapter_closure<Pattern>>
2694 template <
typename Range>
2695 using target_view_type = join_with_view<Range, Pattern>;
2697 join_with_range_adapter_closure(
const Pattern& pattern)
2702 template <
typename Range>
2703 constexpr auto operator()(Range&& r)
2705 return join_with_view(views::all(etl::forward<Range>(r)), private_ranges::make_pattern<Pattern>(_pattern));
2708 const Pattern& _pattern;
2713 namespace private_views
2717 template <
class Range,
class Pattern>
2718 constexpr auto operator()(Range&& r, Pattern&& pattern)
const
2720 return join_with_view(views::all(etl::forward<Range>(r)),
2721 views::all(etl::ranges::private_ranges::make_pattern<Pattern>(etl::forward<Pattern>(pattern))));
2724 template <
class Pattern>
2725 constexpr auto operator()(
const Pattern& pattern)
const
2727 return ranges::join_with_range_adapter_closure(pattern);
2732 inline constexpr private_views::join_with join_with;
2735 template <
class Range,
class Pattern>
2736 class split_iterator
2740 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
2742 using iterator =
typename trait::iterator;
2743 using const_iterator =
typename trait::const_iterator;
2744 using difference_type =
typename trait::difference_type;
2746 using iterator_category = ETL_OR_STD::forward_iterator_tag;
2748 using pattern_trait =
typename etl::ranges::private_ranges::iterator_trait<Pattern>;
2749 using pattern_const_iterator =
typename pattern_trait::const_iterator;
2751 using value_type = etl::ranges::subrange<iterator>;
2752 using pointer = value_type*;
2753 using reference = value_type;
2755 split_iterator(iterator it, iterator it_end,
const Pattern& pattern,
bool is_end =
false)
2759 , _next(find_next())
2760 , _trailing_empty(!is_end && _it == _it_end)
2764 split_iterator(
const split_iterator& other) =
default;
2766 split_iterator& operator++()
2773 auto pat_size = etl::distance(ETL_OR_STD::cbegin(_pattern), ETL_OR_STD::cend(_pattern));
2774 for (difference_type i = 0; i < pat_size && _it != _it_end; ++i)
2778 _next = find_next();
2781 if (_it == _it_end && !_trailing_empty)
2783 _trailing_empty =
true;
2789 _trailing_empty =
false;
2795 split_iterator operator++(
int)
2797 split_iterator tmp{*
this};
2802 split_iterator& operator=(
const split_iterator& other)
2805 _it_end = other._it_end;
2806 _next = other._next;
2807 _trailing_empty = other._trailing_empty;
2813 return value_type(_it, _next);
2816 constexpr bool operator==(
const split_iterator& other)
const
2818 if (_it == _it_end && other._it == other._it_end)
2820 return _trailing_empty == other._trailing_empty;
2822 return _it == other._it;
2825 constexpr bool operator!=(
const split_iterator& other)
const
2827 return !(*
this == other);
2832 iterator find_next()
const
2834 auto pat_begin = ETL_OR_STD::cbegin(_pattern);
2835 auto pat_end = ETL_OR_STD::cend(_pattern);
2836 auto pat_size = etl::distance(pat_begin, pat_end);
2842 if (result != _it_end)
2849 for (
auto search = _it; search != _it_end; ++search)
2855 while (p != pat_end)
2857 if (s == _it_end || !(*s == *p))
2876 const Pattern& _pattern;
2880 bool _trailing_empty;
2883 template <
class Range,
class Pattern>
2884 class split_view :
public etl::ranges::view_interface<split_view<Range, Pattern>>
2888 using iterator = split_iterator<Range, Pattern>;
2889 using const_iterator = split_iterator<Range, Pattern>;
2891 split_view(Range&& r, Pattern&& pattern)
2893 , _pattern{etl::move(pattern)}
2897 constexpr Range& base() const&
2902 constexpr const Pattern& pattern()
const
2907 constexpr iterator
begin()
const
2909 return iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), _pattern);
2912 constexpr iterator
end()
const
2914 auto it = iterator(ETL_OR_STD::end(_r), ETL_OR_STD::end(_r), _pattern,
true);
2925 template <
class Range,
class Pattern, etl::enable_if_t<etl::is_
class_v<etl::decay_t<Pattern>>,
int> = 0>
2926 split_view(Range&&, Pattern&&) -> split_view<views::all_t<Range>, views::all_t<Pattern>>;
2929 template <
class Range,
class Pattern, etl::enable_if_t<!etl::is_
class_v<etl::decay_t<Pattern>>,
int> = 0>
2930 split_view(Range&&, Pattern&&) -> split_view<views::all_t<Range>, etl::ranges::single_view<etl::decay_t<Pattern>>>;
2932 template <
class Pattern>
2933 struct split_range_adapter_closure :
public range_adapter_closure<split_range_adapter_closure<Pattern>>
2935 template <
typename Range>
2936 using target_view_type = split_view<Range, Pattern>;
2938 split_range_adapter_closure(
const Pattern& pattern)
2943 template <
typename Range>
2944 constexpr auto operator()(Range&& r)
2947 if constexpr (etl::is_class_v<etl::decay_t<Pattern>>)
2949 return split_view(views::all(etl::forward<Range>(r)), views::all(_pattern));
2953 return split_view(views::all(etl::forward<Range>(r)), etl::ranges::single_view(_pattern));
2957 const Pattern& _pattern;
2962 namespace private_views
2967 template <
class Range,
class Pattern, etl::enable_if_t<etl::is_
class_v<etl::decay_t<Pattern>>,
int> = 0>
2968 constexpr auto operator()(Range&& r, Pattern&& pattern)
const
2970 return split_view(views::all(etl::forward<Range>(r)), views::all(etl::forward<Pattern>(pattern)));
2974 template <
class Range,
class Pattern, etl::enable_if_t<!etl::is_
class_v<etl::decay_t<Pattern>>,
int> = 0>
2975 constexpr auto operator()(Range&& r, Pattern&& pattern)
const
2977 return split_view(views::all(etl::forward<Range>(r)), etl::ranges::single_view(pattern));
2981 template <
class Pattern>
2982 constexpr auto operator()(
const Pattern& pattern)
const
2984 return ranges::split_range_adapter_closure<Pattern>(pattern);
2989 inline constexpr private_views::split split;
3000 template <
class Range,
class Pattern>
3001 class lazy_split_view;
3006 template <
class Range,
class Pattern>
3007 class lazy_split_inner_range
3011 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
3012 using iterator_type =
typename trait::iterator;
3013 using const_iterator_type =
typename trait::const_iterator;
3014 using value_type =
typename trait::value_type;
3016 using pattern_trait =
typename etl::ranges::private_ranges::iterator_trait<Pattern>;
3017 using pattern_const_iterator =
typename pattern_trait::const_iterator;
3023 using value_type =
typename trait::value_type;
3024 using difference_type =
typename trait::difference_type;
3025 using reference =
decltype(*etl::declval<iterator_type&>());
3026 using pointer = etl::remove_reference_t<reference>*;
3027 using iterator_category = ETL_OR_STD::forward_iterator_tag;
3029 iterator() =
default;
3031 iterator(iterator_type current, iterator_type segment_end,
bool is_end)
3032 : _current_it(current)
3033 , _segment_end(segment_end)
3034 , _is_end(is_end || (current == segment_end))
3038 constexpr decltype(
auto)
operator*()
const
3040 return *_current_it;
3043 pointer operator->()
const
3045 return &(*_current_it);
3048 iterator& operator++()
3051 if (_current_it == _segment_end)
3058 iterator operator++(
int)
3060 iterator tmp{*
this};
3065 constexpr bool operator==(
const iterator& other)
const
3067 if (_is_end && other._is_end)
3071 if (_is_end != other._is_end)
3075 return _current_it == other._current_it;
3078 constexpr bool operator!=(
const iterator& other)
const
3080 return !(*
this == other);
3085 iterator_type _current_it{};
3086 iterator_type _segment_end{};
3087 bool _is_end =
true;
3090 using const_iterator = iterator;
3092 lazy_split_inner_range(iterator_type segment_begin, iterator_type segment_end)
3093 : _segment_begin(segment_begin)
3094 , _segment_end(segment_end)
3098 iterator
begin()
const
3100 return iterator(_segment_begin, _segment_end,
false);
3103 iterator
end()
const
3105 return iterator(_segment_end, _segment_end,
true);
3110 return _segment_begin == _segment_end;
3115 iterator_type _segment_begin;
3116 iterator_type _segment_end;
3122 template <
class Range,
class Pattern>
3123 class lazy_split_iterator
3127 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
3129 using source_iterator =
typename trait::iterator;
3130 using const_iterator =
typename trait::const_iterator;
3131 using difference_type =
typename trait::difference_type;
3133 using iterator_category = ETL_OR_STD::forward_iterator_tag;
3135 using pattern_trait =
typename etl::ranges::private_ranges::iterator_trait<Pattern>;
3136 using pattern_const_iterator =
typename pattern_trait::const_iterator;
3138 using value_type = lazy_split_inner_range<Range, Pattern>;
3139 using pointer = value_type*;
3140 using reference = value_type;
3142 lazy_split_iterator(source_iterator it, source_iterator it_end,
const Pattern& pattern,
bool is_end =
false)
3146 , _next(find_next())
3147 , _trailing_empty(!is_end && _it == _it_end)
3151 lazy_split_iterator(
const lazy_split_iterator& other) =
default;
3153 lazy_split_iterator& operator=(
const lazy_split_iterator& other)
3156 _it_end = other._it_end;
3157 _next = other._next;
3158 _trailing_empty = other._trailing_empty;
3162 lazy_split_iterator& operator++()
3169 auto pat_size = etl::distance(ETL_OR_STD::cbegin(_pattern), ETL_OR_STD::cend(_pattern));
3170 for (difference_type i = 0; i < pat_size && _it != _it_end; ++i)
3174 _next = find_next();
3177 if (_it == _it_end && !_trailing_empty)
3179 _trailing_empty =
true;
3185 _trailing_empty =
false;
3191 lazy_split_iterator operator++(
int)
3193 lazy_split_iterator tmp{*
this};
3202 return value_type(_it, _next);
3205 constexpr bool operator==(
const lazy_split_iterator& other)
const
3207 if (_it == _it_end && other._it == other._it_end)
3209 return _trailing_empty == other._trailing_empty;
3211 return _it == other._it;
3214 constexpr bool operator!=(
const lazy_split_iterator& other)
const
3216 return !(*
this == other);
3223 source_iterator find_next()
const
3225 auto pat_begin = ETL_OR_STD::cbegin(_pattern);
3226 auto pat_end = ETL_OR_STD::cend(_pattern);
3227 auto pat_size = etl::distance(pat_begin, pat_end);
3233 if (result != _it_end)
3240 for (
auto search = _it; search != _it_end; ++search)
3246 while (p != pat_end)
3248 if (s == _it_end || !(*s == *p))
3265 source_iterator _it;
3266 source_iterator _it_end;
3267 const Pattern& _pattern;
3268 source_iterator _next;
3269 bool _trailing_empty;
3272 template <
class Range,
class Pattern>
3273 class lazy_split_view :
public etl::ranges::view_interface<lazy_split_view<Range, Pattern>>
3277 using iterator = lazy_split_iterator<Range, Pattern>;
3278 using const_iterator = lazy_split_iterator<Range, Pattern>;
3280 lazy_split_view(Range&& r, Pattern&& pattern)
3282 , _pattern{etl::move(pattern)}
3286 constexpr Range& base() const&
3291 constexpr const Pattern& pattern()
const
3296 constexpr iterator
begin()
const
3298 return iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), _pattern);
3301 constexpr iterator
end()
const
3303 return iterator(ETL_OR_STD::end(_r), ETL_OR_STD::end(_r), _pattern,
true);
3313 template <
class Range,
class Pattern, etl::enable_if_t<etl::is_
class_v<etl::decay_t<Pattern>>,
int> = 0>
3314 lazy_split_view(Range&&, Pattern&&) -> lazy_split_view<views::all_t<Range>, views::all_t<Pattern>>;
3317 template <
class Range,
class Pattern, etl::enable_if_t<!etl::is_
class_v<etl::decay_t<Pattern>>,
int> = 0>
3318 lazy_split_view(Range&&, Pattern&&) -> lazy_split_view<views::all_t<Range>, etl::ranges::single_view<etl::decay_t<Pattern>>>;
3320 template <
class Pattern>
3321 struct lazy_split_range_adapter_closure :
public range_adapter_closure<lazy_split_range_adapter_closure<Pattern>>
3323 template <
typename Range>
3324 using target_view_type = lazy_split_view<Range, Pattern>;
3326 lazy_split_range_adapter_closure(
const Pattern& pattern)
3331 template <
typename Range>
3332 constexpr auto operator()(Range&& r)
3334 if constexpr (etl::is_class_v<etl::decay_t<Pattern>>)
3336 return lazy_split_view(views::all(etl::forward<Range>(r)), views::all(_pattern));
3340 return lazy_split_view(views::all(etl::forward<Range>(r)), etl::ranges::single_view(_pattern));
3344 const Pattern& _pattern;
3349 namespace private_views
3354 template <
class Range,
class Pattern, etl::enable_if_t<etl::is_
class_v<etl::decay_t<Pattern>>,
int> = 0>
3355 constexpr auto operator()(Range&& r, Pattern&& pattern)
const
3357 return lazy_split_view(views::all(etl::forward<Range>(r)), views::all(etl::forward<Pattern>(pattern)));
3361 template <
class Range,
class Pattern, etl::enable_if_t<!etl::is_
class_v<etl::decay_t<Pattern>>,
int> = 0>
3362 constexpr auto operator()(Range&& r, Pattern&& pattern)
const
3364 return lazy_split_view(views::all(etl::forward<Range>(r)), etl::ranges::single_view(pattern));
3368 template <
class Pattern>
3369 constexpr auto operator()(
const Pattern& pattern)
const
3371 return ranges::lazy_split_range_adapter_closure<Pattern>(pattern);
3376 inline constexpr private_views::lazy_split lazy_split;
3381 namespace private_views
3385 template <
class Iterator,
class DifferenceType>
3386 constexpr auto operator()(Iterator&& it, DifferenceType&& count)
const
3388 using T = etl::decay_t<
decltype(it)>;
3389 using D = etl::iter_difference_t<T>;
3400 if constexpr (etl::is_same_v< typename etl::iterator_traits< Iterator>::iterator_category, ETL_OR_STD::random_access_iterator_tag>)
3402 return etl::ranges::subrange(it, it +
static_cast<D
>(count));
3406 return etl::ranges::subrange(etl::counted_iterator(it, count), etl::default_sentinel);
3412 inline constexpr private_views::counted counted;
3415 template <
class... Ranges>
3418 template <
class... Ranges>
3419 class concat_iterator
3421 static_assert(
sizeof...(Ranges) > 0,
"Type list must be non-empty");
3425 using types =
typename etl::type_list<Ranges...>;
3426 using first_range =
typename etl::type_list_type_at_index_t<types, 0>;
3427 using value_type =
typename etl::ranges::private_ranges::iterator_trait< first_range>::value_type;
3428 using reference =
typename etl::ranges::private_ranges::iterator_trait< first_range>::reference;
3429 using difference_type = ptrdiff_t;
3431 using iterator_variant_type =
typename concat_view<Ranges...>::iterator_variant_type;
3433 concat_iterator(
size_t index, concat_view<Ranges...>& view, iterator_variant_type current)
3434 : _ranges_index{index}
3436 , _current_it(current)
3440 concat_iterator(
const concat_iterator& other) =
default;
3444 return _view.get_value(_ranges_index, _current_it);
3447 constexpr decltype(
auto)
operator[](difference_type pos)
const
3452 for (difference_type i = 0; i < pos; ++i)
3454 tmp._view.advance(tmp._ranges_index, tmp._current_it, 1);
3459 for (difference_type i = 0; i < -pos; ++i)
3461 tmp._view.advance(tmp._ranges_index, tmp._current_it, -1);
3467 constexpr concat_iterator& operator++()
3469 _view.advance(_ranges_index, _current_it, 1);
3473 constexpr concat_iterator operator++(
int)
3475 auto result = *
this;
3476 _view.advance(_ranges_index, _current_it, 1);
3480 constexpr concat_iterator& operator--()
3482 _view.advance(_ranges_index, _current_it, -1);
3486 constexpr concat_iterator operator--(
int)
3488 auto result = *
this;
3489 _view.advance(_ranges_index, _current_it, -1);
3493 constexpr concat_iterator& operator+=(difference_type n)
3495 for (difference_type i = 0; i < n; ++i)
3497 _view.advance(_ranges_index, _current_it, 1);
3502 constexpr concat_iterator& operator-=(difference_type n)
3504 for (difference_type i = 0; i < n; ++i)
3506 _view.advance(_ranges_index, _current_it, -1);
3511 friend constexpr bool operator==(
const concat_iterator<Ranges...>& x, etl::default_sentinel_t)
3513 return x._ranges_index == x._view.number_of_ranges - 1
3517 friend constexpr bool operator==(
const concat_iterator<Ranges...>& x,
const concat_iterator<Ranges...>& y)
3519 return x._ranges_index == y._ranges_index && x._current_it.index() == y._current_it.index() && x._current_it == y._current_it;
3522 friend constexpr bool operator!=(
const concat_iterator<Ranges...>& x, etl::default_sentinel_t)
3524 return !(x == etl::default_sentinel);
3527 friend constexpr bool operator!=(
const concat_iterator<Ranges...>& x,
const concat_iterator<Ranges...>& y)
3534 size_t _ranges_index;
3535 const concat_view<Ranges...>& _view;
3536 iterator_variant_type _current_it;
3539 template <
class... Ranges>
3540 class concat_view :
public etl::ranges::view_interface<concat_view<Ranges...>>
3542 static_assert(
sizeof...(Ranges) > 0,
"Type list must be non-empty");
3546 using types =
typename etl::type_list<Ranges...>;
3547 using first_range =
typename etl::type_list_type_at_index_t<types, 0>;
3548 using value_type =
typename etl::ranges::private_ranges::iterator_trait< first_range>::value_type;
3549 using reference =
typename etl::ranges::private_ranges::iterator_trait< first_range>::reference;
3550 using iterator = concat_iterator<Ranges...>;
3551 using const_iterator = concat_iterator<Ranges...>;
3552 using difference_type =
typename etl::make_signed_t<size_t>;
3554 using iterator_variant_type =
3555 etl::ranges::private_ranges::mini_variant< typename etl::ranges::private_ranges::iterator_trait< Ranges>::iterator...>;
3557 using get_value_delegates_type = reference (*)(
const iterator_variant_type& );
3558 using advance_delegates_type = void (*)(
size_t& ,
const etl::tuple<Ranges...>& , iterator_variant_type& ,
3561 static constexpr const size_t number_of_ranges =
sizeof...(Ranges);
3563 constexpr concat_view(Ranges&&... r)
3564 : _r{etl::move(r)...}
3569 concat_view(
const concat_view& other) =
default;
3571 constexpr iterator
begin()
3573 iterator_variant_type current;
3575 return iterator{0, *
this, current};
3578 constexpr iterator
end()
3580 iterator_variant_type current;
3581 current.template emplace<number_of_ranges - 1>(
etl::get<number_of_ranges - 1>(_r).end());
3582 return iterator{number_of_ranges - 1, *
this, current};
3585 constexpr size_t size()
const
3592 template <
class... Rs>
3593 friend class concat_iterator;
3595 template <
size_t n = 0>
3596 constexpr size_t get_size()
const
3598 if constexpr (n < etl::tuple_size_v<
decltype(_r)>)
3600 return etl::get<n>(_r).size() + get_size<n + 1>();
3609 void advance(
size_t& index, iterator_variant_type& current, difference_type n)
const
3611 advance_delegates[index](index, _r, current, n);
3614 template <
size_t i = 0>
3615 void set_delegates()
3617 if constexpr (i < number_of_ranges)
3619 advance_delegates[i] = [](
size_t& index,
const etl::tuple<Ranges...>& r, iterator_variant_type& current, difference_type n)
3631 if constexpr (i + 1 < number_of_ranges)
3639 ETL_ASSERT(it == end && i + 1 == number_of_ranges, ETL_ERROR_GENERIC(
"Wrong iterator state at end"));
3649 if constexpr (i > 0)
3651 current.template emplace<i - 1>(
etl::get<i - 1>(r).end());
3655 auto& it2 =
etl::get<i - 1>(current);
3664 ETL_ASSERT(it == begin && i == 0, ETL_ERROR_GENERIC(
"Wrong iterator state at begin"));
3674 get_value_delegates[i] = [](
const iterator_variant_type& current) -> reference
3679 set_delegates<i + 1>();
3683 reference get_value(
size_t index,
const iterator_variant_type& current)
const
3685 return get_value_delegates[index](current);
3688 etl::tuple<Ranges...> _r;
3689 get_value_delegates_type get_value_delegates[number_of_ranges];
3690 advance_delegates_type advance_delegates[number_of_ranges];
3693 template <
class... Ranges>
3694 concat_view(Ranges&&...) -> concat_view<views::all_t<Ranges>...>;
3698 namespace private_views
3702 template <
class... Ranges>
3703 constexpr auto operator()(Ranges&&... r)
const
3705 return concat_view(views::all(etl::forward<Ranges>(r))...);
3710 inline constexpr private_views::concat concat;
3718 template <
class... Ranges>
3721 static_assert(
sizeof...(Ranges) > 0,
"Type list must be non-empty");
3725 using iterators_type = etl::tuple< typename etl::ranges::private_ranges::iterator_trait< Ranges>::iterator...>;
3726 using value_type = etl::tuple<typename etl::ranges::private_ranges::iterator_trait< Ranges>::value_type...>;
3727 using difference_type = ptrdiff_t;
3731 using reference = etl::tuple<
decltype(*etl::declval< typename etl::ranges::private_ranges::iterator_trait<Ranges>::iterator&>())...>;
3732 using pointer = value_type*;
3734 using iterator_category = ETL_OR_STD::forward_iterator_tag;
3736 constexpr zip_iterator(iterators_type iters)
3741 constexpr zip_iterator(
const zip_iterator& other) =
default;
3743 constexpr zip_iterator& operator=(
const zip_iterator& other) =
default;
3745 constexpr zip_iterator& operator++()
3747 increment(etl::make_index_sequence<
sizeof...(Ranges)>{});
3751 constexpr zip_iterator operator++(
int)
3753 zip_iterator tmp = *
this;
3760 return deref(etl::make_index_sequence<
sizeof...(Ranges)>{});
3763 friend constexpr bool operator==(
const zip_iterator& lhs,
const zip_iterator& rhs)
3765 return lhs.any_equal(rhs, etl::make_index_sequence<
sizeof...(Ranges)>{});
3768 friend constexpr bool operator!=(
const zip_iterator& lhs,
const zip_iterator& rhs)
3770 return !(lhs == rhs);
3775 template <
size_t... Is>
3776 constexpr void increment(etl::index_sequence<Is...>)
3781 template <
size_t... Is>
3782 constexpr reference deref(etl::index_sequence<Is...>)
const
3789 template <
size_t... Is>
3790 constexpr bool any_equal(
const zip_iterator& other, etl::index_sequence<Is...>)
const
3795 iterators_type _iters;
3804 template <
class... Ranges>
3805 class zip_view :
public etl::ranges::view_interface<zip_view<Ranges...>>
3807 static_assert(
sizeof...(Ranges) > 0,
"Type list must be non-empty");
3811 using iterator = zip_iterator<Ranges...>;
3812 using const_iterator = zip_iterator<Ranges...>;
3814 constexpr zip_view(Ranges&&... r)
3815 : _r{etl::move(r)...}
3819 zip_view(
const zip_view& other) =
default;
3821 constexpr const_iterator
begin()
const
3823 return make_begin(etl::make_index_sequence<
sizeof...(Ranges)>{});
3826 constexpr const_iterator
end()
const
3828 return make_end(etl::make_index_sequence<
sizeof...(Ranges)>{});
3831 constexpr size_t size()
const
3833 return get_min_size(etl::make_index_sequence<
sizeof...(Ranges)>{});
3838 template <
size_t... Is>
3839 constexpr const_iterator make_begin(etl::index_sequence<Is...>)
const
3841 return const_iterator(
typename const_iterator::iterators_type(ETL_OR_STD::begin(
etl::get<Is>(_r))...));
3844 template <
size_t... Is>
3845 constexpr const_iterator make_end(etl::index_sequence<Is...>)
const
3847 return const_iterator(
typename const_iterator::iterators_type(ETL_OR_STD::end(
etl::get<Is>(_r))...));
3850 template <
size_t... Is>
3851 constexpr size_t get_min_size(etl::index_sequence<Is...>)
const
3853 size_t sizes[] = {
static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(
etl::get<Is>(_r)), ETL_OR_STD::cend(
etl::get<Is>(_r))))...};
3854 size_t min_val = sizes[0];
3855 for (
size_t i = 1; i <
sizeof...(Ranges); ++i)
3857 if (sizes[i] < min_val)
3865 mutable etl::tuple<Ranges...> _r;
3868 template <
class... Ranges>
3869 zip_view(Ranges&&...) -> zip_view<views::all_t<Ranges>...>;
3873 namespace private_views
3877 template <
class... Ranges>
3878 constexpr auto operator()(Ranges&&... r)
const
3880 return zip_view(views::all(etl::forward<Ranges>(r))...);
3885 inline constexpr private_views::zip zip;
3893 template <
class Fun,
class... Ranges>
3894 class zip_transform_iterator
3896 static_assert(
sizeof...(Ranges) > 0,
"Type list must be non-empty");
3900 using iterators_type = etl::tuple< typename etl::ranges::private_ranges::iterator_trait< Ranges>::const_iterator...>;
3901 using value_type = etl::invoke_result_t< Fun, typename etl::ranges::private_ranges::iterator_trait<Ranges>::value_type...>;
3902 using difference_type = ptrdiff_t;
3903 using pointer =
const value_type*;
3904 using reference = value_type;
3906 using iterator_category = ETL_OR_STD::forward_iterator_tag;
3908 constexpr zip_transform_iterator(Fun f, iterators_type iters)
3914 constexpr zip_transform_iterator(
const zip_transform_iterator& other) =
default;
3916 constexpr zip_transform_iterator& operator=(
const zip_transform_iterator& other) =
default;
3918 constexpr zip_transform_iterator& operator++()
3920 increment(etl::make_index_sequence<
sizeof...(Ranges)>{});
3924 constexpr zip_transform_iterator operator++(
int)
3926 zip_transform_iterator tmp = *
this;
3933 return deref(etl::make_index_sequence<
sizeof...(Ranges)>{});
3936 friend constexpr bool operator==(
const zip_transform_iterator& lhs,
const zip_transform_iterator& rhs)
3938 return lhs.any_equal(rhs, etl::make_index_sequence<
sizeof...(Ranges)>{});
3941 friend constexpr bool operator!=(
const zip_transform_iterator& lhs,
const zip_transform_iterator& rhs)
3943 return !(lhs == rhs);
3948 template <
size_t... Is>
3949 constexpr void increment(etl::index_sequence<Is...>)
3954 template <
size_t... Is>
3955 constexpr value_type deref(etl::index_sequence<Is...>)
const
3962 template <
size_t... Is>
3963 constexpr bool any_equal(
const zip_transform_iterator& other, etl::index_sequence<Is...>)
const
3969 iterators_type _iters;
3979 template <
class Fun,
class... Ranges>
3980 class zip_transform_view :
public etl::ranges::view_interface<zip_transform_view<Fun, Ranges...>>
3982 static_assert(
sizeof...(Ranges) > 0,
"Type list must be non-empty");
3986 using iterator = zip_transform_iterator<Fun, Ranges...>;
3987 using const_iterator = zip_transform_iterator<Fun, Ranges...>;
3989 constexpr zip_transform_view(Fun f, Ranges&&... r)
3991 , _r{etl::move(r)...}
3995 zip_transform_view(
const zip_transform_view& other) =
default;
3997 constexpr const_iterator
begin()
const
3999 return make_begin(etl::make_index_sequence<
sizeof...(Ranges)>{});
4002 constexpr const_iterator
end()
const
4004 return make_end(etl::make_index_sequence<
sizeof...(Ranges)>{});
4007 constexpr size_t size()
const
4009 return get_min_size(etl::make_index_sequence<
sizeof...(Ranges)>{});
4014 template <
size_t... Is>
4015 constexpr const_iterator make_begin(etl::index_sequence<Is...>)
const
4017 return const_iterator(_f,
typename const_iterator::iterators_type(ETL_OR_STD::begin(
etl::get<Is>(_r))...));
4020 template <
size_t... Is>
4021 constexpr const_iterator make_end(etl::index_sequence<Is...>)
const
4023 return const_iterator(_f,
typename const_iterator::iterators_type(ETL_OR_STD::end(
etl::get<Is>(_r))...));
4026 template <
size_t... Is>
4027 constexpr size_t get_min_size(etl::index_sequence<Is...>)
const
4029 size_t sizes[] = {
static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(
etl::get<Is>(_r)), ETL_OR_STD::cend(
etl::get<Is>(_r))))...};
4030 size_t min_val = sizes[0];
4031 for (
size_t i = 1; i <
sizeof...(Ranges); ++i)
4033 if (sizes[i] < min_val)
4042 mutable etl::tuple<Ranges...> _r;
4045 template <
class Fun,
class... Ranges>
4046 zip_transform_view(Fun, Ranges&&...) -> zip_transform_view<Fun, views::all_t<Ranges>...>;
4050 namespace private_views
4052 struct zip_transform
4054 template <
class Fun,
class... Ranges>
4055 constexpr auto operator()(Fun&& f, Ranges&&... r)
const
4057 return zip_transform_view(etl::forward<Fun>(f), views::all(etl::forward<Ranges>(r))...);
4062 inline constexpr private_views::zip_transform zip_transform;
4070 template <
class I,
class S>
4071 class common_iterator
4075 using value_type =
typename etl::iterator_traits<I>::value_type;
4076 using difference_type =
typename etl::iterator_traits<I>::difference_type;
4077 using pointer =
typename etl::iterator_traits<I>::pointer;
4078 using reference =
typename etl::iterator_traits<I>::reference;
4079 using iterator_category = ETL_OR_STD::input_iterator_tag;
4081 constexpr common_iterator()
4082 : _is_sentinel{false}
4088 constexpr common_iterator(I it)
4089 : _is_sentinel{false}
4095 constexpr common_iterator(S s)
4096 : _is_sentinel{true}
4102 constexpr common_iterator(
const common_iterator& other)
4103 : _is_sentinel{other._is_sentinel}
4105 , _sentinel{other._sentinel}
4109 constexpr common_iterator& operator=(
const common_iterator& other)
4111 _is_sentinel = other._is_sentinel;
4113 _sentinel = other._sentinel;
4117 constexpr decltype(
auto)
operator*()
const
4122 constexpr decltype(
auto)
operator*()
4127 constexpr auto operator->()
const
4132 constexpr common_iterator& operator++()
4138 constexpr common_iterator operator++(
int)
4140 common_iterator tmp = *
this;
4145 friend constexpr bool operator==(
const common_iterator& lhs,
const common_iterator& rhs)
4147 if (lhs._is_sentinel && rhs._is_sentinel)
4151 if (!lhs._is_sentinel && !rhs._is_sentinel)
4153 return lhs._it == rhs._it;
4155 if (lhs._is_sentinel)
4157 return rhs._it == lhs._sentinel;
4159 return lhs._it == rhs._sentinel;
4162 friend constexpr bool operator!=(
const common_iterator& lhs,
const common_iterator& rhs)
4164 return !(lhs == rhs);
4178 namespace private_ranges
4180 template <
typename Range,
typename =
void>
4185 template <
typename Range>
4186 struct is_common_range<
4188 etl::enable_if_t< etl::is_same_v< decltype(ETL_OR_STD::begin(etl::declval<Range&>())), decltype(ETL_OR_STD::end(etl::declval<Range&>())) > >>
4200 template <class Range, bool IsCommon = private_ranges::is_common_range<Range>::value>
4204 template <
class Range>
4205 class common_view<Range, true> :
public etl::ranges::view_interface<common_view<Range, true>>
4209 using iterator =
decltype(ETL_OR_STD::begin(etl::declval<Range&>()));
4210 using const_iterator =
decltype(ETL_OR_STD::cbegin(etl::declval<const Range&>()));
4211 using difference_type =
typename etl::iterator_traits<iterator>::difference_type;
4213 constexpr common_view(Range&& r)
4218 common_view(
const common_view& other) =
default;
4220 constexpr Range base() const&
4225 constexpr iterator
begin()
const
4227 return iterator(ETL_OR_STD::begin(_r));
4230 constexpr iterator
end()
const
4232 return iterator(ETL_OR_STD::end(_r));
4235 constexpr size_t size()
const
4237 return static_cast<size_t>(etl::distance(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r)));
4246 template <
class Range>
4247 class common_view<Range, false> :
public etl::ranges::view_interface<common_view<Range, false>>
4251 using base_iterator =
decltype(ETL_OR_STD::begin(etl::declval<Range&>()));
4252 using base_sentinel =
decltype(ETL_OR_STD::end(etl::declval<Range&>()));
4253 using iterator = common_iterator<base_iterator, base_sentinel>;
4254 using const_iterator = iterator;
4255 using difference_type =
typename etl::iterator_traits<base_iterator>::difference_type;
4257 constexpr common_view(Range&& r)
4262 common_view(
const common_view& other) =
default;
4264 constexpr Range base() const&
4269 constexpr iterator
begin()
const
4271 return iterator(ETL_OR_STD::begin(_r));
4274 constexpr iterator
end()
const
4276 return iterator(ETL_OR_STD::end(_r));
4284 template <
class Range>
4285 common_view(Range&&) -> common_view<views::all_t<Range>>;
4287 struct common_range_adapter_closure :
public range_adapter_closure<common_range_adapter_closure>
4289 template <
typename Range>
4290 using target_view_type = common_view<Range>;
4292 common_range_adapter_closure() =
default;
4294 template <
typename Range>
4295 constexpr auto operator()(Range&& r)
4297 return common_view(views::all(etl::forward<Range>(r)));
4303 namespace private_views
4305 struct common :
public range_adapter_closure_base
4307 template <
class Range>
4308 constexpr auto operator()(Range&& r)
const
4310 return common_view(views::all(etl::forward<Range>(r)));
4313 constexpr auto operator()()
const
4315 return ranges::common_range_adapter_closure();
4320 inline constexpr private_views::common common;
4328 template <
class Range>
4329 class enumerate_iterator
4333 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
4335 using base_iterator =
typename trait::iterator;
4336 using base_value_type =
typename trait::value_type;
4337 using base_reference =
decltype(*etl::declval<base_iterator&>());
4338 using value_type = etl::tuple<size_t, base_value_type>;
4339 using difference_type =
typename trait::difference_type;
4343 using reference = etl::tuple<size_t, base_reference>;
4344 using pointer = value_type*;
4346 using iterator_category = ETL_OR_STD::forward_iterator_tag;
4348 enumerate_iterator(base_iterator it,
size_t index)
4354 enumerate_iterator(
const enumerate_iterator& other)
4356 , _index{other._index}
4360 enumerate_iterator& operator++()
4367 enumerate_iterator operator++(
int)
4369 enumerate_iterator tmp = *
this;
4375 enumerate_iterator& operator=(
const enumerate_iterator& other)
4378 _index = other._index;
4384 return reference(_index, *_it);
4387 bool operator==(
const enumerate_iterator& other)
const
4389 return other._it == _it;
4392 bool operator!=(
const enumerate_iterator& other)
const
4394 return !(*
this == other);
4408 template <
class Range>
4409 class enumerate_view :
public etl::ranges::view_interface<enumerate_view<Range>>
4413 using iterator = enumerate_iterator<Range>;
4414 using const_iterator = enumerate_iterator<Range>;
4416 enumerate_view(Range&& r)
4421 enumerate_view(
const enumerate_view& other) =
default;
4423 constexpr Range& base() const&
4428 constexpr const_iterator
begin()
const
4430 return const_iterator(ETL_OR_STD::begin(_r), 0);
4433 constexpr const_iterator
end()
const
4435 return const_iterator(ETL_OR_STD::end(_r),
static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r))));
4438 constexpr size_t size()
const
4440 return static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
4448 template <
class Range>
4449 enumerate_view(Range&&) -> enumerate_view<views::all_t<Range>>;
4451 struct enumerate_range_adapter_closure :
public range_adapter_closure<enumerate_range_adapter_closure>
4453 template <
typename Range>
4454 using target_view_type = enumerate_view<Range>;
4456 enumerate_range_adapter_closure() =
default;
4458 template <
typename Range>
4459 constexpr auto operator()(Range&& r)
4461 return enumerate_view(views::all(etl::forward<Range>(r)));
4467 namespace private_views
4469 struct enumerate :
public range_adapter_closure_base
4471 template <
class Range>
4472 constexpr auto operator()(Range&& r)
const
4474 return enumerate_view(views::all(etl::forward<Range>(r)));
4477 constexpr auto operator()()
const
4479 return ranges::enumerate_range_adapter_closure();
4484 inline constexpr private_views::enumerate enumerate;
4492 template <
class Range,
size_t N>
4493 class elements_iterator
4497 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
4499 using base_iterator =
typename trait::iterator;
4500 using base_value_type =
typename trait::value_type;
4501 using value_type = etl::tuple_element_t<N, base_value_type>;
4502 using difference_type =
typename trait::difference_type;
4510 static decltype(
auto) deref_element(
const base_iterator& it)
4518 using reference =
decltype(deref_element(etl::declval<const base_iterator&>()));
4519 using pointer = etl::remove_reference_t<reference>*;
4521 using iterator_category = ETL_OR_STD::forward_iterator_tag;
4523 elements_iterator(base_iterator it)
4528 elements_iterator(
const elements_iterator& other)
4533 elements_iterator& operator++()
4539 elements_iterator operator++(
int)
4541 elements_iterator tmp = *
this;
4546 elements_iterator& operator=(
const elements_iterator& other)
4552 decltype(
auto)
operator*()
const
4554 return deref_element(_it);
4557 bool operator==(
const elements_iterator& other)
const
4559 return other._it == _it;
4562 bool operator!=(
const elements_iterator& other)
const
4564 return !(*
this == other);
4577 template <
class Range,
size_t N>
4578 class elements_view :
public etl::ranges::view_interface<elements_view<Range, N>>
4582 using iterator = elements_iterator<Range, N>;
4583 using const_iterator = elements_iterator<Range, N>;
4585 elements_view(Range&& r)
4590 elements_view(
const elements_view& other) =
default;
4592 constexpr Range& base() const&
4597 constexpr const_iterator
begin()
const
4599 return const_iterator(ETL_OR_STD::begin(_r));
4602 constexpr const_iterator
end()
const
4604 return const_iterator(ETL_OR_STD::end(_r));
4607 constexpr size_t size()
const
4609 return static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
4617 template <
class Range,
size_t N>
4618 elements_view(Range&&, etl::integral_constant<size_t, N>) -> elements_view<views::all_t<Range>, N>;
4621 struct elements_range_adapter_closure :
public range_adapter_closure<elements_range_adapter_closure<N>>
4623 template <
typename Range>
4624 using target_view_type = elements_view<Range, N>;
4626 elements_range_adapter_closure() =
default;
4628 template <
typename Range>
4629 constexpr auto operator()(Range&& r)
4631 return elements_view<views::all_t<Range>, N>(views::all(etl::forward<Range>(r)));
4636 template <
class Range>
4637 using keys_view = elements_view<Range, 0>;
4640 template <
class Range>
4641 using values_view = elements_view<Range, 1>;
4645 namespace private_views
4648 struct elements_fn :
public range_adapter_closure_base
4650 template <
class Range>
4651 constexpr auto operator()(Range&& r)
const
4653 return elements_view<views::all_t<Range>, N>(views::all(etl::forward<Range>(r)));
4656 constexpr auto operator()()
const
4658 return ranges::elements_range_adapter_closure<N>();
4664 inline constexpr private_views::elements_fn<N> elements{};
4666 inline constexpr private_views::elements_fn<0> keys{};
4667 inline constexpr private_views::elements_fn<1> values{};
4673 namespace private_ranges
4675 template <
typename T,
size_t N,
typename = etl::make_index_sequence<N>>
4676 struct repeat_tuple;
4678 template <
typename T,
size_t N,
size_t... Is>
4679 struct repeat_tuple<T, N, etl::index_sequence<Is...>>
4684 using type = etl::tuple<always<Is>...>;
4687 template <
typename T,
size_t N>
4688 using repeat_tuple_t =
typename repeat_tuple<T, N>::type;
4692 template <
typename Fun,
typename T,
size_t N,
typename = etl::make_index_sequence<N>>
4693 struct repeat_invoke_result;
4695 template <
typename Fun,
typename T,
size_t N,
size_t... Is>
4696 struct repeat_invoke_result<Fun, T, N, etl::index_sequence<Is...>>
4701 using type = etl::invoke_result_t<Fun, always<Is>...>;
4704 template <
typename Fun,
typename T,
size_t N>
4705 using repeat_invoke_result_t =
typename repeat_invoke_result<Fun, T, N>::type;
4714 template <
class Range,
size_t N>
4715 class adjacent_iterator
4717 static_assert(N > 0,
"adjacent window size must be > 0");
4721 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
4723 using base_iterator =
typename trait::iterator;
4724 using base_value_type =
typename trait::value_type;
4725 using base_reference =
decltype(*etl::declval<base_iterator&>());
4726 using value_type = private_ranges::repeat_tuple_t<base_value_type, N>;
4727 using difference_type =
typename trait::difference_type;
4731 using reference = private_ranges::repeat_tuple_t<base_reference, N>;
4732 using pointer = value_type*;
4734 using iterator_category = ETL_OR_STD::forward_iterator_tag;
4737 template <
size_t... Is>
4738 constexpr adjacent_iterator(base_iterator first, base_iterator last, etl::index_sequence<Is...>)
4739 : _iters{advance_copy(first, last, Is)...}
4744 constexpr adjacent_iterator(
const adjacent_iterator& other) =
default;
4746 constexpr adjacent_iterator& operator=(
const adjacent_iterator& other) =
default;
4748 constexpr adjacent_iterator& operator++()
4750 increment(etl::make_index_sequence<N>{});
4754 constexpr adjacent_iterator operator++(
int)
4756 adjacent_iterator tmp = *
this;
4763 return deref(etl::make_index_sequence<N>{});
4766 friend constexpr bool operator==(
const adjacent_iterator& lhs,
const adjacent_iterator& rhs)
4770 return lhs._iters[N - 1] == rhs._iters[N - 1];
4773 friend constexpr bool operator!=(
const adjacent_iterator& lhs,
const adjacent_iterator& rhs)
4775 return !(lhs == rhs);
4780 static constexpr base_iterator advance_copy(base_iterator it, base_iterator last,
size_t n)
4782 for (
size_t i = 0; i < n && it != last; ++i)
4789 template <
size_t... Is>
4790 constexpr void increment(etl::index_sequence<Is...>)
4792 ((void)((_iters[Is] != _end) ? (void)++_iters[Is] : (void)0), ...);
4795 template <
size_t... Is>
4796 constexpr reference deref(etl::index_sequence<Is...>)
const
4798 return reference(*_iters[Is]...);
4801 base_iterator _iters[N];
4813 template <
class Range,
size_t N>
4814 class adjacent_view :
public etl::ranges::view_interface<adjacent_view<Range, N>>
4816 static_assert(N > 0,
"adjacent window size must be > 0");
4820 using iterator = adjacent_iterator<Range, N>;
4821 using const_iterator = adjacent_iterator<Range, N>;
4823 constexpr adjacent_view(Range&& r)
4828 adjacent_view(
const adjacent_view& other) =
default;
4830 constexpr Range& base() const&
4835 constexpr const_iterator
begin()
const
4837 return const_iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), etl::make_index_sequence<N>{});
4840 constexpr const_iterator
end()
const
4843 return const_iterator(ETL_OR_STD::end(_r), ETL_OR_STD::end(_r), etl::make_index_sequence<N>{});
4846 constexpr size_t size()
const
4848 auto total =
static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
4849 return (total >= N) ? (total - N + 1) : 0;
4857 template <
class Range,
size_t N>
4858 adjacent_view(Range&&, etl::integral_constant<size_t, N>) -> adjacent_view<views::all_t<Range>, N>;
4861 struct adjacent_range_adapter_closure :
public range_adapter_closure<adjacent_range_adapter_closure<N>>
4863 template <
typename Range>
4864 using target_view_type = adjacent_view<Range, N>;
4866 adjacent_range_adapter_closure() =
default;
4868 template <
typename Range>
4869 constexpr auto operator()(Range&& r)
4871 return adjacent_view<views::all_t<Range>, N>(views::all(etl::forward<Range>(r)));
4877 namespace private_views
4880 struct adjacent_fn :
public range_adapter_closure_base
4882 template <
class Range>
4883 constexpr auto operator()(Range&& r)
const
4885 return adjacent_view<views::all_t<Range>, N>(views::all(etl::forward<Range>(r)));
4888 constexpr auto operator()()
const
4890 return ranges::adjacent_range_adapter_closure<N>();
4896 inline constexpr private_views::adjacent_fn<N> adjacent{};
4899 inline constexpr private_views::adjacent_fn<2> pairwise{};
4908 template <
class Range,
class Fun,
size_t N>
4909 class adjacent_transform_iterator
4911 static_assert(N > 0,
"adjacent window size must be > 0");
4915 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
4917 using base_iterator =
typename trait::const_iterator;
4918 using base_value_type =
typename trait::value_type;
4919 using value_type = private_ranges::repeat_invoke_result_t<Fun, base_value_type, N>;
4920 using difference_type =
typename trait::difference_type;
4921 using pointer =
const value_type*;
4922 using reference = value_type;
4924 using iterator_category = ETL_OR_STD::forward_iterator_tag;
4928 template <
size_t... Is>
4929 constexpr adjacent_transform_iterator(Fun f, base_iterator first, base_iterator last, etl::index_sequence<Is...>)
4931 , _iters{advance_copy(first, last, Is)...}
4936 constexpr adjacent_transform_iterator(
const adjacent_transform_iterator& other) =
default;
4938 constexpr adjacent_transform_iterator& operator=(
const adjacent_transform_iterator& other) =
default;
4940 constexpr adjacent_transform_iterator& operator++()
4942 increment(etl::make_index_sequence<N>{});
4946 constexpr adjacent_transform_iterator operator++(
int)
4948 adjacent_transform_iterator tmp = *
this;
4955 return deref(etl::make_index_sequence<N>{});
4958 friend constexpr bool operator==(
const adjacent_transform_iterator& lhs,
const adjacent_transform_iterator& rhs)
4962 return lhs._iters[N - 1] == rhs._iters[N - 1];
4965 friend constexpr bool operator!=(
const adjacent_transform_iterator& lhs,
const adjacent_transform_iterator& rhs)
4967 return !(lhs == rhs);
4972 static constexpr base_iterator advance_copy(base_iterator it, base_iterator last,
size_t n)
4974 for (
size_t i = 0; i < n && it != last; ++i)
4981 template <
size_t... Is>
4982 constexpr void increment(etl::index_sequence<Is...>)
4984 ((void)((_iters[Is] != _end) ? (void)++_iters[Is] : (void)0), ...);
4987 template <
size_t... Is>
4988 constexpr value_type deref(etl::index_sequence<Is...>)
const
4990 return etl::invoke(_f, *_iters[Is]...);
4994 base_iterator _iters[N];
5007 template <
class Range,
class Fun,
size_t N>
5008 class adjacent_transform_view :
public etl::ranges::view_interface< adjacent_transform_view<Range, Fun, N>>
5010 static_assert(N > 0,
"adjacent window size must be > 0");
5014 using iterator = adjacent_transform_iterator<Range, Fun, N>;
5015 using const_iterator = adjacent_transform_iterator<Range, Fun, N>;
5017 constexpr adjacent_transform_view(Fun f, Range&& r)
5023 adjacent_transform_view(
const adjacent_transform_view& other) =
default;
5025 constexpr Range& base() const&
5030 constexpr const_iterator
begin()
const
5032 return const_iterator(_f, ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), etl::make_index_sequence<N>{});
5035 constexpr const_iterator
end()
const
5038 return const_iterator(_f, ETL_OR_STD::end(_r), ETL_OR_STD::end(_r), etl::make_index_sequence<N>{});
5041 constexpr size_t size()
const
5043 auto total =
static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
5044 return (total >= N) ? (total - N + 1) : 0;
5053 template <
class Fun,
class Range,
size_t N>
5054 adjacent_transform_view(Fun, Range&&, etl::integral_constant<size_t, N>) -> adjacent_transform_view<views::all_t<Range>, Fun, N>;
5056 template <
size_t N,
typename Fun>
5057 struct adjacent_transform_range_adapter_closure :
public range_adapter_closure< adjacent_transform_range_adapter_closure<N, Fun>>
5059 template <
typename Range>
5060 using target_view_type = adjacent_transform_view<Range, Fun, N>;
5062 adjacent_transform_range_adapter_closure(Fun f)
5067 template <
typename Range>
5068 constexpr auto operator()(Range&& r)
5070 return adjacent_transform_view<views::all_t<Range>, Fun, N>(_f, views::all(etl::forward<Range>(r)));
5078 namespace private_views
5081 struct adjacent_transform_fn
5083 template <
class Range,
typename Fun>
5084 constexpr auto operator()(Range&& r, Fun&& f)
const
5086 return adjacent_transform_view<views::all_t<Range>, etl::decay_t<Fun>, N>(etl::forward<Fun>(f), views::all(etl::forward<Range>(r)));
5089 template <
typename Fun>
5090 constexpr auto operator()(Fun&& f)
const
5092 return ranges::adjacent_transform_range_adapter_closure< N, etl::decay_t<Fun>>(etl::forward<Fun>(f));
5098 inline constexpr private_views::adjacent_transform_fn<N> adjacent_transform{};
5101 inline constexpr private_views::adjacent_transform_fn<2> pairwise_transform{};
5107 template <
class Range>
5108 class chunk_iterator
5112 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
5114 using inner_iterator =
typename trait::iterator;
5115 using const_inner_iterator =
typename trait::const_iterator;
5116 using difference_type =
typename trait::difference_type;
5118 using iterator_category = ETL_OR_STD::forward_iterator_tag;
5120 using value_type = etl::ranges::subrange<inner_iterator>;
5121 using pointer = value_type*;
5122 using reference = value_type;
5124 chunk_iterator(inner_iterator it, inner_iterator it_end, difference_type chunk_size)
5127 , _chunk_size(chunk_size)
5131 chunk_iterator(
const chunk_iterator& other) =
default;
5133 chunk_iterator& operator=(
const chunk_iterator& other) =
default;
5135 chunk_iterator& operator++()
5137 difference_type remaining = etl::distance(_it, _it_end);
5138 difference_type step = (_chunk_size < remaining) ? _chunk_size : remaining;
5139 etl::advance(_it, step);
5143 chunk_iterator operator++(
int)
5145 chunk_iterator tmp{*
this};
5152 difference_type remaining = etl::distance(_it, _it_end);
5153 difference_type step = (_chunk_size < remaining) ? _chunk_size : remaining;
5154 inner_iterator chunk_end = _it;
5155 etl::advance(chunk_end, step);
5156 return value_type(_it, chunk_end);
5159 constexpr bool operator==(
const chunk_iterator& other)
const
5161 return _it == other._it;
5164 constexpr bool operator!=(
const chunk_iterator& other)
const
5166 return !(*
this == other);
5172 inner_iterator _it_end;
5173 difference_type _chunk_size;
5181 template <
class Range>
5182 class chunk_view :
public etl::ranges::view_interface<chunk_view<Range>>
5186 using iterator = chunk_iterator<Range>;
5187 using const_iterator = chunk_iterator<Range>;
5188 using difference_type =
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type;
5190 constexpr chunk_view(Range&& r, difference_type chunk_size)
5192 , _chunk_size{chunk_size}
5196 chunk_view(
const chunk_view& other) =
default;
5198 constexpr Range base() const&
5203 constexpr iterator
begin()
const
5205 return iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), _chunk_size);
5208 constexpr iterator
end()
const
5210 return iterator(ETL_OR_STD::end(_r), ETL_OR_STD::end(_r), _chunk_size);
5216 difference_type _chunk_size;
5219 template <
class Range>
5220 chunk_view(Range&&,
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type) -> chunk_view<views::all_t<Range>>;
5222 struct chunk_range_adapter_closure :
public range_adapter_closure<chunk_range_adapter_closure>
5224 template <
typename Range>
5225 using target_view_type = chunk_view<Range>;
5227 template <
class DifferenceType>
5228 constexpr chunk_range_adapter_closure(DifferenceType chunk_size)
5229 : _chunk_size{static_cast<size_t>(chunk_size)}
5233 template <
typename Range>
5234 constexpr auto operator()(Range&& r)
const
5236 return chunk_view(views::all(etl::forward<Range>(r)),
static_cast< typename chunk_view<views::all_t<Range>
>::difference_type>(_chunk_size));
5239 const size_t _chunk_size;
5244 namespace private_views
5248 template <
class Range>
5249 constexpr auto operator()(Range&& r, ranges::range_difference_t<Range> chunk_size)
const
5251 return chunk_view(views::all(etl::forward<Range>(r)), chunk_size);
5254 template <
class DifferenceType>
5255 constexpr auto operator()(DifferenceType chunk_size)
const
5257 return ranges::chunk_range_adapter_closure(chunk_size);
5262 inline constexpr private_views::chunk chunk;
5269 template <
class Range>
5270 class slide_iterator
5274 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
5276 using inner_iterator =
typename trait::iterator;
5277 using const_inner_iterator =
typename trait::const_iterator;
5278 using difference_type =
typename trait::difference_type;
5280 using iterator_category = ETL_OR_STD::forward_iterator_tag;
5282 using value_type = etl::ranges::subrange<inner_iterator>;
5283 using pointer = value_type*;
5284 using reference = value_type;
5286 slide_iterator(inner_iterator it, inner_iterator it_end, difference_type window_size)
5289 , _window_size(window_size)
5293 slide_iterator(
const slide_iterator& other) =
default;
5295 slide_iterator& operator=(
const slide_iterator& other) =
default;
5297 slide_iterator& operator++()
5303 slide_iterator operator++(
int)
5305 slide_iterator tmp{*
this};
5312 inner_iterator window_end = _it;
5313 etl::advance(window_end, _window_size);
5314 return value_type(_it, window_end);
5317 constexpr bool operator==(
const slide_iterator& other)
const
5319 return _it == other._it;
5322 constexpr bool operator!=(
const slide_iterator& other)
const
5324 return !(*
this == other);
5330 inner_iterator _it_end;
5331 difference_type _window_size;
5341 template <
class Range>
5342 class slide_view :
public etl::ranges::view_interface<slide_view<Range>>
5346 using iterator = slide_iterator<Range>;
5347 using const_iterator = slide_iterator<Range>;
5348 using difference_type =
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type;
5350 constexpr slide_view(Range&& r, difference_type window_size)
5352 , _window_size{window_size}
5356 slide_view(
const slide_view& other) =
default;
5358 constexpr Range base() const&
5363 constexpr iterator
begin()
const
5365 return iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), _window_size);
5368 constexpr iterator
end()
const
5370 auto total =
static_cast<difference_type
>(etl::distance(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r)));
5371 if (total < _window_size)
5374 return iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), _window_size);
5376 auto end_it = ETL_OR_STD::begin(_r);
5377 etl::advance(end_it, total - _window_size + 1);
5378 return iterator(end_it, ETL_OR_STD::end(_r), _window_size);
5381 constexpr size_t size()
const
5383 auto total =
static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
5384 return (total >=
static_cast<size_t>(_window_size)) ? (total -
static_cast<size_t>(_window_size) + 1) : 0;
5390 difference_type _window_size;
5393 template <
class Range>
5394 slide_view(Range&&,
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type) -> slide_view<views::all_t<Range>>;
5396 struct slide_range_adapter_closure :
public range_adapter_closure<slide_range_adapter_closure>
5398 template <
typename Range>
5399 using target_view_type = slide_view<Range>;
5401 template <
class DifferenceType>
5402 constexpr slide_range_adapter_closure(DifferenceType window_size)
5403 : _window_size{static_cast<size_t>(window_size)}
5407 template <
typename Range>
5408 constexpr auto operator()(Range&& r)
const
5410 return slide_view(views::all(etl::forward<Range>(r)),
static_cast< typename slide_view<views::all_t<Range>
>::difference_type>(_window_size));
5413 const size_t _window_size;
5418 namespace private_views
5422 template <
class Range>
5423 constexpr auto operator()(Range&& r, ranges::range_difference_t<Range> window_size)
const
5425 return slide_view(views::all(etl::forward<Range>(r)), window_size);
5428 template <
class DifferenceType>
5429 constexpr auto operator()(DifferenceType window_size)
const
5431 return ranges::slide_range_adapter_closure(window_size);
5436 inline constexpr private_views::slide slide;
5445 template <
class Range,
class Pred>
5446 class chunk_by_iterator
5450 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
5452 using inner_iterator =
typename trait::iterator;
5453 using const_inner_iterator =
typename trait::const_iterator;
5454 using difference_type =
typename trait::difference_type;
5456 using iterator_category = ETL_OR_STD::forward_iterator_tag;
5458 using value_type = etl::ranges::subrange<inner_iterator>;
5459 using pointer = value_type*;
5460 using reference = value_type;
5462 chunk_by_iterator(inner_iterator it, inner_iterator it_end,
const Pred& pred)
5467 _chunk_end = find_next_chunk_end();
5470 chunk_by_iterator(
const chunk_by_iterator& other) =
default;
5472 chunk_by_iterator& operator=(
const chunk_by_iterator& other) =
default;
5474 chunk_by_iterator& operator++()
5477 _chunk_end = find_next_chunk_end();
5481 chunk_by_iterator operator++(
int)
5483 chunk_by_iterator tmp{*
this};
5490 return value_type(_it, _chunk_end);
5493 constexpr bool operator==(
const chunk_by_iterator& other)
const
5495 return _it == other._it;
5498 constexpr bool operator!=(
const chunk_by_iterator& other)
const
5500 return !(*
this == other);
5505 inner_iterator find_next_chunk_end()
const
5512 inner_iterator it_prev = _it;
5513 inner_iterator it_curr = _it;
5516 while (it_curr != _it_end)
5518 if (!_pred(*it_prev, *it_curr))
5530 inner_iterator _it_end;
5531 inner_iterator _chunk_end;
5541 template <
class Range,
class Pred>
5542 class chunk_by_view :
public etl::ranges::view_interface<chunk_by_view<Range, Pred>>
5546 using iterator = chunk_by_iterator<Range, Pred>;
5547 using const_iterator = chunk_by_iterator<Range, Pred>;
5549 chunk_by_view(Range&& r,
const Pred& pred)
5555 chunk_by_view(
const chunk_by_view& other) =
default;
5557 constexpr Range base() const&
5562 constexpr const Pred& pred()
const
5567 constexpr const_iterator
begin()
const
5569 return const_iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), _pred);
5572 constexpr const_iterator
end()
const
5574 return const_iterator(ETL_OR_STD::end(_r), ETL_OR_STD::end(_r), _pred);
5583 template <
class Range,
typename Pred>
5584 chunk_by_view(Range&&, Pred) -> chunk_by_view<views::all_t<Range>, Pred>;
5586 template <
typename Pred>
5587 struct chunk_by_range_adapter_closure :
public range_adapter_closure<chunk_by_range_adapter_closure<Pred>>
5589 template <
typename Range>
5590 using target_view_type = chunk_by_view<Range, Pred>;
5592 chunk_by_range_adapter_closure(
const Pred& p)
5597 template <
typename Range>
5598 constexpr auto operator()(Range&& r)
const
5600 return chunk_by_view(views::all(etl::forward<Range>(r)), _p);
5608 namespace private_views
5612 template <
class Range,
typename Pred>
5613 constexpr auto operator()(Range&& r,
const Pred& p)
const
5615 return chunk_by_view(views::all(etl::forward<Range>(r)), p);
5618 template <
typename Pred>
5619 constexpr auto operator()(
const Pred& p)
const
5621 return ranges::chunk_by_range_adapter_closure<Pred>(p);
5626 inline constexpr private_views::chunk_by chunk_by;
5633 template <
class Range>
5634 class stride_iterator
5638 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
5640 using inner_iterator =
typename trait::iterator;
5641 using const_inner_iterator =
typename trait::const_iterator;
5642 using difference_type =
typename trait::difference_type;
5644 using iterator_category = ETL_OR_STD::forward_iterator_tag;
5646 using value_type =
typename trait::value_type;
5647 using reference =
decltype(*etl::declval<inner_iterator&>());
5648 using pointer = etl::remove_reference_t<reference>*;
5650 constexpr stride_iterator(inner_iterator it, inner_iterator it_end, difference_type stride_n)
5653 , _stride_n(stride_n)
5657 stride_iterator(
const stride_iterator& other) =
default;
5659 stride_iterator& operator=(
const stride_iterator& other) =
default;
5661 constexpr stride_iterator& operator++()
5663 difference_type remaining = etl::distance(_it, _it_end);
5664 difference_type step = (_stride_n < remaining) ? _stride_n : remaining;
5665 etl::advance(_it, step);
5669 constexpr stride_iterator operator++(
int)
5671 stride_iterator tmp{*
this};
5676 constexpr decltype(
auto)
operator*()
const
5681 constexpr pointer operator->()
const
5686 constexpr bool operator==(
const stride_iterator& other)
const
5688 return _it == other._it;
5691 constexpr bool operator!=(
const stride_iterator& other)
const
5693 return !(*
this == other);
5698 mutable inner_iterator _it;
5699 inner_iterator _it_end;
5700 difference_type _stride_n;
5707 template <
class Range>
5708 class stride_view :
public etl::ranges::view_interface<stride_view<Range>>
5712 using iterator = stride_iterator<Range>;
5713 using const_iterator = stride_iterator<Range>;
5714 using difference_type =
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type;
5716 constexpr stride_view(Range&& r, difference_type stride_n)
5718 , _stride_n{stride_n}
5722 stride_view(
const stride_view& other) =
default;
5724 constexpr Range base() const&
5729 constexpr iterator
begin()
const
5731 return iterator(ETL_OR_STD::begin(_r), ETL_OR_STD::end(_r), _stride_n);
5734 constexpr iterator
end()
const
5736 return iterator(ETL_OR_STD::end(_r), ETL_OR_STD::end(_r), _stride_n);
5742 difference_type _stride_n;
5745 template <
class Range>
5746 stride_view(Range&&,
typename etl::ranges::private_ranges::iterator_trait< Range>::difference_type) -> stride_view<views::all_t<Range>>;
5748 struct stride_range_adapter_closure :
public range_adapter_closure<stride_range_adapter_closure>
5750 template <
typename Range>
5751 using target_view_type = stride_view<Range>;
5753 template <
class DifferenceType>
5754 constexpr stride_range_adapter_closure(DifferenceType stride_n)
5755 : _stride_n{static_cast<size_t>(stride_n)}
5759 template <
typename Range>
5760 constexpr auto operator()(Range&& r)
const
5762 return stride_view(views::all(etl::forward<Range>(r)),
static_cast< typename stride_view<views::all_t<Range>
>::difference_type>(_stride_n));
5765 const size_t _stride_n;
5770 namespace private_views
5774 template <
class Range>
5775 constexpr auto operator()(Range&& r, ranges::range_difference_t<Range> stride_n)
const
5777 return stride_view(views::all(etl::forward<Range>(r)), stride_n);
5780 template <
class DifferenceType>
5781 constexpr auto operator()(DifferenceType stride_n)
const
5783 return ranges::stride_range_adapter_closure(stride_n);
5788 inline constexpr private_views::stride stride;
5798 template <
class... Ranges>
5799 class cartesian_product_iterator
5801 static_assert(
sizeof...(Ranges) > 0,
"Type list must be non-empty");
5805 using iterators_type = etl::tuple< typename etl::ranges::private_ranges::iterator_trait< Ranges>::const_iterator...>;
5806 using value_type = etl::tuple<typename etl::ranges::private_ranges::iterator_trait< Ranges>::value_type...>;
5807 using difference_type = ptrdiff_t;
5808 using pointer =
const value_type*;
5809 using reference = value_type;
5811 using iterator_category = ETL_OR_STD::forward_iterator_tag;
5813 constexpr cartesian_product_iterator(iterators_type current, iterators_type begins, iterators_type ends,
bool is_end =
false)
5814 : _current_it(current)
5821 constexpr cartesian_product_iterator(
const cartesian_product_iterator& other) =
default;
5823 constexpr cartesian_product_iterator& operator=(
const cartesian_product_iterator& other) =
default;
5825 constexpr cartesian_product_iterator& operator++()
5831 constexpr cartesian_product_iterator operator++(
int)
5833 cartesian_product_iterator tmp = *
this;
5840 return deref(etl::make_index_sequence<
sizeof...(Ranges)>{});
5843 friend constexpr bool operator==(
const cartesian_product_iterator& lhs,
const cartesian_product_iterator& rhs)
5845 return lhs._is_end == rhs._is_end && (lhs._is_end || lhs.all_equal(rhs, etl::make_index_sequence<
sizeof...(Ranges)>{}));
5848 friend constexpr bool operator!=(
const cartesian_product_iterator& lhs,
const cartesian_product_iterator& rhs)
5850 return !(lhs == rhs);
5857 constexpr void increment()
5861 increment_at<
sizeof...(Ranges) - 1>();
5865 constexpr etl::enable_if_t<(I > 0)> increment_at()
5872 increment_at<I - 1>();
5877 constexpr etl::enable_if_t<(I == 0)> increment_at()
5887 template <
size_t... Is>
5888 constexpr value_type deref(etl::index_sequence<Is...>)
const
5893 template <
size_t... Is>
5894 constexpr bool all_equal(
const cartesian_product_iterator& other, etl::index_sequence<Is...>)
const
5899 iterators_type _current_it;
5900 iterators_type _begins;
5901 iterators_type _ends;
5913 template <
class... Ranges>
5914 class cartesian_product_view :
public etl::ranges::view_interface<cartesian_product_view<Ranges...>>
5916 static_assert(
sizeof...(Ranges) > 0,
"Type list must be non-empty");
5920 using iterator = cartesian_product_iterator<Ranges...>;
5921 using const_iterator = cartesian_product_iterator<Ranges...>;
5923 constexpr cartesian_product_view(Ranges&&... r)
5924 : _r{etl::move(r)...}
5928 cartesian_product_view(
const cartesian_product_view& other) =
default;
5930 constexpr const_iterator
begin()
const
5932 if (any_empty(etl::make_index_sequence<
sizeof...(Ranges)>{}))
5936 return make_begin(etl::make_index_sequence<
sizeof...(Ranges)>{});
5939 constexpr const_iterator
end()
const
5941 return make_end(etl::make_index_sequence<
sizeof...(Ranges)>{});
5944 constexpr size_t size()
const
5946 return get_product_size(etl::make_index_sequence<
sizeof...(Ranges)>{});
5951 template <
size_t... Is>
5952 constexpr const_iterator make_begin(etl::index_sequence<Is...>)
const
5954 return const_iterator(
typename const_iterator::iterators_type(ETL_OR_STD::begin(
etl::get<Is>(_r))...),
5955 typename const_iterator::iterators_type(ETL_OR_STD::begin(
etl::get<Is>(_r))...),
5956 typename const_iterator::iterators_type(ETL_OR_STD::end(
etl::get<Is>(_r))...),
false);
5959 template <
size_t... Is>
5960 constexpr const_iterator make_end(etl::index_sequence<Is...>)
const
5962 return const_iterator(
typename const_iterator::iterators_type(ETL_OR_STD::end(
etl::get<Is>(_r))...),
5963 typename const_iterator::iterators_type(ETL_OR_STD::begin(
etl::get<Is>(_r))...),
5964 typename const_iterator::iterators_type(ETL_OR_STD::end(
etl::get<Is>(_r))...),
true);
5967 template <
size_t... Is>
5968 constexpr bool any_empty(etl::index_sequence<Is...>)
const
5973 template <
size_t... Is>
5974 constexpr size_t get_product_size(etl::index_sequence<Is...>)
const
5976 size_t sizes[] = {
static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(
etl::get<Is>(_r)), ETL_OR_STD::cend(
etl::get<Is>(_r))))...};
5978 for (
size_t i = 0; i <
sizeof...(Ranges); ++i)
5980 product *= sizes[i];
5985 mutable etl::tuple<Ranges...> _r;
5988 template <
class... Ranges>
5989 cartesian_product_view(Ranges&&...) -> cartesian_product_view<views::all_t<Ranges>...>;
5993 namespace private_views
5995 struct cartesian_product
5997 template <
class... Ranges>
5998 constexpr auto operator()(Ranges&&... r)
const
6000 return cartesian_product_view(views::all(etl::forward<Ranges>(r))...);
6005 inline constexpr private_views::cartesian_product cartesian_product;
6014 template <
class Range>
6015 class to_input_iterator
6019 using trait =
typename etl::ranges::private_ranges::iterator_trait<Range>;
6021 using iterator =
typename trait::iterator;
6022 using const_iterator =
typename trait::const_iterator;
6023 using value_type =
typename trait::value_type;
6024 using difference_type =
typename trait::difference_type;
6025 using pointer =
typename trait::pointer;
6026 using reference =
typename trait::reference;
6028 using iterator_category = ETL_OR_STD::input_iterator_tag;
6030 to_input_iterator() =
default;
6032 to_input_iterator(iterator it)
6037 to_input_iterator(
const to_input_iterator& other) =
default;
6039 to_input_iterator& operator=(
const to_input_iterator& other) =
default;
6041 to_input_iterator& operator++()
6047 to_input_iterator operator++(
int)
6049 to_input_iterator tmp = *
this;
6054 decltype(
auto)
operator*()
const
6059 pointer operator->()
const
6064 bool operator==(
const to_input_iterator& other)
const
6066 return _it == other._it;
6069 bool operator!=(
const to_input_iterator& other)
const
6071 return !(*
this == other);
6076 mutable iterator _it;
6086 template <
class Range>
6087 class to_input_view :
public etl::ranges::view_interface<to_input_view<Range>>
6091 using iterator = to_input_iterator<Range>;
6092 using const_iterator = iterator;
6094 to_input_view(
const to_input_view& other) =
default;
6096 to_input_view(Range&& r)
6101 constexpr Range& base()
const
6106 constexpr iterator
begin()
const
6108 return iterator(ETL_OR_STD::begin(_r));
6111 constexpr iterator
end()
const
6113 return iterator(ETL_OR_STD::end(_r));
6116 constexpr size_t size()
const
6118 return static_cast<size_t>(etl::distance(ETL_OR_STD::cbegin(_r), ETL_OR_STD::cend(_r)));
6126 template <
class Range>
6127 to_input_view(Range&&) -> to_input_view<views::all_t<Range>>;
6129 struct to_input_range_adapter_closure :
public range_adapter_closure<to_input_range_adapter_closure>
6131 template <
typename Range>
6132 using target_view_type = to_input_view<Range>;
6134 to_input_range_adapter_closure() =
default;
6136 template <
typename Range>
6137 constexpr auto operator()(Range&& r)
6139 return to_input_view(views::all(etl::forward<Range>(r)));
6145 namespace private_views
6147 struct to_input :
public range_adapter_closure_base
6149 template <
class Range>
6150 constexpr auto operator()(Range&& r)
const
6152 return to_input_view(views::all(etl::forward<Range>(r)));
6155 constexpr auto operator()()
const
6157 return ranges::to_input_range_adapter_closure();
6162 inline constexpr private_views::to_input to_input;
6180 elements_of(R&&) -> elements_of<R>;
6182 namespace private_ranges
6185 struct to_range_adapter_closure :
public range_adapter_closure<to_range_adapter_closure<C>>
6187 template <
class Range =
void>
6188 using target_view_type = C;
6190 to_range_adapter_closure() =
default;
6192 template <
class Range>
6193 C operator()(
const Range& r)
const
6195 using result_type = C;
6201 result.push_back(i);
6207 template <
class Range>
6208 C operator()(Range&& r)
6210 using result_type = C;
6216 result.emplace_back(etl::move(i));
6225 private_ranges::to_range_adapter_closure<C> to()
6227 return private_ranges::to_range_adapter_closure<C>();
6232 namespace views = ranges::views;
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
ETL_CONSTEXPR14 void iota(TIterator first, TIterator last, T value)
Definition numeric.h:58
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1470
ETL_CONSTEXPR14 etl::circular_iterator< TIterator > operator-(etl::circular_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type offset)
Definition circular_iterator.h:675
TContainer::const_iterator cbegin(const TContainer &container)
Definition iterator.h:1156
etl::byte operator|(etl::byte lhs, etl::byte rhs)
Or.
Definition byte.h:250
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits.h:80
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1434
ETL_CONSTEXPR14 enable_if<!etl::is_specialization< TRep2, etl::chrono::duration >::value, etl::chrono::duration< typenameetl::common_type< TRep1, TRep2 >::type, TPeriod1 > >::type operator*(const etl::chrono::duration< TRep1, TPeriod1 > &lhs, const TRep2 &rhs) ETL_NOEXCEPT
Operator *.
Definition duration.h:541
TContainer::iterator end(TContainer &container)
Definition iterator.h:1166
ETL_CONSTEXPR14 etl::circular_iterator< TIterator > operator+(etl::circular_iterator< TIterator > &lhs, typename etl::iterator_traits< TIterator >::difference_type offset)
Definition circular_iterator.h:662
T & get(array< T, Size > &a)
Definition array.h:1158
TContainer::const_iterator cend(const TContainer &container)
Definition iterator.h:1186
TContainer::iterator begin(TContainer &container)
Definition iterator.h:1136
etl::add_const< T >::type & as_const(T &t)
as_const
Definition utility.h:540
ETL_CONSTEXPR14 bool operator==(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Equality test for etl::to_arithmetic_result.
Definition to_arithmetic.h:903
ETL_CONSTEXPR14 bool operator!=(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Inequality test for etl::to_arithmetic_result.
Definition to_arithmetic.h:937