10template <
typename... Types>
11class alignas(max_align<Types...>::value)
Variant {
34 copy_construct_from(other);
88 template <
typename T,
typename... Args>
106 template <
typename T>
bool is() const noexcept {
110 template <
typename T> T *
ptr() {
111 if (!
is<T>())
return nullptr;
117 template <
typename T>
const T *
ptr()
const {
118 if (!
is<T>())
return nullptr;
129 template <
typename T> T &
get() {
140 template <
typename T>
const T &
get()
const {
146 template <
typename T>
bool equals(
const T &other)
const {
154 template <
typename Visitor>
void visit(Visitor &visitor) {
159 using Fn = void (*)(
void *, Visitor &);
164 static constexpr Fn table[] = {
169 size_t index =
_tag - 1;
170 if (index <
sizeof...(Types)) {
175 template <
typename Visitor>
void visit(Visitor &visitor)
const {
180 using Fn = void (*)(
const void *, Visitor &);
183 static constexpr Fn table[] = {
188 size_t index =
_tag - 1;
189 if (index <
sizeof...(Types)) {
196 template <
typename T,
typename Visitor>
201 v.accept(*typed_ptr);
204 template <
typename T,
typename Visitor>
209 v.accept(*typed_ptr);
214 using Fn = void (*)(
void *);
221 template <
typename T>
static void destroy_fn(
void *storage) {
230 using Fn = void (*)(
void *,
const Variant &);
231 static constexpr Fn table[] = {&Variant::template
copy_fn<Types>...};
236 template <
typename T>
241 new (storage) T(*source_ptr);
246 using Fn = void (*)(
void *,
Variant &);
247 static constexpr Fn table[] = {&Variant::template
move_fn<Types>...};
248 table[other._tag - 1](&
_storage, other);
257 new (storage) T(
fl::move(*source_ptr));
268 return type_to_tag_impl<T, Types...>::value;
278 template <
typename T,
typename U,
typename... Rest>
char _storage[max_size< Types... >::value]
Variant & operator=(Variant &&other) noexcept
Variant & operator=(const T &value)
Variant & operator=(const Variant &other)
void construct(Args &&...args)
static void visit_fn_const(const void *storage, Visitor &v)
static void visit_fn(void *storage, Visitor &v)
Variant(const Variant &other)
static constexpr Tag Empty
static constexpr Tag type_to_tag()
fl::enable_if< contains_type< T, Types... >::value, T & >::type emplace(Args &&...args)
static void move_fn(void *storage, Variant &other)
static void copy_fn(void *storage, const Variant &other)
void destroy_current() noexcept
void visit(Visitor &visitor) const
Variant & operator=(T &&value)
void visit(Visitor &visitor)
bool empty() const noexcept
static void destroy_fn(void *storage)
const T & get() const
Get a const reference to the stored value of type T.
void copy_construct_from(const Variant &other)
T & get()
Get a reference to the stored value of type T.
bool equals(const T &other) const
Variant(Variant &&other) noexcept
void move_construct_from(Variant &other) noexcept
constexpr remove_reference< T >::type && move(T &&t) noexcept
To * bit_cast_ptr(void *storage) noexcept
constexpr T && forward(typename remove_reference< T >::type &t) noexcept
static constexpr Tag value
static constexpr Tag value
static constexpr bool value