@@ -264,13 +264,25 @@ class concat_view<_Views...>::__iterator {
264
264
}
265
265
}
266
266
267
+ template <typename _Func>
268
+ _LIBCPP_HIDE_FROM_ABI constexpr auto __invoke_at_index (_Func&& __func) const {
269
+ return [&__func, this ]<std::size_t _Is>(this auto && __self) {
270
+ if (_Is == __it_.index ()) {
271
+ return __func.template operator ()<_Is>();
272
+ } else if constexpr (_Is + 1 < sizeof ...(_Views)) {
273
+ return __self.template operator ()<_Is + 1 >();
274
+ }
275
+ __builtin_unreachable ();
276
+ }.template operator ()<0 >();
277
+ }
278
+
267
279
template <size_t ... _Is, typename _Func>
268
- _LIBCPP_HIDE_FROM_ABI constexpr void __apply_at_index (size_t __index, _Func&& __func, index_sequence<_Is...>) {
280
+ _LIBCPP_HIDE_FROM_ABI constexpr void __apply_at_index (size_t __index, _Func&& __func, index_sequence<_Is...>) const {
269
281
((__index == _Is ? (__func (integral_constant<size_t , _Is>{}), 0 ) : 0 ), ...);
270
282
}
271
283
272
284
template <size_t _Idx, typename _Func>
273
- _LIBCPP_HIDE_FROM_ABI constexpr void __apply_at_index (size_t __index, _Func&& __func) {
285
+ _LIBCPP_HIDE_FROM_ABI constexpr void __apply_at_index (size_t __index, _Func&& __func) const {
274
286
__apply_at_index (__index, std::forward<_Func>(__func), make_index_sequence<_Idx>{});
275
287
}
276
288
@@ -280,6 +292,7 @@ class concat_view<_Views...>::__iterator {
280
292
: __it_(std::forward<_Args>(__args)...), __parent_(__parent) {}
281
293
282
294
friend class concat_view ;
295
+ friend class __iterator <!_Const>;
283
296
284
297
public:
285
298
_LIBCPP_HIDE_FROM_ABI __iterator () = default;
@@ -517,35 +530,28 @@ class concat_view<_Views...>::__iterator {
517
530
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
518
531
!__x.__it_ .valueless_by_exception () && !__y.__it_ .valueless_by_exception (),
519
532
" Trying to subtract two iterators of concat_view where at least one iterator is valueless." );
520
- size_t __ix = __x.__it_ .index ();
521
- size_t __iy = __y.__it_ .index ();
522
-
523
- if (__ix > __iy) {
524
- __x.__it_ .template __apply_at_index <tuple_size_v<decltype (__x.__parent_ ->__views_ )>>(
525
- __ix, [&](auto __index_constant_x) {
526
- constexpr size_t __index_x = __index_constant_x.value ;
527
- auto __dx = ranges::distance (
528
- ranges::begin (std::get<__index_x>(__x.__parent_ ->__views_ )), std::get<__index_x>(__x.__it_ ));
529
-
530
- __y.__it_ .template __apply_at_index <tuple_size_v<decltype (__y.__parent_ ->__views_ )>>(
531
- __iy, [&](auto __index_constant_y) {
532
- constexpr size_t __index_y = __index_constant_y.value ;
533
- auto __dy = ranges::distance (
534
- std::get<__index_y>(__y.__it_ ), ranges::end (std::get<__index_y>(__y.__parent_ ->__views_ )));
535
- difference_type __s = 0 ;
536
- for (size_t __idx = __index_y + 1 ; __idx < __index_x; __idx++) {
537
- __s += ranges::size (std::get<__idx>(__x.__parent_ ->__views_ ));
538
- }
539
- return __dy + __s + __dx;
540
- });
541
- });
542
-
543
- } else if (__ix < __iy) {
544
- return -(__y - __x);
545
- } else {
546
- __variant_detail::__visitation::__variant::__visit_value (
547
- [&](const auto & __it1, const auto & __it2) { return __it1 - __it2; }, __x.__it_ , __y.__it_ );
548
- }
533
+ return __x.__invoke_at_index ([&]<std::size_t __index_x>() -> difference_type {
534
+ return __y.__invoke_at_index ([&]<std::size_t __index_y>() -> difference_type {
535
+ if (__index_x > __index_y) {
536
+ auto __dx = ranges::distance (
537
+ ranges::begin (std::get<__index_x>(__x.__parent_ ->__views_ )), std::get<__index_x>(__x.__it_ ));
538
+ auto __dy = ranges::distance (
539
+ std::get<__index_y>(__y.__it_ ), ranges::end (std::get<__index_y>(__y.__parent_ ->__views_ )));
540
+ difference_type __s = [&]<std::size_t __start, std::size_t __end>(this auto && self) -> difference_type {
541
+ if constexpr (__start < __end) {
542
+ return ranges::size (std::get<__start>(__x.__parent_ ->__views_ )) +
543
+ self.template operator ()<__start + 1 , __end>();
544
+ }
545
+ return 0 ;
546
+ }.template operator ()<__index_y + 1 , __index_x>();
547
+ return __dy + __s + __dx;
548
+ } else if (__index_x < __index_y) {
549
+ return -(__y - __x);
550
+ } else {
551
+ return std::get<__index_x>(__x.__it_ ) - std::get<__index_y>(__y.__it_ );
552
+ }
553
+ });
554
+ });
549
555
}
550
556
551
557
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator -(const __iterator& __it, difference_type __n)
@@ -566,19 +572,17 @@ class concat_view<_Views...>::__iterator {
566
572
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
567
573
!__x.__it_ .valueless_by_exception (),
568
574
" Trying to subtract a valuess iterators of concat_view from the default sentinel." );
569
- size_t __ix = __x.__it_ .index ();
570
- __x.__it_ .template __apply_at_index <tuple_size_v<decltype (__x.__parent_ ->__views_ )>>(
571
- __ix, [&](auto __index_constant) {
572
- constexpr size_t __index_x = __index_constant.value ;
573
- auto __dx = ranges::distance (ranges::begin (std::get<__index_x>(__x.__parent_ ->__views_ )), __x.__it_ );
574
-
575
- difference_type __s = 0 ;
576
- for (size_t __idx = 0 ; __idx < __index_x; __idx++) {
577
- __s += ranges::size (std::get<__idx>(__x.__parent_ ->__views_ ));
578
- }
579
-
580
- return -(__dx + __s);
581
- });
575
+ __x.__invoke_at_index ([&]<std::size_t __index_x>() -> difference_type {
576
+ auto __dx = ranges::distance (ranges::begin (std::get<__index_x>(__x.__parent_ ->__views_ )), __x.__it_ );
577
+ difference_type __s = [&]<std::size_t __start, std::size_t __end>(this auto && self) -> difference_type {
578
+ if constexpr (__start < __end) {
579
+ return ranges::size (std::get<__start>(__x.__parent_ ->__views_ )) +
580
+ self.template operator ()<__start + 1 , __end>();
581
+ }
582
+ return 0 ;
583
+ }.template operator ()<0 , __index_x>();
584
+ return -(__dx + __s);
585
+ });
582
586
}
583
587
584
588
_LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator -(default_sentinel_t , const __iterator& __x)
0 commit comments