2022-08-12 13:26:36 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <Orange/Core/AlignedStorage.h>
|
|
|
|
#include <Orange/Core/Traits.h>
|
2023-01-18 08:39:29 +00:00
|
|
|
#include <cstring>
|
2022-08-12 13:26:36 +01:00
|
|
|
|
|
|
|
namespace orange
|
|
|
|
{
|
|
|
|
template <typename... Types>
|
|
|
|
class Variant
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static constexpr size_t MaxElementSize = Max({sizeof(Types)...});
|
|
|
|
static constexpr size_t Alignment = Max({alignof(Types)...});
|
2023-01-18 08:39:29 +00:00
|
|
|
|
2022-08-12 13:26:36 +01:00
|
|
|
explicit Variant()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename... Args>
|
|
|
|
Variant(Args&&... args)
|
|
|
|
{
|
2023-01-18 08:39:29 +00:00
|
|
|
Construct<T>(Forward<Args>(args)...);
|
2022-08-12 13:26:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename... Args>
|
|
|
|
void Construct(Args&&... args)
|
|
|
|
{
|
2023-01-18 08:39:29 +00:00
|
|
|
new (Ptr<T>()) T(Forward<Args>(args)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void Destruct()
|
|
|
|
{
|
|
|
|
Ptr<T>()->~T();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Clear()
|
|
|
|
{
|
|
|
|
std::memset(&data, 0, sizeof(data));
|
2022-08-12 13:26:36 +01:00
|
|
|
}
|
|
|
|
|
2022-08-12 20:08:28 +01:00
|
|
|
template <typename T> T* Ptr() { return reinterpret_cast<T*> (data.data); }
|
|
|
|
template <typename T> const T* Ptr() const { return reinterpret_cast<const T*>(data.data); }
|
2022-08-12 13:26:36 +01:00
|
|
|
|
|
|
|
template <typename T> T& Get() { return *Ptr<T>(); }
|
|
|
|
template <typename T> const T& Get() const { return *Ptr<T>(); }
|
|
|
|
private:
|
|
|
|
AlignedStorage<MaxElementSize, Alignment> data;
|
|
|
|
};
|
|
|
|
}
|