Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions c++/nda/mem/handle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,11 @@ namespace nda::mem {
* @brief Move assignment operator first releases the resources held by the current handle and then moves the
* resources from the source to the current handle.
*
* @param h Source handle.
* @param h Source handle. Must not alias `*this`.
*/
handle_heap &operator=(handle_heap &&h) noexcept {
EXPECTS(this != &h);

// release current resources if they are not shared and not null
if (not sptr and not(is_null())) destruct({_data, _size});

Expand Down Expand Up @@ -206,6 +208,7 @@ namespace nda::mem {
* @param h Source handle.
*/
handle_heap &operator=(handle_heap const &h) {
if (this == &h) return *this;
*this = handle_heap{h};
return *this;
}
Expand Down Expand Up @@ -382,9 +385,10 @@ namespace nda::mem {
/**
* @brief Move assignment operator simply calls the copy assignment operator.
* @details If an exception occurs in the constructor of `T`, the program terminates.
* @param h Source handle.
* @param h Source handle. Must not alias `*this`.
*/
handle_stack &operator=(handle_stack &&h) noexcept {
EXPECTS(this != &h);
operator=(h);
return *this;
}
Expand All @@ -401,6 +405,7 @@ namespace nda::mem {
* @param h Source handle.
*/
handle_stack &operator=(handle_stack const &h) {
if (this == &h) return *this;
for (size_t i = 0; i < Size; ++i) new (data() + i) T(h[i]);
return *this;
}
Expand Down Expand Up @@ -545,9 +550,10 @@ namespace nda::mem {
*
* @details In both cases, it resets the source handle to a null state.
*
* @param h Source handle.
* @param h Source handle. Must not alias `*this`.
*/
handle_sso &operator=(handle_sso &&h) noexcept {
EXPECTS(this != &h);
clean();
_size = h._size;
if (on_heap()) {
Expand Down
7 changes: 5 additions & 2 deletions test/c++/nda_mem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,21 @@ H check_handle() {
move2 = std::move(copy1);
EXPECT_EQ(handle.size(), move1.size());
EXPECT_EQ(handle.size(), move2.size());
std::swap(handle, handle); // check self swap
#ifdef NDEBUG // self-swap violates the handle move-assign precondition; release-only.
std::swap(handle, handle);
#endif
for (int i = 0; i < handle.size(); ++i) {
EXPECT_EQ(handle[i], static_cast<value_t>(i));
EXPECT_EQ(move1[i], static_cast<value_t>(i));
EXPECT_EQ(move2[i], static_cast<value_t>(i));
}

// check self move assignment (see https://stackoverflow.com/questions/9322174/move-assignment-operator-and-if-this-rhs)
#ifdef NDEBUG // self-move-assign violates the handle move-assign precondition; release-only.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wself-move"
move1 = std::move(move1);
#pragma GCC diagnostic pop
#endif

return handle;
}
Expand Down