libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

mpark_variant.hpp (85328B)


      1 // Changed from mpark variant v1.3.0: use std::in_place*
      2 
      3 // MPark.Variant
      4 //
      5 // Copyright Michael Park, 2015-2017
      6 //
      7 // Distributed under the Boost Software License, Version 1.0.
      8 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
      9 
     10 #ifndef MPARK_VARIANT_HPP
     11 #define MPARK_VARIANT_HPP
     12 
     13 /*
     14    variant synopsis
     15 
     16 namespace std {
     17 
     18   // 20.7.2, class template variant
     19   template <class... Types>
     20   class variant {
     21   public:
     22 
     23     // 20.7.2.1, constructors
     24     constexpr variant() noexcept(see below);
     25     variant(const variant&);
     26     variant(variant&&) noexcept(see below);
     27 
     28     template <class T> constexpr variant(T&&) noexcept(see below);
     29 
     30     template <class T, class... Args>
     31     constexpr explicit variant(in_place_type_t<T>, Args&&...);
     32 
     33     template <class T, class U, class... Args>
     34     constexpr explicit variant(
     35         in_place_type_t<T>, initializer_list<U>, Args&&...);
     36 
     37     template <size_t I, class... Args>
     38     constexpr explicit variant(in_place_index_t<I>, Args&&...);
     39 
     40     template <size_t I, class U, class... Args>
     41     constexpr explicit variant(
     42         in_place_index_t<I>, initializer_list<U>, Args&&...);
     43 
     44     // 20.7.2.2, destructor
     45     ~variant();
     46 
     47     // 20.7.2.3, assignment
     48     variant& operator=(const variant&);
     49     variant& operator=(variant&&) noexcept(see below);
     50 
     51     template <class T> variant& operator=(T&&) noexcept(see below);
     52 
     53     // 20.7.2.4, modifiers
     54     template <class T, class... Args>
     55     T& emplace(Args&&...);
     56 
     57     template <class T, class U, class... Args>
     58     T& emplace(initializer_list<U>, Args&&...);
     59 
     60     template <size_t I, class... Args>
     61     variant_alternative<I, variant>& emplace(Args&&...);
     62 
     63     template <size_t I, class U, class...  Args>
     64     variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
     65 
     66     // 20.7.2.5, value status
     67     constexpr bool valueless_by_exception() const noexcept;
     68     constexpr size_t index() const noexcept;
     69 
     70     // 20.7.2.6, swap
     71     void swap(variant&) noexcept(see below);
     72   };
     73 
     74   // 20.7.3, variant helper classes
     75   template <class T> struct variant_size; // undefined
     76 
     77   template <class T>
     78   constexpr size_t variant_size_v = variant_size<T>::value;
     79 
     80   template <class T> struct variant_size<const T>;
     81   template <class T> struct variant_size<volatile T>;
     82   template <class T> struct variant_size<const volatile T>;
     83 
     84   template <class... Types>
     85   struct variant_size<variant<Types...>>;
     86 
     87   template <size_t I, class T> struct variant_alternative; // undefined
     88 
     89   template <size_t I, class T>
     90   using variant_alternative_t = typename variant_alternative<I, T>::type;
     91 
     92   template <size_t I, class T> struct variant_alternative<I, const T>;
     93   template <size_t I, class T> struct variant_alternative<I, volatile T>;
     94   template <size_t I, class T> struct variant_alternative<I, const volatile T>;
     95 
     96   template <size_t I, class... Types>
     97   struct variant_alternative<I, variant<Types...>>;
     98 
     99   constexpr size_t variant_npos = -1;
    100 
    101   // 20.7.4, value access
    102   template <class T, class... Types>
    103   constexpr bool holds_alternative(const variant<Types...>&) noexcept;
    104 
    105   template <size_t I, class... Types>
    106   constexpr variant_alternative_t<I, variant<Types...>>&
    107   get(variant<Types...>&);
    108 
    109   template <size_t I, class... Types>
    110   constexpr variant_alternative_t<I, variant<Types...>>&&
    111   get(variant<Types...>&&);
    112 
    113   template <size_t I, class... Types>
    114   constexpr variant_alternative_t<I, variant<Types...>> const&
    115   get(const variant<Types...>&);
    116 
    117   template <size_t I, class... Types>
    118   constexpr variant_alternative_t<I, variant<Types...>> const&&
    119   get(const variant<Types...>&&);
    120 
    121   template <class T, class...  Types>
    122   constexpr T& get(variant<Types...>&);
    123 
    124   template <class T, class... Types>
    125   constexpr T&& get(variant<Types...>&&);
    126 
    127   template <class T, class... Types>
    128   constexpr const T& get(const variant<Types...>&);
    129 
    130   template <class T, class... Types>
    131   constexpr const T&& get(const variant<Types...>&&);
    132 
    133   template <size_t I, class... Types>
    134   constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
    135   get_if(variant<Types...>*) noexcept;
    136 
    137   template <size_t I, class... Types>
    138   constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
    139   get_if(const variant<Types...>*) noexcept;
    140 
    141   template <class T, class... Types>
    142   constexpr add_pointer_t<T>
    143   get_if(variant<Types...>*) noexcept;
    144 
    145   template <class T, class... Types>
    146   constexpr add_pointer_t<const T>
    147   get_if(const variant<Types...>*) noexcept;
    148 
    149   // 20.7.5, relational operators
    150   template <class... Types>
    151   constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
    152 
    153   template <class... Types>
    154   constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
    155 
    156   template <class... Types>
    157   constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
    158 
    159   template <class... Types>
    160   constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
    161 
    162   template <class... Types>
    163   constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
    164 
    165   template <class... Types>
    166   constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
    167 
    168   // 20.7.6, visitation
    169   template <class Visitor, class... Variants>
    170   constexpr see below visit(Visitor&&, Variants&&...);
    171 
    172   // 20.7.7, class monostate
    173   struct monostate;
    174 
    175   // 20.7.8, monostate relational operators
    176   constexpr bool operator<(monostate, monostate) noexcept;
    177   constexpr bool operator>(monostate, monostate) noexcept;
    178   constexpr bool operator<=(monostate, monostate) noexcept;
    179   constexpr bool operator>=(monostate, monostate) noexcept;
    180   constexpr bool operator==(monostate, monostate) noexcept;
    181   constexpr bool operator!=(monostate, monostate) noexcept;
    182 
    183   // 20.7.9, specialized algorithms
    184   template <class... Types>
    185   void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
    186 
    187   // 20.7.10, class bad_variant_access
    188   class bad_variant_access;
    189 
    190   // 20.7.11, hash support
    191   template <class T> struct hash;
    192   template <class... Types> struct hash<variant<Types...>>;
    193   template <> struct hash<monostate>;
    194 
    195 } // namespace std
    196 
    197 */
    198 
    199 #include <cstddef>
    200 #include <exception>
    201 #include <functional>
    202 #include <initializer_list>
    203 #include <new>
    204 #include <type_traits>
    205 #include <utility>
    206 
    207 // MPark.Variant
    208 //
    209 // Copyright Michael Park, 2015-2017
    210 //
    211 // Distributed under the Boost Software License, Version 1.0.
    212 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
    213 
    214 #ifndef MPARK_CONFIG_HPP
    215 #define MPARK_CONFIG_HPP
    216 
    217 // MSVC 2015 Update 3.
    218 #if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024210)
    219 #error "MPark.Variant requires C++11 support."
    220 #endif
    221 
    222 #ifndef __has_builtin
    223 #define __has_builtin(x) 0
    224 #endif
    225 
    226 #ifndef __has_include
    227 #define __has_include(x) 0
    228 #endif
    229 
    230 #ifndef __has_feature
    231 #define __has_feature(x) 0
    232 #endif
    233 
    234 #if __has_builtin(__builtin_addressof) || \
    235     (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
    236 #define MPARK_BUILTIN_ADDRESSOF
    237 #endif
    238 
    239 #if __has_builtin(__builtin_unreachable)
    240 #define MPARK_BUILTIN_UNREACHABLE
    241 #endif
    242 
    243 #if __has_builtin(__type_pack_element)
    244 #define MPARK_TYPE_PACK_ELEMENT
    245 #endif
    246 
    247 #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
    248 #define MPARK_CPP14_CONSTEXPR
    249 #endif
    250 
    251 #if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \
    252     (defined(_MSC_VER) && defined(_CPPUNWIND))
    253 #define MPARK_EXCEPTIONS
    254 #endif
    255 
    256 #if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
    257 #define MPARK_GENERIC_LAMBDAS
    258 #endif
    259 
    260 #if defined(__cpp_lib_integer_sequence)
    261 #define MPARK_INTEGER_SEQUENCE
    262 #endif
    263 
    264 #if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
    265 #define MPARK_RETURN_TYPE_DEDUCTION
    266 #endif
    267 
    268 #if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
    269 #define MPARK_TRANSPARENT_OPERATORS
    270 #endif
    271 
    272 #if defined(__cpp_variable_templates) || defined(_MSC_VER)
    273 #define MPARK_VARIABLE_TEMPLATES
    274 #endif
    275 
    276 #if !defined(__GLIBCXX__) || __has_include(<codecvt>)  // >= libstdc++-5
    277 #define MPARK_TRIVIALITY_TYPE_TRAITS
    278 #endif
    279 
    280 #endif  // MPARK_CONFIG_HPP
    281 
    282 // MPark.Variant
    283 //
    284 // Copyright Michael Park, 2015-2017
    285 //
    286 // Distributed under the Boost Software License, Version 1.0.
    287 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
    288 
    289 #ifndef MPARK_IN_PLACE_HPP
    290 #define MPARK_IN_PLACE_HPP
    291 
    292 #include <utility>
    293 
    294 namespace mpark {
    295 
    296   using std::in_place_t;
    297   using std::in_place_index_t;
    298   using std::in_place_type_t;
    299 
    300 }  // namespace mpark
    301 
    302 #endif  // MPARK_IN_PLACE_HPP
    303 
    304 // MPark.Variant
    305 //
    306 // Copyright Michael Park, 2015-2017
    307 //
    308 // Distributed under the Boost Software License, Version 1.0.
    309 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
    310 
    311 #ifndef MPARK_LIB_HPP
    312 #define MPARK_LIB_HPP
    313 
    314 #include <memory>
    315 #include <functional>
    316 #include <type_traits>
    317 #include <utility>
    318 
    319 
    320 #define RETURN(...)                                          \
    321   noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { \
    322     return __VA_ARGS__;                                      \
    323   }
    324 
    325 namespace mpark {
    326   namespace lib {
    327     template <typename T>
    328     struct identity { using type = T; };
    329 
    330     inline namespace cpp14 {
    331       template <typename T, std::size_t N>
    332       struct array {
    333         constexpr const T &operator[](std::size_t index) const {
    334           return data[index];
    335         }
    336 
    337         T data[N == 0 ? 1 : N];
    338       };
    339 
    340       template <typename T>
    341       using add_pointer_t = typename std::add_pointer<T>::type;
    342 
    343       template <typename... Ts>
    344       using common_type_t = typename std::common_type<Ts...>::type;
    345 
    346       template <typename T>
    347       using decay_t = typename std::decay<T>::type;
    348 
    349       template <bool B, typename T = void>
    350       using enable_if_t = typename std::enable_if<B, T>::type;
    351 
    352       template <typename T>
    353       using remove_const_t = typename std::remove_const<T>::type;
    354 
    355       template <typename T>
    356       using remove_reference_t = typename std::remove_reference<T>::type;
    357 
    358       template <typename T>
    359       inline constexpr T &&forward(remove_reference_t<T> &t) noexcept {
    360         return static_cast<T &&>(t);
    361       }
    362 
    363       template <typename T>
    364       inline constexpr T &&forward(remove_reference_t<T> &&t) noexcept {
    365         static_assert(!std::is_lvalue_reference<T>::value,
    366                       "can not forward an rvalue as an lvalue");
    367         return static_cast<T &&>(t);
    368       }
    369 
    370       template <typename T>
    371       inline constexpr remove_reference_t<T> &&move(T &&t) noexcept {
    372         return static_cast<remove_reference_t<T> &&>(t);
    373       }
    374 
    375 #ifdef MPARK_INTEGER_SEQUENCE
    376       using std::integer_sequence;
    377       using std::index_sequence;
    378       using std::make_index_sequence;
    379       using std::index_sequence_for;
    380 #else
    381       template <typename T, T... Is>
    382       struct integer_sequence {
    383         using value_type = T;
    384         static constexpr std::size_t size() noexcept { return sizeof...(Is); }
    385       };
    386 
    387       template <std::size_t... Is>
    388       using index_sequence = integer_sequence<std::size_t, Is...>;
    389 
    390       template <typename Lhs, typename Rhs>
    391       struct make_index_sequence_concat;
    392 
    393       template <std::size_t... Lhs, std::size_t... Rhs>
    394       struct make_index_sequence_concat<index_sequence<Lhs...>,
    395                                         index_sequence<Rhs...>>
    396           : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
    397 
    398       template <std::size_t N>
    399       struct make_index_sequence_impl;
    400 
    401       template <std::size_t N>
    402       using make_index_sequence = typename make_index_sequence_impl<N>::type;
    403 
    404       template <std::size_t N>
    405       struct make_index_sequence_impl
    406           : make_index_sequence_concat<make_index_sequence<N / 2>,
    407                                        make_index_sequence<N - (N / 2)>> {};
    408 
    409       template <>
    410       struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
    411 
    412       template <>
    413       struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
    414 
    415       template <typename... Ts>
    416       using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
    417 #endif
    418 
    419       // <functional>
    420 #ifdef MPARK_TRANSPARENT_OPERATORS
    421       using equal_to = std::equal_to<>;
    422 #else
    423       struct equal_to {
    424         template <typename Lhs, typename Rhs>
    425         inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
    426           RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
    427       };
    428 #endif
    429 
    430 #ifdef MPARK_TRANSPARENT_OPERATORS
    431       using not_equal_to = std::not_equal_to<>;
    432 #else
    433       struct not_equal_to {
    434         template <typename Lhs, typename Rhs>
    435         inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
    436           RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
    437       };
    438 #endif
    439 
    440 #ifdef MPARK_TRANSPARENT_OPERATORS
    441       using less = std::less<>;
    442 #else
    443       struct less {
    444         template <typename Lhs, typename Rhs>
    445         inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
    446           RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
    447       };
    448 #endif
    449 
    450 #ifdef MPARK_TRANSPARENT_OPERATORS
    451       using greater = std::greater<>;
    452 #else
    453       struct greater {
    454         template <typename Lhs, typename Rhs>
    455         inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
    456           RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
    457       };
    458 #endif
    459 
    460 #ifdef MPARK_TRANSPARENT_OPERATORS
    461       using less_equal = std::less_equal<>;
    462 #else
    463       struct less_equal {
    464         template <typename Lhs, typename Rhs>
    465         inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
    466           RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
    467       };
    468 #endif
    469 
    470 #ifdef MPARK_TRANSPARENT_OPERATORS
    471       using greater_equal = std::greater_equal<>;
    472 #else
    473       struct greater_equal {
    474         template <typename Lhs, typename Rhs>
    475         inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
    476           RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
    477       };
    478 #endif
    479     }  // namespace cpp14
    480 
    481     inline namespace cpp17 {
    482 
    483       // <type_traits>
    484       template <bool B>
    485       using bool_constant = std::integral_constant<bool, B>;
    486 
    487       template <typename...>
    488       struct voider : identity<void> {};
    489 
    490       template <typename... Ts>
    491       using void_t = typename voider<Ts...>::type;
    492 
    493       namespace detail {
    494         namespace swappable {
    495 
    496           using std::swap;
    497 
    498           template <typename T>
    499           struct is_swappable {
    500             private:
    501             template <typename U,
    502                       typename = decltype(swap(std::declval<U &>(),
    503                                                std::declval<U &>()))>
    504             inline static std::true_type test(int);
    505 
    506             template <typename U>
    507             inline static std::false_type test(...);
    508 
    509             public:
    510             static constexpr bool value = decltype(test<T>(0))::value;
    511           };
    512 
    513           template <typename T, bool = is_swappable<T>::value>
    514           struct is_nothrow_swappable {
    515             static constexpr bool value =
    516                 noexcept(swap(std::declval<T &>(), std::declval<T &>()));
    517           };
    518 
    519           template <typename T>
    520           struct is_nothrow_swappable<T, false> : std::false_type {};
    521 
    522         }  // namespace swappable
    523       }  // namespace detail
    524 
    525       using detail::swappable::is_swappable;
    526       using detail::swappable::is_nothrow_swappable;
    527 
    528       // <functional>
    529 #ifdef _MSC_VER
    530 #pragma warning(push)
    531 #pragma warning(disable : 4100)
    532 #endif
    533       template <typename F, typename... As>
    534       inline constexpr auto invoke(F &&f, As &&... as)
    535           RETURN(lib::forward<F>(f)(lib::forward<As>(as)...))
    536 #ifdef _MSC_VER
    537 #pragma warning(pop)
    538 #endif
    539 
    540       template <typename B, typename T, typename D>
    541       inline constexpr auto invoke(T B::*pmv, D &&d)
    542           RETURN(lib::forward<D>(d).*pmv)
    543 
    544       template <typename Pmv, typename Ptr>
    545       inline constexpr auto invoke(Pmv pmv, Ptr &&ptr)
    546           RETURN((*lib::forward<Ptr>(ptr)).*pmv)
    547 
    548       template <typename B, typename T, typename D, typename... As>
    549       inline constexpr auto invoke(T B::*pmf, D &&d, As &&... as)
    550           RETURN((lib::forward<D>(d).*pmf)(lib::forward<As>(as)...))
    551 
    552       template <typename Pmf, typename Ptr, typename... As>
    553       inline constexpr auto invoke(Pmf pmf, Ptr &&ptr, As &&... as)
    554           RETURN(((*lib::forward<Ptr>(ptr)).*pmf)(lib::forward<As>(as)...))
    555 
    556       namespace detail {
    557 
    558         template <typename Void, typename, typename...>
    559         struct invoke_result {};
    560 
    561         template <typename F, typename... Args>
    562         struct invoke_result<void_t<decltype(lib::invoke(
    563                                  std::declval<F>(), std::declval<Args>()...))>,
    564                              F,
    565                              Args...>
    566             : identity<decltype(
    567                   lib::invoke(std::declval<F>(), std::declval<Args>()...))> {};
    568 
    569       }  // namespace detail
    570 
    571       template <typename F, typename... Args>
    572       using invoke_result = detail::invoke_result<void, F, Args...>;
    573 
    574       template <typename F, typename... Args>
    575       using invoke_result_t = typename invoke_result<F, Args...>::type;
    576 
    577       namespace detail {
    578 
    579         template <typename Void, typename, typename...>
    580         struct is_invocable : std::false_type {};
    581 
    582         template <typename F, typename... Args>
    583         struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
    584             : std::true_type {};
    585 
    586         template <typename Void, typename, typename, typename...>
    587         struct is_invocable_r : std::false_type {};
    588 
    589         template <typename R, typename F, typename... Args>
    590         struct is_invocable_r<void_t<invoke_result_t<F, Args...>>,
    591                               R,
    592                               F,
    593                               Args...>
    594             : std::is_convertible<invoke_result_t<F, Args...>, R> {};
    595 
    596       }  // namespace detail
    597 
    598       template <typename F, typename... Args>
    599       using is_invocable = detail::is_invocable<void, F, Args...>;
    600 
    601       template <typename R, typename F, typename... Args>
    602       using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
    603 
    604       // <memory>
    605 #ifdef MPARK_BUILTIN_ADDRESSOF
    606       template <typename T>
    607       inline constexpr T *addressof(T &arg) {
    608         return __builtin_addressof(arg);
    609       }
    610 #else
    611       namespace detail {
    612 
    613         namespace has_addressof_impl {
    614 
    615           struct fail;
    616 
    617           template <typename T>
    618           inline fail operator&(T &&);
    619 
    620           template <typename T>
    621           inline static constexpr bool impl() {
    622             return (std::is_class<T>::value || std::is_union<T>::value) &&
    623                    !std::is_same<decltype(&std::declval<T &>()), fail>::value;
    624           }
    625 
    626         }  // namespace has_addressof_impl
    627 
    628         template <typename T>
    629         using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
    630 
    631         template <typename T>
    632         inline constexpr T *addressof(T &arg, std::true_type) {
    633           return std::addressof(arg);
    634         }
    635 
    636         template <typename T>
    637         inline constexpr T *addressof(T &arg, std::false_type) {
    638           return &arg;
    639         }
    640 
    641       }  // namespace detail
    642 
    643       template <typename T>
    644       inline constexpr T *addressof(T &arg) {
    645         return detail::addressof(arg, detail::has_addressof<T>{});
    646       }
    647 #endif
    648 
    649       template <typename T>
    650       inline constexpr T *addressof(const T &&) = delete;
    651 
    652     }  // namespace cpp17
    653 
    654     template <typename T>
    655     struct remove_all_extents : identity<T> {};
    656 
    657     template <typename T, std::size_t N>
    658     struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
    659 
    660     template <typename T>
    661     using remove_all_extents_t = typename remove_all_extents<T>::type;
    662 
    663     template <std::size_t N>
    664     using size_constant = std::integral_constant<std::size_t, N>;
    665 
    666     template <std::size_t I, typename T>
    667     struct indexed_type : size_constant<I>, identity<T> {};
    668 
    669     template <bool... Bs>
    670     using all = std::is_same<integer_sequence<bool, true, Bs...>,
    671                              integer_sequence<bool, Bs..., true>>;
    672 
    673 #ifdef MPARK_TYPE_PACK_ELEMENT
    674     template <std::size_t I, typename... Ts>
    675     using type_pack_element_t = __type_pack_element<I, Ts...>;
    676 #else
    677     template <std::size_t I, typename... Ts>
    678     struct type_pack_element_impl {
    679       private:
    680       template <typename>
    681       struct set;
    682 
    683       template <std::size_t... Is>
    684       struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
    685 
    686       template <typename T>
    687       inline static std::enable_if<true, T> impl(indexed_type<I, T>);
    688 
    689       inline static std::enable_if<false> impl(...);
    690 
    691       public:
    692       using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
    693     };
    694 
    695     template <std::size_t I, typename... Ts>
    696     using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
    697 
    698     template <std::size_t I, typename... Ts>
    699     using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
    700 #endif
    701 
    702 #ifdef MPARK_TRIVIALITY_TYPE_TRAITS
    703     using std::is_trivially_copy_constructible;
    704     using std::is_trivially_move_constructible;
    705     using std::is_trivially_copy_assignable;
    706     using std::is_trivially_move_assignable;
    707 #else
    708     template <typename T>
    709     struct is_trivially_copy_constructible
    710         : bool_constant<
    711               std::is_copy_constructible<T>::value && __has_trivial_copy(T)> {};
    712 
    713     template <typename T>
    714     struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {};
    715 
    716     template <typename T>
    717     struct is_trivially_copy_assignable
    718         : bool_constant<
    719               std::is_copy_assignable<T>::value && __has_trivial_assign(T)> {};
    720 
    721     template <typename T>
    722     struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {};
    723 #endif
    724 
    725     template <typename T, bool>
    726     struct dependent_type : T {};
    727 
    728     template <typename Is, std::size_t J>
    729     struct push_back;
    730 
    731     template <typename Is, std::size_t J>
    732     using push_back_t = typename push_back<Is, J>::type;
    733 
    734     template <std::size_t... Is, std::size_t J>
    735     struct push_back<index_sequence<Is...>, J> {
    736       using type = index_sequence<Is..., J>;
    737     };
    738 
    739   }  // namespace lib
    740 }  // namespace mpark
    741 
    742 #undef RETURN
    743 
    744 #endif  // MPARK_LIB_HPP
    745 
    746 
    747 namespace mpark {
    748 
    749 #ifdef MPARK_RETURN_TYPE_DEDUCTION
    750 
    751 #define AUTO auto
    752 #define AUTO_RETURN(...) { return __VA_ARGS__; }
    753 
    754 #define AUTO_REFREF auto &&
    755 #define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; }
    756 
    757 #define DECLTYPE_AUTO decltype(auto)
    758 #define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; }
    759 
    760 #else
    761 
    762 #define AUTO auto
    763 #define AUTO_RETURN(...) \
    764   -> lib::decay_t<decltype(__VA_ARGS__)> { return __VA_ARGS__; }
    765 
    766 #define AUTO_REFREF auto
    767 #define AUTO_REFREF_RETURN(...)                                           \
    768   -> decltype((__VA_ARGS__)) {                                            \
    769     static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
    770     return __VA_ARGS__;                                                   \
    771   }
    772 
    773 #define DECLTYPE_AUTO auto
    774 #define DECLTYPE_AUTO_RETURN(...) \
    775   -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
    776 
    777 #endif
    778 
    779   class bad_variant_access : public std::exception {
    780     public:
    781     virtual const char *what() const noexcept { return "bad_variant_access"; }
    782   };
    783 
    784   [[noreturn]] inline void throw_bad_variant_access() {
    785 #ifdef MPARK_EXCEPTIONS
    786     throw bad_variant_access{};
    787 #else
    788     std::terminate();
    789 #ifdef MPARK_BUILTIN_UNREACHABLE
    790     __builtin_unreachable();
    791 #endif
    792 #endif
    793   }
    794 
    795   template <typename... Ts>
    796   class variant;
    797 
    798   template <typename T>
    799   struct variant_size;
    800 
    801 #ifdef MPARK_VARIABLE_TEMPLATES
    802   template <typename T>
    803   constexpr std::size_t variant_size_v = variant_size<T>::value;
    804 #endif
    805 
    806   template <typename T>
    807   struct variant_size<const T> : variant_size<T> {};
    808 
    809   template <typename T>
    810   struct variant_size<volatile T> : variant_size<T> {};
    811 
    812   template <typename T>
    813   struct variant_size<const volatile T> : variant_size<T> {};
    814 
    815   template <typename... Ts>
    816   struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
    817 
    818   template <std::size_t I, typename T>
    819   struct variant_alternative;
    820 
    821   template <std::size_t I, typename T>
    822   using variant_alternative_t = typename variant_alternative<I, T>::type;
    823 
    824   template <std::size_t I, typename T>
    825   struct variant_alternative<I, const T>
    826       : std::add_const<variant_alternative_t<I, T>> {};
    827 
    828   template <std::size_t I, typename T>
    829   struct variant_alternative<I, volatile T>
    830       : std::add_volatile<variant_alternative_t<I, T>> {};
    831 
    832   template <std::size_t I, typename T>
    833   struct variant_alternative<I, const volatile T>
    834       : std::add_cv<variant_alternative_t<I, T>> {};
    835 
    836   template <std::size_t I, typename... Ts>
    837   struct variant_alternative<I, variant<Ts...>> {
    838     static_assert(I < sizeof...(Ts),
    839                   "Index out of bounds in std::variant_alternative<>");
    840     using type = lib::type_pack_element_t<I, Ts...>;
    841   };
    842 
    843   constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
    844 
    845   namespace detail {
    846 
    847     constexpr std::size_t not_found = static_cast<std::size_t>(-1);
    848     constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
    849 
    850 #ifdef MPARK_CPP14_CONSTEXPR
    851     template <typename T, typename... Ts>
    852     inline constexpr std::size_t find_index() {
    853       constexpr lib::array<bool, sizeof...(Ts)> matches = {
    854           {std::is_same<T, Ts>::value...}
    855       };
    856       std::size_t result = not_found;
    857       for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
    858         if (matches[i]) {
    859           if (result != not_found) {
    860             return ambiguous;
    861           }
    862           result = i;
    863         }
    864       }
    865       return result;
    866     }
    867 #else
    868     inline constexpr std::size_t find_index_impl(std::size_t result,
    869                                                  std::size_t) {
    870       return result;
    871     }
    872 
    873     template <typename... Bs>
    874     inline constexpr std::size_t find_index_impl(std::size_t result,
    875                                                  std::size_t idx,
    876                                                  bool b,
    877                                                  Bs... bs) {
    878       return b ? (result != not_found ? ambiguous
    879                                       : find_index_impl(idx, idx + 1, bs...))
    880                : find_index_impl(result, idx + 1, bs...);
    881     }
    882 
    883     template <typename T, typename... Ts>
    884     inline constexpr std::size_t find_index() {
    885       return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
    886     }
    887 #endif
    888 
    889     template <std::size_t I>
    890     using find_index_sfinae_impl =
    891         lib::enable_if_t<I != not_found && I != ambiguous,
    892                          lib::size_constant<I>>;
    893 
    894     template <typename T, typename... Ts>
    895     using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
    896 
    897     template <std::size_t I>
    898     struct find_index_checked_impl : lib::size_constant<I> {
    899       static_assert(I != not_found, "the specified type is not found.");
    900       static_assert(I != ambiguous, "the specified type is ambiguous.");
    901     };
    902 
    903     template <typename T, typename... Ts>
    904     using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
    905 
    906     struct valueless_t {};
    907 
    908     enum class Trait { TriviallyAvailable, Available, Unavailable };
    909 
    910     template <typename T,
    911               template <typename> class IsTriviallyAvailable,
    912               template <typename> class IsAvailable>
    913     inline constexpr Trait trait() {
    914       return IsTriviallyAvailable<T>::value
    915                  ? Trait::TriviallyAvailable
    916                  : IsAvailable<T>::value ? Trait::Available
    917                                          : Trait::Unavailable;
    918     }
    919 
    920 #ifdef MPARK_CPP14_CONSTEXPR
    921     template <typename... Traits>
    922     inline constexpr Trait common_trait(Traits... traits) {
    923       Trait result = Trait::TriviallyAvailable;
    924       for (Trait t : {traits...}) {
    925         if (static_cast<int>(t) > static_cast<int>(result)) {
    926           result = t;
    927         }
    928       }
    929       return result;
    930     }
    931 #else
    932     inline constexpr Trait common_trait_impl(Trait result) { return result; }
    933 
    934     template <typename... Traits>
    935     inline constexpr Trait common_trait_impl(Trait result,
    936                                              Trait t,
    937                                              Traits... ts) {
    938       return static_cast<int>(t) > static_cast<int>(result)
    939                  ? common_trait_impl(t, ts...)
    940                  : common_trait_impl(result, ts...);
    941     }
    942 
    943     template <typename... Traits>
    944     inline constexpr Trait common_trait(Traits... ts) {
    945       return common_trait_impl(Trait::TriviallyAvailable, ts...);
    946     }
    947 #endif
    948 
    949     template <typename... Ts>
    950     struct traits {
    951       static constexpr Trait copy_constructible_trait =
    952           common_trait(trait<Ts,
    953                              lib::is_trivially_copy_constructible,
    954                              std::is_copy_constructible>()...);
    955 
    956       static constexpr Trait move_constructible_trait =
    957           common_trait(trait<Ts,
    958                              lib::is_trivially_move_constructible,
    959                              std::is_move_constructible>()...);
    960 
    961       static constexpr Trait copy_assignable_trait =
    962           common_trait(copy_constructible_trait,
    963                        trait<Ts,
    964                              lib::is_trivially_copy_assignable,
    965                              std::is_copy_assignable>()...);
    966 
    967       static constexpr Trait move_assignable_trait =
    968           common_trait(move_constructible_trait,
    969                        trait<Ts,
    970                              lib::is_trivially_move_assignable,
    971                              std::is_move_assignable>()...);
    972 
    973       static constexpr Trait destructible_trait =
    974           common_trait(trait<Ts,
    975                              std::is_trivially_destructible,
    976                              std::is_destructible>()...);
    977     };
    978 
    979     namespace access {
    980 
    981       struct recursive_union {
    982 #ifdef MPARK_RETURN_TYPE_DEDUCTION
    983         template <typename V>
    984         inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
    985           return lib::forward<V>(v).head_;
    986         }
    987 
    988         template <typename V, std::size_t I>
    989         inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
    990           return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
    991         }
    992 #else
    993         template <std::size_t I, bool Dummy = true>
    994         struct get_alt_impl {
    995           template <typename V>
    996           inline constexpr AUTO_REFREF operator()(V &&v) const
    997             AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
    998         };
    999 
   1000         template <bool Dummy>
   1001         struct get_alt_impl<0, Dummy> {
   1002           template <typename V>
   1003           inline constexpr AUTO_REFREF operator()(V &&v) const
   1004             AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
   1005         };
   1006 
   1007         template <typename V, std::size_t I>
   1008         inline static constexpr AUTO_REFREF get_alt(V &&v, in_place_index_t<I>)
   1009           AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
   1010 #endif
   1011       };
   1012 
   1013       struct base {
   1014         template <std::size_t I, typename V>
   1015         inline static constexpr AUTO_REFREF get_alt(V &&v)
   1016           AUTO_REFREF_RETURN(recursive_union::get_alt(
   1017               data(lib::forward<V>(v)), in_place_index_t<I>{}))
   1018       };
   1019 
   1020       struct variant {
   1021         template <std::size_t I, typename V>
   1022         inline static constexpr AUTO_REFREF get_alt(V &&v)
   1023           AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
   1024       };
   1025 
   1026     }  // namespace access
   1027 
   1028     namespace visitation {
   1029 
   1030       struct base {
   1031         template <typename T>
   1032         inline static constexpr const T &at(const T &elem) {
   1033           return elem;
   1034         }
   1035 
   1036         template <typename T, std::size_t N, typename... Is>
   1037         inline static constexpr const lib::remove_all_extents_t<T> &at(
   1038             const lib::array<T, N> &elems, std::size_t i, Is... is) {
   1039           return at(elems[i], is...);
   1040         }
   1041 
   1042         template <typename F, typename... Fs>
   1043         inline static constexpr int visit_visitor_return_type_check() {
   1044           static_assert(lib::all<std::is_same<F, Fs>::value...>::value,
   1045                         "`mpark::visit` requires the visitor to have a single "
   1046                         "return type.");
   1047           return 0;
   1048         }
   1049 
   1050         template <typename... Fs>
   1051         inline static constexpr lib::array<
   1052             lib::common_type_t<lib::decay_t<Fs>...>,
   1053             sizeof...(Fs)>
   1054         make_farray(Fs &&... fs) {
   1055           using result = lib::array<lib::common_type_t<lib::decay_t<Fs>...>,
   1056                                     sizeof...(Fs)>;
   1057           return visit_visitor_return_type_check<lib::decay_t<Fs>...>(),
   1058                  result{{lib::forward<Fs>(fs)...}};
   1059         }
   1060 
   1061         template <std::size_t... Is>
   1062         struct dispatcher {
   1063           template <typename F, typename... Vs>
   1064           struct impl {
   1065             inline static constexpr DECLTYPE_AUTO dispatch(F f, Vs... vs)
   1066               DECLTYPE_AUTO_RETURN(lib::invoke(
   1067                   static_cast<F>(f),
   1068                   access::base::get_alt<Is>(static_cast<Vs>(vs))...))
   1069           };
   1070         };
   1071 
   1072         template <typename F, typename... Vs, std::size_t... Is>
   1073         inline static constexpr AUTO make_dispatch(lib::index_sequence<Is...>)
   1074           AUTO_RETURN(&dispatcher<Is...>::template impl<F, Vs...>::dispatch)
   1075 
   1076         template <std::size_t I, typename F, typename... Vs>
   1077         inline static constexpr AUTO make_fdiagonal_impl()
   1078           AUTO_RETURN(make_dispatch<F, Vs...>(
   1079               lib::index_sequence<lib::indexed_type<I, Vs>::value...>{}))
   1080 
   1081         template <typename F, typename... Vs, std::size_t... Is>
   1082         inline static constexpr AUTO make_fdiagonal_impl(
   1083             lib::index_sequence<Is...>)
   1084           AUTO_RETURN(make_farray(make_fdiagonal_impl<Is, F, Vs...>()...))
   1085 
   1086         template <typename F, typename V, typename... Vs>
   1087         inline static constexpr /* auto * */ auto make_fdiagonal()
   1088             -> decltype(make_fdiagonal_impl<F, V, Vs...>(
   1089                 lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
   1090           static_assert(lib::all<(lib::decay_t<V>::size() ==
   1091                                   lib::decay_t<Vs>::size())...>::value,
   1092                         "all of the variants must be the same size.");
   1093           return make_fdiagonal_impl<F, V, Vs...>(
   1094               lib::make_index_sequence<lib::decay_t<V>::size()>{});
   1095         }
   1096 
   1097 #ifdef MPARK_RETURN_TYPE_DEDUCTION
   1098         template <typename F, typename... Vs, typename Is>
   1099         inline static constexpr auto make_fmatrix_impl(Is is) {
   1100           return make_dispatch<F, Vs...>(is);
   1101         }
   1102 
   1103         template <typename F,
   1104                   typename... Vs,
   1105                   typename Is,
   1106                   std::size_t... Js,
   1107                   typename... Ls>
   1108         inline static constexpr auto make_fmatrix_impl(
   1109             Is, lib::index_sequence<Js...>, Ls... ls) {
   1110           return make_farray(make_fmatrix_impl<F, Vs...>(
   1111               lib::push_back_t<Is, Js>{}, ls...)...);
   1112         }
   1113 
   1114         template <typename F, typename... Vs>
   1115         inline static constexpr auto make_fmatrix() {
   1116           return make_fmatrix_impl<F, Vs...>(
   1117               lib::index_sequence<>{},
   1118               lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
   1119         }
   1120 #else
   1121         template <typename F, typename... Vs>
   1122         struct make_fmatrix_impl {
   1123           template <typename...>
   1124           struct impl;
   1125 
   1126           template <typename Is>
   1127           struct impl<Is> {
   1128             inline constexpr AUTO operator()() const
   1129               AUTO_RETURN(make_dispatch<F, Vs...>(Is{}))
   1130           };
   1131 
   1132           template <typename Is, std::size_t... Js, typename... Ls>
   1133           struct impl<Is, lib::index_sequence<Js...>, Ls...> {
   1134             inline constexpr AUTO operator()() const
   1135               AUTO_RETURN(
   1136                   make_farray(impl<lib::push_back_t<Is, Js>, Ls...>{}()...))
   1137           };
   1138         };
   1139 
   1140         template <typename F, typename... Vs>
   1141         inline static constexpr AUTO make_fmatrix()
   1142           AUTO_RETURN(
   1143               typename make_fmatrix_impl<F, Vs...>::template impl<
   1144                   lib::index_sequence<>,
   1145                   lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
   1146 #endif
   1147       };  // namespace base
   1148 
   1149       template <typename F, typename... Vs>
   1150       using FDiagonal = decltype(base::make_fdiagonal<F, Vs...>());
   1151 
   1152       template <typename F, typename... Vs>
   1153       struct fdiagonal {
   1154 #ifdef _MSC_VER
   1155 #pragma warning(push)
   1156 #pragma warning(disable : 4268)
   1157 #endif
   1158         static constexpr FDiagonal<F, Vs...> value =
   1159             base::make_fdiagonal<F, Vs...>();
   1160 #ifdef _MSC_VER
   1161 #pragma warning(pop)
   1162 #endif
   1163       };
   1164 
   1165       template <typename F, typename... Vs>
   1166       constexpr FDiagonal<F, Vs...> fdiagonal<F, Vs...>::value;
   1167 
   1168       template <typename F, typename... Vs>
   1169       using FMatrix = decltype(base::make_fmatrix<F, Vs...>());
   1170 
   1171       template <typename F, typename... Vs>
   1172       struct fmatrix {
   1173 #ifdef _MSC_VER
   1174 #pragma warning(push)
   1175 #pragma warning(disable : 4268)
   1176 #endif
   1177         static constexpr FMatrix<F, Vs...> value =
   1178             base::make_fmatrix<F, Vs...>();
   1179 #ifdef _MSC_VER
   1180 #pragma warning(pop)
   1181 #endif
   1182       };
   1183 
   1184       template <typename F, typename... Vs>
   1185       constexpr FMatrix<F, Vs...> fmatrix<F, Vs...>::value;
   1186 
   1187       struct alt {
   1188         template <typename Visitor, typename... Vs>
   1189         inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
   1190                                                            Visitor &&visitor,
   1191                                                            Vs &&... vs)
   1192           DECLTYPE_AUTO_RETURN(base::at(
   1193               fdiagonal<Visitor &&,
   1194                         decltype(as_base(lib::forward<Vs>(vs)))...>::value,
   1195               index)(lib::forward<Visitor>(visitor),
   1196                      as_base(lib::forward<Vs>(vs))...))
   1197 
   1198         template <typename Visitor, typename... Vs>
   1199         inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
   1200                                                         Vs &&... vs)
   1201           DECLTYPE_AUTO_RETURN(base::at(
   1202               fmatrix<Visitor &&,
   1203                       decltype(as_base(lib::forward<Vs>(vs)))...>::value,
   1204               vs.index()...)(lib::forward<Visitor>(visitor),
   1205                              as_base(lib::forward<Vs>(vs))...))
   1206       };
   1207 
   1208       struct variant {
   1209         private:
   1210         template <typename Visitor, typename... Values>
   1211         struct visit_exhaustive_visitor_check {
   1212           static_assert(
   1213               lib::is_invocable<Visitor, Values...>::value,
   1214               "`mpark::visit` requires the visitor to be exhaustive.");
   1215 
   1216 #ifdef _MSC_VER
   1217 #pragma warning(push)
   1218 #pragma warning(disable : 4100)
   1219 #endif
   1220           inline constexpr DECLTYPE_AUTO operator()(Visitor &&visitor,
   1221                                                     Values &&... values) const
   1222             DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
   1223                                              lib::forward<Values>(values)...))
   1224 #ifdef _MSC_VER
   1225 #pragma warning(pop)
   1226 #endif
   1227         };
   1228 
   1229         template <typename Visitor>
   1230         struct value_visitor {
   1231           Visitor &&visitor_;
   1232 
   1233           template <typename... Alts>
   1234           inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const
   1235             DECLTYPE_AUTO_RETURN(
   1236                 visit_exhaustive_visitor_check<
   1237                     Visitor,
   1238                     decltype((lib::forward<Alts>(alts).value))...>{}(
   1239                     lib::forward<Visitor>(visitor_),
   1240                     lib::forward<Alts>(alts).value...))
   1241         };
   1242 
   1243         template <typename Visitor>
   1244         inline static constexpr AUTO make_value_visitor(Visitor &&visitor)
   1245           AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
   1246 
   1247         public:
   1248         template <typename Visitor, typename... Vs>
   1249         inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
   1250                                                            Visitor &&visitor,
   1251                                                            Vs &&... vs)
   1252           DECLTYPE_AUTO_RETURN(
   1253               alt::visit_alt_at(index,
   1254                                 lib::forward<Visitor>(visitor),
   1255                                 lib::forward<Vs>(vs).impl_...))
   1256 
   1257         template <typename Visitor, typename... Vs>
   1258         inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
   1259                                                         Vs &&... vs)
   1260           DECLTYPE_AUTO_RETURN(alt::visit_alt(lib::forward<Visitor>(visitor),
   1261                                               lib::forward<Vs>(vs).impl_...))
   1262 
   1263         template <typename Visitor, typename... Vs>
   1264         inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index,
   1265                                                              Visitor &&visitor,
   1266                                                              Vs &&... vs)
   1267           DECLTYPE_AUTO_RETURN(
   1268               visit_alt_at(index,
   1269                            make_value_visitor(lib::forward<Visitor>(visitor)),
   1270                            lib::forward<Vs>(vs)...))
   1271 
   1272         template <typename Visitor, typename... Vs>
   1273         inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor,
   1274                                                           Vs &&... vs)
   1275           DECLTYPE_AUTO_RETURN(
   1276               visit_alt(make_value_visitor(lib::forward<Visitor>(visitor)),
   1277                         lib::forward<Vs>(vs)...))
   1278       };
   1279 
   1280     }  // namespace visitation
   1281 
   1282     template <std::size_t Index, typename T>
   1283     struct alt {
   1284       using value_type = T;
   1285 
   1286 #ifdef _MSC_VER
   1287 #pragma warning(push)
   1288 #pragma warning(disable : 4244)
   1289 #endif
   1290       template <typename... Args>
   1291       inline explicit constexpr alt(in_place_t, Args &&... args)
   1292           : value(lib::forward<Args>(args)...) {}
   1293 #ifdef _MSC_VER
   1294 #pragma warning(pop)
   1295 #endif
   1296 
   1297       T value;
   1298     };
   1299 
   1300     template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
   1301     union recursive_union;
   1302 
   1303     template <Trait DestructibleTrait, std::size_t Index>
   1304     union recursive_union<DestructibleTrait, Index> {};
   1305 
   1306 #define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)      \
   1307   template <std::size_t Index, typename T, typename... Ts>                 \
   1308   union recursive_union<destructible_trait, Index, T, Ts...> {             \
   1309     public:                                                                \
   1310     inline explicit constexpr recursive_union(valueless_t) noexcept        \
   1311         : dummy_{} {}                                                      \
   1312                                                                            \
   1313     template <typename... Args>                                            \
   1314     inline explicit constexpr recursive_union(in_place_index_t<0>,         \
   1315                                               Args &&... args)             \
   1316         : head_(in_place_t{}, lib::forward<Args>(args)...) {}              \
   1317                                                                            \
   1318     template <std::size_t I, typename... Args>                             \
   1319     inline explicit constexpr recursive_union(in_place_index_t<I>,         \
   1320                                               Args &&... args)             \
   1321         : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
   1322                                                                            \
   1323     recursive_union(const recursive_union &) = default;                    \
   1324     recursive_union(recursive_union &&) = default;                         \
   1325                                                                            \
   1326     destructor                                                             \
   1327                                                                            \
   1328     recursive_union &operator=(const recursive_union &) = default;         \
   1329     recursive_union &operator=(recursive_union &&) = default;              \
   1330                                                                            \
   1331     private:                                                               \
   1332     char dummy_;                                                           \
   1333     alt<Index, T> head_;                                                   \
   1334     recursive_union<destructible_trait, Index + 1, Ts...> tail_;           \
   1335                                                                            \
   1336     friend struct access::recursive_union;                                 \
   1337   }
   1338 
   1339     MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
   1340                                   ~recursive_union() = default;);
   1341     MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
   1342                                   ~recursive_union() {});
   1343     MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
   1344                                   ~recursive_union() = delete;);
   1345 
   1346 #undef MPARK_VARIANT_RECURSIVE_UNION
   1347 
   1348     using index_t = unsigned int;
   1349 
   1350     template <Trait DestructibleTrait, typename... Ts>
   1351     class base {
   1352       public:
   1353       inline explicit constexpr base(valueless_t tag) noexcept
   1354           : data_(tag), index_(static_cast<index_t>(-1)) {}
   1355 
   1356       template <std::size_t I, typename... Args>
   1357       inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
   1358           : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...),
   1359             index_(I) {}
   1360 
   1361       inline constexpr bool valueless_by_exception() const noexcept {
   1362         return index_ == static_cast<index_t>(-1);
   1363       }
   1364 
   1365       inline constexpr std::size_t index() const noexcept {
   1366         return valueless_by_exception() ? variant_npos : index_;
   1367       }
   1368 
   1369       protected:
   1370       using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
   1371 
   1372       friend inline constexpr base &as_base(base &b) { return b; }
   1373       friend inline constexpr const base &as_base(const base &b) { return b; }
   1374       friend inline constexpr base &&as_base(base &&b) { return lib::move(b); }
   1375       friend inline constexpr const base &&as_base(const base &&b) { return lib::move(b); }
   1376 
   1377       friend inline constexpr data_t &data(base &b) { return b.data_; }
   1378       friend inline constexpr const data_t &data(const base &b) { return b.data_; }
   1379       friend inline constexpr data_t &&data(base &&b) { return lib::move(b).data_; }
   1380       friend inline constexpr const data_t &&data(const base &&b) { return lib::move(b).data_; }
   1381 
   1382       inline static constexpr std::size_t size() { return sizeof...(Ts); }
   1383 
   1384       data_t data_;
   1385       index_t index_;
   1386 
   1387       friend struct access::base;
   1388       friend struct visitation::base;
   1389     };
   1390 
   1391     struct dtor {
   1392 #ifdef _MSC_VER
   1393 #pragma warning(push)
   1394 #pragma warning(disable : 4100)
   1395 #endif
   1396       template <typename Alt>
   1397       inline void operator()(Alt &alt) const noexcept { alt.~Alt(); }
   1398 #ifdef _MSC_VER
   1399 #pragma warning(pop)
   1400 #endif
   1401     };
   1402 
   1403 #if defined(_MSC_VER) && _MSC_VER < 1910
   1404 #define INHERITING_CTOR(type, base)               \
   1405   template <typename... Args>                     \
   1406   inline explicit constexpr type(Args &&... args) \
   1407       : base(lib::forward<Args>(args)...) {}
   1408 #else
   1409 #define INHERITING_CTOR(type, base) using base::base;
   1410 #endif
   1411 
   1412     template <typename Traits, Trait = Traits::destructible_trait>
   1413     class destructor;
   1414 
   1415 #define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
   1416   template <typename... Ts>                                               \
   1417   class destructor<traits<Ts...>, destructible_trait>                     \
   1418       : public base<destructible_trait, Ts...> {                          \
   1419     using super = base<destructible_trait, Ts...>;                        \
   1420                                                                           \
   1421     public:                                                               \
   1422     INHERITING_CTOR(destructor, super)                                    \
   1423     using super::operator=;                                               \
   1424                                                                           \
   1425     destructor(const destructor &) = default;                             \
   1426     destructor(destructor &&) = default;                                  \
   1427     definition                                                            \
   1428     destructor &operator=(const destructor &) = default;                  \
   1429     destructor &operator=(destructor &&) = default;                       \
   1430                                                                           \
   1431     protected:                                                            \
   1432     destroy                                                               \
   1433   }
   1434 
   1435     MPARK_VARIANT_DESTRUCTOR(
   1436         Trait::TriviallyAvailable,
   1437         ~destructor() = default;,
   1438         inline void destroy() noexcept {
   1439           this->index_ = static_cast<index_t>(-1);
   1440         });
   1441 
   1442     MPARK_VARIANT_DESTRUCTOR(
   1443         Trait::Available,
   1444         ~destructor() { destroy(); },
   1445         inline void destroy() noexcept {
   1446           if (!this->valueless_by_exception()) {
   1447             visitation::alt::visit_alt(dtor{}, *this);
   1448           }
   1449           this->index_ = static_cast<index_t>(-1);
   1450         });
   1451 
   1452     MPARK_VARIANT_DESTRUCTOR(
   1453         Trait::Unavailable,
   1454         ~destructor() = delete;,
   1455         inline void destroy() noexcept = delete;);
   1456 
   1457 #undef MPARK_VARIANT_DESTRUCTOR
   1458 
   1459     template <typename Traits>
   1460     class constructor : public destructor<Traits> {
   1461       using super = destructor<Traits>;
   1462 
   1463       public:
   1464       INHERITING_CTOR(constructor, super)
   1465       using super::operator=;
   1466 
   1467       protected:
   1468 #ifndef MPARK_GENERIC_LAMBDAS
   1469       struct ctor {
   1470         template <typename LhsAlt, typename RhsAlt>
   1471         inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const {
   1472           constructor::construct_alt(lhs_alt,
   1473                                      lib::forward<RhsAlt>(rhs_alt).value);
   1474         }
   1475       };
   1476 #endif
   1477 
   1478       template <std::size_t I, typename T, typename... Args>
   1479       inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
   1480         ::new (static_cast<void *>(lib::addressof(a)))
   1481             alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
   1482         return a.value;
   1483       }
   1484 
   1485       template <typename Rhs>
   1486       inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
   1487         lhs.destroy();
   1488         if (!rhs.valueless_by_exception()) {
   1489           visitation::alt::visit_alt_at(
   1490               rhs.index(),
   1491 #ifdef MPARK_GENERIC_LAMBDAS
   1492               [](auto &lhs_alt, auto &&rhs_alt) {
   1493                 constructor::construct_alt(
   1494                     lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
   1495               }
   1496 #else
   1497               ctor{}
   1498 #endif
   1499               ,
   1500               lhs,
   1501               lib::forward<Rhs>(rhs));
   1502           lhs.index_ = rhs.index_;
   1503         }
   1504       }
   1505     };
   1506 
   1507     template <typename Traits, Trait = Traits::move_constructible_trait>
   1508     class move_constructor;
   1509 
   1510 #define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
   1511   template <typename... Ts>                                                  \
   1512   class move_constructor<traits<Ts...>, move_constructible_trait>            \
   1513       : public constructor<traits<Ts...>> {                                  \
   1514     using super = constructor<traits<Ts...>>;                                \
   1515                                                                              \
   1516     public:                                                                  \
   1517     INHERITING_CTOR(move_constructor, super)                                 \
   1518     using super::operator=;                                                  \
   1519                                                                              \
   1520     move_constructor(const move_constructor &) = default;                    \
   1521     definition                                                               \
   1522     ~move_constructor() = default;                                           \
   1523     move_constructor &operator=(const move_constructor &) = default;         \
   1524     move_constructor &operator=(move_constructor &&) = default;              \
   1525   }
   1526 
   1527     MPARK_VARIANT_MOVE_CONSTRUCTOR(
   1528         Trait::TriviallyAvailable,
   1529         move_constructor(move_constructor &&that) = default;);
   1530 
   1531     MPARK_VARIANT_MOVE_CONSTRUCTOR(
   1532         Trait::Available,
   1533         move_constructor(move_constructor &&that) noexcept(
   1534             lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
   1535             : move_constructor(valueless_t{}) {
   1536           this->generic_construct(*this, lib::move(that));
   1537         });
   1538 
   1539     MPARK_VARIANT_MOVE_CONSTRUCTOR(
   1540         Trait::Unavailable,
   1541         move_constructor(move_constructor &&) = delete;);
   1542 
   1543 #undef MPARK_VARIANT_MOVE_CONSTRUCTOR
   1544 
   1545     template <typename Traits, Trait = Traits::copy_constructible_trait>
   1546     class copy_constructor;
   1547 
   1548 #define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
   1549   template <typename... Ts>                                                  \
   1550   class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
   1551       : public move_constructor<traits<Ts...>> {                             \
   1552     using super = move_constructor<traits<Ts...>>;                           \
   1553                                                                              \
   1554     public:                                                                  \
   1555     INHERITING_CTOR(copy_constructor, super)                                 \
   1556     using super::operator=;                                                  \
   1557                                                                              \
   1558     definition                                                               \
   1559     copy_constructor(copy_constructor &&) = default;                         \
   1560     ~copy_constructor() = default;                                           \
   1561     copy_constructor &operator=(const copy_constructor &) = default;         \
   1562     copy_constructor &operator=(copy_constructor &&) = default;              \
   1563   }
   1564 
   1565     MPARK_VARIANT_COPY_CONSTRUCTOR(
   1566         Trait::TriviallyAvailable,
   1567         copy_constructor(const copy_constructor &that) = default;);
   1568 
   1569     MPARK_VARIANT_COPY_CONSTRUCTOR(
   1570         Trait::Available,
   1571         copy_constructor(const copy_constructor &that)
   1572             : copy_constructor(valueless_t{}) {
   1573           this->generic_construct(*this, that);
   1574         });
   1575 
   1576     MPARK_VARIANT_COPY_CONSTRUCTOR(
   1577         Trait::Unavailable,
   1578         copy_constructor(const copy_constructor &) = delete;);
   1579 
   1580 #undef MPARK_VARIANT_COPY_CONSTRUCTOR
   1581 
   1582     template <typename Traits>
   1583     class assignment : public copy_constructor<Traits> {
   1584       using super = copy_constructor<Traits>;
   1585 
   1586       public:
   1587       INHERITING_CTOR(assignment, super)
   1588       using super::operator=;
   1589 
   1590       template <std::size_t I, typename... Args>
   1591       inline /* auto & */ auto emplace(Args &&... args)
   1592           -> decltype(this->construct_alt(access::base::get_alt<I>(*this),
   1593                                           lib::forward<Args>(args)...)) {
   1594         this->destroy();
   1595         auto &result = this->construct_alt(access::base::get_alt<I>(*this),
   1596                                            lib::forward<Args>(args)...);
   1597         this->index_ = I;
   1598         return result;
   1599       }
   1600 
   1601       protected:
   1602 #ifndef MPARK_GENERIC_LAMBDAS
   1603       template <typename That>
   1604       struct assigner {
   1605         template <typename ThisAlt, typename ThatAlt>
   1606         inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const {
   1607           self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
   1608         }
   1609         assignment *self;
   1610       };
   1611 #endif
   1612 
   1613       template <std::size_t I, typename T, typename Arg>
   1614       inline void assign_alt(alt<I, T> &a, Arg &&arg) {
   1615         if (this->index() == I) {
   1616 #ifdef _MSC_VER
   1617 #pragma warning(push)
   1618 #pragma warning(disable : 4244)
   1619 #endif
   1620           a.value = lib::forward<Arg>(arg);
   1621 #ifdef _MSC_VER
   1622 #pragma warning(pop)
   1623 #endif
   1624         } else {
   1625           struct {
   1626             void operator()(std::true_type) const {
   1627               this_->emplace<I>(lib::forward<Arg>(arg_));
   1628             }
   1629             void operator()(std::false_type) const {
   1630               this_->emplace<I>(T(lib::forward<Arg>(arg_)));
   1631             }
   1632             assignment *this_;
   1633             Arg &&arg_;
   1634           } impl{this, lib::forward<Arg>(arg)};
   1635           impl(lib::bool_constant<
   1636                    std::is_nothrow_constructible<T, Arg>::value ||
   1637                    !std::is_nothrow_move_constructible<T>::value>{});
   1638         }
   1639       }
   1640 
   1641       template <typename That>
   1642       inline void generic_assign(That &&that) {
   1643         if (this->valueless_by_exception() && that.valueless_by_exception()) {
   1644           // do nothing.
   1645         } else if (that.valueless_by_exception()) {
   1646           this->destroy();
   1647         } else {
   1648           visitation::alt::visit_alt_at(
   1649               that.index(),
   1650 #ifdef MPARK_GENERIC_LAMBDAS
   1651               [this](auto &this_alt, auto &&that_alt) {
   1652                 this->assign_alt(
   1653                     this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
   1654               }
   1655 #else
   1656               assigner<That>{this}
   1657 #endif
   1658               ,
   1659               *this,
   1660               lib::forward<That>(that));
   1661         }
   1662       }
   1663     };
   1664 
   1665     template <typename Traits, Trait = Traits::move_assignable_trait>
   1666     class move_assignment;
   1667 
   1668 #define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
   1669   template <typename... Ts>                                              \
   1670   class move_assignment<traits<Ts...>, move_assignable_trait>            \
   1671       : public assignment<traits<Ts...>> {                               \
   1672     using super = assignment<traits<Ts...>>;                             \
   1673                                                                          \
   1674     public:                                                              \
   1675     INHERITING_CTOR(move_assignment, super)                              \
   1676     using super::operator=;                                              \
   1677                                                                          \
   1678     move_assignment(const move_assignment &) = default;                  \
   1679     move_assignment(move_assignment &&) = default;                       \
   1680     ~move_assignment() = default;                                        \
   1681     move_assignment &operator=(const move_assignment &) = default;       \
   1682     definition                                                           \
   1683   }
   1684 
   1685     MPARK_VARIANT_MOVE_ASSIGNMENT(
   1686         Trait::TriviallyAvailable,
   1687         move_assignment &operator=(move_assignment &&that) = default;);
   1688 
   1689     MPARK_VARIANT_MOVE_ASSIGNMENT(
   1690         Trait::Available,
   1691         move_assignment &
   1692         operator=(move_assignment &&that) noexcept(
   1693             lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
   1694                       std::is_nothrow_move_assignable<Ts>::value)...>::value) {
   1695           this->generic_assign(lib::move(that));
   1696           return *this;
   1697         });
   1698 
   1699     MPARK_VARIANT_MOVE_ASSIGNMENT(
   1700         Trait::Unavailable,
   1701         move_assignment &operator=(move_assignment &&) = delete;);
   1702 
   1703 #undef MPARK_VARIANT_MOVE_ASSIGNMENT
   1704 
   1705     template <typename Traits, Trait = Traits::copy_assignable_trait>
   1706     class copy_assignment;
   1707 
   1708 #define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
   1709   template <typename... Ts>                                              \
   1710   class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
   1711       : public move_assignment<traits<Ts...>> {                          \
   1712     using super = move_assignment<traits<Ts...>>;                        \
   1713                                                                          \
   1714     public:                                                              \
   1715     INHERITING_CTOR(copy_assignment, super)                              \
   1716     using super::operator=;                                              \
   1717                                                                          \
   1718     copy_assignment(const copy_assignment &) = default;                  \
   1719     copy_assignment(copy_assignment &&) = default;                       \
   1720     ~copy_assignment() = default;                                        \
   1721     definition                                                           \
   1722     copy_assignment &operator=(copy_assignment &&) = default;            \
   1723   }
   1724 
   1725     MPARK_VARIANT_COPY_ASSIGNMENT(
   1726         Trait::TriviallyAvailable,
   1727         copy_assignment &operator=(const copy_assignment &that) = default;);
   1728 
   1729     MPARK_VARIANT_COPY_ASSIGNMENT(
   1730         Trait::Available,
   1731         copy_assignment &operator=(const copy_assignment &that) {
   1732           this->generic_assign(that);
   1733           return *this;
   1734         });
   1735 
   1736     MPARK_VARIANT_COPY_ASSIGNMENT(
   1737         Trait::Unavailable,
   1738         copy_assignment &operator=(const copy_assignment &) = delete;);
   1739 
   1740 #undef MPARK_VARIANT_COPY_ASSIGNMENT
   1741 
   1742     template <typename... Ts>
   1743     class impl : public copy_assignment<traits<Ts...>> {
   1744       using super = copy_assignment<traits<Ts...>>;
   1745 
   1746       public:
   1747       INHERITING_CTOR(impl, super)
   1748       using super::operator=;
   1749 
   1750       template <std::size_t I, typename Arg>
   1751       inline void assign(Arg &&arg) {
   1752         this->assign_alt(access::base::get_alt<I>(*this),
   1753                          lib::forward<Arg>(arg));
   1754       }
   1755 
   1756       inline void swap(impl &that) {
   1757         if (this->valueless_by_exception() && that.valueless_by_exception()) {
   1758           // do nothing.
   1759         } else if (this->index() == that.index()) {
   1760           visitation::alt::visit_alt_at(this->index(),
   1761 #ifdef MPARK_GENERIC_LAMBDAS
   1762                                         [](auto &this_alt, auto &that_alt) {
   1763                                           using std::swap;
   1764                                           swap(this_alt.value,
   1765                                                that_alt.value);
   1766                                         }
   1767 #else
   1768                                         swapper{}
   1769 #endif
   1770                                         ,
   1771                                         *this,
   1772                                         that);
   1773         } else {
   1774           impl *lhs = this;
   1775           impl *rhs = lib::addressof(that);
   1776           if (lhs->move_nothrow() && !rhs->move_nothrow()) {
   1777             std::swap(lhs, rhs);
   1778           }
   1779           impl tmp(lib::move(*rhs));
   1780 #ifdef MPARK_EXCEPTIONS
   1781           // EXTENSION: When the move construction of `lhs` into `rhs` throws
   1782           // and `tmp` is nothrow move constructible then we move `tmp` back
   1783           // into `rhs` and provide the strong exception safety guarantee.
   1784           try {
   1785             this->generic_construct(*rhs, lib::move(*lhs));
   1786           } catch (...) {
   1787             if (tmp.move_nothrow()) {
   1788               this->generic_construct(*rhs, lib::move(tmp));
   1789             }
   1790             throw;
   1791           }
   1792 #else
   1793           this->generic_construct(*rhs, lib::move(*lhs));
   1794 #endif
   1795           this->generic_construct(*lhs, lib::move(tmp));
   1796         }
   1797       }
   1798 
   1799       private:
   1800 #ifndef MPARK_GENERIC_LAMBDAS
   1801       struct swapper {
   1802         template <typename ThisAlt, typename ThatAlt>
   1803         inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const {
   1804           using std::swap;
   1805           swap(this_alt.value, that_alt.value);
   1806         }
   1807       };
   1808 #endif
   1809 
   1810       inline constexpr bool move_nothrow() const {
   1811         return this->valueless_by_exception() ||
   1812                lib::array<bool, sizeof...(Ts)>{
   1813                    {std::is_nothrow_move_constructible<Ts>::value...}
   1814                }[this->index()];
   1815       }
   1816     };
   1817 
   1818     template <std::size_t I, typename T>
   1819     struct overload_leaf {
   1820       using F = lib::size_constant<I> (*)(T);
   1821       operator F() const { return nullptr; }
   1822     };
   1823 
   1824     template <typename... Ts>
   1825     struct overload_impl {
   1826       private:
   1827       template <typename>
   1828       struct impl;
   1829 
   1830       template <std::size_t... Is>
   1831       struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>... {};
   1832 
   1833       public:
   1834       using type = impl<lib::index_sequence_for<Ts...>>;
   1835     };
   1836 
   1837     template <typename... Ts>
   1838     using overload = typename overload_impl<Ts...>::type;
   1839 
   1840     template <typename T, typename... Ts>
   1841     using best_match = lib::invoke_result_t<overload<Ts...>, T &&>;
   1842 
   1843     template <typename T>
   1844     struct is_in_place_index : std::false_type {};
   1845 
   1846     template <std::size_t I>
   1847     struct is_in_place_index<in_place_index_t<I>> : std::true_type {};
   1848 
   1849     template <typename T>
   1850     struct is_in_place_type : std::false_type {};
   1851 
   1852     template <typename T>
   1853     struct is_in_place_type<in_place_type_t<T>> : std::true_type {};
   1854 
   1855   }  // detail
   1856 
   1857   template <typename... Ts>
   1858   class variant {
   1859     static_assert(0 < sizeof...(Ts),
   1860                   "variant must consist of at least one alternative.");
   1861 
   1862     static_assert(lib::all<!std::is_array<Ts>::value...>::value,
   1863                   "variant can not have an array type as an alternative.");
   1864 
   1865     static_assert(lib::all<!std::is_reference<Ts>::value...>::value,
   1866                   "variant can not have a reference type as an alternative.");
   1867 
   1868     static_assert(lib::all<!std::is_void<Ts>::value...>::value,
   1869                   "variant can not have a void type as an alternative.");
   1870 
   1871     public:
   1872     template <
   1873         typename Front = lib::type_pack_element_t<0, Ts...>,
   1874         lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
   1875     inline constexpr variant() noexcept(
   1876         std::is_nothrow_default_constructible<Front>::value)
   1877         : impl_(in_place_index_t<0>{}) {}
   1878 
   1879     variant(const variant &) = default;
   1880     variant(variant &&) = default;
   1881 
   1882     template <
   1883         typename Arg,
   1884         typename Decayed = lib::decay_t<Arg>,
   1885         lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
   1886         lib::enable_if_t<!detail::is_in_place_index<Decayed>::value, int> = 0,
   1887         lib::enable_if_t<!detail::is_in_place_type<Decayed>::value, int> = 0,
   1888         std::size_t I = detail::best_match<Arg, Ts...>::value,
   1889         typename T = lib::type_pack_element_t<I, Ts...>,
   1890         lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
   1891     inline constexpr variant(Arg &&arg) noexcept(
   1892         std::is_nothrow_constructible<T, Arg>::value)
   1893         : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {}
   1894 
   1895     template <
   1896         std::size_t I,
   1897         typename... Args,
   1898         typename T = lib::type_pack_element_t<I, Ts...>,
   1899         lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
   1900     inline explicit constexpr variant(
   1901         in_place_index_t<I>,
   1902         Args &&... args) noexcept(std::is_nothrow_constructible<T,
   1903                                                                 Args...>::value)
   1904         : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
   1905 
   1906     template <
   1907         std::size_t I,
   1908         typename Up,
   1909         typename... Args,
   1910         typename T = lib::type_pack_element_t<I, Ts...>,
   1911         lib::enable_if_t<std::is_constructible<T,
   1912                                                std::initializer_list<Up> &,
   1913                                                Args...>::value,
   1914                          int> = 0>
   1915     inline explicit constexpr variant(
   1916         in_place_index_t<I>,
   1917         std::initializer_list<Up> il,
   1918         Args &&... args) noexcept(std::
   1919                                       is_nothrow_constructible<
   1920                                           T,
   1921                                           std::initializer_list<Up> &,
   1922                                           Args...>::value)
   1923         : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
   1924 
   1925     template <
   1926         typename T,
   1927         typename... Args,
   1928         std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
   1929         lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
   1930     inline explicit constexpr variant(
   1931         in_place_type_t<T>,
   1932         Args &&... args) noexcept(std::is_nothrow_constructible<T,
   1933                                                                 Args...>::value)
   1934         : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
   1935 
   1936     template <
   1937         typename T,
   1938         typename Up,
   1939         typename... Args,
   1940         std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
   1941         lib::enable_if_t<std::is_constructible<T,
   1942                                                std::initializer_list<Up> &,
   1943                                                Args...>::value,
   1944                          int> = 0>
   1945     inline explicit constexpr variant(
   1946         in_place_type_t<T>,
   1947         std::initializer_list<Up> il,
   1948         Args &&... args) noexcept(std::
   1949                                       is_nothrow_constructible<
   1950                                           T,
   1951                                           std::initializer_list<Up> &,
   1952                                           Args...>::value)
   1953         : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
   1954 
   1955     ~variant() = default;
   1956 
   1957     variant &operator=(const variant &) = default;
   1958     variant &operator=(variant &&) = default;
   1959 
   1960     template <typename Arg,
   1961               lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value,
   1962                                int> = 0,
   1963               std::size_t I = detail::best_match<Arg, Ts...>::value,
   1964               typename T = lib::type_pack_element_t<I, Ts...>,
   1965               lib::enable_if_t<(std::is_assignable<T &, Arg>::value &&
   1966                                 std::is_constructible<T, Arg>::value),
   1967                                int> = 0>
   1968     inline variant &operator=(Arg &&arg) noexcept(
   1969         (std::is_nothrow_assignable<T &, Arg>::value &&
   1970          std::is_nothrow_constructible<T, Arg>::value)) {
   1971       impl_.template assign<I>(lib::forward<Arg>(arg));
   1972       return *this;
   1973     }
   1974 
   1975     template <
   1976         std::size_t I,
   1977         typename... Args,
   1978         typename T = lib::type_pack_element_t<I, Ts...>,
   1979         lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
   1980     inline T &emplace(Args &&... args) {
   1981       return impl_.template emplace<I>(lib::forward<Args>(args)...);
   1982     }
   1983 
   1984     template <
   1985         std::size_t I,
   1986         typename Up,
   1987         typename... Args,
   1988         typename T = lib::type_pack_element_t<I, Ts...>,
   1989         lib::enable_if_t<std::is_constructible<T,
   1990                                                std::initializer_list<Up> &,
   1991                                                Args...>::value,
   1992                          int> = 0>
   1993     inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
   1994       return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
   1995     }
   1996 
   1997     template <
   1998         typename T,
   1999         typename... Args,
   2000         std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
   2001         lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
   2002     inline T &emplace(Args &&... args) {
   2003       return impl_.template emplace<I>(lib::forward<Args>(args)...);
   2004     }
   2005 
   2006     template <
   2007         typename T,
   2008         typename Up,
   2009         typename... Args,
   2010         std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
   2011         lib::enable_if_t<std::is_constructible<T,
   2012                                                std::initializer_list<Up> &,
   2013                                                Args...>::value,
   2014                          int> = 0>
   2015     inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
   2016       return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
   2017     }
   2018 
   2019     inline constexpr bool valueless_by_exception() const noexcept {
   2020       return impl_.valueless_by_exception();
   2021     }
   2022 
   2023     inline constexpr std::size_t index() const noexcept {
   2024       return impl_.index();
   2025     }
   2026 
   2027     template <bool Dummy = true,
   2028               lib::enable_if_t<
   2029                   lib::all<Dummy,
   2030                            (lib::dependent_type<std::is_move_constructible<Ts>,
   2031                                                 Dummy>::value &&
   2032                             lib::dependent_type<lib::is_swappable<Ts>,
   2033                                                 Dummy>::value)...>::value,
   2034                   int> = 0>
   2035     inline void swap(variant &that) noexcept(
   2036         lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
   2037                   lib::is_nothrow_swappable<Ts>::value)...>::value) {
   2038       impl_.swap(that.impl_);
   2039     }
   2040 
   2041     private:
   2042     detail::impl<Ts...> impl_;
   2043 
   2044     friend struct detail::access::variant;
   2045     friend struct detail::visitation::variant;
   2046   };
   2047 
   2048   template <std::size_t I, typename... Ts>
   2049   inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
   2050     return v.index() == I;
   2051   }
   2052 
   2053   template <typename T, typename... Ts>
   2054   inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
   2055     return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
   2056   }
   2057 
   2058   namespace detail {
   2059     template <std::size_t I, typename V>
   2060     struct generic_get_impl {
   2061       constexpr generic_get_impl(int) {}
   2062 
   2063       constexpr AUTO_REFREF operator()(V &&v) const
   2064         AUTO_REFREF_RETURN(
   2065             access::variant::get_alt<I>(lib::forward<V>(v)).value)
   2066     };
   2067 
   2068     template <std::size_t I, typename V>
   2069     inline constexpr AUTO_REFREF generic_get(V &&v)
   2070       AUTO_REFREF_RETURN(generic_get_impl<I, V>(
   2071           holds_alternative<I>(v) ? 0 : (throw_bad_variant_access(), 0))(
   2072           lib::forward<V>(v)))
   2073   }  // namespace detail
   2074 
   2075   template <std::size_t I, typename... Ts>
   2076   inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
   2077       variant<Ts...> &v) {
   2078     return detail::generic_get<I>(v);
   2079   }
   2080 
   2081   template <std::size_t I, typename... Ts>
   2082   inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
   2083       variant<Ts...> &&v) {
   2084     return detail::generic_get<I>(lib::move(v));
   2085   }
   2086 
   2087   template <std::size_t I, typename... Ts>
   2088   inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
   2089       const variant<Ts...> &v) {
   2090     return detail::generic_get<I>(v);
   2091   }
   2092 
   2093   template <std::size_t I, typename... Ts>
   2094   inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
   2095       const variant<Ts...> &&v) {
   2096     return detail::generic_get<I>(lib::move(v));
   2097   }
   2098 
   2099   template <typename T, typename... Ts>
   2100   inline constexpr T &get(variant<Ts...> &v) {
   2101     return get<detail::find_index_checked<T, Ts...>::value>(v);
   2102   }
   2103 
   2104   template <typename T, typename... Ts>
   2105   inline constexpr T &&get(variant<Ts...> &&v) {
   2106     return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
   2107   }
   2108 
   2109   template <typename T, typename... Ts>
   2110   inline constexpr const T &get(const variant<Ts...> &v) {
   2111     return get<detail::find_index_checked<T, Ts...>::value>(v);
   2112   }
   2113 
   2114   template <typename T, typename... Ts>
   2115   inline constexpr const T &&get(const variant<Ts...> &&v) {
   2116     return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
   2117   }
   2118 
   2119   namespace detail {
   2120 
   2121     template <std::size_t I, typename V>
   2122     inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept
   2123       AUTO_RETURN(v && holds_alternative<I>(*v)
   2124                       ? lib::addressof(access::variant::get_alt<I>(*v).value)
   2125                       : nullptr)
   2126 
   2127   }  // namespace detail
   2128 
   2129   template <std::size_t I, typename... Ts>
   2130   inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
   2131   get_if(variant<Ts...> *v) noexcept {
   2132     return detail::generic_get_if<I>(v);
   2133   }
   2134 
   2135   template <std::size_t I, typename... Ts>
   2136   inline constexpr lib::add_pointer_t<
   2137       const variant_alternative_t<I, variant<Ts...>>>
   2138   get_if(const variant<Ts...> *v) noexcept {
   2139     return detail::generic_get_if<I>(v);
   2140   }
   2141 
   2142   template <typename T, typename... Ts>
   2143   inline constexpr lib::add_pointer_t<T>
   2144   get_if(variant<Ts...> *v) noexcept {
   2145     return get_if<detail::find_index_checked<T, Ts...>::value>(v);
   2146   }
   2147 
   2148   template <typename T, typename... Ts>
   2149   inline constexpr lib::add_pointer_t<const T>
   2150   get_if(const variant<Ts...> *v) noexcept {
   2151     return get_if<detail::find_index_checked<T, Ts...>::value>(v);
   2152   }
   2153 
   2154   template <typename... Ts>
   2155   inline constexpr bool operator==(const variant<Ts...> &lhs,
   2156                                    const variant<Ts...> &rhs) {
   2157     using detail::visitation::variant;
   2158     using lib::equal_to;
   2159 #ifdef MPARK_CPP14_CONSTEXPR
   2160     if (lhs.index() != rhs.index()) return false;
   2161     if (lhs.valueless_by_exception()) return true;
   2162     return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
   2163 #else
   2164     return lhs.index() == rhs.index() &&
   2165            (lhs.valueless_by_exception() ||
   2166             variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
   2167 #endif
   2168   }
   2169 
   2170   template <typename... Ts>
   2171   inline constexpr bool operator!=(const variant<Ts...> &lhs,
   2172                                    const variant<Ts...> &rhs) {
   2173     using detail::visitation::variant;
   2174     using lib::not_equal_to;
   2175 #ifdef MPARK_CPP14_CONSTEXPR
   2176     if (lhs.index() != rhs.index()) return true;
   2177     if (lhs.valueless_by_exception()) return false;
   2178     return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
   2179 #else
   2180     return lhs.index() != rhs.index() ||
   2181            (!lhs.valueless_by_exception() &&
   2182             variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
   2183 #endif
   2184   }
   2185 
   2186   template <typename... Ts>
   2187   inline constexpr bool operator<(const variant<Ts...> &lhs,
   2188                                   const variant<Ts...> &rhs) {
   2189     using detail::visitation::variant;
   2190     using lib::less;
   2191 #ifdef MPARK_CPP14_CONSTEXPR
   2192     if (rhs.valueless_by_exception()) return false;
   2193     if (lhs.valueless_by_exception()) return true;
   2194     if (lhs.index() < rhs.index()) return true;
   2195     if (lhs.index() > rhs.index()) return false;
   2196     return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
   2197 #else
   2198     return !rhs.valueless_by_exception() &&
   2199            (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
   2200             (lhs.index() == rhs.index() &&
   2201              variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
   2202 #endif
   2203   }
   2204 
   2205   template <typename... Ts>
   2206   inline constexpr bool operator>(const variant<Ts...> &lhs,
   2207                                   const variant<Ts...> &rhs) {
   2208     using detail::visitation::variant;
   2209     using lib::greater;
   2210 #ifdef MPARK_CPP14_CONSTEXPR
   2211     if (lhs.valueless_by_exception()) return false;
   2212     if (rhs.valueless_by_exception()) return true;
   2213     if (lhs.index() > rhs.index()) return true;
   2214     if (lhs.index() < rhs.index()) return false;
   2215     return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
   2216 #else
   2217     return !lhs.valueless_by_exception() &&
   2218            (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
   2219             (lhs.index() == rhs.index() &&
   2220              variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
   2221 #endif
   2222   }
   2223 
   2224   template <typename... Ts>
   2225   inline constexpr bool operator<=(const variant<Ts...> &lhs,
   2226                                    const variant<Ts...> &rhs) {
   2227     using detail::visitation::variant;
   2228     using lib::less_equal;
   2229 #ifdef MPARK_CPP14_CONSTEXPR
   2230     if (lhs.valueless_by_exception()) return true;
   2231     if (rhs.valueless_by_exception()) return false;
   2232     if (lhs.index() < rhs.index()) return true;
   2233     if (lhs.index() > rhs.index()) return false;
   2234     return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
   2235 #else
   2236     return lhs.valueless_by_exception() ||
   2237            (!rhs.valueless_by_exception() &&
   2238             (lhs.index() < rhs.index() ||
   2239              (lhs.index() == rhs.index() &&
   2240               variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
   2241 #endif
   2242   }
   2243 
   2244   template <typename... Ts>
   2245   inline constexpr bool operator>=(const variant<Ts...> &lhs,
   2246                                    const variant<Ts...> &rhs) {
   2247     using detail::visitation::variant;
   2248     using lib::greater_equal;
   2249 #ifdef MPARK_CPP14_CONSTEXPR
   2250     if (rhs.valueless_by_exception()) return true;
   2251     if (lhs.valueless_by_exception()) return false;
   2252     if (lhs.index() > rhs.index()) return true;
   2253     if (lhs.index() < rhs.index()) return false;
   2254     return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
   2255 #else
   2256     return rhs.valueless_by_exception() ||
   2257            (!lhs.valueless_by_exception() &&
   2258             (lhs.index() > rhs.index() ||
   2259              (lhs.index() == rhs.index() &&
   2260               variant::visit_value_at(
   2261                   lhs.index(), greater_equal{}, lhs, rhs))));
   2262 #endif
   2263   }
   2264 
   2265   struct monostate {};
   2266 
   2267   inline constexpr bool operator<(monostate, monostate) noexcept {
   2268     return false;
   2269   }
   2270 
   2271   inline constexpr bool operator>(monostate, monostate) noexcept {
   2272     return false;
   2273   }
   2274 
   2275   inline constexpr bool operator<=(monostate, monostate) noexcept {
   2276     return true;
   2277   }
   2278 
   2279   inline constexpr bool operator>=(monostate, monostate) noexcept {
   2280     return true;
   2281   }
   2282 
   2283   inline constexpr bool operator==(monostate, monostate) noexcept {
   2284     return true;
   2285   }
   2286 
   2287   inline constexpr bool operator!=(monostate, monostate) noexcept {
   2288     return false;
   2289   }
   2290 
   2291 #ifdef MPARK_CPP14_CONSTEXPR
   2292   namespace detail {
   2293 
   2294     inline constexpr bool all(std::initializer_list<bool> bs) {
   2295       for (bool b : bs) {
   2296         if (!b) {
   2297           return false;
   2298         }
   2299       }
   2300       return true;
   2301     }
   2302 
   2303   }  // namespace detail
   2304 
   2305   template <typename Visitor, typename... Vs>
   2306   inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
   2307     return (detail::all({!vs.valueless_by_exception()...})
   2308                 ? (void)0
   2309                 : throw_bad_variant_access()),
   2310            detail::visitation::variant::visit_value(
   2311                lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
   2312   }
   2313 #else
   2314   namespace detail {
   2315 
   2316     template <std::size_t N>
   2317     inline constexpr bool all_impl(const lib::array<bool, N> &bs,
   2318                                    std::size_t idx) {
   2319       return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
   2320     }
   2321 
   2322     template <std::size_t N>
   2323     inline constexpr bool all(const lib::array<bool, N> &bs) {
   2324       return all_impl(bs, 0);
   2325     }
   2326 
   2327   }  // namespace detail
   2328 
   2329   template <typename Visitor, typename... Vs>
   2330   inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs)
   2331     DECLTYPE_AUTO_RETURN(
   2332         (detail::all(
   2333              lib::array<bool, sizeof...(Vs)>{{!vs.valueless_by_exception()...}})
   2334              ? (void)0
   2335              : throw_bad_variant_access()),
   2336         detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
   2337                                                  lib::forward<Vs>(vs)...))
   2338 #endif
   2339 
   2340   template <typename... Ts>
   2341   inline auto swap(variant<Ts...> &lhs,
   2342                    variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
   2343       -> decltype(lhs.swap(rhs)) {
   2344     lhs.swap(rhs);
   2345   }
   2346 
   2347   namespace detail {
   2348 
   2349     template <typename T, typename...>
   2350     using enabled_type = T;
   2351 
   2352     namespace hash {
   2353 
   2354       template <typename H, typename K>
   2355       constexpr bool meets_requirements() {
   2356         return std::is_copy_constructible<H>::value &&
   2357                std::is_move_constructible<H>::value &&
   2358                lib::is_invocable_r<std::size_t, H, const K &>::value;
   2359       }
   2360 
   2361       template <typename K>
   2362       constexpr bool is_enabled() {
   2363         using H = std::hash<K>;
   2364         return meets_requirements<H, K>() &&
   2365                std::is_default_constructible<H>::value &&
   2366                std::is_copy_assignable<H>::value &&
   2367                std::is_move_assignable<H>::value;
   2368       }
   2369 
   2370     }  // namespace hash
   2371 
   2372   }  // namespace detail
   2373 
   2374 #undef AUTO
   2375 #undef AUTO_RETURN
   2376 
   2377 #undef AUTO_REFREF
   2378 #undef AUTO_REFREF_RETURN
   2379 
   2380 #undef DECLTYPE_AUTO
   2381 #undef DECLTYPE_AUTO_RETURN
   2382 
   2383 }  // namespace mpark
   2384 
   2385 namespace std {
   2386 
   2387   template <typename... Ts>
   2388   struct hash<mpark::detail::enabled_type<
   2389       mpark::variant<Ts...>,
   2390       mpark::lib::enable_if_t<mpark::lib::all<mpark::detail::hash::is_enabled<
   2391           mpark::lib::remove_const_t<Ts>>()...>::value>>> {
   2392     using argument_type = mpark::variant<Ts...>;
   2393     using result_type = std::size_t;
   2394 
   2395     inline result_type operator()(const argument_type &v) const {
   2396       using mpark::detail::visitation::variant;
   2397       std::size_t result =
   2398           v.valueless_by_exception()
   2399               ? 299792458  // Random value chosen by the universe upon creation
   2400               : variant::visit_alt(
   2401 #ifdef MPARK_GENERIC_LAMBDAS
   2402                     [](const auto &alt) {
   2403                       using alt_type = mpark::lib::decay_t<decltype(alt)>;
   2404                       using value_type = mpark::lib::remove_const_t<
   2405                           typename alt_type::value_type>;
   2406                       return hash<value_type>{}(alt.value);
   2407                     }
   2408 #else
   2409                     hasher{}
   2410 #endif
   2411                     ,
   2412                     v);
   2413       return hash_combine(result, hash<std::size_t>{}(v.index()));
   2414     }
   2415 
   2416     private:
   2417 #ifndef MPARK_GENERIC_LAMBDAS
   2418     struct hasher {
   2419       template <typename Alt>
   2420       inline std::size_t operator()(const Alt &alt) const {
   2421         using alt_type = mpark::lib::decay_t<Alt>;
   2422         using value_type =
   2423             mpark::lib::remove_const_t<typename alt_type::value_type>;
   2424         return hash<value_type>{}(alt.value);
   2425       }
   2426     };
   2427 #endif
   2428 
   2429     static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
   2430       return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
   2431     }
   2432   };
   2433 
   2434   template <>
   2435   struct hash<mpark::monostate> {
   2436     using argument_type = mpark::monostate;
   2437     using result_type = std::size_t;
   2438 
   2439     inline result_type operator()(const argument_type &) const noexcept {
   2440       return 66740831;  // return a fundamentally attractive random value.
   2441     }
   2442   };
   2443 
   2444 }  // namespace std
   2445 
   2446 #endif  // MPARK_VARIANT_HPP