Add lo-hi to the class; return whether class got bigger.
| 756 | |
| 757 | // Add lo-hi to the class; return whether class got bigger. |
| 758 | bool CharClassBuilder::AddRange(Rune lo, Rune hi) { |
| 759 | if (hi < lo) |
| 760 | return false; |
| 761 | |
| 762 | if (lo <= 'z' && hi >= 'A') { |
| 763 | // Overlaps some alpha, maybe not all. |
| 764 | // Update bitmaps telling which ASCII letters are in the set. |
| 765 | Rune lo1 = std::max<Rune>(lo, 'A'); |
| 766 | Rune hi1 = std::min<Rune>(hi, 'Z'); |
| 767 | if (lo1 <= hi1) |
| 768 | upper_ |= ((1 << (hi1 - lo1 + 1)) - 1) << (lo1 - 'A'); |
| 769 | |
| 770 | lo1 = std::max<Rune>(lo, 'a'); |
| 771 | hi1 = std::min<Rune>(hi, 'z'); |
| 772 | if (lo1 <= hi1) |
| 773 | lower_ |= ((1 << (hi1 - lo1 + 1)) - 1) << (lo1 - 'a'); |
| 774 | } |
| 775 | |
| 776 | { // Check whether lo, hi is already in the class. |
| 777 | iterator it = ranges_.find(RuneRange(lo, lo)); |
| 778 | if (it != end() && it->lo <= lo && hi <= it->hi) |
| 779 | return false; |
| 780 | } |
| 781 | |
| 782 | // Look for a range abutting lo on the left. |
| 783 | // If it exists, take it out and increase our range. |
| 784 | if (lo > 0) { |
| 785 | iterator it = ranges_.find(RuneRange(lo-1, lo-1)); |
| 786 | if (it != end()) { |
| 787 | lo = it->lo; |
| 788 | if (it->hi > hi) |
| 789 | hi = it->hi; |
| 790 | nrunes_ -= it->hi - it->lo + 1; |
| 791 | ranges_.erase(it); |
| 792 | } |
| 793 | } |
| 794 | |
| 795 | // Look for a range abutting hi on the right. |
| 796 | // If it exists, take it out and increase our range. |
| 797 | if (hi < Runemax) { |
| 798 | iterator it = ranges_.find(RuneRange(hi+1, hi+1)); |
| 799 | if (it != end()) { |
| 800 | hi = it->hi; |
| 801 | nrunes_ -= it->hi - it->lo + 1; |
| 802 | ranges_.erase(it); |
| 803 | } |
| 804 | } |
| 805 | |
| 806 | // Look for ranges between lo and hi. Take them out. |
| 807 | // This is only safe because the set has no overlapping ranges. |
| 808 | // We've already removed any ranges abutting lo and hi, so |
| 809 | // any that overlap [lo, hi] must be contained within it. |
| 810 | for (;;) { |
| 811 | iterator it = ranges_.find(RuneRange(lo, hi)); |
| 812 | if (it == end()) |
| 813 | break; |
| 814 | nrunes_ -= it->hi - it->lo + 1; |
| 815 | ranges_.erase(it); |