* @brief Finds the first occurrence of @c c character in string @c str that is * outside of embedded lists delimited by @c pairs. * * @param[out] pos Character position of @c std::string::npos if character not * found. Position is left unchanged, if @c true is returned. * @param str String to find occerrences in. * @param c Character to find. * @param pairs Vector of delimit
| 1255 | * <tt>','</tt>, delimiters <tt>"{}()"</tt>): <tt>"{a(b}c),def"</tt>. |
| 1256 | */ |
| 1257 | bool findFirstInEmbeddedLists(std::size_t &pos, const std::string &str, |
| 1258 | char c, const std::vector<std::pair<char, char>> &pairs) { |
| 1259 | if (str.empty()) { |
| 1260 | pos = std::string::npos; |
| 1261 | return false; |
| 1262 | } |
| 1263 | |
| 1264 | std::map<std::pair<char, char>, unsigned> counters; |
| 1265 | for (const auto &p : pairs) { |
| 1266 | counters[p] = 0; |
| 1267 | } |
| 1268 | |
| 1269 | for (std::size_t i = 0; i < str.size(); ++i) { |
| 1270 | for (const auto &p : pairs) { |
| 1271 | if (str[i] == p.first) { |
| 1272 | ++counters[p]; |
| 1273 | } |
| 1274 | if (str[i] == p.second) { |
| 1275 | if (counters[p] > 0) { |
| 1276 | --counters[p]; |
| 1277 | } |
| 1278 | else { |
| 1279 | return true; |
| 1280 | } |
| 1281 | } |
| 1282 | } |
| 1283 | |
| 1284 | if (str[i] == c) { |
| 1285 | bool ok = true; |
| 1286 | for (const auto &p : pairs) { |
| 1287 | if (counters[p] > 0) { |
| 1288 | ok = false; |
| 1289 | break; |
| 1290 | } |
| 1291 | } |
| 1292 | |
| 1293 | if (!ok) { |
| 1294 | continue; |
| 1295 | } |
| 1296 | |
| 1297 | pos = i; |
| 1298 | return false; |
| 1299 | } |
| 1300 | } |
| 1301 | |
| 1302 | for (const auto &p : pairs) { |
| 1303 | if (counters[p] > 0) { |
| 1304 | return true; |
| 1305 | } |
| 1306 | } |
| 1307 | |
| 1308 | pos = std::string::npos; |
| 1309 | return false; |
| 1310 | } |
| 1311 | |
| 1312 | std::string removeConsecutiveSpaces(const std::string& str) |
| 1313 | { |