Files
2025-10-25 03:02:53 +03:00

196 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[range.split]
# 25 Ranges library [[ranges]](./#ranges)
## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.split)
### 25.7.17 Split view [range.split]
#### [25.7.17.1](#overview) Overview [[range.split.overview]](range.split.overview)
[1](#overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8383)
split_view takes a view and a delimiter, and
splits the view into subranges on the delimiter[.](#overview-1.sentence-1)
The delimiter can be a single element or a view of elements[.](#overview-1.sentence-2)
[2](#overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8388)
The name views::split denotes
a range adaptor object ([[range.adaptor.object]](range.adaptor.object "25.7.2Range adaptor objects"))[.](#overview-2.sentence-1)
Given subexpressions E and F,
the expression views::split(E, F) is expression-equivalent tosplit_view(E, F)[.](#overview-2.sentence-2)
[3](#overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8395)
[*Example [1](#overview-example-1)*: string str{"the quick brown fox"};for (auto word : views::split(str, ' ')) { cout << string_view(word) << '*';}// The above prints the*quick*brown*fox* — *end example*]
#### [25.7.17.2](#view) Class template split_view [[range.split.view]](range.split.view)
[🔗](#lib:split_view)
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5Views[range.view]")<V> && [view](range.view#concept:view "25.4.5Views[range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5Concept indirectly_­comparable[alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>class split_view : public view_interface<split_view<V, Pattern>> {private: V *base_* = V(); // *exposition only* Pattern *pattern_* = Pattern(); // *exposition only*// [[range.split.iterator]](#iterator "25.7.17.3Class split_­view::iterator"), class split_view::*iterator*struct *iterator*; // *exposition only*// [[range.split.sentinel]](#sentinel "25.7.17.4Class split_­view::sentinel"), class split_view::*sentinel*struct *sentinel*; // *exposition only*public: split_view()requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept default_­initializable[concept.default.init]")<V> && [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept default_­initializable[concept.default.init]")<Pattern> = default; constexpr explicit split_view(V base, Pattern pattern); template<[forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") R>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<V, views::all_t<R>> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<Pattern, single_view<range_value_t<R>>>constexpr explicit split_view(R&& r, range_value_t<R> e); constexpr V base() const & requires [copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14Concept copy_­constructible[concept.copyconstructible]")<V> { return *base_*; }constexpr V base() && { return std::move(*base_*); }constexpr *iterator* begin(); constexpr auto end() {if constexpr ([common_range](range.refinements#concept:common_range "25.4.6Other range refinements[range.refinements]")<V>) {return *iterator*{*this, ranges::end(*base_*), {}}; } else {return *sentinel*{*this}; }}constexpr subrange<iterator_t<V>> *find-next*(iterator_t<V>); // *exposition only*}; template<class R, class P> split_view(R&&, P&&) -> split_view<views::all_t<R>, views::all_t<P>>; template<[forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") R> split_view(R&&, range_value_t<R>)-> split_view<views::all_t<R>, single_view<range_value_t<R>>>;}
[🔗](#lib:split_view,constructor)
`constexpr explicit split_view(V base, Pattern pattern);
`
[1](#view-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8466)
*Effects*: Initializes *base_* with std::move(base), and*pattern_* with std::move(pattern)[.](#view-1.sentence-1)
[🔗](#lib:split_view,constructor_)
`template<[forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") R>
requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<V, views::all_t<R>> &&
[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<Pattern, single_view<range_value_t<R>>>
constexpr explicit split_view(R&& r, range_value_t<R> e);
`
[2](#view-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8481)
*Effects*: Initializes *base_* with views::all(std::forward<R>(r)), and*pattern_* with views::single(std::move(e))[.](#view-2.sentence-1)
[🔗](#lib:begin,split_view)
`constexpr iterator begin();
`
[3](#view-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8493)
*Returns*: {*this, ranges::begin(*base_*), *find-next*(ranges::begin(*base_*))}[.](#view-3.sentence-1)
[4](#view-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8497)
*Remarks*: In order to provide the amortized constant time complexity
required by the [range](range.range#concept:range "25.4.2Ranges[range.range]") concept,
this function caches the result within the split_view for use on subsequent calls[.](#view-4.sentence-1)
[🔗](#lib:find-next,split_view)
`constexpr subrange<iterator_t<V>> find-next(iterator_t<V> it);
`
[5](#view-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8511)
*Effects*: Equivalent to:auto [b, e] = ranges::search(subrange(it, ranges::end(*base_*)), *pattern_*);if (b != ranges::end(*base_*) && ranges::empty(*pattern_*)) {++b; ++e;}return {b, e};
#### [25.7.17.3](#iterator) Class split_view::*iterator* [[range.split.iterator]](range.split.iterator)
[🔗](#lib:split_view::iterator)
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5Views[range.view]")<V> && [view](range.view#concept:view "25.4.5Views[range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5Concept indirectly_­comparable[alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>class split_view<V, Pattern>::*iterator* {private: split_view* *parent_* = nullptr; // *exposition only* iterator_t<V> *cur_* = iterator_t<V>(); // *exposition only* subrange<iterator_t<V>> *next_* = subrange<iterator_t<V>>(); // *exposition only*bool *trailing_empty_* = false; // *exposition only*public:using iterator_concept = forward_iterator_tag; using iterator_category = input_iterator_tag; using value_type = subrange<iterator_t<V>>; using difference_type = range_difference_t<V>; *iterator*() = default; constexpr *iterator*(split_view& parent, iterator_t<V> current, subrange<iterator_t<V>> next); constexpr iterator_t<V> base() const; constexpr value_type operator*() const; constexpr *iterator*& operator++(); constexpr *iterator* operator++(int); friend constexpr bool operator==(const *iterator*& x, const *iterator*& y); };}
[🔗](#lib:split_view::iterator,constructor)
`constexpr iterator(split_view& parent, iterator_t<V> current, subrange<iterator_t<V>> next);
`
[1](#iterator-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8565)
*Effects*: Initializes *parent_* with addressof(parent),*cur_* with std::move(current), and*next_* with std::move(next)[.](#iterator-1.sentence-1)
[🔗](#lib:base,split_view::iterator)
`constexpr iterator_t<V> base() const;
`
[2](#iterator-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8578)
*Effects*: Equivalent to: return *cur_*;
[🔗](#lib:operator*,split_view::iterator)
`constexpr value_type operator*() const;
`
[3](#iterator-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8589)
*Effects*: Equivalent to: return {*cur_*, *next_*.begin()};
[🔗](#lib:operator++,split_view::iterator)
`constexpr iterator& operator++();
`
[4](#iterator-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8600)
*Effects*: Equivalent to:*cur_* = *next_*.begin();if (*cur_* != ranges::end(*parent_*->*base_*)) {*cur_* = *next_*.end(); if (*cur_* == ranges::end(*parent_*->*base_*)) {*trailing_empty_* = true; *next_* = {*cur_*, *cur_*}; } else {*next_* = *parent_*->*find-next*(*cur_*); }} else {*trailing_empty_* = false;}return *this;
[🔗](#lib:operator++,split_view::iterator_)
`constexpr iterator operator++(int);
`
[5](#iterator-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8626)
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
[🔗](#lib:operator==,split_view::iterator)
`friend constexpr bool operator==(const iterator& x, const iterator& y);
`
[6](#iterator-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8642)
*Effects*: Equivalent to:return x.*cur_* == y.*cur_* && x.*trailing_empty_* == y.*trailing_empty_*;
#### [25.7.17.4](#sentinel) Class split_view::*sentinel* [[range.split.sentinel]](range.split.sentinel)
[🔗](#lib:split_view::sentinel)
namespace std::ranges {template<[forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") V, [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") Pattern>requires [view](range.view#concept:view "25.4.5Views[range.view]")<V> && [view](range.view#concept:view "25.4.5Views[range.view]")<Pattern> &&[indirectly_comparable](alg.req.ind.cmp#concept:indirectly_comparable "24.3.7.5Concept indirectly_­comparable[alg.req.ind.cmp]")<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to>struct split_view<V, Pattern>::*sentinel* {private: sentinel_t<V> *end_* = sentinel_t<V>(); // *exposition only*public:*sentinel*() = default; constexpr explicit *sentinel*(split_view& parent); friend constexpr bool operator==(const *iterator*& x, const *sentinel*& y); };}
[🔗](#lib:split_view::sentinel,constructor)
`constexpr explicit sentinel(split_view& parent);
`
[1](#sentinel-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8677)
*Effects*: Initializes *end_* with ranges::end(parent.*base_*)[.](#sentinel-1.sentence-1)
[🔗](#lib:operator==,split_view::sentinel)
`friend constexpr bool operator==(const iterator& x, const sentinel& y);
`
[2](#sentinel-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L8688)
*Effects*: Equivalent to: return x.*cur_* == y.*end_* && !x.*trailing_empty_*;