diff --git a/CMakeLists.txt b/CMakeLists.txt index dd71111e..3e72acbe 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,8 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR -Wno-unneeded-member-function -Wno-unused-member-function -Wno-unsafe-buffer-usage + -Wno-deprecated-declarations + -Wno-ctad-maybe-unsupported -Werror ) elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") diff --git a/include/cista/containers/string.h b/include/cista/containers/string.h index 9c3c9e52..ce64a0c2 100644 --- a/include/cista/containers/string.h +++ b/include/cista/containers/string.h @@ -45,6 +45,12 @@ struct generic_string { set_non_owning(s, len); } + generic_string(generic_string&& o) { move_from(std::move(o)); } + generic_string(generic_string const& o) { copy_from(o); } + + generic_string& operator=(generic_string&& o) { move_from(std::move(o)); } + generic_string& operator=(generic_string const& o) { copy_from(o); } + char* begin() noexcept { return data(); } char* end() noexcept { return data() + size(); } char const* begin() const noexcept { return data(); } @@ -311,6 +317,19 @@ struct generic_string { return h_.size_; } + generic_string& erase(msize_t const pos, msize_t const n) { + if (!is_short() && !h_.self_allocated_) { + set_owning(view()); + } + auto const size_before = size(); + std::memmove(data() + pos, data() + pos + n, size_before - (pos + n)); + std::memset(data() + size_before - n, 0U, n); + if (!is_short()) { + h_.size_ = size_before - n; + } + return *this; + } + struct heap { bool is_short_{false}; bool self_allocated_{false}; diff --git a/test/string_test.cc b/test/string_test.cc index 42d10092..7c6d839b 100644 --- a/test/string_test.cc +++ b/test/string_test.cc @@ -1,4 +1,5 @@ #include +#include #include "doctest.h" @@ -31,6 +32,26 @@ TEST_CASE("string long short corner 14") { CHECK(s.view() == CORNER_CASE_SHORT_14); } +TEST_CASE("string erase") { + auto uut = std::vector>{}; + auto ref = std::vector{}; + for (auto const s : + {CORNER_CASE_SHORT_14, CORNER_CASE_SHORT_15, CORNER_CASE_LONG_16}) { + auto x = cista::generic_string{ + s, cista::generic_string::non_owning}; + x.erase(3, 7); + uut.emplace_back(std::move(x)); + + auto y = std::string{s}; + y.erase(3, 7); + ref.emplace_back(std::move(y)); + } + + for (auto i = 0U; i != ref.size(); ++i) { + CHECK(ref[i] == uut[i].view()); + } +} + TEST_CASE("string long short corner 15") { auto s = string{CORNER_CASE_SHORT_15, string::owning}; CHECK(s.is_short());