Skip to content

Commit

Permalink
string: fix self-assignment, fixes #222
Browse files Browse the repository at this point in the history
  • Loading branch information
felixguendling committed May 26, 2024
1 parent 8255bcd commit 14389be
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR
-Wno-unsafe-buffer-usage
-Wno-deprecated-declarations
-Wno-ctad-maybe-unsupported
-Wno-self-assign-overloaded
-Werror
)
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
Expand Down
12 changes: 12 additions & 0 deletions include/cista/containers/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ struct generic_string {
}

void move_from(generic_string&& s) noexcept {
if (&s == this) {
return *this;
}
reset();
std::memcpy(static_cast<void*>(this), &s, sizeof(*this));
if constexpr (std::is_pointer_v<Ptr>) {
Expand All @@ -151,6 +154,9 @@ struct generic_string {
}

void copy_from(generic_string const& s) {
if (&s == this) {
return *this;
}
reset();
if (s.is_short()) {
std::memcpy(static_cast<void*>(this), &s, sizeof(s));
Expand Down Expand Up @@ -434,11 +440,17 @@ struct basic_string : public generic_string<Ptr> {
basic_string(basic_string&& o) { base::move_from(std::move(o)); }

basic_string& operator=(basic_string const& o) {
if (&o == this) {
return;
}
base::set_owning(o.data(), o.size());
return *this;
}

basic_string& operator=(basic_string&& o) {
if (&o == this) {
return;
}
base::move_from(std::move(o));
return *this;
}
Expand Down
18 changes: 18 additions & 0 deletions test/string_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@ constexpr auto const CORNER_CASE_LONG_16 = "0123456789123456";
constexpr auto const LONG_STR = "hello world hello world";
constexpr auto const SHORT_STR = "hello world";

TEST_CASE("self assignment") {
// case short string
cista::raw::string test_short{"test_short"};
std::string output_short_pre{test_short};
test_short = test_short;
std::string output_short_post{test_short};
// test_short is empty now
CHECK(output_short_pre == output_short_post);

// case long string
cista::raw::string test_long{"test_long_12345678901234567890123456789012"};
std::string output_long_pre{test_long};
test_long = test_long;
std::string output_long_post{test_long};
// test_long is filled with 0x01 now
CHECK(output_long_pre == output_long_post);
}

TEST_CASE("string init") {
auto s = string{};
CHECK(!s.is_short());
Expand Down

0 comments on commit 14389be

Please sign in to comment.