| 161 | }); |
| 162 | } |
| 163 | string string::strip(bool left, bool right, std::optional<const std::string_view> chars) { |
| 164 | static auto strip_part = [](const std::string & s, bool left, bool right, std::optional<const std::string_view> chars) -> std::string { |
| 165 | size_t start = 0; |
| 166 | size_t end = s.length(); |
| 167 | auto match_char = [&chars](unsigned char c) -> bool { |
| 168 | return chars ? (*chars).find(c) != std::string::npos : isspace(c); |
| 169 | }; |
| 170 | if (left) { |
| 171 | while (start < end && match_char(static_cast<unsigned char>(s[start]))) { |
| 172 | ++start; |
| 173 | } |
| 174 | } |
| 175 | if (right) { |
| 176 | while (end > start && match_char(static_cast<unsigned char>(s[end - 1]))) { |
| 177 | --end; |
| 178 | } |
| 179 | } |
| 180 | return s.substr(start, end - start); |
| 181 | }; |
| 182 | if (parts.empty()) { |
| 183 | return *this; |
| 184 | } |
| 185 | if (left) { |
| 186 | for (size_t i = 0; i < parts.size(); ++i) { |
| 187 | parts[i].val = strip_part(parts[i].val, true, false, chars); |
| 188 | if (parts[i].val.empty()) { |
| 189 | // remove empty part |
| 190 | parts.erase(parts.begin() + i); |
| 191 | --i; |
| 192 | continue; |
| 193 | } else { |
| 194 | break; |
| 195 | } |
| 196 | } |
| 197 | } |
| 198 | if (right) { |
| 199 | for (size_t i = parts.size(); i-- > 0;) { |
| 200 | parts[i].val = strip_part(parts[i].val, false, true, chars); |
| 201 | if (parts[i].val.empty()) { |
| 202 | // remove empty part |
| 203 | parts.erase(parts.begin() + i); |
| 204 | continue; |
| 205 | } else { |
| 206 | break; |
| 207 | } |
| 208 | } |
| 209 | } |
| 210 | return *this; |
| 211 | } |
| 212 | |
| 213 | } // namespace jinja |