From f2c9e80a8ace92908cb6d550a578d200b2d42aae Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:24:06 +0800 Subject: [PATCH 1/2] feat add StrJoin --- CMakeLists.txt | 1 + src/ulib/utils/utils.cpp | 29 ++++++++++++++++++++++++ src/ulib/utils/utils.h | 19 +++++++++++----- tests/CMakeLists.txt | 1 + tests/ulib/utils/utils_unittest.cpp | 34 +++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 src/ulib/utils/utils.cpp create mode 100644 tests/ulib/utils/utils_unittest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f269d28..87ca1e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ endif() target_sources( ${PROJECT_NAME} PRIVATE 3party/mongoose/mongoose.c + src/ulib/utils/utils.cpp src/ulib/base/location.h src/ulib/base/location.cpp src/ulib/status.h diff --git a/src/ulib/utils/utils.cpp b/src/ulib/utils/utils.cpp new file mode 100644 index 0000000..58a763f --- /dev/null +++ b/src/ulib/utils/utils.cpp @@ -0,0 +1,29 @@ +#include "utils.h" +#include + +namespace ulib { +std::string +StrJoin(std::vector &vec, + nonstd::string_view delimiter, + bool ignore_empty_str) +{ + if (vec.empty()) { return ""; } + + auto iter = vec.cbegin(); + if (ignore_empty_str) { + // find first non-empty string + while (iter != vec.cend() && iter->empty()) { ++iter; } + } + + if (iter == vec.cend()) { return ""; } + std::stringstream ss; + ss << *iter; + for (++iter; iter != iter + 1; ++iter) { + if (ignore_empty_str && iter->empty()) { continue; } + ss << delimiter << *iter; + } + + return std::move(ss.str()); +} + +}// namespace ulib diff --git a/src/ulib/utils/utils.h b/src/ulib/utils/utils.h index 0d5ff4e..cdcf16c 100644 --- a/src/ulib/utils/utils.h +++ b/src/ulib/utils/utils.h @@ -2,8 +2,18 @@ #define ULIB_SRC_ULIB_UTILS_UTILS_H_ #include +#include +#include +#include namespace ulib { +template +const T & +Clamp(const T &value, const T &low, const T &high, Comp comp) +{ + return comp(value, low) ? low : (comp(high, value) ? high : value); +} + template const T & Clamp(const T &value, const T &low, const T &high) @@ -11,12 +21,9 @@ Clamp(const T &value, const T &low, const T &high) return Clamp(value, low, high, std::less{}); } -template -const T & -Clamp(const T &value, const T &low, const T &high, Comp comp) -{ - return comp(value, low) ? low : (comp(high, value) ? high : value); -} +std::string StrJoin(std::vector &vec, + nonstd::string_view delimiter = ",", + bool ignore_empty_str = true); }// namespace ulib #endif// ULIB_SRC_ULIB_UTILS_UTILS_H_ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6bb2763..59260d1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable( 3party/optional/optional_unittest.cpp 3party/sqlpp11/sqlpp11_unittest.cpp ulib/utils/defer_unittest.cpp + ulib/utils/utils_unittest.cpp ulib/status_or_unittest.cpp) target_link_libraries(ulib_test PRIVATE ulib gtest gtest_main) diff --git a/tests/ulib/utils/utils_unittest.cpp b/tests/ulib/utils/utils_unittest.cpp new file mode 100644 index 0000000..a54d7a5 --- /dev/null +++ b/tests/ulib/utils/utils_unittest.cpp @@ -0,0 +1,34 @@ +#include +#include + +TEST(Utils, Clamp) +{ + EXPECT_EQ(ulib::Clamp(1, 2, 3), 2); + EXPECT_EQ(ulib::Clamp(2, 2, 3), 2); + EXPECT_EQ(ulib::Clamp(3, 2, 3), 3); + EXPECT_EQ(ulib::Clamp(4, 2, 3), 3); +} + +TEST(Utils, StrJoin) +{ + std::vector vec{"a", "b", "c"}; + EXPECT_EQ(ulib::StrJoin(vec, ","), "a,b,c"); + EXPECT_EQ(ulib::StrJoin(vec, ",", false), "a,b,c"); + EXPECT_EQ(ulib::StrJoin(vec, ",", true), "a,b,c"); + vec = {"a", "", "c"}; + EXPECT_EQ(ulib::StrJoin(vec, ","), "a,c"); + EXPECT_EQ(ulib::StrJoin(vec, ",", false), "a,,c"); + EXPECT_EQ(ulib::StrJoin(vec, ",", true), "a,c"); + vec = {"", "", ""}; + EXPECT_EQ(ulib::StrJoin(vec, ","), ""); + EXPECT_EQ(ulib::StrJoin(vec, ",", false), ",,"); + EXPECT_EQ(ulib::StrJoin(vec, ",", true), ""); + vec = {"a", "b", ""}; + EXPECT_EQ(ulib::StrJoin(vec, ","), "a,b"); + EXPECT_EQ(ulib::StrJoin(vec, ",", false), "a,b,"); + EXPECT_EQ(ulib::StrJoin(vec, ",", true), "a,b"); + vec = {"", "b", "c"}; + EXPECT_EQ(ulib::StrJoin(vec, ","), "b,c"); + EXPECT_EQ(ulib::StrJoin(vec, ",", false), ",b,c"); + EXPECT_EQ(ulib::StrJoin(vec, ",", true), "b,c"); +} From e63273fa2bd15a1b1d2153864c56e3bffa0fc162 Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:29:05 +0800 Subject: [PATCH 2/2] fix out of range --- src/ulib/utils/utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ulib/utils/utils.cpp b/src/ulib/utils/utils.cpp index 58a763f..3805fd7 100644 --- a/src/ulib/utils/utils.cpp +++ b/src/ulib/utils/utils.cpp @@ -18,7 +18,7 @@ StrJoin(std::vector &vec, if (iter == vec.cend()) { return ""; } std::stringstream ss; ss << *iter; - for (++iter; iter != iter + 1; ++iter) { + for (++iter; iter != vec.cend(); ++iter) { if (ignore_empty_str && iter->empty()) { continue; } ss << delimiter << *iter; }