#endif
}
+template<typename T>
+std::vector<T>
+split_at(string_view input, const char* separators)
+{
+ assert(separators != nullptr && separators[0] != '\0');
+
+ std::vector<T> result;
+
+ size_t start = 0;
+ while (start < input.size()) {
+ size_t end = input.find_first_of(separators, start);
+
+ if (end == string_view::npos) {
+ result.emplace_back(input.data() + start, input.size() - start);
+ break;
+ } else if (start != end) {
+ result.emplace_back(input.data() + start, end - start);
+ }
+
+ start = end + 1;
+ }
+
+ return result;
+}
+
} // namespace
namespace Util {
return path.substr(0, path.length() - get_extension(path).length());
}
+std::vector<string_view>
+split_into_views(string_view s, const char* separators)
+{
+ return split_at<string_view>(s, separators);
+}
+
+std::vector<std::string>
+split_into_strings(string_view s, const char* separators)
+{
+ return split_at<std::string>(s, separators);
+}
+
bool
starts_with(string_view string, string_view prefix)
{
// extension as determined by `get_extension()`.
nonstd::string_view remove_extension(nonstd::string_view path);
+// Split `input` into words at any of the characters listed in `separators`.
+// These words are a view into `input`; empty words are omitted. `separators`
+// must neither be the empty string nor a nullptr.
+std::vector<nonstd::string_view> split_into_views(nonstd::string_view input,
+ const char* separators);
+
+// Same as `split_into_views` but the words are copied from `input`.
+std::vector<std::string> split_into_strings(nonstd::string_view input,
+ const char* separators);
+
// Return true if prefix is a prefix of string.
bool starts_with(nonstd::string_view string, nonstd::string_view prefix);
CHECK(Util::remove_extension("/foo/bar/f.abc.txt") == "/foo/bar/f.abc");
}
+TEST_CASE("Util::split_into_views")
+{
+ {
+ CHECK(Util::split_into_views("", "/").empty());
+ }
+ {
+ CHECK(Util::split_into_views("///", "/").empty());
+ }
+ {
+ auto s = Util::split_into_views("a/b", "/");
+ REQUIRE(s.size() == 2);
+ CHECK(s.at(0) == "a");
+ CHECK(s.at(1) == "b");
+ }
+ {
+ auto s = Util::split_into_views("a/b", "x");
+ REQUIRE(s.size() == 1);
+ CHECK(s.at(0) == "a/b");
+ }
+ {
+ auto s = Util::split_into_views("a/b:c", "/:");
+ REQUIRE(s.size() == 3);
+ CHECK(s.at(0) == "a");
+ CHECK(s.at(1) == "b");
+ CHECK(s.at(2) == "c");
+ }
+ {
+ auto s = Util::split_into_views(":a//b..:.c/:/.", "/:.");
+ REQUIRE(s.size() == 3);
+ CHECK(s.at(0) == "a");
+ CHECK(s.at(1) == "b");
+ CHECK(s.at(2) == "c");
+ }
+ {
+ auto s = Util::split_into_views(".0.1.2.3.4.5.6.7.8.9.", "/:.+_abcdef");
+ REQUIRE(s.size() == 10);
+ CHECK(s.at(0) == "0");
+ CHECK(s.at(9) == "9");
+ }
+}
+
+TEST_CASE("Util::split_into_strings")
+{
+ {
+ CHECK(Util::split_into_strings("", "/").empty());
+ }
+ {
+ CHECK(Util::split_into_strings("///", "/").empty());
+ }
+ {
+ auto s = Util::split_into_strings("a/b", "/");
+ REQUIRE(s.size() == 2);
+ CHECK(s.at(0) == "a");
+ CHECK(s.at(1) == "b");
+ }
+ {
+ auto s = Util::split_into_strings("a/b", "x");
+ REQUIRE(s.size() == 1);
+ CHECK(s.at(0) == "a/b");
+ }
+ {
+ auto s = Util::split_into_strings("a/b:c", "/:");
+ REQUIRE(s.size() == 3);
+ CHECK(s.at(0) == "a");
+ CHECK(s.at(1) == "b");
+ CHECK(s.at(2) == "c");
+ }
+ {
+ auto s = Util::split_into_strings(":a//b..:.c/:/.", "/:.");
+ REQUIRE(s.size() == 3);
+ CHECK(s.at(0) == "a");
+ CHECK(s.at(1) == "b");
+ CHECK(s.at(2) == "c");
+ }
+ {
+ auto s = Util::split_into_strings(".0.1.2.3.4.5.6.7.8.9.", "/:.+_abcdef");
+ REQUIRE(s.size() == 10);
+ CHECK(s.at(0) == "0");
+ CHECK(s.at(9) == "9");
+ }
+}
+
TEST_CASE("Util::starts_with")
{
CHECK(Util::starts_with("", ""));