[range.split] (original) (raw)

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]

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.

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

[Example 1: string str{"the quick brown fox"};for (auto word : views::split(str, ' ')) { cout << string_view(word) << '*';} — _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<V> && view<Pattern> && indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> class split_view : public view_interface<split_view<V, Pattern>> { private: V base_ = V(); Pattern pattern_ = Pattern(); struct iterator; struct sentinel; public: split_view() requires default_initializable<V> && default_initializable<Pattern> = default;constexpr explicit split_view(V base, Pattern pattern);template<forward_range R> requires constructible_from<V, views::all_t<R>> && constructible_from<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<V> { return base_; } constexpr V base() && { return std::move(base_); } constexpr iterator begin();constexpr auto end() { if constexpr (common_range<V>) { return iterator{*this, ranges::end(base_), {}};} else { return sentinel{*this};} } constexpr subrange<iterator_t<V>> find-next(iterator_t<V>); };template<class R, class P> split_view(R&&, P&&) -> split_view<views::all_t<R>, views::all_t<P>>;template<forward_range R> split_view(R&&, range_value_t<R>) -> split_view<views::all_t<R>, single_view<range_value_t<R>>>;}

constexpr explicit split_view(V base, Pattern pattern);

Effects: Initializes base_ with std​::​move(base), and_pattern__ with std​::​move(pattern).

Effects: Initializes base_ with views​::​all(std​::​forward<R>(r)), and_pattern__ with views​::​single(std​::​move(e)).

constexpr _iterator_ begin();

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

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

constexpr subrange<iterator_t<V>> _find-next_(iterator_t<V> it);

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<V> && view<Pattern> && indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> class split_view<V, Pattern>::iterator { private: split_view* parent_ = nullptr; iterator_t<V> cur_ = iterator_t<V>(); subrange<iterator_t<V>> next_ = subrange<iterator_t<V>>(); bool trailing_empty_ = false; 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);};}

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

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

constexpr iterator_t<V> base() const;

Effects: Equivalent to: return cur_;

constexpr value_type operator*() const;

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

constexpr _iterator_& operator++();

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);

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

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

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<V> && view<Pattern> && indirectly_comparable<iterator_t<V>, iterator_t<Pattern>, ranges::equal_to> struct split_view<V, Pattern>::sentinel { private: sentinel_t<V> end_ = sentinel_t<V>(); public: sentinel() = default;constexpr explicit sentinel(split_view& parent);friend constexpr bool operator==(const iterator& x, const sentinel& y);};}

constexpr explicit _sentinel_(split_view& parent);

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

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

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