|
@ -15,6 +15,11 @@ |
|
|
|
|
|
|
|
|
namespace gp{ |
|
|
namespace gp{ |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief A form of variant that expect only classes whose size is strictly defined at compile time |
|
|
|
|
|
* |
|
|
|
|
|
* @tparam T The list of types accepted by the variant |
|
|
|
|
|
*/ |
|
|
template<typename ...T> |
|
|
template<typename ...T> |
|
|
class fixed_variant final { |
|
|
class fixed_variant final { |
|
|
std::size_t index = std::numeric_limits<std::size_t>::max(); |
|
|
std::size_t index = std::numeric_limits<std::size_t>::max(); |
|
@ -29,6 +34,12 @@ namespace gp{ |
|
|
: fixed_variant(typename first_of<T...>::type{}) |
|
|
: fixed_variant(typename first_of<T...>::type{}) |
|
|
{} |
|
|
{} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief Construct a new fixed variant from an object that is legal in it |
|
|
|
|
|
* |
|
|
|
|
|
* @tparam U A type that belongs in the list of types the variant supports |
|
|
|
|
|
* @param value The copied value |
|
|
|
|
|
*/ |
|
|
template<typename U, std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int> = 0> |
|
|
template<typename U, std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int> = 0> |
|
|
fixed_variant(U& value) |
|
|
fixed_variant(U& value) |
|
|
: index{r_index_of<gp::remove_cvref_t<U>, T...>::value} |
|
|
: index{r_index_of<gp::remove_cvref_t<U>, T...>::value} |
|
@ -52,6 +63,12 @@ namespace gp{ |
|
|
static_assert(list_contains_class<int, char, int, char>::value, "list_contains_class doesn't work properly"); |
|
|
static_assert(list_contains_class<int, char, int, char>::value, "list_contains_class doesn't work properly"); |
|
|
static_assert(!list_contains_class<int, char, char>::value, "list_contains_class doesn't work properly"); |
|
|
static_assert(!list_contains_class<int, char, char>::value, "list_contains_class doesn't work properly"); |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief Construct a new fixed variant from an object that is legal in it by moving said object |
|
|
|
|
|
* |
|
|
|
|
|
* @tparam U A type that belongs in the list of types the variant supports |
|
|
|
|
|
* @param value The moved value |
|
|
|
|
|
*/ |
|
|
template<typename U, std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int> = 0> |
|
|
template<typename U, std::enable_if_t<list_contains_class<gp::remove_cvref_t<U>,T...>::value,int> = 0> |
|
|
fixed_variant(U&& value) |
|
|
fixed_variant(U&& value) |
|
|
: index{r_index_of<gp::remove_cvref_t<U>, T...>::value} |
|
|
: index{r_index_of<gp::remove_cvref_t<U>, T...>::value} |
|
@ -97,11 +114,24 @@ namespace gp{ |
|
|
mvtor(oth.buffer, buffer); |
|
|
mvtor(oth.buffer, buffer); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief Gives an alternative (value usable in a switch statement) representing the given type |
|
|
|
|
|
* |
|
|
|
|
|
* @tparam U the type to match against |
|
|
|
|
|
* @return constexpr size_t a value that can be used in the case part of a switch case statement |
|
|
|
|
|
* @see type() |
|
|
|
|
|
*/ |
|
|
template<typename U> |
|
|
template<typename U> |
|
|
constexpr static size_t alt() { |
|
|
constexpr static size_t alt() { |
|
|
return r_index_of<U, T...>::value; |
|
|
return r_index_of<U, T...>::value; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief Gives the type as can be matched in a switch statement using alternatives |
|
|
|
|
|
* |
|
|
|
|
|
* @return size_t a value that can be used in the switch part of a switch case statement |
|
|
|
|
|
* @see alt() |
|
|
|
|
|
*/ |
|
|
size_t type() const { |
|
|
size_t type() const { |
|
|
return index; |
|
|
return index; |
|
|
} |
|
|
} |
|
@ -170,6 +200,13 @@ namespace gp{ |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief Brutally decay the variant into the given type. |
|
|
|
|
|
Will throw (@see bad_variant_access) if exceptions are enabled, else behaviour is undefined. |
|
|
|
|
|
* |
|
|
|
|
|
* @tparam U the type to decay towards |
|
|
|
|
|
* @return constexpr U& a decayed reference to the variant |
|
|
|
|
|
*/ |
|
|
template<typename U> |
|
|
template<typename U> |
|
|
constexpr U& value() |
|
|
constexpr U& value() |
|
|
{ |
|
|
{ |
|
@ -183,6 +220,13 @@ namespace gp{ |
|
|
return *reinterpret_cast<U*>(buffer); |
|
|
return *reinterpret_cast<U*>(buffer); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief Tests if the variant is of a particular type. |
|
|
|
|
|
* |
|
|
|
|
|
* @tparam U the type to match against |
|
|
|
|
|
* @return true if the types match |
|
|
|
|
|
* @return false if the types don't match |
|
|
|
|
|
*/ |
|
|
template<typename U> |
|
|
template<typename U> |
|
|
constexpr bool is_a() |
|
|
constexpr bool is_a() |
|
|
{ |
|
|
{ |
|
|