| 669 | range_rmatches(string_type haystack, matcher_type needle) : matcher_(needle), haystack_(haystack) {} |
| 670 | |
| 671 | class iterator { |
| 672 | matcher_type matcher_; |
| 673 | string_view_type remaining_; |
| 674 | |
| 675 | public: |
| 676 | using iterator_category = std::forward_iterator_tag; |
| 677 | using difference_type = std::ptrdiff_t; |
| 678 | using value_type = string_view_type; |
| 679 | using pointer = string_view_type; // Needed for compatibility with STL container constructors. |
| 680 | using reference = string_view_type; // Needed for compatibility with STL container constructors. |
| 681 | |
| 682 | iterator(string_view_type haystack, matcher_type matcher) noexcept : matcher_(matcher), remaining_(haystack) { |
| 683 | auto position = matcher_(remaining_); |
| 684 | remaining_.remove_suffix( // |
| 685 | position != string_type::npos // |
| 686 | ? remaining_.size() - position - matcher_.needle_length() |
| 687 | : remaining_.size()); |
| 688 | } |
| 689 | |
| 690 | pointer operator->() const noexcept = delete; |
| 691 | value_type operator*() const noexcept { |
| 692 | return remaining_.substr(remaining_.size() - matcher_.needle_length()); |
| 693 | } |
| 694 | |
| 695 | iterator &operator++() noexcept { |
| 696 | remaining_.remove_suffix(matcher_.skip_length()); |
| 697 | auto position = matcher_(remaining_); |
| 698 | remaining_.remove_suffix( // |
| 699 | position != string_type::npos // |
| 700 | ? remaining_.size() - position - matcher_.needle_length() |
| 701 | : remaining_.size()); |
| 702 | return *this; |
| 703 | } |
| 704 | |
| 705 | iterator operator++(int) noexcept { |
| 706 | iterator temp = *this; |
| 707 | ++(*this); |
| 708 | return temp; |
| 709 | } |
| 710 | |
| 711 | // Assumes both iterators point to the same underlying string. |
| 712 | // This has to be `.data() + .size()`, to be compatible with `std::string_view` on MSVC. |
| 713 | bool operator!=(iterator const &other) const noexcept { |
| 714 | return remaining_.data() + remaining_.size() != other.remaining_.data() + other.remaining_.size(); |
| 715 | } |
| 716 | bool operator==(iterator const &other) const noexcept { |
| 717 | return remaining_.data() + remaining_.size() == other.remaining_.data() + other.remaining_.size(); |
| 718 | } |
| 719 | bool operator!=(end_sentinel_type) const noexcept { return !remaining_.empty(); } |
| 720 | bool operator==(end_sentinel_type) const noexcept { return remaining_.empty(); } |
| 721 | }; |
| 722 | |
| 723 | iterator begin() const noexcept { return {string_view_type(haystack_), matcher_}; } |
| 724 | iterator end() const noexcept { return {string_view_type(haystack_.data(), 0ull), matcher_}; } |
nothing calls this directly
no test coverage detected
searching dependent graphs…