From 5267a4726deb418bf9f2b18455f5947be3393f9f Mon Sep 17 00:00:00 2001 From: Jessica James Date: Tue, 9 Nov 2021 22:57:40 -0600 Subject: [PATCH] vector pass --- src/include/split.hpp | 23 +++++++++++------ src/test/split.cpp | 57 ++++++++++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/include/split.hpp b/src/include/split.hpp index 3e93b1e..777acda 100644 --- a/src/include/split.hpp +++ b/src/include/split.hpp @@ -47,7 +47,15 @@ using split_container_helper_t = decltype(split_container_helper_f typename ContainerT = std::vector, typename... ContainerArgsT, typename InputT> constexpr auto split(const InputT& in_string, typename InputT::value_type in_delim) { using MemberT = typename impl::first_arg>::first_type; @@ -63,13 +71,13 @@ constexpr auto split(const InputT& in_string, typename InputT::value_type in_del for (auto itr = begin; itr != end; ++itr) { if (*itr == in_delim) { // Push token to result - result.emplace_back(begin, itr - begin); + result.emplace_back(begin, itr); begin = itr + 1; } } // Push final token to the end; may be empty - result.emplace_back(begin, end - begin); + result.emplace_back(begin, end); return result; } @@ -79,8 +87,9 @@ constexpr auto split(const InputT& in_string, typename InputT::value_type in_del * An empty pair if in_string is empty, * otherwise if the delimiter is not present, a pair who's `second` member is empty and `first` member is equal to `in_string`, * otherwise, a pair split at first instance of the delimiter - * Complexity: O(in_string.size()) * + * @tparam InStringT String type being passed into split_once + * @tparam ResultMemberT String type used to populate the result * @param in_string string to split * @param in_delim delimiter to split on * @return A pair representing `in_string` split at a delimiter, with first half stored in `first` and second in `last` @@ -117,7 +126,7 @@ constexpr std::pair split_once(const InStringT& in * @param in_string String to split * @param in_delim Delimiter to split upon * @param in_limit Maximum number of times to split - * @return ResultT containing to up `in_limit` + 1 substrings + * @return Container containing to up `in_limit` + 1 substrings; result[in_limit] is the unprocessed remainder */ template typename ContainerT = std::vector, typename... ContainerArgsT, typename InputT> constexpr auto split_n(const InputT& in_string, typename InputT::value_type in_delim, size_t in_limit) { @@ -134,14 +143,14 @@ constexpr auto split_n(const InputT& in_string, typename InputT::value_type in_d for (auto itr = begin; itr != end && in_limit != 0; ++itr) { if (*itr == in_delim) { // Push token to result - result.emplace_back(begin, itr - begin); + result.emplace_back(begin, itr); begin = itr + 1; --in_limit; } } // Push final token to the end; may be empty - result.emplace_back(begin, end - begin); + result.emplace_back(begin, end); return result; } diff --git a/src/test/split.cpp b/src/test/split.cpp index 1d59a0f..3e0101f 100644 --- a/src/test/split.cpp +++ b/src/test/split.cpp @@ -67,9 +67,9 @@ public: }; TYPED_TEST_SUITE(SplitNTest, char_types); -template -std::basic_string make_word(size_t length = 8, T delim = static_cast(0)) { - std::basic_string result; +template> +ResultT make_word(size_t length = 8, T delim = static_cast(0)) { + ResultT result; if (length == 0) { return {}; @@ -99,7 +99,7 @@ std::basic_string_view make_word_view(size_t length = 8, T delim = static_cas return s_result; } -template +template> struct RandomTestData { RandomTestData(T in_delim) : m_delim{ in_delim } { @@ -116,21 +116,22 @@ struct RandomTestData { auto random_words = word_count_distribution(randgen); while (m_tokens.size() < random_words) { - m_tokens.push_back(make_word(word_length_distribution(randgen))); - m_str += m_tokens.back(); + m_tokens.push_back(make_word(word_length_distribution(randgen))); + m_str.insert(m_str.end(), m_tokens.back().begin(), m_tokens.back().end()); if (m_tokens.size() < random_words) { - m_str += m_delim; + m_str.insert(m_str.end(), m_delim); } } } - std::basic_string get_remainder(size_t in_times_split) { - std::basic_string result; + StringT get_remainder(size_t in_times_split) { + StringT result; while (in_times_split < m_tokens.size()) { - result += m_tokens[in_times_split]; + auto& token = m_tokens[in_times_split]; + result.insert(result.end(), token.begin(), token.end()); ++in_times_split; if (in_times_split < m_tokens.size()) { - result += m_delim; + result.insert(result.end(), m_delim); } } @@ -138,8 +139,8 @@ struct RandomTestData { } T m_delim; - std::basic_string m_str; - std::vector> m_tokens; + StringT m_str; + std::vector m_tokens; }; TYPED_TEST(SplitSVTest, empty) { @@ -224,6 +225,14 @@ TYPED_TEST(SplitOnceTest, random) { EXPECT_EQ(split_result.second, data.get_remainder(1)); } +TYPED_TEST(SplitOnceTest, random_vector) { + RandomTestData> data{ static_cast(0) }; + std::pair, std::vector> split_result = split_once(data.m_str, data.m_delim); + + EXPECT_EQ(split_result.first, data.m_tokens[0]); + EXPECT_EQ(split_result.second, data.get_remainder(1)); +} + TYPED_TEST(SplitOnceTest, random_view) { RandomTestData data{ static_cast(0) }; std::pair, std::basic_string_view> split_result = split_once_view(data.m_str, data.m_delim); @@ -248,6 +257,20 @@ TYPED_TEST(SplitNTest, random) { EXPECT_EQ(split_result[n], data.get_remainder(n)); } +TYPED_TEST(SplitNTest, random_vector) { + RandomTestData> data{ static_cast(0) }; + constexpr size_t n = 4; + std::vector> split_result = split_n>(data.m_str, data.m_delim, n); + + // Tokens shall be same up until last one (n + 1) + EXPECT_EQ(split_result.size(), n + 1); + for (size_t index = 0; index != n; ++index) { + EXPECT_EQ(split_result[index], data.m_tokens[index]); + } + + EXPECT_EQ(split_result[n], data.get_remainder(n)); +} + TYPED_TEST(SplitNTest, random_view) { RandomTestData data{ static_cast(0) }; constexpr size_t n = 4; @@ -279,7 +302,13 @@ TYPED_TEST(SplitSringTest, single_word) { TYPED_TEST(SplitSringTest, random) { RandomTestData data{ static_cast(0) }; - auto split_result = split(data.m_str, data.m_delim); + std::vector> split_result = split(data.m_str, data.m_delim); + EXPECT_EQ(split_result, data.m_tokens); +} + +TYPED_TEST(SplitSringTest, random_vector) { + RandomTestData> data{ static_cast(0) }; + std::vector> split_result = split>(data.m_str, data.m_delim); EXPECT_EQ(split_result, data.m_tokens); }