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

12 KiB
Raw Permalink Blame History

[range.split]

25 Ranges library [ranges]

25.7 Range adaptors [range.adaptors]

25.7.17 Split view [range.split]

25.7.17.1 Overview [range.split.overview]

1

#

split_view takes a view and a delimiter, and splits the view into subranges on the delimiter.

The delimiter can be a single element or a view of elements.

2

#

The name views::split denotes a range adaptor object ([range.adaptor.object]).

Given subexpressions E and F, the expression views::split(E, F) is expression-equivalent tosplit_view(E, F).

3

#

[Example 1: string str{"the quick brown fox"};for (auto word : views::split(str, ' ')) { cout << string_view(word) << '';}// The above prints thequickbrownfox* — end example]

25.7.17.2 Class template split_view [range.split.view]

🔗

namespace std::ranges {template<forward_range V, forward_range Pattern>requires view && view &&indirectly_comparable<iterator_t, iterator_t, 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], class split_view::iteratorstruct iterator; // exposition only// [range.split.sentinel], class split_view::sentinelstruct sentinel; // exposition onlypublic: split_view()requires default_initializable && default_initializable = default; constexpr explicit split_view(V base, Pattern pattern); template<forward_range R>requires constructible_from<V, views::all_t> &&constructible_from<Pattern, single_view<range_value_t>>constexpr explicit split_view(R&& r, range_value_t e); constexpr V base() const & requires copy_constructible { return base_; }constexpr V base() && { return std::move(base_); }constexpr iterator begin(); constexpr auto end() {if constexpr (common_range) {return iterator{*this, ranges::end(base_), {}}; } else {return sentinel{*this}; }}constexpr subrange<iterator_t> find-next(iterator_t); // exposition only}; template<class R, class P> split_view(R&&, P&&) -> split_view<views::all_t, views::all_t

>; template<forward_range R> split_view(R&&, range_value_t)-> split_view<views::all_t, single_view<range_value_t>>;}

🔗

constexpr explicit split_view(V base, Pattern pattern);

1

#

Effects: Initializes base_ with std::move(base), andpattern_ with std::move(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);

2

#

Effects: Initializes base_ with views::all(std::forward(r)), andpattern_ with views::single(std::move(e)).

🔗

constexpr iterator begin();

3

#

Returns: {*this, ranges::begin(base_), find-next(ranges::begin(base_))}.

4

#

Remarks: In order to provide the amortized constant time complexity required by the range concept, this function caches the result within the split_view for use on subsequent calls.

🔗

constexpr subrange<iterator_t<V>> find-next(iterator_t<V> it);

5

#

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 Class split_view::iterator [range.split.iterator]

🔗

namespace std::ranges {template<forward_range V, forward_range Pattern>requires view && view &&indirectly_comparable<iterator_t, iterator_t, ranges::equal_to>class split_view<V, Pattern>::iterator {private: split_view* parent_ = nullptr; // exposition only iterator_t cur_ = iterator_t(); // exposition only subrange<iterator_t> next_ = subrange<iterator_t>(); // exposition onlybool trailing_empty_ = false; // exposition onlypublic:using iterator_concept = forward_iterator_tag; using iterator_category = input_iterator_tag; using value_type = subrange<iterator_t>; using difference_type = range_difference_t; iterator() = default; constexpr iterator(split_view& parent, iterator_t current, subrange<iterator_t> next); constexpr iterator_t base() const; constexpr value_type operator*() const; constexpr iterator& operator++(); constexpr iterator operator++(int); friend constexpr bool operator==(const iterator& x, const iterator& y); };}

🔗

constexpr iterator(split_view& parent, iterator_t<V> current, subrange<iterator_t<V>> next);

1

#

Effects: Initializes parent_ with addressof(parent),cur_ with std::move(current), andnext_ with std::move(next).

🔗

constexpr iterator_t<V> base() const;

2

#

Effects: Equivalent to: return cur_;

🔗

constexpr value_type operator*() const;

3

#

Effects: Equivalent to: return {cur_, next_.begin()};

🔗

constexpr iterator& operator++();

4

#

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;

🔗

constexpr iterator operator++(int);

5

#

Effects: Equivalent to:auto tmp = *this;++*this;return tmp;

🔗

friend constexpr bool operator==(const iterator& x, const iterator& y);

6

#

Effects: Equivalent to:return x.cur_ == y.cur_ && x.trailing_empty_ == y.trailing_empty_;

25.7.17.4 Class split_view::sentinel [range.split.sentinel]

🔗

namespace std::ranges {template<forward_range V, forward_range Pattern>requires view && view &&indirectly_comparable<iterator_t, iterator_t, ranges::equal_to>struct split_view<V, Pattern>::sentinel {private: sentinel_t end_ = sentinel_t(); // exposition onlypublic:sentinel() = default; constexpr explicit sentinel(split_view& parent); friend constexpr bool operator==(const iterator& x, const sentinel& y); };}

🔗

constexpr explicit sentinel(split_view& parent);

1

#

Effects: Initializes end_ with ranges::end(parent.base_).

🔗

friend constexpr bool operator==(const iterator& x, const sentinel& y);

2

#

Effects: Equivalent to: return x.cur_ == y.end_ && !x.trailing_empty_;