Skip to content

Instantly share code, notes, and snippets.

@milasudril
Created October 23, 2020 19:59
Show Gist options
  • Save milasudril/05689532df8a6396d2b37e1a39876d5f to your computer and use it in GitHub Desktop.
Save milasudril/05689532df8a6396d2b37e1a39876d5f to your computer and use it in GitHub Desktop.
Make variant from enum
#include <variant>
#include <type_traits>
namespace Library
{
template<class T>
using Empty = std::type_identity<T>;
namespace detail
{
template <class EnumType, template<EnumType> class EnumItemTraits, class T=std::make_integer_sequence<std::underlying_type_t<EnumType>, end(Empty<EnumType>{})> >
struct make_variant;
template<class EnumType, template<EnumType> class EnumItemTraits, std::underlying_type_t<EnumType> val>
struct IntToType:public EnumItemTraits<static_cast<EnumType>(val)>{};
template <class EnumType, template<EnumType> class EnumItemTraits, std::underlying_type_t<EnumType>... indices>
struct make_variant<EnumType, EnumItemTraits, std::integer_sequence<std::underlying_type_t<EnumType>, indices...> >
{
using type = std::variant<typename IntToType<EnumType, EnumItemTraits, indices>::type...>;
};
}
template<class EnumType, template<EnumType> class EnumItemTraits>
using Variant = typename detail::make_variant<EnumType, EnumItemTraits>::type;
}
#include <cstdint>
namespace Client
{
enum class TypeId:uint8_t{Int32, Float32};
constexpr auto end(Library::Empty<TypeId>){return static_cast<std::underlying_type_t<TypeId>>(TypeId::Float32) + 1;}
template<TypeId n>
struct TypeInfo;
template<>
struct TypeInfo<TypeId::Int32>
{
using type = int32_t;
static constexpr char const* name = "i32";
};
template<>
struct TypeInfo<TypeId::Float32>
{
using type = float;
static constexpr char const* name = "f32";
};
using MyVariant = Library::Variant<TypeId, TypeInfo>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment