From 5b0eaa74e5c4c243d322899f3bcd9d73ff8b3959 Mon Sep 17 00:00:00 2001 From: Seth Parker Date: Fri, 28 Jun 2024 10:22:21 -0400 Subject: [PATCH 1/5] (string) Add partition --- include/educelab/core/utils/String.hpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/educelab/core/utils/String.hpp b/include/educelab/core/utils/String.hpp index 24a99a8..c4d2a6b 100644 --- a/include/educelab/core/utils/String.hpp +++ b/include/educelab/core/utils/String.hpp @@ -189,6 +189,28 @@ static auto split(std::string_view s, const Ds&... ds) return tokens; } +/** @brief Partition a string by a separator substring */ +static auto partition(std::string_view s, const std::string_view sep) + -> std::tuple +{ + // Find the starting position + const auto startPos = s.find(sep); + + // Didn't find the delimiter + if (startPos == std::string::npos) { + return {s, "", ""}; + } + + // Split into parts + const auto endPos = startPos + sep.size(); + auto pre = s.substr(0, startPos); + auto mid = s.substr(startPos, endPos); + auto post = s.substr(endPos); + + // Return the parts + return {pre, mid, post}; +} + /** * @brief Convert a string to a numeric type. * From 048fb797f229cbc57511501d8e973820585453c9 Mon Sep 17 00:00:00 2001 From: Seth Parker Date: Fri, 28 Jun 2024 11:49:26 -0400 Subject: [PATCH 2/5] (string) Add to_padded_string --- include/educelab/core/utils/String.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/educelab/core/utils/String.hpp b/include/educelab/core/utils/String.hpp index c4d2a6b..1472864 100644 --- a/include/educelab/core/utils/String.hpp +++ b/include/educelab/core/utils/String.hpp @@ -211,6 +211,18 @@ static auto partition(std::string_view s, const std::string_view sep) return {pre, mid, post}; } +/** @brief Convert an Integer to a padded string */ +template < + typename Integer, + std::enable_if_t, bool> = true> +auto to_padded_string(Integer val, const int padding, const char fill = '0') + -> std::string +{ + std::stringstream stream; + stream << std::setw(padding) << std::setfill(fill) << val; + return stream.str(); +} + /** * @brief Convert a string to a numeric type. * From 7aeed432480a454c69392017a517599caaf2e395 Mon Sep 17 00:00:00 2001 From: Seth Parker Date: Fri, 28 Jun 2024 11:56:51 -0400 Subject: [PATCH 3/5] Add missing include --- include/educelab/core/utils/String.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/educelab/core/utils/String.hpp b/include/educelab/core/utils/String.hpp index 1472864..46b1cc2 100644 --- a/include/educelab/core/utils/String.hpp +++ b/include/educelab/core/utils/String.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include From c6180d3058f62f7868e4ceb313f8412313ee2b1e Mon Sep 17 00:00:00 2001 From: Seth Parker Date: Fri, 28 Jun 2024 13:55:40 -0400 Subject: [PATCH 4/5] Fix partition. Add unit tests --- include/educelab/core/utils/String.hpp | 6 ++-- tests/src/TestString.cpp | 50 +++++++++++++++++++++----- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/include/educelab/core/utils/String.hpp b/include/educelab/core/utils/String.hpp index 46b1cc2..457781e 100644 --- a/include/educelab/core/utils/String.hpp +++ b/include/educelab/core/utils/String.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -203,10 +204,9 @@ static auto partition(std::string_view s, const std::string_view sep) } // Split into parts - const auto endPos = startPos + sep.size(); auto pre = s.substr(0, startPos); - auto mid = s.substr(startPos, endPos); - auto post = s.substr(endPos); + auto mid = s.substr(startPos, sep.size()); + auto post = s.substr(startPos + sep.size()); // Return the parts return {pre, mid, post}; diff --git a/tests/src/TestString.cpp b/tests/src/TestString.cpp index 55ac8bf..9a6d7e1 100644 --- a/tests/src/TestString.cpp +++ b/tests/src/TestString.cpp @@ -1,6 +1,7 @@ #include #include +#include #include "educelab/core/utils/String.hpp" @@ -151,17 +152,50 @@ TEST(String, Split) EXPECT_EQ(split("This is only a test."), expected); } +TEST(String, Partition) +{ + // key=value + const auto [p0, m0, s0] = partition("key=value", "="); + EXPECT_EQ(p0, "key"); + EXPECT_EQ(m0, "="); + EXPECT_EQ(s0, "value"); + + // {} replacement + const auto [p1, m1, s1] = partition("prefix{}suffix", "{}"); + EXPECT_EQ(p1, "prefix"); + EXPECT_EQ(m1, "{}"); + EXPECT_EQ(s1, "suffix"); + + // to existing strings + std::string p2, m2, s2; + std::tie(p2, m2, s2) = partition("abc", "b"); + EXPECT_EQ(p2, "a"); + EXPECT_EQ(m2, "b"); + EXPECT_EQ(s2, "c"); +} + +TEST(String, ToPaddedString) +{ + // zero-pad (default) + EXPECT_EQ(to_padded_string(5, 3), "005"); + EXPECT_EQ(to_padded_string(5, 10), "0000000005"); + + // zero-pad (custom) + EXPECT_EQ(to_padded_string(5, 3, '5'), "555"); + EXPECT_EQ(to_padded_string(5, 3, 'x'), "xx5"); +} + TEST(String, ToNumeric) { std::string test{"100.3456 unparsed"}; - EXPECT_EQ(to_numeric(test), int8_t(100)); - EXPECT_EQ(to_numeric(test), uint8_t(100)); - EXPECT_EQ(to_numeric(test), int16_t(100)); - EXPECT_EQ(to_numeric(test), uint16_t(100)); - EXPECT_EQ(to_numeric(test), int32_t(100)); - EXPECT_EQ(to_numeric(test), uint32_t(100)); - EXPECT_EQ(to_numeric(test), int64_t(100)); - EXPECT_EQ(to_numeric(test), uint64_t(100)); + EXPECT_EQ(to_numeric(test), std::int8_t{100}); + EXPECT_EQ(to_numeric(test), std::uint8_t{100}); + EXPECT_EQ(to_numeric(test), std::int16_t{100}); + EXPECT_EQ(to_numeric(test), std::uint16_t{100}); + EXPECT_EQ(to_numeric(test), std::int32_t{100}); + EXPECT_EQ(to_numeric(test), std::uint32_t{100}); + EXPECT_EQ(to_numeric(test), std::int64_t{100}); + EXPECT_EQ(to_numeric(test), std::uint64_t{100}); EXPECT_EQ(to_numeric(test), 100.3456F); EXPECT_EQ(to_numeric(test), 100.3456); From 40b850e9a2a852c96fdee84c42b056464e04ced8 Mon Sep 17 00:00:00 2001 From: Seth Parker Date: Fri, 28 Jun 2024 16:15:06 -0400 Subject: [PATCH 5/5] Version bump --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54bb08e..a4deb98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) -project(EduceLabCore VERSION 0.2.1) +project(EduceLabCore VERSION 0.3.0) # Setup project directories set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)