From 8fbb0262a1cdb98f21eb140d1f7badc754048a71 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Fri, 31 May 2019 21:22:29 +0200 Subject: [PATCH] Added tests for bug when swapping value/null-value and null-value value --- CMakeLists.txt | 3 ++- tests/swap.cpp | 26 ++++++++++++++++++++++++++ tl/optional.hpp | 3 ++- 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tests/swap.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5352502..46fbf1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,8 @@ if(OPTIONAL_ENABLE_TESTS) ${CMAKE_CURRENT_SOURCE_DIR}/tests/assignment.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests/issues.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests/bases.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests/nullopt.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/tests/nullopt.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests/swap.cpp) add_executable(tests ${TEST_SOURCES}) diff --git a/tests/swap.cpp b/tests/swap.cpp new file mode 100644 index 0000000..b78c794 --- /dev/null +++ b/tests/swap.cpp @@ -0,0 +1,26 @@ +#include "catch.hpp" +#include "optional.hpp" + +TEST_CASE("Swap value", "[swap.value]") { + tl::optional o1 = 42; + tl::optional o2 = 12; + o1.swap(o2); + CHECK(o1.value() == 12); + CHECK(o2.value() == 42); +} + +TEST_CASE("Swap value with null intialized", "[swap.value_nullopt]") { + tl::optional o1 = 42; + tl::optional o2 = tl::nullopt; + o1.swap(o2); + CHECK(!o1.has_value()); + CHECK(o2.value() == 42); +} + +TEST_CASE("Swap null intialized with value", "[swap.nullopt_value]") { + tl::optional o1 = tl::nullopt; + tl::optional o2 = 42; + o1.swap(o2); + CHECK(o1.value() == 42); + CHECK(!o2.has_value()); +} diff --git a/tl/optional.hpp b/tl/optional.hpp index e33682c..666ef4e 100644 --- a/tl/optional.hpp +++ b/tl/optional.hpp @@ -1238,9 +1238,9 @@ public: void swap(optional &rhs) noexcept(std::is_nothrow_move_constructible::value &&detail::is_nothrow_swappable::value) { + using std::swap; if (has_value()) { if (rhs.has_value()) { - using std::swap; swap(**this, *rhs); } else { new (std::addressof(rhs.m_value)) T(std::move(this->m_value)); @@ -1250,6 +1250,7 @@ public: new (std::addressof(this->m_value)) T(std::move(rhs.m_value)); rhs.m_value.T::~T(); } + swap(this->m_has_value, rhs.m_has_value); } /// Returns a pointer to the stored value