diff --git a/CMakeLists.txt b/CMakeLists.txt index 1843fd3..8f6616f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.6) PROJECT( PeeloResult - VERSION 0.3.0 + VERSION 0.4.0 DESCRIPTION "Header only C++ result type." HOMEPAGE_URL "https://github.com/peelonet/peelo-result" LANGUAGES CXX diff --git a/README.md b/README.md index a638ba7..b287120 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,9 @@ method of `result` class. If this method returns `true`, then it's value can be accessed with the `value` method, otherwise it's error can be accessed with the `error` method. -**Note**: The underlying containers are implemented with [std::unique_ptr], so -accessing `value` of erroneous result leads to undefined behavior and vice +Note: Accessing `value` or erronous result leads to undefined behavior and vice versa. -[std::unique_ptr]: https://en.cppreference.com/w/cpp/memory/unique_ptr - ### Usage example ```C++ diff --git a/include/peelo/result.hpp b/include/peelo/result.hpp index 60dcacb..f0589d9 100644 --- a/include/peelo/result.hpp +++ b/include/peelo/result.hpp @@ -26,12 +26,12 @@ */ #pragma once -#include +#include namespace peelo { template - class result + class result final { public: using value_type = T; @@ -51,17 +51,53 @@ namespace peelo : m_value(that.m_value ? new value_type(*that.m_value) : nullptr) , m_error(that.m_error ? new error_type(*that.m_error) : nullptr) {} + result(result&& that) + : m_value(std::move(that.m_value)) + , m_error(std::move(that.m_error)) + { + that.m_value = nullptr; + that.m_error = nullptr; + } + template result(const result& that) : m_value(that ? new value_type(that.value()) : nullptr) , m_error(that ? nullptr : new error_type(that.error())) {} + ~result() + { + if (m_value) + { + delete m_value; + } + if (m_error) + { + delete m_error; + } + } + result& operator=(const result& that) { if (this != &that) { - m_value.reset(that.m_value ? new value_type(*that.m_value) : nullptr); - m_error.reset(that.m_error ? new error_type(*that.m_error) : nullptr); + if (m_value) + { + delete m_value; + m_value = nullptr; + } + if (m_error) + { + delete m_error; + m_error = nullptr; + } + if (that.m_value) + { + m_value = new value_type(*that.m_value); + } + if (that.m_error) + { + m_error = new error_type(*that.m_error); + } } return *this; @@ -70,10 +106,43 @@ namespace peelo template result& operator=(const result& that) { - const auto has_value = that.has_value(); + if (m_value) + { + delete m_value; + m_value = nullptr; + } + if (m_error) + { + delete m_error; + m_error = nullptr; + } + if (that) + { + m_value = new value_type(that.value()); + } else { + m_error = new error_type(that.error()); + } + + return *this; + } - m_value.reset(has_value ? new value_type(that.value()) : nullptr); - m_error.reset(has_value ? nullptr : new error_type(that.error())); + result& operator=(result&& that) + { + if (this != &that) + { + if (m_value) + { + delete m_value; + } + if (m_error) + { + delete m_error; + } + m_value = std::move(that.m_value); + m_error = std::move(that.m_error); + that.m_value = nullptr; + that.m_error = nullptr; + } return *this; } @@ -105,16 +174,16 @@ namespace peelo inline bool equals(const result& that) const { - if (has_value()) + if (m_value) { - if (!that.has_value()) + if (!that) { return false; } return *m_value == *that.m_value; } - else if (that.has_value()) + else if (that) { return false; } @@ -135,16 +204,16 @@ namespace peelo template inline bool equals(const result& that) const { - if (has_value()) + if (m_value) { - if (!that.has_value()) + if (!that) { return false; } return *m_value == that.value(); } - else if (that.has_value()) + else if (that) { return false; } @@ -170,7 +239,7 @@ namespace peelo , m_error(error) {} private: - std::unique_ptr m_value; - std::unique_ptr m_error; + value_type* m_value; + error_type* m_error; }; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 65b5401..3e4897b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,7 +14,7 @@ FOREACH(TEST_FILENAME ${TEST_SOURCES}) TARGET_COMPILE_FEATURES( ${TEST_NAME} PUBLIC - cxx_std_17 + cxx_std_11 ) IF(MSVC)