mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Establish the basic functionality of the optional_variant
This commit is contained in:
parent
22896a69af
commit
e78291669c
@ -46,8 +46,7 @@ namespace variant {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
// We don't want to pull the algorithm header in
|
// We don't want to pull the algorithm header in
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
constexpr std::size_t max_size(T... i) {
|
constexpr std::size_t max_element_of(std::initializer_list<std::size_t> list) {
|
||||||
constexpr std::initializer_list<std::size_t> const list{i...};
|
|
||||||
std::size_t m = 0;
|
std::size_t m = 0;
|
||||||
for (auto current : list) {
|
for (auto current : list) {
|
||||||
if (current > m) {
|
if (current > m) {
|
||||||
@ -56,11 +55,16 @@ constexpr std::size_t max_size(T... i) {
|
|||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
template <typename... T>
|
||||||
|
constexpr std::size_t storage_of_impl() {
|
||||||
|
constexpr auto size = max_element_of({sizeof(T)...});
|
||||||
|
constexpr auto align = max_element_of({alignof(T)...});
|
||||||
|
return std::aligned_storage_t<size, align>{};
|
||||||
|
}
|
||||||
|
|
||||||
/// Declares the aligned storage union for the given types
|
/// Declares the aligned storage union for the given types
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
using storage_of_t =
|
using storage_of_t = decltype(storage_of_impl<T...>());
|
||||||
std::aligned_storage_t<max_size(sizeof(T)...), max_size(alignof(T)...)>;
|
|
||||||
|
|
||||||
/// The value fpr the empty slot
|
/// The value fpr the empty slot
|
||||||
using slot_t = std::uint8_t;
|
using slot_t = std::uint8_t;
|
||||||
@ -257,20 +261,20 @@ public:
|
|||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
V& cast() noexcept {
|
V& cast() noexcept {
|
||||||
assert(!is_slot(traits::index_of_t<std::decay_t<V>, T...>::value));
|
assert(is_slot(traits::index_of_t<std::decay_t<V>, T...>::value));
|
||||||
return *reinterpret_cast<std::decay_t<V>*>(&this->storage_);
|
return *reinterpret_cast<std::decay_t<V>*>(&this->storage_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
V const& cast() const noexcept {
|
V const& cast() const noexcept {
|
||||||
assert(!is_slot(traits::index_of_t<std::decay_t<V>, T...>::value));
|
assert(is_slot(traits::index_of_t<std::decay_t<V>, T...>::value));
|
||||||
return *reinterpret_cast<std::decay_t<V> const*>(&this->storage_);
|
return *reinterpret_cast<std::decay_t<V> const*>(&this->storage_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename C, typename V>
|
template <typename C, typename V>
|
||||||
static void visit_dispatch(optional_variant* me, V&& visitor) {
|
static void visit_dispatch(optional_variant* me, V&& visitor) {
|
||||||
std::forward<V>(me->cast<C>());
|
std::forward<V>(visitor)(me->cast<C>());
|
||||||
}
|
}
|
||||||
template <typename C, typename V>
|
template <typename C, typename V>
|
||||||
static void visit_dispatch_const(optional_variant const* me, V&& visitor) {
|
static void visit_dispatch_const(optional_variant const* me, V&& visitor) {
|
||||||
|
|||||||
@ -177,5 +177,12 @@ int main(int, char**) {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
variant::optional_variant<int, float> v;
|
{
|
||||||
|
variant::optional_variant<int, float> var;
|
||||||
|
|
||||||
|
var = 1;
|
||||||
|
var = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user