| 710 | } |
| 711 | |
| 712 | size_t Prev(IterType what) override |
| 713 | { |
| 714 | int32_t pos; |
| 715 | switch (what) { |
| 716 | case ITER_CHARACTER: |
| 717 | pos = this->char_itr->previous(); |
| 718 | break; |
| 719 | |
| 720 | case ITER_WORD: |
| 721 | pos = this->word_itr->preceding(this->char_itr->current()); |
| 722 | /* The ICU word iterator considers both the start and the end of a word a valid |
| 723 | * break point, but we only want word starts. Move to the previous location in |
| 724 | * case the new position points to whitespace. */ |
| 725 | while (pos != icu::BreakIterator::DONE && |
| 726 | IsWhitespace(Utf16DecodeChar((const uint16_t *)&this->utf16_str[pos]))) { |
| 727 | int32_t new_pos = this->word_itr->previous(); |
| 728 | /* Don't set it to DONE if it was valid before. Otherwise we'll return END |
| 729 | * even though the iterator wasn't at the start of the string before. */ |
| 730 | if (new_pos == icu::BreakIterator::DONE) break; |
| 731 | pos = new_pos; |
| 732 | } |
| 733 | |
| 734 | this->char_itr->isBoundary(pos); |
| 735 | break; |
| 736 | |
| 737 | default: |
| 738 | NOT_REACHED(); |
| 739 | } |
| 740 | |
| 741 | return pos == icu::BreakIterator::DONE ? END : this->utf16_to_utf8[pos]; |
| 742 | } |
| 743 | }; |
| 744 | |
| 745 | /* static */ std::unique_ptr<StringIterator> StringIterator::Create() |
nothing calls this directly
no test coverage detected