diff --git a/include/continuable/detail/traits.hpp b/include/continuable/detail/traits.hpp index fec1fd9..cba0245 100644 --- a/include/continuable/detail/traits.hpp +++ b/include/continuable/detail/traits.hpp @@ -46,6 +46,22 @@ namespace traits { template using at_t = decltype(std::get(std::declval>())); +namespace detail { +template +struct index_of_impl; +template +struct index_of_impl : std::integral_constant { +}; +template +struct index_of_impl + : std::integral_constant::value> {}; +} // namespace detail + +/// Evaluates to the index of T in the given pack +template +using index_of_t = detail::index_of_impl; + /// A tagging type for wrapping other types template struct identity {}; diff --git a/include/continuable/detail/variant.hpp b/include/continuable/detail/variant.hpp index 3c294e8..68f0a37 100644 --- a/include/continuable/detail/variant.hpp +++ b/include/continuable/detail/variant.hpp @@ -9,11 +9,11 @@ Copyright(c) 2015 - 2018 Denis Blank - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files(the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and / or sell - copies of the Software, and to permit persons to whom the Software is + Permission is_slot hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files(the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and / or +sell copies of the Software, and to permit persons to whom the Software is_slot furnished to do so, subject to the following conditions : The above copyright notice and this permission notice shall be included in @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -54,16 +55,24 @@ constexpr std::size_t max_size(std::initializer_list list) { return m; } +/// Declares the aligned storage union for the given types template using storage_of_t = std::aligned_storage_t; +/// The value fpr the empty slot +using slot_t = std::uint8_t; + +/// The value which is used to mark the empty slot +using empty_slot = + std::integral_constant::max()>; + template struct optional_variant_base { storage_of_t storage_; - std::uint8_t slot_; + slot_t slot_; - constexpr optional_variant_base() : slot_(0U) { + constexpr optional_variant_base() : slot_(empty_slot::value) { } optional_variant_base(optional_variant_base const&) noexcept { @@ -89,14 +98,14 @@ struct optional_variant_move_base { assert(!other.is_empty()); #ifndef _NDEBUG - me.set(slot_t::empty); + me.set_slot(empty_slot::value); #endif other.visit([&](auto&& value) { // ... me.init(std::move(value)); }); - me.set(other.get()); + me.set_slot(other.get()); other.destroy(); } optional_variant_move_base& @@ -112,7 +121,7 @@ struct optional_variant_move_base { // ... me.init(std::move(value)); }); - me.set(other.get()); + me.set_slot(other.get()); other.destroy(); return *this; } @@ -131,14 +140,14 @@ struct optional_variant_copy_base : optional_variant_copy_base { assert(!other.is_empty()); #ifndef _NDEBUG - me.set(slot_t::empty); + me.set_slot(empty_slot::value); #endif other.visit([&](auto&& value) { // ... me.init(std::move(value)); }); - me.set(other.get()); + me.set_slot(other.get()); } optional_variant_copy_base& operator=(optional_variant_copy_base&&) = default; optional_variant_copy_base& operator=(optional_variant_copy_base const& right) @@ -154,7 +163,7 @@ struct optional_variant_copy_base : optional_variant_copy_base { // ... me.init(std::move(value)); }); - me.set(other.get()); + me.set_slot(other.get()); return *this; } }; @@ -168,21 +177,22 @@ struct optional_variant_copy_base default; optional_variant_copy_base& operator=(optional_variant_copy_base const&) = delete; - optional_variant_copy_base& - operator=(optional_variant_copy_base&& right) = default; + optional_variant_copy_base& operator=(optional_variant_copy_base&&) = default; }; + +/// Deduces to a true_type if all parameters T satisfy the predicate. +template