diff --git a/CMakeLists.txt b/CMakeLists.txt index 937cedc..5d4495c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,8 @@ project(${projectname} VERSION 0.1.0) if (NOT DEFINED CPPAPIFRAMEWORK_APPLY_FLAGS) message("Applying flags") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_DEFAULT 17) + set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_DEFAULT 20) set(CXX17 ON) set(CMAKE_CXX_EXTENSIONS ON) set(CMAKE_C_EXTENSIONS ON) @@ -94,19 +94,19 @@ if (NOT DEFINED USING_COMPILER_FLAGS) if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") message(STATUS "Setting G++ flags") # G++ - target_compile_options(${projectname} PRIVATE -Wall -Werror -Wextra -std=gnu++17 -Wformat-security -Wconversion -Wsign-conversion -Wno-gnu -Wno-gnu-statement-expression) + target_compile_options(${projectname} PRIVATE -Wall -Werror -Wextra -std=gnu++20 -Wformat-security -Wconversion -Wsign-conversion -Wno-gnu -Wno-gnu-statement-expression) elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") message(STATUS "Setting MSVC flags") # MSVC target_compile_options(${projectname} PRIVATE /EHsc /W2 /c) elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") message(STATUS "Setting Clang flags") - set(USING_COMPILER_FLAGS -Weverything -Werror -Wno-unused-macros -std=gnu++17 -Wno-disabled-macro-expansion -Wpedantic -Wno-padded -Wno-constant-conversion -Wno-c++98-compat -Wno-padded -Wno-date-time -Wno-c++98-compat-pedantic -Wno-exit-time-destructors -Wno-global-constructors -Wno-gnu -Wno-gnu-statement-expression) + set(USING_COMPILER_FLAGS -Weverything -Werror -Wno-unused-macros -std=gnu++20 -Wno-disabled-macro-expansion -Wpedantic -Wno-padded -Wno-constant-conversion -Wno-c++98-compat -Wno-padded -Wno-date-time -Wno-c++98-compat-pedantic -Wno-exit-time-destructors -Wno-global-constructors -Wno-gnu -Wno-gnu-statement-expression) target_compile_options(${PROJECT_NAME} PRIVATE ${USING_COMPILER_FLAGS}) # Clang-tidy if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") message(STATUS "Setting clang-tidy flags") - set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src;--warnings-as-errors=\"*\";-extra-arg=-std=gnu++17;-extra-arg=-Wno-gnu;-export-fixes=clang-tidy-sugested-fixes.txt") + set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src;--warnings-as-errors=\"*\";-extra-arg=-std=gnu++20;-extra-arg=-Wno-gnu;-export-fixes=clang-tidy-sugested-fixes.txt") endif() endif() endif() diff --git a/src/WebSocket/HandshakeWebSocket.cpp b/src/WebSocket/HandshakeWebSocket.cpp index 6aa6575..4d6fd91 100644 --- a/src/WebSocket/HandshakeWebSocket.cpp +++ b/src/WebSocket/HandshakeWebSocket.cpp @@ -160,7 +160,7 @@ void putOnWire(Pistache::Http::ResponseWriter &response_) { } const std::string WEBSOCKET_GUID("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); -const std::string WEBSOCKET_VERSION("13"); +[[maybe_unused]] const std::string WEBSOCKET_VERSION("13"); // https://github.com/pocoproject/poco/blob/devel/Net/src/WebSocket.cpp#L301 auto computeAccept(const std::string &key) -> std::string { diff --git a/src/utils/Strutils.hpp b/src/utils/Strutils.hpp index 5f5c3a0..9c8067c 100644 --- a/src/utils/Strutils.hpp +++ b/src/utils/Strutils.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,23 @@ class Strutils { std::string("$1")); } + static inline auto join(const std::span &vec, + const std::string &term) -> std::string { + std::string result; + result.reserve(vec.size() * term.size()); + + for (const auto &str : vec) { + result += str; + result += term; + } + + if (!result.empty() && !term.empty()) { + result.erase(result.size() - term.size()); + } + + return result; + } + template static auto explode(std::string_view strview, std::string_view term) -> std::vector { diff --git a/src/utils/stringviewstream.hpp b/src/utils/stringviewstream.hpp index b0d5108..507ec5e 100644 --- a/src/utils/stringviewstream.hpp +++ b/src/utils/stringviewstream.hpp @@ -72,51 +72,6 @@ class basic_stringviewbuf : public std::basic_streambuf { : basic_stringviewbuf(std::move(i_rhs), xfer_bufptrs(i_rhs, this)) { i_rhs.M_sync(const_cast(i_rhs.M_string.data()), 0, 0); } - -#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - explicit basic_stringviewbuf(const allocator_type &i_a) - : basic_stringviewbuf(ios_base::in | std::ios_base::out, i_a) {} - - basic_stringviewbuf(ios_base::openmode inMode, const allocator_type &i_a) - : streambuf_type(), MMode(inMode), M_string(i_a) {} - - explicit basic_stringviewbuf(stringview_type &&i_s, - ios_base::openmode inMode = ios_base::in | - ios_base::out) - : streambuf_type(), MMode(inMode), M_string(std::move(i_s)) { - M_stringviewbuf_init(inMode); - } - - template - basic_stringviewbuf(const basic_string &i_s, - const allocator_type &i_a) - : basic_stringviewbuf(i_s, ios_base::in | std::ios_base::out, i_a) {} - - template - basic_stringviewbuf(const basic_string &i_s, - ios_base::openmode inMode, const allocator_type &i_a) - : streambuf_type(), MMode(inMode), - M_string(i_s.data(), i_s.size(), i_a) { - M_stringviewbuf_init(inMode); - } - - template - explicit basic_stringviewbuf( - const basic_string &i_s, - ios_base::openmode inMode = ios_base::in | ios_base::out) - : basic_stringviewbuf(i_s, inMode, allocator_type{}) {} - - basic_stringviewbuf(basic_stringviewbuf &&i_rhs, const allocator_type &i_a) - : basic_stringviewbuf(std::move(i_rhs), i_a, - xfer_bufptrs(i_rhs, this)) { - i_rhs.M_sync(const_cast(i_rhs.M_string.data()), 0, 0); - } - - allocator_type getAllocator() const noexcept { - return M_string.getAllocator(); - } -#endif // C++20 - // 27.8.2.2 Assign and swap: auto operator=(const basic_stringviewbuf &) @@ -164,35 +119,6 @@ class basic_stringviewbuf : public std::basic_streambuf { } return i_ret; } - -#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI -#if i_cpp_concepts - template <_Allocator_like _SAlloc> - basic_string str(const _SAlloc &i_sa) const { - auto i_sv = view(); - return {i_sv.data(), i_sv.size(), i_sa}; - } -#endif - - stringview_type str() && { - if (char_type *i_hi = M_highMark()) { - // Set length to end of character sequence and add null terminator. - M_string.M_set_length(M_highMark() - this->pbase()); - } - auto in_str = std::move(M_string); - M_string.clear(); - M_sync(M_string.data(), 0, 0); - return in_str; - } - - basic_string_view view() const noexcept { - if (char_type *i_hi = M_highMark()) - return {this->pbase(), i_hi}; - else - return M_string; - } -#endif // C++20 - /** * @brief Setting a new buffer. * @param i_s The string to use as a new sequence. @@ -208,15 +134,6 @@ class basic_stringviewbuf : public std::basic_streambuf { } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI -#if i_cpp_concepts - template <_Allocator_like _SAlloc> - requires(!is_same_v<_SAlloc, Alloc>) - void str(const basic_string &i_s) { - M_string.assign(i_s.data(), i_s.size()); - M_stringviewbuf_init(MMode); - } -#endif - void str(stringview_type &&i_s) { M_string = std::move(i_s); M_stringviewbuf_init(MMode); @@ -507,15 +424,6 @@ class basic_stringviewbuf : public std::basic_streambuf { basic_stringviewbuf(basic_stringviewbuf &&i_rhs, xfer_bufptrs && /*unused*/) : streambuf_type(static_cast(i_rhs)), MMode(i_rhs.MMode), M_string(std::move(i_rhs.M_string)) {} - -#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - // The move constructor initializes an xfer_bufptrs temporary then - // delegates to this constructor to performs moves during its lifetime. - basic_stringviewbuf(basic_stringviewbuf &&i_rhs, const allocator_type &i_a, - xfer_bufptrs &&) - : streambuf_type(static_cast(i_rhs)), - MMode(i_rhs.MMode), M_string(std::move(i_rhs.M_string), i_a) {} -#endif #endif // C++11 }; diff --git a/tests/test_strutils.cpp b/tests/test_strutils.cpp index e0e032f..c59ef64 100644 --- a/tests/test_strutils.cpp +++ b/tests/test_strutils.cpp @@ -27,3 +27,26 @@ TEST(TestStrutils, TestExplodeFunction) { std::vector{"a,b,c"}); EXPECT_EQ(Strutils::explode("a,b,c", ","), fullvecabc); } + +// NOLINTNEXTLINE +TEST(TestStrutils, JoinTest) { + std::vector vec1 = {"hello", "world", "!"}; + std::string result1 = Strutils::join(vec1, " "); + EXPECT_EQ(result1, "hello world !"); + + std::vector vec2 = {"apple", "banana", "cherry"}; + std::string result2 = Strutils::join(vec2, ", "); + EXPECT_EQ(result2, "apple, banana, cherry"); + + std::vector vec3 = {"1", "2", "3", "4", "5"}; + std::string result3 = Strutils::join(vec3, ""); + EXPECT_EQ(result3, "12345"); + + std::vector vec4 = {"", "", ""}; + std::string result4 = Strutils::join(vec4, " "); + EXPECT_EQ(result4, " "); + + std::vector vec5 = {}; + std::string result5 = Strutils::join(vec5, " "); + EXPECT_EQ(result5, ""); +}