| 118 | } |
| 119 | |
| 120 | int String::naturalCompare(const std::u32string& a, const std::u32string& b) { |
| 121 | size_t i = 0; |
| 122 | size_t j = 0; |
| 123 | |
| 124 | auto is_digit = [](char32_t c) { return c >= U'0' && c <= U'9'; }; |
| 125 | |
| 126 | while (i < a.size() && j < b.size()) { |
| 127 | if (is_digit(a[i]) && is_digit(b[j])) { |
| 128 | size_t leading_zeros_a = 0; |
| 129 | size_t leading_zeros_b = 0; |
| 130 | |
| 131 | while (i < a.size() && a[i] == U'0') { |
| 132 | ++leading_zeros_a; |
| 133 | ++i; |
| 134 | } |
| 135 | |
| 136 | while (j < b.size() && b[j] == U'0') { |
| 137 | ++leading_zeros_b; |
| 138 | ++j; |
| 139 | } |
| 140 | |
| 141 | size_t start_a = i; |
| 142 | size_t start_b = j; |
| 143 | |
| 144 | while (i < a.size() && is_digit(a[i])) |
| 145 | ++i; |
| 146 | |
| 147 | while (j < b.size() && is_digit(b[j])) |
| 148 | ++j; |
| 149 | |
| 150 | size_t len_a = i - start_a; |
| 151 | size_t len_b = j - start_b; |
| 152 | |
| 153 | if (len_a != len_b) |
| 154 | return len_a < len_b ? -1 : 1; |
| 155 | |
| 156 | for (size_t k = 0; k < len_a; ++k) { |
| 157 | if (a[start_a + k] != b[start_b + k]) |
| 158 | return a[start_a + k] < b[start_b + k] ? -1 : 1; |
| 159 | } |
| 160 | |
| 161 | if (leading_zeros_a != leading_zeros_b) |
| 162 | return leading_zeros_a < leading_zeros_b ? -1 : 1; |
| 163 | } |
| 164 | else { |
| 165 | if (a[i] != b[j]) |
| 166 | return a[i] < b[j] ? -1 : 1; |
| 167 | |
| 168 | ++i; |
| 169 | ++j; |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | if (i < a.size()) |
| 174 | return 1; |
| 175 | if (j < b.size()) |
| 176 | return -1; |
| 177 |
no test coverage detected