From 0f5dd265fdb7c5b1719652f3d431f81b1547092f Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Wed, 22 Nov 2017 02:11:27 +0100 Subject: [PATCH] more --- include/continuable/detail/expected.hpp | 71 +++++++++++++++++++------ 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/include/continuable/detail/expected.hpp b/include/continuable/detail/expected.hpp index 7fb455e..35d4716 100644 --- a/include/continuable/detail/expected.hpp +++ b/include/continuable/detail/expected.hpp @@ -42,22 +42,66 @@ namespace cti { namespace detail { namespace expected { namespace detail { -template -struct expected_base { - explicit expected_base(expected_base const& right) { - static_cast(&right)->visit([&](auto&& value) { +enum class slot_t { empty, value, error }; + +template +struct expected_base_util { + slot_t slot_; + +protected: + template + void init(T&& value, slot_t slot) { + set(slot); + using type = std::decay_t; + auto storage = &base()->storage_; + new (storage) type(std::forward(value)); + } + void destroy() { + weak_destroy(); + set(slot_t::empty); + } + void weak_destroy() { + base()->visit([&](auto&& value) { using type = std::decay_t; - auto storage = &static_cast(this)->storage_; - new (storage) type(std::forward(value)); + value.~type(); }); } - expected_base& operator=(expected_base const& right) { - static_cast(&right)->visit([&](auto&& value) { - using type = std::decay_t; - auto storage = &static_cast(this)->storage_; - new (storage) type(std::forward(value)); + slot_t get() const noexcept { + return slot_; + } + bool is(slot_t slot) const noexcept { + return get() == slot; + } + void set(slot_t slot) { + slot_ = slot; + } + slot_t consume(slot_t slot) { + auto current = get(); + destroy(); + return current; + } + Base* base() noexcept { + return static_cast(this); + } + Base const* base() const noexcept { + return static_cast(this); + } +}; + +template +struct expected_base : expected_base_util { + explicit expected_base(expected_base const& right) { + right.visit([&](auto&& value) { + this->init(std::forward(value)); }); - return *this; + set(right.consume()); + } + expected_base& operator=(expected_base const& right) { + this->weak_destroy(); + right.visit([&](auto&& value) { + this->init(std::forward(value)); + }); + set(right.consume()); } }; } // namespace detail @@ -70,10 +114,7 @@ template