112template <
typename... Types>
116 static constexpr Tag Empty = 0;
122 template <
typename T,
typename =
typename fl::enable_if<
123 contains_type<T, Types...>
::value>::type>
128 template <
typename T,
typename =
typename fl::enable_if<
129 contains_type<T, Types...>
::value>::type>
134 variant(
const variant &other)
FL_NO_EXCEPT : _tag(Empty) {
135 if (!other.empty()) {
136 copy_construct_from(other);
141 if (!other.empty()) {
142 move_construct_from(other);
151 if (
this != &other) {
153 if (!other.empty()) {
154 copy_construct_from(other);
161 if (
this != &other) {
163 if (!other.empty()) {
164 move_construct_from(other);
172 template <
typename T,
typename =
typename fl::enable_if<
173 contains_type<T, Types...>
::value>::type>
183 template <
typename T,
typename =
typename fl::enable_if<
184 contains_type<T, Types...>
::value>::type>
193 template <
typename T,
typename... Args>
194 typename fl::enable_if<contains_type<T, Types...>
::value, T &>::type
209 bool empty() const
FL_NO_EXCEPT {
return _tag == Empty; }
212 return _tag == type_to_tag<T>();
216 if (!is<T>())
return nullptr;
222 template <
typename T>
const T *ptr() const
FL_NO_EXCEPT {
223 if (!is<T>())
return nullptr;
251 template <
typename T>
bool equals(
const T &other)
const FL_NO_EXCEPT {
252 if (
auto p = ptr<T>()) {
259 template <
typename Visitor>
void visit(Visitor &visitor)
FL_NO_EXCEPT {
264 using Fn = void (*)(
void *, Visitor &);
269 static constexpr Fn table[] = {
270 &variant::template visit_fn<Types, Visitor>...};
274 size_t index = _tag - 1;
275 if (index <
sizeof...(Types)) {
276 table[index](&_storage, visitor);
280 template <
typename Visitor>
void visit(Visitor &visitor)
const FL_NO_EXCEPT {
285 using Fn = void (*)(
const void *, Visitor &);
288 static constexpr Fn table[] = {
289 &variant::template visit_fn_const<Types, Visitor>...};
293 size_t index = _tag - 1;
294 if (index <
sizeof...(Types)) {
295 table[index](&_storage, visitor);
301 template <
typename T,
typename Visitor>
302 static void visit_fn(
void *storage, Visitor &v)
FL_NO_EXCEPT {
306 v.accept(*typed_ptr);
309 template <
typename T,
typename Visitor>
310 static void visit_fn_const(
const void *storage, Visitor &v)
FL_NO_EXCEPT {
314 v.accept(*typed_ptr);
327 table[_tag - 1](&_storage);
334 void copy_construct_from(
const variant &other)
FL_NO_EXCEPT {
340 table[other._tag - 1](&_storage, &other._storage[0]);
353 table[other._tag - 1](&_storage, &other._storage[0]);
366 template <
typename T>
static constexpr Tag type_to_tag()
FL_NO_EXCEPT {
367 return type_to_tag_impl<T, Types...>
::value;
371 template <
typename T,
typename... Ts>
struct type_to_tag_impl;
373 template <
typename T>
struct type_to_tag_impl<T> {
374 static constexpr Tag value = 0;
377 template <
typename T,
typename U,
typename... Rest>
378 struct type_to_tag_impl<T, U, Rest...> {
379 static constexpr Tag value =
382 : (type_to_tag_impl<T, Rest...>::value == 0
384 : type_to_tag_impl<T, Rest...>::value + 1);
387 template <
typename T,
typename... Args>
void construct(Args &&...
args)
FL_NO_EXCEPT {
389 _tag = type_to_tag<T>();