| 777 | range_splits(string_type haystack, matcher_type needle) noexcept : matcher_(needle), haystack_(haystack) {} |
| 778 | |
| 779 | class iterator { |
| 780 | char const *start_; // Start of current segment |
| 781 | char const *end_; // End of haystack (immutable) |
| 782 | size_type match_length_; // Length of current segment |
| 783 | matcher_type matcher_; |
| 784 | |
| 785 | public: |
| 786 | using iterator_category = std::forward_iterator_tag; |
| 787 | using difference_type = std::ptrdiff_t; |
| 788 | using value_type = string_view_type; |
| 789 | using pointer = string_view_type; // Needed for compatibility with STL container constructors. |
| 790 | using reference = string_view_type; // Needed for compatibility with STL container constructors. |
| 791 | |
| 792 | iterator(string_view_type haystack, matcher_type matcher) noexcept |
| 793 | : start_(haystack.data()), end_(haystack.data() + haystack.size()), match_length_(0), matcher_(matcher) { |
| 794 | auto position = matcher_(haystack); |
| 795 | match_length_ = position != string_type::npos ? position : haystack.size(); |
| 796 | } |
| 797 | |
| 798 | iterator(string_view_type haystack, matcher_type matcher, end_sentinel_type) noexcept |
| 799 | : start_(haystack.data() + haystack.size() + 1), end_(haystack.data() + haystack.size()), match_length_(0), |
| 800 | matcher_(matcher) {} |
| 801 | |
| 802 | pointer operator->() const noexcept = delete; |
| 803 | value_type operator*() const noexcept { return string_view_type(start_, match_length_); } |
| 804 | |
| 805 | iterator &operator++() noexcept { |
| 806 | start_ += match_length_; |
| 807 | if (start_ > end_) return *this; |
| 808 | // If we were at the end (yielded final empty segment), move past to terminate |
| 809 | if (start_ == end_) { |
| 810 | ++start_; |
| 811 | match_length_ = 0; |
| 812 | return *this; |
| 813 | } |
| 814 | // Skip delimiter |
| 815 | start_ += matcher_.needle_length(); |
| 816 | if (start_ > end_) { |
| 817 | match_length_ = 0; |
| 818 | return *this; |
| 819 | } |
| 820 | // Find next delimiter |
| 821 | string_view_type remaining(start_, static_cast<size_type>(end_ - start_)); |
| 822 | auto position = matcher_(remaining); |
| 823 | match_length_ = position != string_type::npos ? position : remaining.size(); |
| 824 | return *this; |
| 825 | } |
| 826 | |
| 827 | iterator operator++(int) noexcept { |
| 828 | iterator temp = *this; |
| 829 | ++(*this); |
| 830 | return temp; |
| 831 | } |
| 832 | |
| 833 | bool operator!=(iterator const &other) const noexcept { return start_ != other.start_; } |
| 834 | bool operator==(iterator const &other) const noexcept { return start_ == other.start_; } |
| 835 | bool operator!=(end_sentinel_type) const noexcept { return start_ <= end_; } |
| 836 | bool operator==(end_sentinel_type) const noexcept { return start_ > end_; } |
no test coverage detected
searching dependent graphs…