Skip to content

Commit 57ef4a1

Browse files
committed
Implement first part of P2210R2 Superior String Splitting
1 parent e745bad commit 57ef4a1

File tree

6 files changed

+99
-66
lines changed

6 files changed

+99
-66
lines changed

stl/inc/ranges

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3218,7 +3218,7 @@ namespace ranges {
32183218
inline constexpr _Join_fn join;
32193219
} // namespace views
32203220

3221-
// CLASS TEMPLATE ranges::split_view
3221+
// CLASS TEMPLATE ranges::lazy_split_view
32223222
// clang-format off
32233223
template <class _Ty>
32243224
concept _Tiny_range = sized_range<_Ty>
@@ -3229,24 +3229,24 @@ namespace ranges {
32293229
requires view<_Vw> && view<_Pat>
32303230
&& indirectly_comparable<iterator_t<_Vw>, iterator_t<_Pat>, _RANGES equal_to>
32313231
&& (forward_range<_Vw> || _Tiny_range<_Pat>)
3232-
class split_view;
3232+
class lazy_split_view;
32333233
// clang-format on
32343234

32353235
template <class _Vw, class _Pat>
3236-
class _Split_view_base : public view_interface<split_view<_Vw, _Pat>> {
3236+
class _Lazy_split_view_base : public view_interface<lazy_split_view<_Vw, _Pat>> {
32373237
protected:
32383238
/* [[no_unique_address]] */ _Defaultabox<iterator_t<_Vw>> _Current{};
32393239
};
32403240

32413241
template <forward_range _Vw, class _Pat>
3242-
class _Split_view_base<_Vw, _Pat> : public view_interface<split_view<_Vw, _Pat>> {};
3242+
class _Lazy_split_view_base<_Vw, _Pat> : public view_interface<lazy_split_view<_Vw, _Pat>> {};
32433243

32443244
// clang-format off
32453245
template <input_range _Vw, forward_range _Pat>
32463246
requires view<_Vw> && view<_Pat>
32473247
&& indirectly_comparable<iterator_t<_Vw>, iterator_t<_Pat>, _RANGES equal_to>
32483248
&& (forward_range<_Vw> || _Tiny_range<_Pat>)
3249-
class split_view : public _Split_view_base<_Vw, _Pat> {
3249+
class lazy_split_view : public _Lazy_split_view_base<_Vw, _Pat> {
32503250
// clang-format on
32513251
private:
32523252
/* [[no_unique_address]] */ _Vw _Range{};
@@ -3281,10 +3281,11 @@ namespace ranges {
32813281
friend _Outer_iter<true>;
32823282

32833283
using _Mybase = _Outer_iter_base<iterator_t<_Maybe_const<_Const, _Vw>>>;
3284-
using _ParentTy = _Maybe_const<_Const, split_view>;
3284+
using _ParentTy = _Maybe_const<_Const, lazy_split_view>;
32853285
using _BaseTy = _Maybe_const<_Const, _Vw>;
32863286

3287-
_ParentTy* _Parent = nullptr;
3287+
_ParentTy* _Parent = nullptr;
3288+
bool _Trailing_empty = false;
32883289

32893290
_NODISCARD constexpr iterator_t<_BaseTy>& _Get_current() noexcept {
32903291
if constexpr (forward_range<_BaseTy>) {
@@ -3356,6 +3357,7 @@ namespace ranges {
33563357
const auto _End = _RANGES end(_Parent->_Range);
33573358
auto& _Cur = _Get_current();
33583359
if (_Cur == _End) {
3360+
_Trailing_empty = false;
33593361
return *this;
33603362
}
33613363

@@ -3367,12 +3369,18 @@ namespace ranges {
33673369
_Cur = _RANGES _Find_unchecked(_STD move(_Cur), _End, *_Pat_first);
33683370
if (_Cur != _End) {
33693371
++_Cur;
3372+
if (_Cur == _End) {
3373+
_Trailing_empty = true;
3374+
}
33703375
}
33713376
} else {
33723377
do {
33733378
auto _Result = _RANGES mismatch(_Cur, _End, _Pat_first, _Pat_last);
33743379
if (_Result.in2 == _Pat_last) { // pattern matches
3375-
_Cur = _STD move(_Result.in1);
3380+
_Cur = _Result.in1;
3381+
if (_Cur == _End) {
3382+
_Trailing_empty = true;
3383+
}
33763384
break;
33773385
}
33783386
} while (++_Cur != _End);
@@ -3392,11 +3400,11 @@ namespace ranges {
33923400

33933401
_NODISCARD friend constexpr bool operator==(const _Outer_iter& _Left, const _Outer_iter& _Right) noexcept(
33943402
noexcept(_Left._Current == _Right._Current)) /* strengthened */ requires forward_range<_BaseTy> {
3395-
return _Left._Current == _Right._Current;
3403+
return _Left._Current == _Right._Current && _Left._Trailing_empty == _Right._Trailing_empty;
33963404
}
33973405
_NODISCARD friend constexpr bool operator==(const _Outer_iter& _Left, default_sentinel_t) noexcept(
33983406
noexcept(_Left._At_end())) /* strengthened */ {
3399-
return _Left._At_end();
3407+
return _Left._At_end() && !_Left._Trailing_empty;
34003408
}
34013409
};
34023410

@@ -3483,6 +3491,14 @@ namespace ranges {
34833491
is_nothrow_move_constructible_v<_Outer_iter<_Const>>) // strengthened
34843492
: _It{_STD move(_It_)} {}
34853493

3494+
constexpr const iterator_t<_BaseTy>& base() const& requires copyable<iterator_t<_BaseTy>> {
3495+
return _It._Get_current();
3496+
}
3497+
3498+
constexpr iterator_t<_BaseTy>& base() && {
3499+
return _STD move(_It._Get_current());
3500+
}
3501+
34863502
_NODISCARD constexpr decltype(auto) operator*() const {
34873503
return *_It._Get_current();
34883504
}
@@ -3533,18 +3549,18 @@ namespace ranges {
35333549

35343550
public:
35353551
// clang-format off
3536-
split_view() requires default_initializable<_Vw> && default_initializable<_Pat> = default;
3552+
lazy_split_view() requires default_initializable<_Vw> && default_initializable<_Pat> = default;
35373553
// clang-format on
35383554

3539-
constexpr split_view(_Vw _Range_, _Pat _Pattern_) noexcept(
3555+
constexpr lazy_split_view(_Vw _Range_, _Pat _Pattern_) noexcept(
35403556
is_nothrow_move_constructible_v<_Vw>&& is_nothrow_move_constructible_v<_Pat>) // strengthened
35413557
: _Range(_STD move(_Range_)), _Pattern(_STD move(_Pattern_)) {}
35423558

35433559
// clang-format off
35443560
template <input_range _Rng>
35453561
requires constructible_from<_Vw, views::all_t<_Rng>>
35463562
&& constructible_from<_Pat, single_view<range_value_t<_Rng>>>
3547-
constexpr split_view(_Rng&& _Range_, range_value_t<_Rng> _Elem)
3563+
constexpr lazy_split_view(_Rng&& _Range_, range_value_t<_Rng> _Elem)
35483564
noexcept(noexcept(_Vw(views::all(_STD forward<_Rng>(_Range_))))
35493565
&& noexcept(_Pat(single_view{_STD move(_Elem)}))) // strengthened
35503566
: _Range(views::all(_STD forward<_Rng>(_Range_))), _Pattern(single_view{_STD move(_Elem)}) {}
@@ -3589,43 +3605,44 @@ namespace ranges {
35893605
};
35903606

35913607
template <class _Rng, class _Pat>
3592-
split_view(_Rng&&, _Pat&&) -> split_view<views::all_t<_Rng>, views::all_t<_Pat>>;
3608+
lazy_split_view(_Rng&&, _Pat&&) -> lazy_split_view<views::all_t<_Rng>, views::all_t<_Pat>>;
35933609

35943610
template <input_range _Rng>
3595-
split_view(_Rng&&, range_value_t<_Rng>) -> split_view<views::all_t<_Rng>, single_view<range_value_t<_Rng>>>;
3611+
lazy_split_view(_Rng&&, range_value_t<_Rng>)
3612+
-> lazy_split_view<views::all_t<_Rng>, single_view<range_value_t<_Rng>>>;
35963613

35973614
namespace views {
35983615
// VARIABLE views::split
3599-
class _Split_fn {
3616+
class _Lazy_split_fn {
36003617
private:
36013618
template <class _Delim>
36023619
struct _Partial : _Pipe::_Base<_Partial<_Delim>> {
36033620
/* [[no_unique_address]] */ _Delim _Delimiter;
36043621

36053622
template <viewable_range _Rng>
36063623
_NODISCARD constexpr auto operator()(_Rng&& _Range) const& noexcept(
3607-
noexcept(split_view{_STD forward<_Rng>(_Range), _Delimiter})) requires requires {
3608-
split_view{static_cast<_Rng&&>(_Range), _Delimiter};
3624+
noexcept(lazy_split_view{_STD forward<_Rng>(_Range), _Delimiter})) requires requires {
3625+
lazy_split_view{static_cast<_Rng&&>(_Range), _Delimiter};
36093626
}
3610-
{ return split_view{_STD forward<_Rng>(_Range), _Delimiter}; }
3627+
{ return lazy_split_view{_STD forward<_Rng>(_Range), _Delimiter}; }
36113628

36123629
template <viewable_range _Rng>
36133630
_NODISCARD constexpr auto operator()(_Rng&& _Range) && noexcept(noexcept(
3614-
split_view{_STD forward<_Rng>(_Range), _STD forward<_Delim>(_Delimiter)})) requires requires {
3615-
split_view{static_cast<_Rng&&>(_Range), static_cast<_Delim&&>(_Delimiter)};
3631+
lazy_split_view{_STD forward<_Rng>(_Range), _STD forward<_Delim>(_Delimiter)})) requires requires {
3632+
lazy_split_view{static_cast<_Rng&&>(_Range), static_cast<_Delim&&>(_Delimiter)};
36163633
}
3617-
{ return split_view{_STD forward<_Rng>(_Range), _STD forward<_Delim>(_Delimiter)}; }
3634+
{ return lazy_split_view{_STD forward<_Rng>(_Range), _STD forward<_Delim>(_Delimiter)}; }
36183635
};
36193636

36203637
public:
36213638
// clang-format off
36223639
template <viewable_range _Rng, class _Pat>
36233640
_NODISCARD constexpr auto operator()(_Rng&& _Range, _Pat&& _Pattern) const noexcept(noexcept(
3624-
split_view{_STD forward<_Rng>(_Range), _STD forward<_Pat>(_Pattern)})) requires requires {
3625-
split_view{static_cast<_Rng&&>(_Range), static_cast<_Pat&&>(_Pattern)};
3641+
lazy_split_view{_STD forward<_Rng>(_Range), _STD forward<_Pat>(_Pattern)})) requires requires {
3642+
lazy_split_view{static_cast<_Rng&&>(_Range), static_cast<_Pat&&>(_Pattern)};
36263643
} {
36273644
// clang-format on
3628-
return split_view{_STD forward<_Rng>(_Range), _STD forward<_Pat>(_Pattern)};
3645+
return lazy_split_view{_STD forward<_Rng>(_Range), _STD forward<_Pat>(_Pattern)};
36293646
}
36303647

36313648
// clang-format off
@@ -3638,7 +3655,7 @@ namespace ranges {
36383655
}
36393656
};
36403657

3641-
inline constexpr _Split_fn split;
3658+
inline constexpr _Lazy_split_fn lazy_split;
36423659

36433660
// VARIABLE views::counted
36443661
class _Counted_fn {

stl/inc/yvals_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@
246246
// P2102R0 Making "Implicit Expression Variations" More Explicit
247247
// P2106R0 Range Algorithm Result Types
248248
// P2116R0 Removing tuple-Like Protocol Support From Fixed-Extent span
249+
// P2210R2 Superior String Splitting
250+
// (partially implemented)
249251
// P2259R1 Repairing Input Range Adaptors And counted_iterator
250252
// (partially implemented)
251253
// P2325R3 Views Should Not Be Required To Be Default Constructible

tests/std/test.lst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ tests\P0896R4_views_iota
389389
tests\P0896R4_views_join
390390
tests\P0896R4_views_reverse
391391
tests\P0896R4_views_single
392-
tests\P0896R4_views_split
392+
tests\P0896R4_views_lazy_split
393393
tests\P0896R4_views_take
394394
tests\P0896R4_views_take_while
395395
tests\P0896R4_views_take_while_death

tests/std/tests/P0896R4_ranges_range_machinery/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ STATIC_ASSERT(test_cpo(ranges::views::join));
109109
STATIC_ASSERT(test_cpo(ranges::views::keys));
110110
STATIC_ASSERT(test_cpo(ranges::views::reverse));
111111
STATIC_ASSERT(test_cpo(ranges::views::single));
112-
STATIC_ASSERT(test_cpo(ranges::views::split));
112+
STATIC_ASSERT(test_cpo(ranges::views::lazy_split));
113113
STATIC_ASSERT(test_cpo(ranges::views::take));
114114
STATIC_ASSERT(test_cpo(ranges::views::take_while));
115115
STATIC_ASSERT(test_cpo(ranges::views::transform));
File renamed without changes.

0 commit comments

Comments
 (0)