mirror of
https://github.com/Naios/continuable.git
synced 2025-12-07 01:06:44 +08:00
more
This commit is contained in:
parent
91b75953a6
commit
0f5dd265fd
@ -42,22 +42,66 @@ namespace cti {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
namespace expected {
|
namespace expected {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <bool IsCopyable, typename Base>
|
enum class slot_t { empty, value, error };
|
||||||
struct expected_base {
|
|
||||||
explicit expected_base(expected_base const& right) {
|
template <typename Base>
|
||||||
static_cast<Base const*>(&right)->visit([&](auto&& value) {
|
struct expected_base_util {
|
||||||
|
slot_t slot_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template <typename T>
|
||||||
|
void init(T&& value, slot_t slot) {
|
||||||
|
set(slot);
|
||||||
using type = std::decay_t<decltype(value)>;
|
using type = std::decay_t<decltype(value)>;
|
||||||
auto storage = &static_cast<Base*>(this)->storage_;
|
auto storage = &base()->storage_;
|
||||||
new (storage) type(std::forward<decltype(value)>(value));
|
new (storage) type(std::forward<decltype(value)>(value));
|
||||||
|
}
|
||||||
|
void destroy() {
|
||||||
|
weak_destroy();
|
||||||
|
set(slot_t::empty);
|
||||||
|
}
|
||||||
|
void weak_destroy() {
|
||||||
|
base()->visit([&](auto&& value) {
|
||||||
|
using type = std::decay_t<decltype(value)>;
|
||||||
|
value.~type();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
expected_base& operator=(expected_base const& right) {
|
slot_t get() const noexcept {
|
||||||
static_cast<Base const*>(&right)->visit([&](auto&& value) {
|
return slot_;
|
||||||
using type = std::decay_t<decltype(value)>;
|
}
|
||||||
auto storage = &static_cast<Base*>(this)->storage_;
|
bool is(slot_t slot) const noexcept {
|
||||||
new (storage) type(std::forward<decltype(value)>(value));
|
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<Base*>(this);
|
||||||
|
}
|
||||||
|
Base const* base() const noexcept {
|
||||||
|
return static_cast<Base*>(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool IsCopyable, typename Base>
|
||||||
|
struct expected_base : expected_base_util<Base> {
|
||||||
|
explicit expected_base(expected_base const& right) {
|
||||||
|
right.visit([&](auto&& value) {
|
||||||
|
this->init(std::forward<decltype(value)>(value));
|
||||||
});
|
});
|
||||||
return *this;
|
set(right.consume());
|
||||||
|
}
|
||||||
|
expected_base& operator=(expected_base const& right) {
|
||||||
|
this->weak_destroy();
|
||||||
|
right.visit([&](auto&& value) {
|
||||||
|
this->init(std::forward<decltype(value)>(value));
|
||||||
|
});
|
||||||
|
set(right.consume());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@ -70,10 +114,7 @@ template <typename T, typename Storage = std::aligned_storage_t<std::max(
|
|||||||
class expected {
|
class expected {
|
||||||
friend class expected_base;
|
friend class expected_base;
|
||||||
|
|
||||||
enum class slot_t { empty, value, error };
|
|
||||||
|
|
||||||
Storage storage_;
|
Storage storage_;
|
||||||
slot_t slot_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit expected() : slot_(slot_t::empty) {
|
explicit expected() : slot_(slot_t::empty) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user