From 9cc226c28a638b37c9f553c6445fcafc9c5bfdf8 Mon Sep 17 00:00:00 2001 From: Christian Kaiser Date: Thu, 5 Dec 2024 12:06:45 -0300 Subject: [PATCH] Add string_view variant of base::split_string() --- base/split_string.cpp | 43 ++++++++++++++++++++++++++++++++++--- base/split_string.h | 5 ++++- base/split_string_tests.cpp | 40 ++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/base/split_string.cpp b/base/split_string.cpp index 747c06f5b..03898b558 100644 --- a/base/split_string.cpp +++ b/base/split_string.cpp @@ -13,12 +13,10 @@ #include namespace { - struct is_separator { const std::string* separators; - is_separator(const std::string* seps) : separators(seps) { - } + is_separator(const std::string* seps) : separators(seps) {} bool operator()(std::string::value_type chr) const { @@ -32,6 +30,22 @@ namespace { } }; + struct is_separator_view { + const std::string_view* separators; + + is_separator_view(const std::string_view* seps) : separators(seps) {} + + bool operator()(std::string_view::value_type chr) const + { + for (std::string_view::const_iterator + it = separators->begin(), + end = separators->end(); it != end; ++it) { + if (chr == *it) + return true; + } + return false; + } + }; } void base::split_string(const std::string& string, @@ -56,3 +70,26 @@ void base::split_string(const std::string& string, } } } + +void base::split_string(const std::string_view& string, + std::vector& parts, + const std::string_view& separators) +{ + const std::size_t elements = + 1 + std::count_if(string.begin(), string.end(), + is_separator_view(&separators)); + parts.reserve(elements); + + std::size_t beg = 0, end; + while (true) { + end = string.find_first_of(separators, beg); + if (end != std::string::npos) { + parts.push_back(string.substr(beg, end - beg)); + beg = end + 1; + } + else { + parts.push_back(string.substr(beg)); + break; + } + } +} diff --git a/base/split_string.h b/base/split_string.h index 65c896dbe..c3c02c2d0 100644 --- a/base/split_string.h +++ b/base/split_string.h @@ -9,14 +9,17 @@ #pragma once #include +#include #include namespace base { - void split_string(const std::string& string, std::vector& parts, const std::string& separators); + void split_string(const std::string_view& string, + std::vector& parts, + const std::string_view& separators); } #endif diff --git a/base/split_string_tests.cpp b/base/split_string_tests.cpp index 6422a7bae..d7a4191a8 100644 --- a/base/split_string_tests.cpp +++ b/base/split_string_tests.cpp @@ -38,7 +38,47 @@ TEST(SplitString, OneSeparator) TEST(SplitString, MultipleSeparators) { + std::string string = "Hello,World"; std::vector result; + base::split_string(string, result, ",r"); + ASSERT_EQ(3, result.size()); + EXPECT_EQ("Hello", result[0]); + EXPECT_EQ("Wo", result[1]); + EXPECT_EQ("ld", result[2]); +} + +TEST(SplitStringView, Empty) +{ + const std::string_view string = ""; + std::vector result; + base::split_string("", result, ","); + ASSERT_EQ(1, result.size()); + EXPECT_EQ("", result[0]); +} + +TEST(SplitStringView, NoSeparator) +{ + const std::string_view string = "Hello,World"; + std::vector result; + base::split_string(string, result, ""); + ASSERT_EQ(1, result.size()); + EXPECT_EQ("Hello,World", result[0]); +} + +TEST(SplitStringView, OneSeparator) +{ + const std::string_view string = "Hello,World"; + std::vector result; + base::split_string("Hello,World", result, ","); + ASSERT_EQ(2, result.size()); + EXPECT_EQ("Hello", result[0]); + EXPECT_EQ("World", result[1]); +} + +TEST(SplitStringView, MultipleSeparators) +{ + const std::string_view string = "Hello,World"; + std::vector result; base::split_string("Hello,World", result, ",r"); ASSERT_EQ(3, result.size()); EXPECT_EQ("Hello", result[0]);