* @brief split a delimited string into a vector of values * * String split from: https://stackoverflow.com/a/5506223/13030801 * This is the fasted string split algorithm that we could find. * * @param input a delimited string to split * @param delimiter_list a string_view of characters representing delimiters * * @return a std
| 61 | * @return a std::vector<std::string> of the delimited items from input |
| 62 | */ |
| 63 | std::vector<std::string> |
| 64 | string_split(std::string const& input, std::string_view delimiter_list) |
| 65 | { |
| 66 | std::vector<std::string> result; |
| 67 | |
| 68 | // Initialize a set of boolean flags indexed by ascii character value, one bit per |
| 69 | // character. If the bit is 1, that character is a delimiter. |
| 70 | std::bitset<255> delim; |
| 71 | std::for_each(std::begin(delimiter_list), std::end(delimiter_list), [&delim](char c) { delim[c] = true; }); |
| 72 | |
| 73 | std::string::const_iterator beg; |
| 74 | bool in_token = false; |
| 75 | // Loop through the input string and check each character for a delimiter. If a |
| 76 | // delimiter is found, add the string processed so far to the result container. |
| 77 | for (auto it = std::begin(input); it != std::end(input); std::advance(it, 1)) |
| 78 | { |
| 79 | // If *it is a delimiter, the value marked by the delimiter is the string between |
| 80 | // "beg" and "it"... save it off into the result container. |
| 81 | if (delim[*it]) |
| 82 | { |
| 83 | if (in_token) |
| 84 | { |
| 85 | // Only store a token if we're actually parsing a token. |
| 86 | result.push_back(std::string(beg, it)); |
| 87 | in_token = false; |
| 88 | } |
| 89 | } |
| 90 | else if (!in_token) |
| 91 | { |
| 92 | // Found a non-delimiter character. If we're not currently processing a token, |
| 93 | // mark that we've found the beginning of a token so the next characters are |
| 94 | // part of the token. |
| 95 | beg = it; |
| 96 | in_token = true; |
| 97 | } |
| 98 | } |
| 99 | // deal with the boundary condition... the last token in input. |
| 100 | if (in_token) |
| 101 | { |
| 102 | result.push_back(std::string(beg, std::end(input))); |
| 103 | } |
| 104 | |
| 105 | return result; |
| 106 | } |
| 107 | #endif |
| 108 | |
| 109 | /** |
no test coverage detected