Преглед на файлове

Merge pull request #50 from martinwinter-huawei/linux_compile_fix_optional

Added missing include file <optional>
Jeremy Ong преди 2 години
родител
ревизия
c9fea9518e

+ 7 - 7
src/AzslcKindInfo.h

@@ -164,7 +164,7 @@ namespace AZ::ShaderCompiler
             // define a single generic visitor functor for the variant.
             // We are lucky that all AST nodes have a start object.
             // So this code compiles and work for all 5 types of nodes.
-            return StdUtils::visit([](auto&& arg)
+            return std::visit([](auto&& arg)
                                    {
                                        return static_cast<antlr4::ParserRuleContext*>(arg);
                                    }, m_declNodeVt);
@@ -179,7 +179,7 @@ namespace AZ::ShaderCompiler
         //! get Name token from declaration contexts
         const Token* GetDeclNodeNameToken() const
         {
-            return StdUtils::visit([](auto&& arg)
+            return std::visit([](auto&& arg)
                                    {
                                        return arg->Name;
                                    }, m_declNodeVt);
@@ -198,13 +198,13 @@ namespace AZ::ShaderCompiler
         template<typename T>
         T* Get()
         {
-            return (holds_alternative<T>(m_subInfo)) ? &get<T>(m_subInfo) : (T*)nullptr;
+            return (std::holds_alternative<T>(m_subInfo)) ? &std::get<T>(m_subInfo) : (T*)nullptr;
         }
 
         template<typename T>
         const T* Get() const
         {
-            return (holds_alternative<T>(m_subInfo)) ? &get<T>(m_subInfo) : (T*)nullptr;
+            return (std::holds_alternative<T>(m_subInfo)) ? &std::get<T>(m_subInfo) : (T*)nullptr;
         }
 
         Kind                           m_kind;   // which of class/struct/interface/srgsemantic ? (repetition of data in the upper KindInfo)
@@ -863,14 +863,14 @@ namespace AZ::ShaderCompiler
         template<typename T>
         const T* GetSubAs() const
         {
-            return (holds_alternative<T>(m_subInfo)) ? &get<T>(m_subInfo) : (const T*)nullptr;
+            return (std::holds_alternative<T>(m_subInfo)) ? &std::get<T>(m_subInfo) : (const T*)nullptr;
         }
 
         //! mutable version
         template<typename T>
         T* GetSubAs()
         {
-            return (holds_alternative<T>(m_subInfo)) ? &get<T>(m_subInfo) : (T*)nullptr;
+            return (std::holds_alternative<T>(m_subInfo)) ? &std::get<T>(m_subInfo) : (T*)nullptr;
         }
 
         //! Throwing version (bad_access) of above helper, gets a reference on success
@@ -967,7 +967,7 @@ namespace AZ::ShaderCompiler
         template<typename Visitor>
         auto VisitSub(Visitor&& v) const
         {
-            return StdUtils::visit(std::forward<Visitor>(v), m_subInfo);
+            return std::visit(std::forward<Visitor>(v), m_subInfo);
         }
 
     private:

+ 44 - 56
src/CMakeLists.txt

@@ -5,20 +5,20 @@ project (Azslc)
 include(FetchContent)
 
 FetchContent_Declare(
-  cli11
-  GIT_REPOSITORY https://github.com/CLIUtils/CLI11.git
-  GIT_TAG 3ce61a169297f5fe7d4b08bdbfa82290950d6f7f
+    cli11
+    GIT_REPOSITORY https://github.com/CLIUtils/CLI11.git
+    GIT_TAG 3ce61a169297f5fe7d4b08bdbfa82290950d6f7f
 )
 
 # Antlr4 external dependency
 FetchContent_Declare(
-  antlr4
-  GIT_REPOSITORY https://github.com/o3de/antlr4.git
-  GIT_TAG o3de-4.9.3
-  SOURCE_SUBDIR runtime/Cpp
-  CMAKE_ARGS "-DCMAKE_BUILD_TYPE=Release"
-  GIT_SHALLOW TRUE
-  GIT_PROGRESS TRUE
+    antlr4
+    GIT_REPOSITORY https://github.com/o3de/antlr4.git
+    GIT_TAG o3de-4.9.3
+    SOURCE_SUBDIR runtime/Cpp
+    CMAKE_ARGS "-DCMAKE_BUILD_TYPE=Release"
+    GIT_SHALLOW TRUE
+    GIT_PROGRESS TRUE
 )
 
 FetchContent_MakeAvailable(cli11 antlr4)
@@ -27,40 +27,30 @@ FetchContent_MakeAvailable(cli11 antlr4)
 string(REGEX MATCH "[^/\\]*$" buildPlatform ${CMAKE_BINARY_DIR})
 
 file(GLOB_RECURSE  azslc_PlatformSRC
-  "${PROJECT_SOURCE_DIR}/../Platform/*.cpp"
-  "${PROJECT_SOURCE_DIR}/../Platform/*.h"
+    "${PROJECT_SOURCE_DIR}/../Platform/*.cpp"
+    "${PROJECT_SOURCE_DIR}/../Platform/*.h"
 )
 
 file(GLOB azslc_LocalSRC
-  "${PROJECT_SOURCE_DIR}/*.cpp"
-  "${PROJECT_SOURCE_DIR}/*.tpl"
-  "${PROJECT_SOURCE_DIR}/*.h"
+    "${PROJECT_SOURCE_DIR}/*.cpp"
+    "${PROJECT_SOURCE_DIR}/*.tpl"
+    "${PROJECT_SOURCE_DIR}/*.h"
 )
 
 file(GLOB azslc_ExternalSRC
-  "${PROJECT_SOURCE_DIR}/external/jsoncpp/dist/json/*.h"
-  "${PROJECT_SOURCE_DIR}/external/jsoncpp/dist/*.cpp"
-  "${PROJECT_SOURCE_DIR}/external/mpark-variant/master/*.hpp"
-  "${PROJECT_SOURCE_DIR}/external/tiny/*.h"
+    "${PROJECT_SOURCE_DIR}/external/jsoncpp/dist/json/*.h"
+    "${PROJECT_SOURCE_DIR}/external/jsoncpp/dist/*.cpp"
 )
 
 file(GLOB azslc_GeneratedSrc
-  "${PROJECT_SOURCE_DIR}/generated/*.cpp"
+    "${PROJECT_SOURCE_DIR}/generated/*.cpp"
 )
 
 set( ANTLR4CPP_INCLUDE_DIRS
-  ${antlr4_SOURCE_DIR}/runtime/Cpp/runtime/src
-  ${antlr4_SOURCE_DIR}/runtime/Cpp/runtime/src/dfa
-  ${antlr4_SOURCE_DIR}/runtime/Cpp/runtime/src/misc
-  ${antlr4_SOURCE_DIR}/runtime/Cpp/runtime/src/tree
-)
-
-set( MPARK_VARIANT_INCLUDE_DIRS
-  ${PROJECT_SOURCE_DIR}/external/mpark-variant/master
-)
-
-set( TINY_OPTIONAL_INCLUDE_DIRS
-  ${PROJECT_SOURCE_DIR}/external/tiny
+    ${antlr4_SOURCE_DIR}/runtime/Cpp/runtime/src
+    ${antlr4_SOURCE_DIR}/runtime/Cpp/runtime/src/dfa
+    ${antlr4_SOURCE_DIR}/runtime/Cpp/runtime/src/misc
+    ${antlr4_SOURCE_DIR}/runtime/Cpp/runtime/src/tree
 )
 
 add_executable(azslc ${azslc_LocalSRC} ${azslc_PlatformSRC} ${azslc_GeneratedSrc} ${azslc_ExternalSRC})
@@ -68,13 +58,11 @@ add_executable(azslc ${azslc_LocalSRC} ${azslc_PlatformSRC} ${azslc_GeneratedSrc
 target_compile_features(azslc PRIVATE cxx_std_17)
 
 target_include_directories(
-  azslc
-  PRIVATE
-  ${PROJECT_SOURCE_DIR}
-  ${PROJECT_SOURCE_DIR}/external
-  ${ANTLR4CPP_INCLUDE_DIRS}
-  ${MPARK_VARIANT_INCLUDE_DIRS}
-  ${TINY_OPTIONAL_INCLUDE_DIRS}
+    azslc
+    PRIVATE
+    ${PROJECT_SOURCE_DIR}
+    ${PROJECT_SOURCE_DIR}/external
+    ${ANTLR4CPP_INCLUDE_DIRS}
 )
 
 source_group("azslc" FILES ${azslc_LocalSRC})
@@ -83,29 +71,29 @@ source_group("external" FILES ${azslc_ExternalSRC})
 source_group("platforms" FILES ${azslc_PlatformSRC})
 
 if (MSVC)
-  set_property(TARGET azslc PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
-  target_compile_options(azslc
-    PRIVATE
-    "/MP" # Build with multiple processes
-    "/permissive-"
-    "/Zc:__cplusplus"
-    "/utf-8")
-  target_compile_definitions(azslc
-    PRIVATE
-    _CRT_SECURE_NO_WARNINGS
-    _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
-    ANTLR4CPP_STATIC)
+    set_property(TARGET azslc PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+    target_compile_options(azslc
+        PRIVATE
+        "/MP" # Build with multiple processes
+        "/permissive-"
+        "/Zc:__cplusplus"
+        "/utf-8")
+    target_compile_definitions(azslc
+        PRIVATE
+        _CRT_SECURE_NO_WARNINGS
+        _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
+        ANTLR4CPP_STATIC)
 elseif (UNIX AND NOT APPLE)
-  target_link_libraries(azslc PRIVATE stdc++fs)
+    target_link_libraries(azslc PRIVATE stdc++fs)
 endif()
 
 target_link_libraries(azslc PRIVATE CLI11::CLI11 antlr4_static)
 
 if (MSVC)
-  add_custom_command(TARGET azslc POST_BUILD
-      COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_SOURCE_DIR}/../bin/${buildPlatform}/$(Configuration)"
-      COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/$(Configuration)/azslc.exe" "${PROJECT_SOURCE_DIR}/../bin/${buildPlatform}/$(Configuration)"
-)
+    add_custom_command(TARGET azslc POST_BUILD
+        COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_SOURCE_DIR}/../bin/${buildPlatform}/$(Configuration)"
+        COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/$(Configuration)/azslc.exe" "${PROJECT_SOURCE_DIR}/../bin/${buildPlatform}/$(Configuration)"
+    )
 endif()
 
 set_property(GLOBAL PROPERTY USE_FOLDERS ON)

+ 5 - 5
src/MetaUtils.h

@@ -370,7 +370,7 @@ namespace AZ
 
 #ifndef NDEBUG
 #include <cassert>
-#include "variant.hpp"
+#include <variant>
 #include <string>
 
 namespace AZ::Tests
@@ -397,10 +397,10 @@ namespace AZ::Tests
             });
 
         {  // check that the variant factory works
-            using mpark::variant;
-            using mpark::monostate;
-            using mpark::get;
-            using mpark::holds_alternative;
+            using std::variant;
+            using std::monostate;
+            using std::get;
+            using std::holds_alternative;
 
             struct S { bool b = true; };
             using V = variant<monostate, int, string, S>;

+ 6 - 56
src/StdUtils.h

@@ -10,13 +10,6 @@
 // setup of low level library includes in this file.
 // if not defined -> fallback to std
 
-#ifdef _WIN32
-// I don't recommend custom lib utilities on windows because they don't have natvis and are hard to debug.
-#else
-#define USE_TINY_OPTIONAL
-#define USE_MPARK_VARIANT
-#endif
-
 #include <cassert>
 #include <cctype>
 #include <cfloat>
@@ -33,52 +26,24 @@
 #include <tuple>
 #include <unordered_map>
 #include <unordered_set>
-
-#ifdef USE_MPARK_VARIANT
-#include "variant.hpp"
-namespace StdUtils = mpark;
-#else
 #include <variant>
-namespace StdUtils = std;
-#endif
+#include <optional>
 
-#if defined(USE_MPARK_VARIANT) && !defined(_WIN32)
-// one shortcut for is_invocable, because Xcode9 couldn't get it right:
-template <typename C, typename... T>
-using is_invocable = mpark::lib::is_invocable<C, T...>;
-// same for invoke_result
-template <typename C, typename... T>
-using invoke_result_t = mpark::lib::invoke_result_t<C, T...>;
-#else
 template <typename C, typename... T>
 using is_invocable = std::is_invocable<C, T...>;
 
 template <typename C, typename... T>
 using invoke_result_t = std::invoke_result_t<C, T...>;
-#endif
 
-#if defined(USE_TINY_OPTIONAL)
-#include <tiny/optional.h>
-#else // std
-#include <optional>
 inline constexpr auto none = std::nullopt;
-#endif
 
 namespace AZ
 {
-    // C++17 `std::variant` for C++11/14/17
-    using StdUtils::get;
-    using StdUtils::holds_alternative;
-    using StdUtils::monostate;
-    using StdUtils::variant;
-
-    // Alternatives for the C++17 std::optional
-#if defined(USE_TINY_OPTIONAL)
-    using tiny::none;
-    using tiny::optional;
-#else
+    using std::get;
+    using std::holds_alternative;
+    using std::monostate;
+    using std::variant;
     using std::optional;
-#endif
 
     // Configure basic symbols so we can use them unqualified -> easy to change to AzStd without big refactorings.
 
@@ -136,21 +101,6 @@ namespace AZ
     template <typename SetType>
     void SetMerge(SetType& dest, SetType& src)
     {
-#ifdef _WIN32
-        dest.merge(src); // when you have correct libraries.
-#else
-        for (auto it = src.begin(); it != src.end(); )
-        {
-            if (dest.find(*it) == dest.end())
-            {
-                dest.insert(std::move(*it));
-                it = src.erase(it);
-            }
-            else
-            {
-                ++it;
-            }
-        }
-#endif
+		dest.merge(src);
     }
 }

+ 0 - 23
src/external/mpark-variant/LICENSE.md

@@ -1,23 +0,0 @@
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.

+ 0 - 37
src/external/mpark-variant/README.md

@@ -1,37 +0,0 @@
-# MPark.Variant
-
-> __C++17__ `std::variant` for __C++11__/__14__/__17__
-
-[![release][badge.release]][release]
-[![header][badge.header]][header]
-[![travis][badge.travis]][travis]
-[![appveyor][badge.appveyor]][appveyor]
-[![license][badge.license]][license]
-[![godbolt][badge.godbolt]][godbolt]
-[![wandbox][badge.wandbox]][wandbox]
-
-[badge.release]: https://img.shields.io/github/release/mpark/variant.svg
-[badge.header]: https://img.shields.io/badge/single%20header-master-blue.svg
-[badge.travis]: https://travis-ci.org/mpark/variant.svg?branch=master
-[badge.appveyor]: https://ci.appveyor.com/api/projects/status/github/mpark/variant?branch=master&svg=true
-[badge.license]: https://img.shields.io/badge/license-boost-blue.svg
-[badge.godbolt]: https://img.shields.io/badge/try%20it-on%20godbolt-222266.svg
-[badge.wandbox]: https://img.shields.io/badge/try%20it-on%20wandbox-5cb85c.svg
-
-[release]: https://github.com/mpark/variant/releases/latest
-[header]: https://github.com/mpark/variant/blob/single-header/master/variant.hpp
-[travis]: https://travis-ci.org/mpark/variant
-[appveyor]: https://ci.appveyor.com/project/mpark/variant
-[license]: https://github.com/mpark/variant/blob/master/LICENSE.md
-[godbolt]: https://godbolt.org/z/4r7hEy
-[wandbox]: https://wandbox.org/permlink/dTZxf85MVhehOqx1
-
-## Single Header
-
-This branch provides a standalone `variant.hpp` file for each
-[release](https://github.com/mpark/variant/releases).
-Copy it and `#include` away!
-
-## License
-
-Distributed under the [Boost Software License, Version 1.0](LICENSE.md).

+ 0 - 2784
src/external/mpark-variant/master/variant.hpp

@@ -1,2784 +0,0 @@
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANT_HPP
-#define MPARK_VARIANT_HPP
-
-/*
-   variant synopsis
-
-namespace std {
-
-  // 20.7.2, class template variant
-  template <class... Types>
-  class variant {
-  public:
-
-    // 20.7.2.1, constructors
-    constexpr variant() noexcept(see below);
-    variant(const variant&);
-    variant(variant&&) noexcept(see below);
-
-    template <class T> constexpr variant(T&&) noexcept(see below);
-
-    template <class T, class... Args>
-    constexpr explicit variant(in_place_type_t<T>, Args&&...);
-
-    template <class T, class U, class... Args>
-    constexpr explicit variant(
-        in_place_type_t<T>, initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    constexpr explicit variant(in_place_index_t<I>, Args&&...);
-
-    template <size_t I, class U, class... Args>
-    constexpr explicit variant(
-        in_place_index_t<I>, initializer_list<U>, Args&&...);
-
-    // 20.7.2.2, destructor
-    ~variant();
-
-    // 20.7.2.3, assignment
-    variant& operator=(const variant&);
-    variant& operator=(variant&&) noexcept(see below);
-
-    template <class T> variant& operator=(T&&) noexcept(see below);
-
-    // 20.7.2.4, modifiers
-    template <class T, class... Args>
-    T& emplace(Args&&...);
-
-    template <class T, class U, class... Args>
-    T& emplace(initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    variant_alternative<I, variant>& emplace(Args&&...);
-
-    template <size_t I, class U, class...  Args>
-    variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
-
-    // 20.7.2.5, value status
-    constexpr bool valueless_by_exception() const noexcept;
-    constexpr size_t index() const noexcept;
-
-    // 20.7.2.6, swap
-    void swap(variant&) noexcept(see below);
-  };
-
-  // 20.7.3, variant helper classes
-  template <class T> struct variant_size; // undefined
-
-  template <class T>
-  constexpr size_t variant_size_v = variant_size<T>::value;
-
-  template <class T> struct variant_size<const T>;
-  template <class T> struct variant_size<volatile T>;
-  template <class T> struct variant_size<const volatile T>;
-
-  template <class... Types>
-  struct variant_size<variant<Types...>>;
-
-  template <size_t I, class T> struct variant_alternative; // undefined
-
-  template <size_t I, class T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <size_t I, class T> struct variant_alternative<I, const T>;
-  template <size_t I, class T> struct variant_alternative<I, volatile T>;
-  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
-
-  template <size_t I, class... Types>
-  struct variant_alternative<I, variant<Types...>>;
-
-  constexpr size_t variant_npos = -1;
-
-  // 20.7.4, value access
-  template <class T, class... Types>
-  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&
-  get(variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&&
-  get(variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&
-  get(const variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&&
-  get(const variant<Types...>&&);
-
-  template <class T, class...  Types>
-  constexpr T& get(variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr T&& get(variant<Types...>&&);
-
-  template <class T, class... Types>
-  constexpr const T& get(const variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr const T&& get(const variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
-  get_if(variant<Types...>*) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
-  get_if(const variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<T>
-  get_if(variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<const T>
-  get_if(const variant<Types...>*) noexcept;
-
-  // 20.7.5, relational operators
-  template <class... Types>
-  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
-
-  // 20.7.6, visitation
-  template <class Visitor, class... Variants>
-  constexpr see below visit(Visitor&&, Variants&&...);
-
-  // 20.7.7, class monostate
-  struct monostate;
-
-  // 20.7.8, monostate relational operators
-  constexpr bool operator<(monostate, monostate) noexcept;
-  constexpr bool operator>(monostate, monostate) noexcept;
-  constexpr bool operator<=(monostate, monostate) noexcept;
-  constexpr bool operator>=(monostate, monostate) noexcept;
-  constexpr bool operator==(monostate, monostate) noexcept;
-  constexpr bool operator!=(monostate, monostate) noexcept;
-
-  // 20.7.9, specialized algorithms
-  template <class... Types>
-  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
-
-  // 20.7.10, class bad_variant_access
-  class bad_variant_access;
-
-  // 20.7.11, hash support
-  template <class T> struct hash;
-  template <class... Types> struct hash<variant<Types...>>;
-  template <> struct hash<monostate>;
-
-} // namespace std
-
-*/
-
-#include <cstddef>
-#include <exception>
-#include <functional>
-#include <initializer_list>
-#include <limits>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_CONFIG_HPP
-#define MPARK_CONFIG_HPP
-
-// MSVC 2015 Update 3.
-#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024210)
-#error "MPark.Variant requires C++11 support."
-#endif
-
-#ifndef __has_attribute
-#define __has_attribute(x) 0
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#ifndef __has_include
-#define __has_include(x) 0
-#endif
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-
-#if __has_attribute(always_inline) || defined(__GNUC__)
-#define MPARK_ALWAYS_INLINE __attribute__((__always_inline__)) inline
-#elif defined(_MSC_VER)
-#define MPARK_ALWAYS_INLINE __forceinline
-#else
-#define MPARK_ALWAYS_INLINE inline
-#endif
-
-#if __has_builtin(__builtin_addressof) || \
-    (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
-#define MPARK_BUILTIN_ADDRESSOF
-#endif
-
-#if __has_builtin(__builtin_unreachable) || defined(__GNUC__)
-#define MPARK_BUILTIN_UNREACHABLE __builtin_unreachable()
-#elif defined(_MSC_VER)
-#define MPARK_BUILTIN_UNREACHABLE __assume(false)
-#else
-#define MPARK_BUILTIN_UNREACHABLE
-#endif
-
-#if __has_builtin(__type_pack_element)
-#define MPARK_TYPE_PACK_ELEMENT
-#endif
-
-#if defined(__cpp_constexpr) && __cpp_constexpr >= 200704 && \
-    !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 9)
-#define MPARK_CPP11_CONSTEXPR
-#endif
-
-#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
-#define MPARK_CPP14_CONSTEXPR
-#endif
-
-#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \
-    (defined(_MSC_VER) && defined(_CPPUNWIND))
-#define MPARK_EXCEPTIONS
-#endif
-
-#if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
-#define MPARK_GENERIC_LAMBDAS
-#endif
-
-#if defined(__cpp_lib_integer_sequence)
-#define MPARK_INTEGER_SEQUENCE
-#endif
-
-#if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
-#define MPARK_RETURN_TYPE_DEDUCTION
-#endif
-
-#if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
-#define MPARK_TRANSPARENT_OPERATORS
-#endif
-
-#if defined(__cpp_variable_templates) || defined(_MSC_VER)
-#define MPARK_VARIABLE_TEMPLATES
-#endif
-
-#if !defined(__GLIBCXX__) || __has_include(<codecvt>)  // >= libstdc++-5
-#define MPARK_TRIVIALITY_TYPE_TRAITS
-#define MPARK_INCOMPLETE_TYPE_TRAITS
-#endif
-
-#endif  // MPARK_CONFIG_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_IN_PLACE_HPP
-#define MPARK_IN_PLACE_HPP
-
-#include <cstddef>
-
-
-namespace mpark {
-
-  struct in_place_t { explicit in_place_t() = default; };
-
-  template <std::size_t I>
-  struct in_place_index_t { explicit in_place_index_t() = default; };
-
-  template <typename T>
-  struct in_place_type_t { explicit in_place_type_t() = default; };
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  constexpr in_place_t in_place{};
-
-  template <std::size_t I> constexpr in_place_index_t<I> in_place_index{};
-
-  template <typename T> constexpr in_place_type_t<T> in_place_type{};
-#endif
-
-}  // namespace mpark
-
-#endif  // MPARK_IN_PLACE_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_LIB_HPP
-#define MPARK_LIB_HPP
-
-#include <memory>
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-
-#define MPARK_RETURN(...) \
-  noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-namespace mpark {
-  namespace lib {
-    template <typename T>
-    struct identity { using type = T; };
-
-    inline namespace cpp14 {
-      template <typename T, std::size_t N>
-      struct array {
-        constexpr const T &operator[](std::size_t index) const {
-          return data[index];
-        }
-
-        T data[N == 0 ? 1 : N];
-      };
-
-      template <typename T>
-      using add_pointer_t = typename std::add_pointer<T>::type;
-
-      template <typename... Ts>
-      using common_type_t = typename std::common_type<Ts...>::type;
-
-      template <typename T>
-      using decay_t = typename std::decay<T>::type;
-
-      template <bool B, typename T = void>
-      using enable_if_t = typename std::enable_if<B, T>::type;
-
-      template <typename T>
-      using remove_const_t = typename std::remove_const<T>::type;
-
-      template <typename T>
-      using remove_reference_t = typename std::remove_reference<T>::type;
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &t) noexcept {
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &&t) noexcept {
-        static_assert(!std::is_lvalue_reference<T>::value,
-                      "can not forward an rvalue as an lvalue");
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr remove_reference_t<T> &&move(T &&t) noexcept {
-        return static_cast<remove_reference_t<T> &&>(t);
-      }
-
-#ifdef MPARK_INTEGER_SEQUENCE
-      using std::integer_sequence;
-      using std::index_sequence;
-      using std::make_index_sequence;
-      using std::index_sequence_for;
-#else
-      template <typename T, T... Is>
-      struct integer_sequence {
-        using value_type = T;
-        static constexpr std::size_t size() noexcept { return sizeof...(Is); }
-      };
-
-      template <std::size_t... Is>
-      using index_sequence = integer_sequence<std::size_t, Is...>;
-
-      template <typename Lhs, typename Rhs>
-      struct make_index_sequence_concat;
-
-      template <std::size_t... Lhs, std::size_t... Rhs>
-      struct make_index_sequence_concat<index_sequence<Lhs...>,
-                                        index_sequence<Rhs...>>
-          : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
-
-      template <std::size_t N>
-      struct make_index_sequence_impl;
-
-      template <std::size_t N>
-      using make_index_sequence = typename make_index_sequence_impl<N>::type;
-
-      template <std::size_t N>
-      struct make_index_sequence_impl
-          : make_index_sequence_concat<make_index_sequence<N / 2>,
-                                       make_index_sequence<N - (N / 2)>> {};
-
-      template <>
-      struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
-
-      template <>
-      struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
-
-      template <typename... Ts>
-      using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
-#endif
-
-      // <functional>
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using equal_to = std::equal_to<>;
-#else
-      struct equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using not_equal_to = std::not_equal_to<>;
-#else
-      struct not_equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less = std::less<>;
-#else
-      struct less {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater = std::greater<>;
-#else
-      struct greater {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less_equal = std::less_equal<>;
-#else
-      struct less_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater_equal = std::greater_equal<>;
-#else
-      struct greater_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
-      };
-#endif
-    }  // namespace cpp14
-
-    inline namespace cpp17 {
-
-      // <type_traits>
-      template <bool B>
-      using bool_constant = std::integral_constant<bool, B>;
-
-      template <typename...>
-      struct voider : identity<void> {};
-
-      template <typename... Ts>
-      using void_t = typename voider<Ts...>::type;
-
-      namespace detail {
-        namespace swappable {
-
-          using std::swap;
-
-          template <typename T>
-          struct is_swappable {
-            private:
-            template <typename U,
-                      typename = decltype(swap(std::declval<U &>(),
-                                               std::declval<U &>()))>
-            inline static std::true_type test(int);
-
-            template <typename U>
-            inline static std::false_type test(...);
-
-            public:
-            static constexpr bool value = decltype(test<T>(0))::value;
-          };
-
-          template <bool IsSwappable, typename T>
-          struct is_nothrow_swappable {
-            static constexpr bool value =
-                noexcept(swap(std::declval<T &>(), std::declval<T &>()));
-          };
-
-          template <typename T>
-          struct is_nothrow_swappable<false, T> : std::false_type {};
-
-        }  // namespace swappable
-      }  // namespace detail
-
-      using detail::swappable::is_swappable;
-
-      template <typename T>
-      using is_nothrow_swappable =
-          detail::swappable::is_nothrow_swappable<is_swappable<T>::value, T>;
-
-      // <functional>
-      namespace detail {
-
-        template <typename T>
-        struct is_reference_wrapper : std::false_type {};
-
-        template <typename T>
-        struct is_reference_wrapper<std::reference_wrapper<T>>
-            : std::true_type {};
-
-        template <bool, int>
-        struct Invoke;
-
-        template <>
-        struct Invoke<true /* pmf */, 0 /* is_base_of */> {
-          template <typename R, typename T, typename Arg, typename... Args>
-          inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&... args)
-            MPARK_RETURN((lib::forward<Arg>(arg).*pmf)(lib::forward<Args>(args)...))
-        };
-
-        template <>
-        struct Invoke<true /* pmf */, 1 /* is_reference_wrapper */> {
-          template <typename R, typename T, typename Arg, typename... Args>
-          inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&... args)
-            MPARK_RETURN((lib::forward<Arg>(arg).get().*pmf)(lib::forward<Args>(args)...))
-        };
-
-        template <>
-        struct Invoke<true /* pmf */, 2 /* otherwise */> {
-          template <typename R, typename T, typename Arg, typename... Args>
-          inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&... args)
-            MPARK_RETURN(((*lib::forward<Arg>(arg)).*pmf)(lib::forward<Args>(args)...))
-        };
-
-        template <>
-        struct Invoke<false /* pmo */, 0 /* is_base_of */> {
-          template <typename R, typename T, typename Arg>
-          inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
-            MPARK_RETURN(lib::forward<Arg>(arg).*pmo)
-        };
-
-        template <>
-        struct Invoke<false /* pmo */, 1 /* is_reference_wrapper */> {
-          template <typename R, typename T, typename Arg>
-          inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
-            MPARK_RETURN(lib::forward<Arg>(arg).get().*pmo)
-        };
-
-        template <>
-        struct Invoke<false /* pmo */, 2 /* otherwise */> {
-          template <typename R, typename T, typename Arg>
-          inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
-              MPARK_RETURN((*lib::forward<Arg>(arg)).*pmo)
-        };
-
-        template <typename R, typename T, typename Arg, typename... Args>
-        inline constexpr auto invoke(R T::*f, Arg &&arg, Args &&... args)
-          MPARK_RETURN(
-              Invoke<std::is_function<R>::value,
-                     (std::is_base_of<T, lib::decay_t<Arg>>::value
-                          ? 0
-                          : is_reference_wrapper<lib::decay_t<Arg>>::value
-                                ? 1
-                                : 2)>::invoke(f,
-                                              lib::forward<Arg>(arg),
-                                              lib::forward<Args>(args)...))
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-        template <typename F, typename... Args>
-        inline constexpr auto invoke(F &&f, Args &&... args)
-          MPARK_RETURN(lib::forward<F>(f)(lib::forward<Args>(args)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      inline constexpr auto invoke(F &&f, Args &&... args)
-        MPARK_RETURN(detail::invoke(lib::forward<F>(f),
-                                    lib::forward<Args>(args)...))
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct invoke_result {};
-
-        template <typename F, typename... Args>
-        struct invoke_result<void_t<decltype(lib::invoke(
-                                 std::declval<F>(), std::declval<Args>()...))>,
-                             F,
-                             Args...>
-            : identity<decltype(
-                  lib::invoke(std::declval<F>(), std::declval<Args>()...))> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using invoke_result = detail::invoke_result<void, F, Args...>;
-
-      template <typename F, typename... Args>
-      using invoke_result_t = typename invoke_result<F, Args...>::type;
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct is_invocable : std::false_type {};
-
-        template <typename F, typename... Args>
-        struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
-            : std::true_type {};
-
-        template <typename Void, typename, typename, typename...>
-        struct is_invocable_r : std::false_type {};
-
-        template <typename R, typename F, typename... Args>
-        struct is_invocable_r<void_t<invoke_result_t<F, Args...>>,
-                              R,
-                              F,
-                              Args...>
-            : std::is_convertible<invoke_result_t<F, Args...>, R> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using is_invocable = detail::is_invocable<void, F, Args...>;
-
-      template <typename R, typename F, typename... Args>
-      using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
-
-      // <memory>
-#ifdef MPARK_BUILTIN_ADDRESSOF
-      template <typename T>
-      inline constexpr T *addressof(T &arg) noexcept {
-        return __builtin_addressof(arg);
-      }
-#else
-      namespace detail {
-
-        namespace has_addressof_impl {
-
-          struct fail;
-
-          template <typename T>
-          inline fail operator&(T &&);
-
-          template <typename T>
-          inline static constexpr bool impl() {
-            return (std::is_class<T>::value || std::is_union<T>::value) &&
-                   !std::is_same<decltype(&std::declval<T &>()), fail>::value;
-          }
-
-        }  // namespace has_addressof_impl
-
-        template <typename T>
-        using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::true_type) noexcept {
-          return std::addressof(arg);
-        }
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::false_type) noexcept {
-          return &arg;
-        }
-
-      }  // namespace detail
-
-      template <typename T>
-      inline constexpr T *addressof(T &arg) noexcept {
-        return detail::addressof(arg, detail::has_addressof<T>{});
-      }
-#endif
-
-      template <typename T>
-      inline constexpr T *addressof(const T &&) = delete;
-
-    }  // namespace cpp17
-
-    template <typename T>
-    struct remove_all_extents : identity<T> {};
-
-    template <typename T, std::size_t N>
-    struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
-
-    template <typename T>
-    using remove_all_extents_t = typename remove_all_extents<T>::type;
-
-    template <std::size_t N>
-    using size_constant = std::integral_constant<std::size_t, N>;
-
-    template <std::size_t I, typename T>
-    struct indexed_type : size_constant<I> { using type = T; };
-
-    template <bool... Bs>
-    using all = std::is_same<integer_sequence<bool, true, Bs...>,
-                             integer_sequence<bool, Bs..., true>>;
-
-#ifdef MPARK_TYPE_PACK_ELEMENT
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = __type_pack_element<I, Ts...>;
-#else
-    template <std::size_t I, typename... Ts>
-    struct type_pack_element_impl {
-      private:
-      template <typename>
-      struct set;
-
-      template <std::size_t... Is>
-      struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
-
-      template <typename T>
-      inline static std::enable_if<true, T> impl(indexed_type<I, T>);
-
-      inline static std::enable_if<false> impl(...);
-
-      public:
-      using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
-    };
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
-#endif
-
-#ifdef MPARK_TRIVIALITY_TYPE_TRAITS
-    using std::is_trivially_copy_constructible;
-    using std::is_trivially_move_constructible;
-    using std::is_trivially_copy_assignable;
-    using std::is_trivially_move_assignable;
-#else
-    template <typename T>
-    struct is_trivially_copy_constructible
-        : bool_constant<
-              std::is_copy_constructible<T>::value && __has_trivial_copy(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {};
-
-    template <typename T>
-    struct is_trivially_copy_assignable
-        : bool_constant<
-              std::is_copy_assignable<T>::value && __has_trivial_assign(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {};
-#endif
-
-    template <typename T, bool>
-    struct dependent_type : T {};
-
-    template <typename Is, std::size_t J>
-    struct push_back;
-
-    template <typename Is, std::size_t J>
-    using push_back_t = typename push_back<Is, J>::type;
-
-    template <std::size_t... Is, std::size_t J>
-    struct push_back<index_sequence<Is...>, J> {
-      using type = index_sequence<Is..., J>;
-    };
-
-  }  // namespace lib
-}  // namespace mpark
-
-#undef MPARK_RETURN
-
-#endif  // MPARK_LIB_HPP
-
-
-namespace mpark {
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-
-#define AUTO auto
-#define AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto &&
-#define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; }
-
-#define DECLTYPE_AUTO decltype(auto)
-#define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#else
-
-#define AUTO auto
-#define AUTO_RETURN(...) \
-  -> lib::decay_t<decltype(__VA_ARGS__)> { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto
-#define AUTO_REFREF_RETURN(...)                                           \
-  -> decltype((__VA_ARGS__)) {                                            \
-    static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
-    return __VA_ARGS__;                                                   \
-  }
-
-#define DECLTYPE_AUTO auto
-#define DECLTYPE_AUTO_RETURN(...) \
-  -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-#endif
-
-  class bad_variant_access : public std::exception {
-    public:
-    virtual const char *what() const noexcept override { return "bad_variant_access"; }
-  };
-
-  [[noreturn]] inline void throw_bad_variant_access() {
-#ifdef MPARK_EXCEPTIONS
-    throw bad_variant_access{};
-#else
-    std::terminate();
-    MPARK_BUILTIN_UNREACHABLE;
-#endif
-  }
-
-  template <typename... Ts>
-  class variant;
-
-  template <typename T>
-  struct variant_size;
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  template <typename T>
-  constexpr std::size_t variant_size_v = variant_size<T>::value;
-#endif
-
-  template <typename T>
-  struct variant_size<const T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<volatile T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<const volatile T> : variant_size<T> {};
-
-  template <typename... Ts>
-  struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative;
-
-  template <std::size_t I, typename T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const T>
-      : std::add_const<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, volatile T>
-      : std::add_volatile<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const volatile T>
-      : std::add_cv<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename... Ts>
-  struct variant_alternative<I, variant<Ts...>> {
-    static_assert(I < sizeof...(Ts),
-                  "index out of bounds in `std::variant_alternative<>`");
-    using type = lib::type_pack_element_t<I, Ts...>;
-  };
-
-  constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
-
-  namespace detail {
-
-    constexpr std::size_t not_found = static_cast<std::size_t>(-1);
-    constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      constexpr lib::array<bool, sizeof...(Ts)> matches = {
-          {std::is_same<T, Ts>::value...}
-      };
-      std::size_t result = not_found;
-      for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
-        if (matches[i]) {
-          if (result != not_found) {
-            return ambiguous;
-          }
-          result = i;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t) {
-      return result;
-    }
-
-    template <typename... Bs>
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t idx,
-                                                 bool b,
-                                                 Bs... bs) {
-      return b ? (result != not_found ? ambiguous
-                                      : find_index_impl(idx, idx + 1, bs...))
-               : find_index_impl(result, idx + 1, bs...);
-    }
-
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
-    }
-#endif
-
-    template <std::size_t I>
-    using find_index_sfinae_impl =
-        lib::enable_if_t<I != not_found && I != ambiguous,
-                         lib::size_constant<I>>;
-
-    template <typename T, typename... Ts>
-    using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
-
-    template <std::size_t I>
-    struct find_index_checked_impl : lib::size_constant<I> {
-      static_assert(I != not_found, "the specified type is not found.");
-      static_assert(I != ambiguous, "the specified type is ambiguous.");
-    };
-
-    template <typename T, typename... Ts>
-    using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
-
-    struct valueless_t {};
-
-    enum class Trait { TriviallyAvailable, Available, Unavailable };
-
-    template <typename T,
-              template <typename> class IsTriviallyAvailable,
-              template <typename> class IsAvailable>
-    inline constexpr Trait trait() {
-      return IsTriviallyAvailable<T>::value
-                 ? Trait::TriviallyAvailable
-                 : IsAvailable<T>::value ? Trait::Available
-                                         : Trait::Unavailable;
-    }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... traits_) {
-      Trait result = Trait::TriviallyAvailable;
-      lib::array<Trait, sizeof...(Traits)> traits = {{traits_...}};
-      for (std::size_t i = 0; i < sizeof...(Traits); ++i) {
-        Trait t = traits[i];
-        if (static_cast<int>(t) > static_cast<int>(result)) {
-          result = t;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr Trait common_trait_impl(Trait result) { return result; }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait_impl(Trait result,
-                                             Trait t,
-                                             Traits... ts) {
-      return static_cast<int>(t) > static_cast<int>(result)
-                 ? common_trait_impl(t, ts...)
-                 : common_trait_impl(result, ts...);
-    }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... ts) {
-      return common_trait_impl(Trait::TriviallyAvailable, ts...);
-    }
-#endif
-
-    template <typename... Ts>
-    struct traits {
-      static constexpr Trait copy_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_copy_constructible,
-                             std::is_copy_constructible>()...);
-
-      static constexpr Trait move_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_move_constructible,
-                             std::is_move_constructible>()...);
-
-      static constexpr Trait copy_assignable_trait =
-          common_trait(copy_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_copy_assignable,
-                             std::is_copy_assignable>()...);
-
-      static constexpr Trait move_assignable_trait =
-          common_trait(move_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_move_assignable,
-                             std::is_move_assignable>()...);
-
-      static constexpr Trait destructible_trait =
-          common_trait(trait<Ts,
-                             std::is_trivially_destructible,
-                             std::is_destructible>()...);
-    };
-
-    namespace access {
-
-      struct recursive_union {
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename V>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
-          return lib::forward<V>(v).head_;
-        }
-
-        template <typename V, std::size_t I>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
-          return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
-        }
-#else
-        template <std::size_t I, bool Dummy = true>
-        struct get_alt_impl {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
-        };
-
-        template <bool Dummy>
-        struct get_alt_impl<0, Dummy> {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
-        };
-
-        template <typename V, std::size_t I>
-        inline static constexpr AUTO_REFREF get_alt(V &&v, in_place_index_t<I>)
-          AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
-#endif
-      };
-
-      struct base {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-#ifdef _MSC_VER
-          AUTO_REFREF_RETURN(recursive_union::get_alt(
-              lib::forward<V>(v).data_, in_place_index_t<I>{}))
-#else
-          AUTO_REFREF_RETURN(recursive_union::get_alt(
-              data(lib::forward<V>(v)), in_place_index_t<I>{}))
-#endif
-      };
-
-      struct variant {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
-      };
-
-    }  // namespace access
-
-    namespace visitation {
-
-#if defined(MPARK_CPP14_CONSTEXPR) && !defined(_MSC_VER)
-#define MPARK_VARIANT_SWITCH_VISIT
-#endif
-
-      struct base {
-        template <typename Visitor, typename... Vs>
-        using dispatch_result_t = decltype(
-            lib::invoke(std::declval<Visitor>(),
-                        access::base::get_alt<0>(std::declval<Vs>())...));
-
-        template <typename Expected>
-        struct expected {
-          template <typename Actual>
-          inline static constexpr bool but_got() {
-            return std::is_same<Expected, Actual>::value;
-          }
-        };
-
-        template <typename Expected, typename Actual>
-        struct visit_return_type_check {
-          static_assert(
-              expected<Expected>::template but_got<Actual>(),
-              "`visit` requires the visitor to have a single return type");
-
-          template <typename Visitor, typename... Alts>
-          inline static constexpr DECLTYPE_AUTO invoke(Visitor &&visitor,
-                                                       Alts &&... alts)
-            DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
-                                             lib::forward<Alts>(alts)...))
-        };
-
-#ifdef MPARK_VARIANT_SWITCH_VISIT
-        template <bool B, typename R, typename... ITs>
-        struct dispatcher;
-
-        template <typename R, typename... ITs>
-        struct dispatcher<false, R, ITs...> {
-          template <std::size_t B, typename F, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch(
-              F &&, typename ITs::type &&..., Vs &&...) {
-            MPARK_BUILTIN_UNREACHABLE;
-          }
-
-          template <std::size_t I, typename F, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch_case(F &&, Vs &&...) {
-            MPARK_BUILTIN_UNREACHABLE;
-          }
-
-          template <std::size_t B, typename F, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch_at(std::size_t,
-                                                             F &&,
-                                                             Vs &&...) {
-            MPARK_BUILTIN_UNREACHABLE;
-          }
-        };
-
-        template <typename R, typename... ITs>
-        struct dispatcher<true, R, ITs...> {
-          template <std::size_t B, typename F>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch(
-              F &&f, typename ITs::type &&... visited_vs) {
-            using Expected = R;
-            using Actual = decltype(lib::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<ITs::value>(
-                    lib::forward<typename ITs::type>(visited_vs))...));
-            return visit_return_type_check<Expected, Actual>::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<ITs::value>(
-                    lib::forward<typename ITs::type>(visited_vs))...);
-          }
-
-          template <std::size_t B, typename F, typename V, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch(
-              F &&f, typename ITs::type &&... visited_vs, V &&v, Vs &&... vs) {
-#define MPARK_DISPATCH(I)                                                   \
-  dispatcher<(I < lib::decay_t<V>::size()),                                 \
-             R,                                                             \
-             ITs...,                                                        \
-             lib::indexed_type<I, V>>::                                     \
-      template dispatch<0>(lib::forward<F>(f),                              \
-                           lib::forward<typename ITs::type>(visited_vs)..., \
-                           lib::forward<V>(v),                              \
-                           lib::forward<Vs>(vs)...)
-
-#define MPARK_DEFAULT(I)                                                      \
-  dispatcher<(I < lib::decay_t<V>::size()), R, ITs...>::template dispatch<I>( \
-      lib::forward<F>(f),                                                     \
-      lib::forward<typename ITs::type>(visited_vs)...,                        \
-      lib::forward<V>(v),                                                     \
-      lib::forward<Vs>(vs)...)
-
-            switch (v.index()) {
-              case B + 0: return MPARK_DISPATCH(B + 0);
-              case B + 1: return MPARK_DISPATCH(B + 1);
-              case B + 2: return MPARK_DISPATCH(B + 2);
-              case B + 3: return MPARK_DISPATCH(B + 3);
-              case B + 4: return MPARK_DISPATCH(B + 4);
-              case B + 5: return MPARK_DISPATCH(B + 5);
-              case B + 6: return MPARK_DISPATCH(B + 6);
-              case B + 7: return MPARK_DISPATCH(B + 7);
-              case B + 8: return MPARK_DISPATCH(B + 8);
-              case B + 9: return MPARK_DISPATCH(B + 9);
-              case B + 10: return MPARK_DISPATCH(B + 10);
-              case B + 11: return MPARK_DISPATCH(B + 11);
-              case B + 12: return MPARK_DISPATCH(B + 12);
-              case B + 13: return MPARK_DISPATCH(B + 13);
-              case B + 14: return MPARK_DISPATCH(B + 14);
-              case B + 15: return MPARK_DISPATCH(B + 15);
-              case B + 16: return MPARK_DISPATCH(B + 16);
-              case B + 17: return MPARK_DISPATCH(B + 17);
-              case B + 18: return MPARK_DISPATCH(B + 18);
-              case B + 19: return MPARK_DISPATCH(B + 19);
-              case B + 20: return MPARK_DISPATCH(B + 20);
-              case B + 21: return MPARK_DISPATCH(B + 21);
-              case B + 22: return MPARK_DISPATCH(B + 22);
-              case B + 23: return MPARK_DISPATCH(B + 23);
-              case B + 24: return MPARK_DISPATCH(B + 24);
-              case B + 25: return MPARK_DISPATCH(B + 25);
-              case B + 26: return MPARK_DISPATCH(B + 26);
-              case B + 27: return MPARK_DISPATCH(B + 27);
-              case B + 28: return MPARK_DISPATCH(B + 28);
-              case B + 29: return MPARK_DISPATCH(B + 29);
-              case B + 30: return MPARK_DISPATCH(B + 30);
-              case B + 31: return MPARK_DISPATCH(B + 31);
-              default: return MPARK_DEFAULT(B + 32);
-            }
-
-#undef MPARK_DEFAULT
-#undef MPARK_DISPATCH
-          }
-
-          template <std::size_t I, typename F, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch_case(F &&f,
-                                                               Vs &&... vs) {
-            using Expected = R;
-            using Actual = decltype(
-                lib::invoke(lib::forward<F>(f),
-                            access::base::get_alt<I>(lib::forward<Vs>(vs))...));
-            return visit_return_type_check<Expected, Actual>::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<I>(lib::forward<Vs>(vs))...);
-          }
-
-          template <std::size_t B, typename F, typename V, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch_at(std::size_t index,
-                                                             F &&f,
-                                                             V &&v,
-                                                             Vs &&... vs) {
-            static_assert(lib::all<(lib::decay_t<V>::size() ==
-                                    lib::decay_t<Vs>::size())...>::value,
-                          "all of the variants must be the same size.");
-#define MPARK_DISPATCH_AT(I)                                               \
-  dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_case<I>( \
-      lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
-
-#define MPARK_DEFAULT(I)                                                 \
-  dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_at<I>( \
-      index, lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
-
-            switch (index) {
-              case B + 0: return MPARK_DISPATCH_AT(B + 0);
-              case B + 1: return MPARK_DISPATCH_AT(B + 1);
-              case B + 2: return MPARK_DISPATCH_AT(B + 2);
-              case B + 3: return MPARK_DISPATCH_AT(B + 3);
-              case B + 4: return MPARK_DISPATCH_AT(B + 4);
-              case B + 5: return MPARK_DISPATCH_AT(B + 5);
-              case B + 6: return MPARK_DISPATCH_AT(B + 6);
-              case B + 7: return MPARK_DISPATCH_AT(B + 7);
-              case B + 8: return MPARK_DISPATCH_AT(B + 8);
-              case B + 9: return MPARK_DISPATCH_AT(B + 9);
-              case B + 10: return MPARK_DISPATCH_AT(B + 10);
-              case B + 11: return MPARK_DISPATCH_AT(B + 11);
-              case B + 12: return MPARK_DISPATCH_AT(B + 12);
-              case B + 13: return MPARK_DISPATCH_AT(B + 13);
-              case B + 14: return MPARK_DISPATCH_AT(B + 14);
-              case B + 15: return MPARK_DISPATCH_AT(B + 15);
-              case B + 16: return MPARK_DISPATCH_AT(B + 16);
-              case B + 17: return MPARK_DISPATCH_AT(B + 17);
-              case B + 18: return MPARK_DISPATCH_AT(B + 18);
-              case B + 19: return MPARK_DISPATCH_AT(B + 19);
-              case B + 20: return MPARK_DISPATCH_AT(B + 20);
-              case B + 21: return MPARK_DISPATCH_AT(B + 21);
-              case B + 22: return MPARK_DISPATCH_AT(B + 22);
-              case B + 23: return MPARK_DISPATCH_AT(B + 23);
-              case B + 24: return MPARK_DISPATCH_AT(B + 24);
-              case B + 25: return MPARK_DISPATCH_AT(B + 25);
-              case B + 26: return MPARK_DISPATCH_AT(B + 26);
-              case B + 27: return MPARK_DISPATCH_AT(B + 27);
-              case B + 28: return MPARK_DISPATCH_AT(B + 28);
-              case B + 29: return MPARK_DISPATCH_AT(B + 29);
-              case B + 30: return MPARK_DISPATCH_AT(B + 30);
-              case B + 31: return MPARK_DISPATCH_AT(B + 31);
-              default: return MPARK_DEFAULT(B + 32);
-            }
-
-#undef MPARK_DEFAULT
-#undef MPARK_DISPATCH_AT
-          }
-        };
-#else
-        template <typename T>
-        inline static constexpr const T &at(const T &elem) noexcept {
-          return elem;
-        }
-
-        template <typename T, std::size_t N, typename... Is>
-        inline static constexpr const lib::remove_all_extents_t<T> &at(
-            const lib::array<T, N> &elems, std::size_t i, Is... is) noexcept {
-          return at(elems[i], is...);
-        }
-
-        template <typename F, typename... Fs>
-        inline static constexpr lib::array<lib::decay_t<F>, sizeof...(Fs) + 1>
-        make_farray(F &&f, Fs &&... fs) {
-          return {{lib::forward<F>(f), lib::forward<Fs>(fs)...}};
-        }
-
-        template <typename F, typename... Vs>
-        struct make_fmatrix_impl {
-
-          template <std::size_t... Is>
-          inline static constexpr dispatch_result_t<F, Vs...> dispatch(
-              F &&f, Vs &&... vs) {
-            using Expected = dispatch_result_t<F, Vs...>;
-            using Actual = decltype(lib::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<Is>(lib::forward<Vs>(vs))...));
-            return visit_return_type_check<Expected, Actual>::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<Is>(lib::forward<Vs>(vs))...);
-          }
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-          template <std::size_t... Is>
-          inline static constexpr auto impl(lib::index_sequence<Is...>) {
-            return &dispatch<Is...>;
-          }
-
-          template <typename Is, std::size_t... Js, typename... Ls>
-          inline static constexpr auto impl(Is,
-                                            lib::index_sequence<Js...>,
-                                            Ls... ls) {
-            return make_farray(impl(lib::push_back_t<Is, Js>{}, ls...)...);
-          }
-#else
-          template <typename...>
-          struct impl;
-
-          template <std::size_t... Is>
-          struct impl<lib::index_sequence<Is...>> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(&dispatch<Is...>)
-          };
-
-          template <typename Is, std::size_t... Js, typename... Ls>
-          struct impl<Is, lib::index_sequence<Js...>, Ls...> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(
-                  make_farray(impl<lib::push_back_t<Is, Js>, Ls...>{}()...))
-          };
-#endif
-        };
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename F, typename... Vs>
-        inline static constexpr auto make_fmatrix() {
-          return make_fmatrix_impl<F, Vs...>::impl(
-              lib::index_sequence<>{},
-              lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
-        }
-#else
-        template <typename F, typename... Vs>
-        inline static constexpr AUTO make_fmatrix()
-          AUTO_RETURN(
-              typename make_fmatrix_impl<F, Vs...>::template impl<
-                  lib::index_sequence<>,
-                  lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
-#endif
-
-        template <typename F, typename... Vs>
-        struct make_fdiagonal_impl {
-          template <std::size_t I>
-          inline static constexpr dispatch_result_t<F, Vs...> dispatch(
-              F &&f, Vs &&... vs) {
-            using Expected = dispatch_result_t<F, Vs...>;
-            using Actual = decltype(
-                lib::invoke(lib::forward<F>(f),
-                            access::base::get_alt<I>(lib::forward<Vs>(vs))...));
-            return visit_return_type_check<Expected, Actual>::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<I>(lib::forward<Vs>(vs))...);
-          }
-
-          template <std::size_t... Is>
-          inline static constexpr AUTO impl(lib::index_sequence<Is...>)
-            AUTO_RETURN(make_farray(&dispatch<Is>...))
-        };
-
-        template <typename F, typename V, typename... Vs>
-        inline static constexpr auto make_fdiagonal()
-            -> decltype(make_fdiagonal_impl<F, V, Vs...>::impl(
-                lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
-          static_assert(lib::all<(lib::decay_t<V>::size() ==
-                                  lib::decay_t<Vs>::size())...>::value,
-                        "all of the variants must be the same size.");
-          return make_fdiagonal_impl<F, V, Vs...>::impl(
-              lib::make_index_sequence<lib::decay_t<V>::size()>{});
-        }
-#endif
-      };
-
-#if !defined(MPARK_VARIANT_SWITCH_VISIT) && \
-    (!defined(_MSC_VER) || _MSC_VER >= 1910)
-      template <typename F, typename... Vs>
-      using fmatrix_t = decltype(base::make_fmatrix<F, Vs...>());
-
-      template <typename F, typename... Vs>
-      struct fmatrix {
-        static constexpr fmatrix_t<F, Vs...> value =
-            base::make_fmatrix<F, Vs...>();
-      };
-
-      template <typename F, typename... Vs>
-      constexpr fmatrix_t<F, Vs...> fmatrix<F, Vs...>::value;
-
-      template <typename F, typename... Vs>
-      using fdiagonal_t = decltype(base::make_fdiagonal<F, Vs...>());
-
-      template <typename F, typename... Vs>
-      struct fdiagonal {
-        static constexpr fdiagonal_t<F, Vs...> value =
-            base::make_fdiagonal<F, Vs...>();
-      };
-
-      template <typename F, typename... Vs>
-      constexpr fdiagonal_t<F, Vs...> fdiagonal<F, Vs...>::value;
-#endif
-
-      struct alt {
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-#ifdef MPARK_VARIANT_SWITCH_VISIT
-          DECLTYPE_AUTO_RETURN(
-              base::dispatcher<
-                  true,
-                  base::dispatch_result_t<Visitor,
-                                          decltype(as_base(
-                                              lib::forward<Vs>(vs)))...>>::
-                  template dispatch<0>(lib::forward<Visitor>(visitor),
-                                       as_base(lib::forward<Vs>(vs))...))
-#elif !defined(_MSC_VER) || _MSC_VER >= 1910
-          DECLTYPE_AUTO_RETURN(base::at(
-              fmatrix<Visitor &&,
-                      decltype(as_base(lib::forward<Vs>(vs)))...>::value,
-              vs.index()...)(lib::forward<Visitor>(visitor),
-                             as_base(lib::forward<Vs>(vs))...))
-#else
-          DECLTYPE_AUTO_RETURN(base::at(
-              base::make_fmatrix<Visitor &&,
-                      decltype(as_base(lib::forward<Vs>(vs)))...>(),
-              vs.index()...)(lib::forward<Visitor>(visitor),
-                             as_base(lib::forward<Vs>(vs))...))
-#endif
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-#ifdef MPARK_VARIANT_SWITCH_VISIT
-          DECLTYPE_AUTO_RETURN(
-              base::dispatcher<
-                  true,
-                  base::dispatch_result_t<Visitor,
-                                          decltype(as_base(
-                                              lib::forward<Vs>(vs)))...>>::
-                  template dispatch_at<0>(index,
-                                          lib::forward<Visitor>(visitor),
-                                          as_base(lib::forward<Vs>(vs))...))
-#elif !defined(_MSC_VER) || _MSC_VER >= 1910
-          DECLTYPE_AUTO_RETURN(base::at(
-              fdiagonal<Visitor &&,
-                        decltype(as_base(lib::forward<Vs>(vs)))...>::value,
-              index)(lib::forward<Visitor>(visitor),
-                     as_base(lib::forward<Vs>(vs))...))
-#else
-          DECLTYPE_AUTO_RETURN(base::at(
-              base::make_fdiagonal<Visitor &&,
-                        decltype(as_base(lib::forward<Vs>(vs)))...>(),
-              index)(lib::forward<Visitor>(visitor),
-                     as_base(lib::forward<Vs>(vs))...))
-#endif
-      };
-
-      struct variant {
-        private:
-        template <typename Visitor>
-        struct visitor {
-          template <typename... Values>
-          inline static constexpr bool does_not_handle() {
-            return lib::is_invocable<Visitor, Values...>::value;
-          }
-        };
-
-        template <typename Visitor, typename... Values>
-        struct visit_exhaustiveness_check {
-          static_assert(visitor<Visitor>::template does_not_handle<Values...>(),
-                        "`visit` requires the visitor to be exhaustive.");
-
-          inline static constexpr DECLTYPE_AUTO invoke(Visitor &&visitor,
-                                                       Values &&... values)
-            DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
-                                             lib::forward<Values>(values)...))
-        };
-
-        template <typename Visitor>
-        struct value_visitor {
-          Visitor &&visitor_;
-
-          template <typename... Alts>
-          inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const
-            DECLTYPE_AUTO_RETURN(
-                visit_exhaustiveness_check<
-                    Visitor,
-                    decltype((lib::forward<Alts>(alts).value))...>::
-                    invoke(lib::forward<Visitor>(visitor_),
-                           lib::forward<Alts>(alts).value...))
-        };
-
-        template <typename Visitor>
-        inline static constexpr AUTO make_value_visitor(Visitor &&visitor)
-          AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(alt::visit_alt(lib::forward<Visitor>(visitor),
-                                              lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              alt::visit_alt_at(index,
-                                lib::forward<Visitor>(visitor),
-                                lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor,
-                                                          Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt(make_value_visitor(lib::forward<Visitor>(visitor)),
-                        lib::forward<Vs>(vs)...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index,
-                                                             Visitor &&visitor,
-                                                             Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt_at(index,
-                           make_value_visitor(lib::forward<Visitor>(visitor)),
-                           lib::forward<Vs>(vs)...))
-      };
-
-    }  // namespace visitation
-
-    template <std::size_t Index, typename T>
-    struct alt {
-      using value_type = T;
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-      template <typename... Args>
-      inline explicit constexpr alt(in_place_t, Args &&... args)
-          : value(lib::forward<Args>(args)...) {}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      T value;
-    };
-
-    template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
-    union recursive_union;
-
-    template <Trait DestructibleTrait, std::size_t Index>
-    union recursive_union<DestructibleTrait, Index> {};
-
-#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)      \
-  template <std::size_t Index, typename T, typename... Ts>                 \
-  union recursive_union<destructible_trait, Index, T, Ts...> {             \
-    public:                                                                \
-    inline explicit constexpr recursive_union(valueless_t) noexcept        \
-        : dummy_{} {}                                                      \
-                                                                           \
-    template <typename... Args>                                            \
-    inline explicit constexpr recursive_union(in_place_index_t<0>,         \
-                                              Args &&... args)             \
-        : head_(in_place_t{}, lib::forward<Args>(args)...) {}              \
-                                                                           \
-    template <std::size_t I, typename... Args>                             \
-    inline explicit constexpr recursive_union(in_place_index_t<I>,         \
-                                              Args &&... args)             \
-        : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
-                                                                           \
-    recursive_union(const recursive_union &) = default;                    \
-    recursive_union(recursive_union &&) = default;                         \
-                                                                           \
-    destructor                                                             \
-                                                                           \
-    recursive_union &operator=(const recursive_union &) = default;         \
-    recursive_union &operator=(recursive_union &&) = default;              \
-                                                                           \
-    private:                                                               \
-    char dummy_;                                                           \
-    alt<Index, T> head_;                                                   \
-    recursive_union<destructible_trait, Index + 1, Ts...> tail_;           \
-                                                                           \
-    friend struct access::recursive_union;                                 \
-  }
-
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
-                                  ~recursive_union() = default;);
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
-                                  ~recursive_union() {});
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
-                                  ~recursive_union() = delete;);
-
-#undef MPARK_VARIANT_RECURSIVE_UNION
-
-    template <typename... Ts>
-    using index_t = typename std::conditional<
-            sizeof...(Ts) < std::numeric_limits<unsigned char>::max(),
-            unsigned char,
-            typename std::conditional<
-                sizeof...(Ts) < std::numeric_limits<unsigned short>::max(),
-                unsigned short,
-                unsigned int>::type
-            >::type;
-
-    template <Trait DestructibleTrait, typename... Ts>
-    class base {
-      public:
-      inline explicit constexpr base(valueless_t tag) noexcept
-          : data_(tag), index_(static_cast<index_t<Ts...>>(-1)) {}
-
-      template <std::size_t I, typename... Args>
-      inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
-          : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...),
-            index_(I) {}
-
-      inline constexpr bool valueless_by_exception() const noexcept {
-        return index_ == static_cast<index_t<Ts...>>(-1);
-      }
-
-      inline constexpr std::size_t index() const noexcept {
-        return valueless_by_exception() ? variant_npos : index_;
-      }
-
-      protected:
-      using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
-
-      friend inline constexpr base &as_base(base &b) { return b; }
-      friend inline constexpr const base &as_base(const base &b) { return b; }
-      friend inline constexpr base &&as_base(base &&b) { return lib::move(b); }
-      friend inline constexpr const base &&as_base(const base &&b) { return lib::move(b); }
-
-      friend inline constexpr data_t &data(base &b) { return b.data_; }
-      friend inline constexpr const data_t &data(const base &b) { return b.data_; }
-      friend inline constexpr data_t &&data(base &&b) { return lib::move(b).data_; }
-      friend inline constexpr const data_t &&data(const base &&b) { return lib::move(b).data_; }
-
-      inline static constexpr std::size_t size() { return sizeof...(Ts); }
-
-      data_t data_;
-      index_t<Ts...> index_;
-
-      friend struct access::base;
-      friend struct visitation::base;
-    };
-
-    struct dtor {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename Alt>
-      inline void operator()(Alt &alt) const noexcept { alt.~Alt(); }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-    };
-
-#if !defined(_MSC_VER) || _MSC_VER >= 1910
-#define MPARK_INHERITING_CTOR(type, base) using base::base;
-#else
-#define MPARK_INHERITING_CTOR(type, base)         \
-  template <typename... Args>                     \
-  inline explicit constexpr type(Args &&... args) \
-      : base(lib::forward<Args>(args)...) {}
-#endif
-
-    template <typename Traits, Trait = Traits::destructible_trait>
-    class destructor;
-
-#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
-  template <typename... Ts>                                               \
-  class destructor<traits<Ts...>, destructible_trait>                     \
-      : public base<destructible_trait, Ts...> {                          \
-    using super = base<destructible_trait, Ts...>;                        \
-                                                                          \
-    public:                                                               \
-    MPARK_INHERITING_CTOR(destructor, super)                              \
-    using super::operator=;                                               \
-                                                                          \
-    destructor(const destructor &) = default;                             \
-    destructor(destructor &&) = default;                                  \
-    definition                                                            \
-    destructor &operator=(const destructor &) = default;                  \
-    destructor &operator=(destructor &&) = default;                       \
-                                                                          \
-    protected:                                                            \
-    destroy                                                               \
-  }
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::TriviallyAvailable,
-        ~destructor() = default;,
-        inline void destroy() noexcept {
-          this->index_ = static_cast<index_t<Ts...>>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Available,
-        ~destructor() { destroy(); },
-        inline void destroy() noexcept {
-          if (!this->valueless_by_exception()) {
-            visitation::alt::visit_alt(dtor{}, *this);
-          }
-          this->index_ = static_cast<index_t<Ts...>>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Unavailable,
-        ~destructor() = delete;,
-        inline void destroy() noexcept = delete;);
-
-#undef MPARK_VARIANT_DESTRUCTOR
-
-    template <typename Traits>
-    class constructor : public destructor<Traits> {
-      using super = destructor<Traits>;
-
-      public:
-      MPARK_INHERITING_CTOR(constructor, super)
-      using super::operator=;
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct ctor {
-        template <typename LhsAlt, typename RhsAlt>
-        inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const {
-          constructor::construct_alt(lhs_alt,
-                                     lib::forward<RhsAlt>(rhs_alt).value);
-        }
-      };
-#endif
-
-      template <std::size_t I, typename T, typename... Args>
-      inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
-        auto *result = ::new (static_cast<void *>(lib::addressof(a)))
-            alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
-        return result->value;
-      }
-
-      template <typename Rhs>
-      inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
-        lhs.destroy();
-        if (!rhs.valueless_by_exception()) {
-          visitation::alt::visit_alt_at(
-              rhs.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [](auto &lhs_alt, auto &&rhs_alt) {
-                constructor::construct_alt(
-                    lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
-              }
-#else
-              ctor{}
-#endif
-              ,
-              lhs,
-              lib::forward<Rhs>(rhs));
-          lhs.index_ = rhs.index_;
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_constructible_trait>
-    class move_constructor;
-
-#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class move_constructor<traits<Ts...>, move_constructible_trait>            \
-      : public constructor<traits<Ts...>> {                                  \
-    using super = constructor<traits<Ts...>>;                                \
-                                                                             \
-    public:                                                                  \
-    MPARK_INHERITING_CTOR(move_constructor, super)                           \
-    using super::operator=;                                                  \
-                                                                             \
-    move_constructor(const move_constructor &) = default;                    \
-    definition                                                               \
-    ~move_constructor() = default;                                           \
-    move_constructor &operator=(const move_constructor &) = default;         \
-    move_constructor &operator=(move_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        move_constructor(move_constructor &&that) = default;);
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Available,
-        move_constructor(move_constructor &&that) noexcept(
-            lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
-            : move_constructor(valueless_t{}) {
-          this->generic_construct(*this, lib::move(that));
-        });
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Unavailable,
-        move_constructor(move_constructor &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_CONSTRUCTOR
-
-    template <typename Traits, Trait = Traits::copy_constructible_trait>
-    class copy_constructor;
-
-#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
-      : public move_constructor<traits<Ts...>> {                             \
-    using super = move_constructor<traits<Ts...>>;                           \
-                                                                             \
-    public:                                                                  \
-    MPARK_INHERITING_CTOR(copy_constructor, super)                           \
-    using super::operator=;                                                  \
-                                                                             \
-    definition                                                               \
-    copy_constructor(copy_constructor &&) = default;                         \
-    ~copy_constructor() = default;                                           \
-    copy_constructor &operator=(const copy_constructor &) = default;         \
-    copy_constructor &operator=(copy_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        copy_constructor(const copy_constructor &that) = default;);
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Available,
-        copy_constructor(const copy_constructor &that)
-            : copy_constructor(valueless_t{}) {
-          this->generic_construct(*this, that);
-        });
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Unavailable,
-        copy_constructor(const copy_constructor &) = delete;);
-
-#undef MPARK_VARIANT_COPY_CONSTRUCTOR
-
-    template <typename Traits>
-    class assignment : public copy_constructor<Traits> {
-      using super = copy_constructor<Traits>;
-
-      public:
-      MPARK_INHERITING_CTOR(assignment, super)
-      using super::operator=;
-
-      template <std::size_t I, typename... Args>
-      inline /* auto & */ auto emplace(Args &&... args)
-          -> decltype(this->construct_alt(access::base::get_alt<I>(*this),
-                                          lib::forward<Args>(args)...)) {
-        this->destroy();
-        auto &result = this->construct_alt(access::base::get_alt<I>(*this),
-                                           lib::forward<Args>(args)...);
-        this->index_ = I;
-        return result;
-      }
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      template <typename That>
-      struct assigner {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const {
-          self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
-        }
-        assignment *self;
-      };
-#endif
-
-      template <std::size_t I, typename T, typename Arg>
-      inline void assign_alt(alt<I, T> &a, Arg &&arg) {
-        if (this->index() == I) {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-          a.value = lib::forward<Arg>(arg);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        } else {
-          struct {
-            void operator()(std::true_type) const {
-              this_->emplace<I>(lib::forward<Arg>(arg_));
-            }
-            void operator()(std::false_type) const {
-              this_->emplace<I>(T(lib::forward<Arg>(arg_)));
-            }
-            assignment *this_;
-            Arg &&arg_;
-          } impl{this, lib::forward<Arg>(arg)};
-          impl(lib::bool_constant<
-                   std::is_nothrow_constructible<T, Arg>::value ||
-                   !std::is_nothrow_move_constructible<T>::value>{});
-        }
-      }
-
-      template <typename That>
-      inline void generic_assign(That &&that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (that.valueless_by_exception()) {
-          this->destroy();
-        } else {
-          visitation::alt::visit_alt_at(
-              that.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [this](auto &this_alt, auto &&that_alt) {
-                this->assign_alt(
-                    this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
-              }
-#else
-              assigner<That>{this}
-#endif
-              ,
-              *this,
-              lib::forward<That>(that));
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_assignable_trait>
-    class move_assignment;
-
-#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class move_assignment<traits<Ts...>, move_assignable_trait>            \
-      : public assignment<traits<Ts...>> {                               \
-    using super = assignment<traits<Ts...>>;                             \
-                                                                         \
-    public:                                                              \
-    MPARK_INHERITING_CTOR(move_assignment, super)                        \
-    using super::operator=;                                              \
-                                                                         \
-    move_assignment(const move_assignment &) = default;                  \
-    move_assignment(move_assignment &&) = default;                       \
-    ~move_assignment() = default;                                        \
-    move_assignment &operator=(const move_assignment &) = default;       \
-    definition                                                           \
-  }
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        move_assignment &operator=(move_assignment &&that) = default;);
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Available,
-        move_assignment &
-        operator=(move_assignment &&that) noexcept(
-            lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                      std::is_nothrow_move_assignable<Ts>::value)...>::value) {
-          this->generic_assign(lib::move(that));
-          return *this;
-        });
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Unavailable,
-        move_assignment &operator=(move_assignment &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_ASSIGNMENT
-
-    template <typename Traits, Trait = Traits::copy_assignable_trait>
-    class copy_assignment;
-
-#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
-      : public move_assignment<traits<Ts...>> {                          \
-    using super = move_assignment<traits<Ts...>>;                        \
-                                                                         \
-    public:                                                              \
-    MPARK_INHERITING_CTOR(copy_assignment, super)                        \
-    using super::operator=;                                              \
-                                                                         \
-    copy_assignment(const copy_assignment &) = default;                  \
-    copy_assignment(copy_assignment &&) = default;                       \
-    ~copy_assignment() = default;                                        \
-    definition                                                           \
-    copy_assignment &operator=(copy_assignment &&) = default;            \
-  }
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        copy_assignment &operator=(const copy_assignment &that) = default;);
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Available,
-        copy_assignment &operator=(const copy_assignment &that) {
-          this->generic_assign(that);
-          return *this;
-        });
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Unavailable,
-        copy_assignment &operator=(const copy_assignment &) = delete;);
-
-#undef MPARK_VARIANT_COPY_ASSIGNMENT
-
-    template <typename... Ts>
-    class impl : public copy_assignment<traits<Ts...>> {
-      using super = copy_assignment<traits<Ts...>>;
-
-      public:
-      MPARK_INHERITING_CTOR(impl, super)
-      using super::operator=;
-
-      template <std::size_t I, typename Arg>
-      inline void assign(Arg &&arg) {
-        this->assign_alt(access::base::get_alt<I>(*this),
-                         lib::forward<Arg>(arg));
-      }
-
-      inline void swap(impl &that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (this->index() == that.index()) {
-          visitation::alt::visit_alt_at(this->index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-                                        [](auto &this_alt, auto &that_alt) {
-                                          using std::swap;
-                                          swap(this_alt.value,
-                                               that_alt.value);
-                                        }
-#else
-                                        swapper{}
-#endif
-                                        ,
-                                        *this,
-                                        that);
-        } else {
-          impl *lhs = this;
-          impl *rhs = lib::addressof(that);
-          if (lhs->move_nothrow() && !rhs->move_nothrow()) {
-            std::swap(lhs, rhs);
-          }
-          impl tmp(lib::move(*rhs));
-#ifdef MPARK_EXCEPTIONS
-          // EXTENSION: When the move construction of `lhs` into `rhs` throws
-          // and `tmp` is nothrow move constructible then we move `tmp` back
-          // into `rhs` and provide the strong exception safety guarantee.
-          try {
-            this->generic_construct(*rhs, lib::move(*lhs));
-          } catch (...) {
-            if (tmp.move_nothrow()) {
-              this->generic_construct(*rhs, lib::move(tmp));
-            }
-            throw;
-          }
-#else
-          this->generic_construct(*rhs, lib::move(*lhs));
-#endif
-          this->generic_construct(*lhs, lib::move(tmp));
-        }
-      }
-
-      private:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct swapper {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const {
-          using std::swap;
-          swap(this_alt.value, that_alt.value);
-        }
-      };
-#endif
-
-      inline constexpr bool move_nothrow() const {
-        return this->valueless_by_exception() ||
-               lib::array<bool, sizeof...(Ts)>{
-                   {std::is_nothrow_move_constructible<Ts>::value...}
-               }[this->index()];
-      }
-    };
-
-#undef MPARK_INHERITING_CTOR
-
-    template <std::size_t I, typename T>
-    struct overload_leaf {
-      using F = lib::size_constant<I> (*)(T);
-      operator F() const { return nullptr; }
-    };
-
-    template <typename... Ts>
-    struct overload_impl {
-      private:
-      template <typename>
-      struct impl;
-
-      template <std::size_t... Is>
-      struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>... {};
-
-      public:
-      using type = impl<lib::index_sequence_for<Ts...>>;
-    };
-
-    template <typename... Ts>
-    using overload = typename overload_impl<Ts...>::type;
-
-    template <typename T, typename... Ts>
-    using best_match = lib::invoke_result_t<overload<Ts...>, T &&>;
-
-    template <typename T>
-    struct is_in_place_index : std::false_type {};
-
-    template <std::size_t I>
-    struct is_in_place_index<in_place_index_t<I>> : std::true_type {};
-
-    template <typename T>
-    struct is_in_place_type : std::false_type {};
-
-    template <typename T>
-    struct is_in_place_type<in_place_type_t<T>> : std::true_type {};
-
-  }  // detail
-
-  template <typename... Ts>
-  class variant {
-    static_assert(0 < sizeof...(Ts),
-                  "variant must consist of at least one alternative.");
-
-    static_assert(lib::all<!std::is_array<Ts>::value...>::value,
-                  "variant can not have an array type as an alternative.");
-
-    static_assert(lib::all<!std::is_reference<Ts>::value...>::value,
-                  "variant can not have a reference type as an alternative.");
-
-    static_assert(lib::all<!std::is_void<Ts>::value...>::value,
-                  "variant can not have a void type as an alternative.");
-
-    public:
-    template <
-        typename Front = lib::type_pack_element_t<0, Ts...>,
-        lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
-    inline constexpr variant() noexcept(
-        std::is_nothrow_default_constructible<Front>::value)
-        : impl_(in_place_index_t<0>{}) {}
-
-    variant(const variant &) = default;
-    variant(variant &&) = default;
-
-    template <
-        typename Arg,
-        typename Decayed = lib::decay_t<Arg>,
-        lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_index<Decayed>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_type<Decayed>::value, int> = 0,
-        std::size_t I = detail::best_match<Arg, Ts...>::value,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
-    inline constexpr variant(Arg &&arg) noexcept(
-        std::is_nothrow_constructible<T, Arg>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {}
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    ~variant() = default;
-
-    variant &operator=(const variant &) = default;
-    variant &operator=(variant &&) = default;
-
-    template <typename Arg,
-              lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              std::size_t I = detail::best_match<Arg, Ts...>::value,
-              typename T = lib::type_pack_element_t<I, Ts...>,
-              lib::enable_if_t<(std::is_assignable<T &, Arg>::value &&
-                                std::is_constructible<T, Arg>::value),
-                               int> = 0>
-    inline variant &operator=(Arg &&arg) noexcept(
-        (std::is_nothrow_assignable<T &, Arg>::value &&
-         std::is_nothrow_constructible<T, Arg>::value)) {
-      impl_.template assign<I>(lib::forward<Arg>(arg));
-      return *this;
-    }
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    inline constexpr bool valueless_by_exception() const noexcept {
-      return impl_.valueless_by_exception();
-    }
-
-    inline constexpr std::size_t index() const noexcept {
-      return impl_.index();
-    }
-
-    template <bool Dummy = true,
-              lib::enable_if_t<
-                  lib::all<Dummy,
-                           (lib::dependent_type<std::is_move_constructible<Ts>,
-                                                Dummy>::value &&
-                            lib::dependent_type<lib::is_swappable<Ts>,
-                                                Dummy>::value)...>::value,
-                  int> = 0>
-    inline void swap(variant &that) noexcept(
-        lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                  lib::is_nothrow_swappable<Ts>::value)...>::value) {
-      impl_.swap(that.impl_);
-    }
-
-    private:
-    detail::impl<Ts...> impl_;
-
-    friend struct detail::access::variant;
-    friend struct detail::visitation::variant;
-  };
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return v.index() == I;
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-    template <std::size_t I, typename V>
-    struct generic_get_impl {
-      constexpr generic_get_impl(int) noexcept {}
-
-      constexpr AUTO_REFREF operator()(V &&v) const
-        AUTO_REFREF_RETURN(
-            access::variant::get_alt<I>(lib::forward<V>(v)).value)
-    };
-
-    template <std::size_t I, typename V>
-    inline constexpr AUTO_REFREF generic_get(V &&v)
-      AUTO_REFREF_RETURN(generic_get_impl<I, V>(
-          holds_alternative<I>(v) ? 0 : (throw_bad_variant_access(), 0))(
-          lib::forward<V>(v)))
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
-      variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
-      variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
-      const variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
-      const variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &get(variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &&get(variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &get(const variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &&get(const variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept
-      AUTO_RETURN(v && holds_alternative<I>(*v)
-                      ? lib::addressof(access::variant::get_alt<I>(*v).value)
-                      : nullptr)
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
-  get_if(variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<
-      const variant_alternative_t<I, variant<Ts...>>>
-  get_if(const variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<T>
-  get_if(variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<const T>
-  get_if(const variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-    template <typename RelOp>
-    struct convert_to_bool {
-      template <typename Lhs, typename Rhs>
-      inline constexpr bool operator()(Lhs &&lhs, Rhs &&rhs) const {
-        static_assert(std::is_convertible<lib::invoke_result_t<RelOp, Lhs, Rhs>,
-                                          bool>::value,
-                      "relational operators must return a type"
-                      " implicitly convertible to bool");
-        return lib::invoke(
-            RelOp{}, lib::forward<Lhs>(lhs), lib::forward<Rhs>(rhs));
-      }
-    };
-  }  // namespace detail
-
-  template <typename... Ts>
-  inline constexpr bool operator==(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using equal_to = detail::convert_to_bool<lib::equal_to>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
-#else
-    return lhs.index() == rhs.index() &&
-           (lhs.valueless_by_exception() ||
-            variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator!=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using not_equal_to = detail::convert_to_bool<lib::not_equal_to>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
-#else
-    return lhs.index() != rhs.index() ||
-           (!lhs.valueless_by_exception() &&
-            variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using less = detail::convert_to_bool<lib::less>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
-#else
-    return !rhs.valueless_by_exception() &&
-           (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using greater = detail::convert_to_bool<lib::greater>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return false;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
-#else
-    return !lhs.valueless_by_exception() &&
-           (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using less_equal = detail::convert_to_bool<lib::less_equal>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return true;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
-#else
-    return lhs.valueless_by_exception() ||
-           (!rhs.valueless_by_exception() &&
-            (lhs.index() < rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using greater_equal = detail::convert_to_bool<lib::greater_equal>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
-#else
-    return rhs.valueless_by_exception() ||
-           (!lhs.valueless_by_exception() &&
-            (lhs.index() > rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(
-                  lhs.index(), greater_equal{}, lhs, rhs))));
-#endif
-  }
-
-  struct monostate {};
-
-  inline constexpr bool operator<(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator>(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator<=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator>=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator==(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator!=(monostate, monostate) noexcept {
-    return false;
-  }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-  namespace detail {
-
-    inline constexpr bool all(std::initializer_list<bool> bs) {
-      for (bool b : bs) {
-        if (!b) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
-    return (detail::all({!vs.valueless_by_exception()...})
-                ? (void)0
-                : throw_bad_variant_access()),
-           detail::visitation::variant::visit_value(
-               lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
-  }
-#else
-  namespace detail {
-
-    template <std::size_t N>
-    inline constexpr bool all_impl(const lib::array<bool, N> &bs,
-                                   std::size_t idx) {
-      return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
-    }
-
-    template <std::size_t N>
-    inline constexpr bool all(const lib::array<bool, N> &bs) {
-      return all_impl(bs, 0);
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs)
-    DECLTYPE_AUTO_RETURN(
-        (detail::all(
-             lib::array<bool, sizeof...(Vs)>{{!vs.valueless_by_exception()...}})
-             ? (void)0
-             : throw_bad_variant_access()),
-        detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
-                                                 lib::forward<Vs>(vs)...))
-#endif
-
-  template <typename... Ts>
-  inline auto swap(variant<Ts...> &lhs,
-                   variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
-      -> decltype(lhs.swap(rhs)) {
-    lhs.swap(rhs);
-  }
-
-  namespace detail {
-
-    template <typename T, typename...>
-    using enabled_type = T;
-
-    namespace hash {
-
-      template <typename H, typename K>
-      constexpr bool meets_requirements() noexcept {
-        return std::is_copy_constructible<H>::value &&
-               std::is_move_constructible<H>::value &&
-               lib::is_invocable_r<std::size_t, H, const K &>::value;
-      }
-
-      template <typename K>
-      constexpr bool is_enabled() noexcept {
-        using H = std::hash<K>;
-        return meets_requirements<H, K>() &&
-               std::is_default_constructible<H>::value &&
-               std::is_copy_assignable<H>::value &&
-               std::is_move_assignable<H>::value;
-      }
-
-    }  // namespace hash
-
-  }  // namespace detail
-
-#undef AUTO
-#undef AUTO_RETURN
-
-#undef AUTO_REFREF
-#undef AUTO_REFREF_RETURN
-
-#undef DECLTYPE_AUTO
-#undef DECLTYPE_AUTO_RETURN
-
-}  // namespace mpark
-
-namespace std {
-
-  template <typename... Ts>
-  struct hash<mpark::detail::enabled_type<
-      mpark::variant<Ts...>,
-      mpark::lib::enable_if_t<mpark::lib::all<mpark::detail::hash::is_enabled<
-          mpark::lib::remove_const_t<Ts>>()...>::value>>> {
-    using argument_type = mpark::variant<Ts...>;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &v) const {
-      using mpark::detail::visitation::variant;
-      std::size_t result =
-          v.valueless_by_exception()
-              ? 299792458  // Random value chosen by the universe upon creation
-              : variant::visit_alt(
-#ifdef MPARK_GENERIC_LAMBDAS
-                    [](const auto &alt) {
-                      using alt_type = mpark::lib::decay_t<decltype(alt)>;
-                      using value_type = mpark::lib::remove_const_t<
-                          typename alt_type::value_type>;
-                      return hash<value_type>{}(alt.value);
-                    }
-#else
-                    hasher{}
-#endif
-                    ,
-                    v);
-      return hash_combine(result, hash<std::size_t>{}(v.index()));
-    }
-
-    private:
-#ifndef MPARK_GENERIC_LAMBDAS
-    struct hasher {
-      template <typename Alt>
-      inline std::size_t operator()(const Alt &alt) const {
-        using alt_type = mpark::lib::decay_t<Alt>;
-        using value_type =
-            mpark::lib::remove_const_t<typename alt_type::value_type>;
-        return hash<value_type>{}(alt.value);
-      }
-    };
-#endif
-
-    static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
-      return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
-    }
-  };
-
-  template <>
-  struct hash<mpark::monostate> {
-    using argument_type = mpark::monostate;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &) const noexcept {
-      return 66740831;  // return a fundamentally attractive random value.
-    }
-  };
-
-}  // namespace std
-
-#endif  // MPARK_VARIANT_HPP

+ 0 - 1729
src/external/mpark-variant/v1.0.0/variant.hpp

@@ -1,1729 +0,0 @@
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2016
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANT_HPP
-#define MPARK_VARIANT_HPP
-
-/*
-   variant synopsis
-
-namespace std {
-
-  // 20.7.2, class template variant
-  template <class... Types>
-  class variant {
-  public:
-
-    // 20.7.2.1, constructors
-    constexpr variant() noexcept(see below);
-    variant(const variant&);
-    variant(variant&&) noexcept(see below);
-
-    template <class T> constexpr variant(T&&) noexcept(see below);
-
-    template <class T, class... Args>
-    constexpr explicit variant(in_place_type_t<T>, Args&&...);
-
-    template <class T, class U, class... Args>
-    constexpr explicit variant(
-        in_place_type_t<T>, initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    constexpr explicit variant(in_place_index_t<I>, Args&&...);
-
-    template <size_t I, class U, class... Args>
-    constexpr explicit variant(
-        in_place_index_t<I>, initializer_list<U>, Args&&...);
-
-    // 20.7.2.2, destructor
-    ~variant();
-
-    // 20.7.2.3, assignment
-    variant& operator=(const variant&);
-    variant& operator=(variant&&) noexcept(see below);
-
-    template <class T> variant& operator=(T&&) noexcept(see below);
-
-    // 20.7.2.4, modifiers
-    template <class T, class... Args>
-    void emplace(Args&&...);
-
-    template <class T, class U, class... Args>
-    void emplace(initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    void emplace(Args&&...);
-
-    template <size_t I, class U, class...  Args>
-    void emplace(initializer_list<U>, Args&&...);
-
-    // 20.7.2.5, value status
-    constexpr bool valueless_by_exception() const noexcept;
-    constexpr size_t index() const noexcept;
-
-    // 20.7.2.6, swap
-    void swap(variant&) noexcept(see below);
-  };
-
-  // 20.7.3, variant helper classes
-  template <class T> struct variant_size; // undefined
-
-  template <class T>
-  constexpr size_t variant_size_v = variant_size<T>::value;
-
-  template <class T> struct variant_size<const T>;
-  template <class T> struct variant_size<volatile T>;
-  template <class T> struct variant_size<const volatile T>;
-
-  template <class... Types>
-  struct variant_size<variant<Types...>>;
-
-  template <size_t I, class T> struct variant_alternative; // undefined
-
-  template <size_t I, class T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <size_t I, class T> struct variant_alternative<I, const T>;
-  template <size_t I, class T> struct variant_alternative<I, volatile T>;
-  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
-
-  template <size_t I, class... Types>
-  struct variant_alternative<I, variant<Types...>>;
-
-  constexpr size_t variant_npos = -1;
-
-  // 20.7.4, value access
-  template <class T, class... Types>
-  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&
-  get(variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&&
-  get(variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&
-  get(const variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&&
-  get(const variant<Types...>&&);
-
-  template <class T, class...  Types>
-  constexpr T& get(variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr T&& get(variant<Types...>&&);
-
-  template <class T, class... Types>
-  constexpr const T& get(const variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr const T&& get(const variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
-  get_if(variant<Types...>*) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
-  get_if(const variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<T>
-  get_if(variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<const T>
-  get_if(const variant<Types...>*) noexcept;
-
-  // 20.7.5, relational operators
-  template <class... Types>
-  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
-
-  // 20.7.6, visitation
-  template <class Visitor, class... Variants>
-  constexpr see below visit(Visitor&&, Variants&&...);
-
-  // 20.7.7, class monostate
-  struct monostate;
-
-  // 20.7.8, monostate relational operators
-  constexpr bool operator<(monostate, monostate) noexcept;
-  constexpr bool operator>(monostate, monostate) noexcept;
-  constexpr bool operator<=(monostate, monostate) noexcept;
-  constexpr bool operator>=(monostate, monostate) noexcept;
-  constexpr bool operator==(monostate, monostate) noexcept;
-  constexpr bool operator!=(monostate, monostate) noexcept;
-
-  // 20.7.9, specialized algorithms
-  template <class... Types>
-  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
-
-  // 20.7.10, class bad_variant_access
-  class bad_variant_access;
-
-  // 20.7.11, hash support
-  template <class T> struct hash;
-  template <class... Types> struct hash<variant<Types...>>;
-  template <> struct hash<monostate>;
-
-} // namespace std
-
-*/
-
-#include <array>
-#include <cstddef>
-#include <exception>
-#include <functional>
-#include <initializer_list>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2016
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_IN_PLACE_HPP
-#define MPARK_IN_PLACE_HPP
-
-#include <cstddef>
-
-namespace mpark {
-
-  struct in_place_t {
-    explicit in_place_t() = default;
-  };
-
-  constexpr in_place_t in_place{};
-
-  template <std::size_t I>
-  struct in_place_index_t {
-    explicit in_place_index_t() = default;
-  };
-
-  template <std::size_t I>
-  constexpr in_place_index_t<I> in_place_index{};
-
-  template <typename T>
-  struct in_place_type_t {
-    explicit in_place_type_t() = default;
-  };
-
-  template <typename T>
-  constexpr in_place_type_t<T> in_place_type{};
-
-}  // namespace mpark
-
-#endif  // MPARK_IN_PLACE_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2016
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_LIB_HPP
-#define MPARK_LIB_HPP
-
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2016
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_CONFIG_HPP
-#define MPARK_CONFIG_HPP
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#if __has_builtin(__builtin_addressof) || __GNUC__ >= 7
-#define MPARK_BUILTIN_ADDRESSOF
-#endif
-
-#if __has_builtin(__type_pack_element)
-#define MPARK_TYPE_PACK_ELEMENT
-#endif
-
-#endif  // MPARK_CONFIG_HPP
-
-
-namespace mpark {
-  namespace lib {
-
-    inline namespace cpp17 {
-
-      // <type_traits>
-      template <bool B>
-      using bool_constant = std::integral_constant<bool, B>;
-
-      template <typename...>
-      using void_t = void;
-
-      template <typename F, typename = void>
-      struct is_callable : std::false_type {};
-
-      template <typename F>
-      struct is_callable<F, void_t<std::result_of_t<F>>> : std::true_type {};
-
-      namespace detail {
-        namespace swappable {
-
-          using std::swap;
-
-          template <typename T>
-          struct is_swappable_impl {
-            private:
-            template <typename U,
-                      typename = decltype(swap(std::declval<U &>(),
-                                               std::declval<U &>()))>
-            inline static std::true_type test(int);
-
-            template <typename U>
-            inline static std::false_type test(...);
-
-            public:
-            using type = decltype(test<T>(0));
-          };
-
-          template <typename T>
-          using is_swappable = typename is_swappable_impl<T>::type;
-
-          template <typename T, bool = is_swappable<T>::value>
-          struct is_nothrow_swappable
-              : bool_constant<noexcept(
-                    swap(std::declval<T &>(), std::declval<T &>()))> {};
-
-          template <typename T>
-          struct is_nothrow_swappable<T, false> : std::false_type {};
-
-        }  // namespace swappable
-      }  // namespace detail
-
-      template <typename T>
-      using is_swappable = detail::swappable::is_swappable<T>;
-
-      template <typename T>
-      using is_nothrow_swappable = detail::swappable::is_nothrow_swappable<T>;
-
-      // <functional>
-#define RETURN(...) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-      template <typename F, typename... As>
-      inline constexpr auto invoke(F &&f, As &&... as)
-          RETURN(std::forward<F>(f)(std::forward<As>(as)...))
-
-      template <typename B, typename T, typename D>
-      inline constexpr auto invoke(T B::*pmv, D &&d)
-          RETURN(std::forward<D>(d).*pmv)
-
-      template <typename Pmv, typename Ptr>
-      inline constexpr auto invoke(Pmv pmv, Ptr &&ptr)
-          RETURN((*std::forward<Ptr>(ptr)).*pmv)
-
-      template <typename B, typename T, typename D, typename... As>
-      inline constexpr auto invoke(T B::*pmf, D &&d, As &&... as)
-          RETURN((std::forward<D>(d).*pmf)(std::forward<As>(as)...))
-
-      template <typename Pmf, typename Ptr, typename... As>
-      inline constexpr auto invoke(Pmf pmf, Ptr &&ptr, As &&... as)
-          RETURN(((*std::forward<Ptr>(ptr)).*pmf)(std::forward<As>(as)...))
-
-#undef RETURN
-
-      // <memory>
-#ifdef MPARK_BUILTIN_ADDRESSOF
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return __builtin_addressof(arg);
-      }
-#else
-      namespace detail {
-
-        namespace has_addressof_impl {
-
-          struct fail;
-
-          template <typename T>
-          inline fail operator&(T &&);
-
-          template <typename T>
-          inline static constexpr bool impl() {
-            return (std::is_class<T>::value || std::is_union<T>::value) &&
-                   !std::is_same<decltype(&std::declval<T &>()), fail>::value;
-          }
-
-        }  // namespace has_addressof_impl
-
-        template <typename T>
-        using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
-
-      }  // namespace detail
-
-      template <typename T,
-                std::enable_if_t<detail::has_addressof<T>::value, int> = 0>
-      inline T *addressof(T &arg) {
-        return std::addressof(arg);
-      }
-
-      template <typename T,
-                std::enable_if_t<!detail::has_addressof<T>::value, int> = 0>
-      inline constexpr T *addressof(T &arg) {
-        return &arg;
-      }
-#endif
-
-      template <typename T>
-      inline const T *addressof(const T &&) = delete;
-
-    }  // namespace cpp17
-
-    template <typename T>
-    struct identity {
-      using type = T;
-    };
-
-#ifdef MPARK_TYPE_PACK_ELEMENT
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = __type_pack_element<I, Ts...>;
-#else
-    template <std::size_t I, typename... Ts>
-    struct type_pack_element_impl {
-      private:
-      template <std::size_t, typename T>
-      struct indexed_type {
-        using type = T;
-      };
-
-      template <std::size_t... Is>
-      inline static auto make_set(std::index_sequence<Is...>) {
-        struct set : indexed_type<Is, Ts>... {};
-        return set{};
-      }
-
-      template <typename T>
-      inline static std::enable_if<true, T> impl(indexed_type<I, T>);
-
-      inline static std::enable_if<false, void> impl(...);
-
-      public:
-      using type = decltype(impl(make_set(std::index_sequence_for<Ts...>{})));
-    };
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
-#endif
-
-  }  // namespace lib
-}  // namespace mpark
-
-#endif  // MPARK_LIB_HPP
-
-
-namespace mpark {
-
-  class bad_variant_access : public std::exception {
-    public:
-    virtual const char *what() const noexcept { return "bad_variant_access"; }
-  };
-
-  template <typename... Ts>
-  class variant;
-
-  template <typename T>
-  struct variant_size;
-
-  template <typename T>
-  constexpr std::size_t variant_size_v = variant_size<T>::value;
-
-  template <typename T>
-  struct variant_size<const T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<volatile T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<const volatile T> : variant_size<T> {};
-
-  template <typename... Ts>
-  struct variant_size<variant<Ts...>>
-      : std::integral_constant<std::size_t, sizeof...(Ts)> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative;
-
-  template <std::size_t I, typename T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const T>
-      : std::add_const<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, volatile T>
-      : std::add_volatile<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const volatile T>
-      : std::add_cv<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename... Ts>
-  struct variant_alternative<I, variant<Ts...>> {
-    static_assert(I < sizeof...(Ts),
-                  "`variant_alternative` index out of range.");
-    using type = lib::type_pack_element_t<I, Ts...>;
-  };
-
-  constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
-
-  namespace detail {
-
-    inline constexpr bool all(std::initializer_list<bool> bs) {
-      for (bool b : bs) {
-        if (!b) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    constexpr std::size_t not_found = static_cast<std::size_t>(-1);
-    constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
-
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      constexpr bool matches[] = {std::is_same<T, Ts>::value...};
-      std::size_t result = not_found;
-      for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
-        if (matches[i]) {
-          if (result != not_found) {
-            return ambiguous;
-          }
-          result = i;
-        }
-      }
-      return result;
-    }
-
-    template <std::size_t I>
-    using find_index_sfinae_impl =
-        std::enable_if_t<I != not_found && I != ambiguous,
-                         std::integral_constant<std::size_t, I>>;
-
-    template <typename T, typename... Ts>
-    using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
-
-    template <std::size_t I>
-    struct find_index_checked_impl : std::integral_constant<std::size_t, I> {
-      static_assert(I != not_found, "the specified type is not found.");
-      static_assert(I != ambiguous, "the specified type is ambiguous.");
-    };
-
-    template <typename T, typename... Ts>
-    using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
-
-    struct valueless_t {};
-
-    enum class Trait { TriviallyAvailable, Available, Unavailable };
-
-    template <typename T,
-              template <typename> class IsTriviallyAvailable,
-              template <typename> class IsAvailable>
-    inline constexpr Trait trait() {
-      return IsTriviallyAvailable<T>::value
-                 ? Trait::TriviallyAvailable
-                 : IsAvailable<T>::value ? Trait::Available
-                                         : Trait::Unavailable;
-    }
-
-    inline constexpr Trait common_trait(std::initializer_list<Trait> traits) {
-      Trait result = Trait::TriviallyAvailable;
-      for (Trait t : traits) {
-        if (static_cast<int>(t) > static_cast<int>(result)) {
-          result = t;
-        }
-      }
-      return result;
-    }
-
-    template <typename... Ts>
-    struct traits {
-      static constexpr Trait copy_constructible_trait =
-          common_trait({trait<Ts,
-                              std::is_trivially_copy_constructible,
-                              std::is_copy_constructible>()...});
-
-      static constexpr Trait move_constructible_trait =
-          common_trait({trait<Ts,
-                              std::is_trivially_move_constructible,
-                              std::is_move_constructible>()...});
-
-      static constexpr Trait copy_assignable_trait =
-          common_trait({copy_constructible_trait,
-                        move_constructible_trait,
-                        trait<Ts,
-                              std::is_trivially_copy_assignable,
-                              std::is_copy_assignable>()...});
-
-      static constexpr Trait move_assignable_trait =
-          common_trait({move_constructible_trait,
-                        trait<Ts,
-                              std::is_trivially_move_assignable,
-                              std::is_move_assignable>()...});
-
-      static constexpr Trait destructible_trait =
-          common_trait({trait<Ts,
-                              std::is_trivially_destructible,
-                              std::is_destructible>()...});
-    };
-
-    namespace access {
-
-      struct recursive_union {
-        template <typename V>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
-          return std::forward<V>(v).head_;
-        }
-
-        template <typename V, std::size_t I>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
-          return get_alt(std::forward<V>(v).tail_, in_place_index<I - 1>);
-        }
-      };
-
-      struct base {
-        template <std::size_t I, typename V>
-        inline static constexpr auto &&get_alt(V &&v) {
-          return recursive_union::get_alt(std::forward<V>(v).data_,
-                                          in_place_index<I>);
-        }
-      };
-
-      struct variant {
-        template <std::size_t I, typename V>
-        inline static constexpr auto &&get_alt(V &&v) {
-          return base::get_alt<I>(std::forward<V>(v).impl_);
-        }
-      };
-
-    }  // namespace access
-
-    namespace visitation {
-
-      struct base {
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_alt_at(std::size_t index,
-                                                            Visitor &&visitor,
-                                                            Vs &&... vs) {
-          constexpr auto fdiagonal =
-              make_fdiagonal<Visitor &&,
-                             decltype(std::forward<Vs>(vs).as_base())...>();
-          return fdiagonal[index](std::forward<Visitor>(visitor),
-                                  std::forward<Vs>(vs).as_base()...);
-        }
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_alt(Visitor &&visitor,
-                                                         Vs &&... vs) {
-          constexpr auto fmatrix =
-              make_fmatrix<Visitor &&,
-                           decltype(std::forward<Vs>(vs).as_base())...>();
-          const std::size_t indices[] = {vs.index()...};
-          return at(fmatrix, indices)(std::forward<Visitor>(visitor),
-                                      std::forward<Vs>(vs).as_base()...);
-        }
-
-        private:
-        template <typename T>
-        inline static constexpr const T &at_impl(const T &elem,
-                                                 const std::size_t *) {
-          return elem;
-        }
-
-        template <typename T, std::size_t N>
-        inline static constexpr auto &&at_impl(const std::array<T, N> &elems,
-                                               const std::size_t *index) {
-          return at_impl(elems[*index], index + 1);
-        }
-
-        template <typename T, std::size_t N, std::size_t I>
-        inline static constexpr auto &&at(const std::array<T, N> &elems,
-                                          const std::size_t (&indices)[I]) {
-          return at_impl(elems, indices);
-        }
-
-        template <typename F, typename... Fs>
-        inline static constexpr void std_visit_visitor_return_type_check() {
-          static_assert(all({std::is_same<F, Fs>::value...}),
-                        "`std::visit` requires the visitor to have a single "
-                        "return type.");
-        }
-
-        template <typename... Fs>
-        inline static constexpr auto make_farray(Fs &&... fs) {
-          std_visit_visitor_return_type_check<std::decay_t<Fs>...>();
-          using result = std::array<std::common_type_t<std::decay_t<Fs>...>,
-                                    sizeof...(Fs)>;
-          return result{{std::forward<Fs>(fs)...}};
-        }
-
-        template <std::size_t... Is>
-        struct dispatcher {
-          template <typename F, typename... Vs>
-          inline static constexpr decltype(auto) dispatch(F f, Vs... vs) {
-            return lib::invoke(
-                static_cast<F>(f),
-                access::base::get_alt<Is>(static_cast<Vs>(vs))...);
-          }
-        };
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_dispatch(std::index_sequence<Is...>) {
-          return &dispatcher<Is...>::template dispatch<F, Vs...>;
-        }
-
-        template <std::size_t I, typename F, typename... Vs>
-        inline static constexpr auto make_fdiagonal_impl() {
-          return make_dispatch<F, Vs...>(
-              std::index_sequence<(lib::identity<Vs>{}, I)...>{});
-        }
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_fdiagonal_impl(
-            std::index_sequence<Is...>) {
-          return base::make_farray(make_fdiagonal_impl<Is, F, Vs...>()...);
-        }
-
-        template <typename F, typename V, typename... Vs>
-        inline static constexpr auto make_fdiagonal() {
-          constexpr std::size_t N = std::decay_t<V>::size();
-          static_assert(all({(N == std::decay_t<Vs>::size())...}),
-                        "all of the variants must be the same size.");
-          return make_fdiagonal_impl<F, V, Vs...>(
-              std::make_index_sequence<N>{});
-        }
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_fmatrix_impl(
-            std::index_sequence<Is...> is) {
-          return make_dispatch<F, Vs...>(is);
-        }
-
-        template <typename F,
-                  typename... Vs,
-                  std::size_t... Is,
-                  std::size_t... Js,
-                  typename... Ls>
-        inline static constexpr auto make_fmatrix_impl(
-            std::index_sequence<Is...>, std::index_sequence<Js...>, Ls... ls) {
-          return base::make_farray(make_fmatrix_impl<F, Vs...>(
-              std::index_sequence<Is..., Js>{}, ls...)...);
-        }
-
-        template <typename F, typename... Vs>
-        inline static constexpr auto make_fmatrix() {
-          return make_fmatrix_impl<F, Vs...>(
-              std::index_sequence<>{},
-              std::make_index_sequence<std::decay_t<Vs>::size()>{}...);
-        }
-      };
-
-      struct variant {
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_alt_at(std::size_t index,
-                                                            Visitor &&visitor,
-                                                            Vs &&... vs) {
-          return base::visit_alt_at(index,
-                                    std::forward<Visitor>(visitor),
-                                    std::forward<Vs>(vs).impl_...);
-        }
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_alt(Visitor &&visitor,
-                                                         Vs &&... vs) {
-          return base::visit_alt(std::forward<Visitor>(visitor),
-                                 std::forward<Vs>(vs).impl_...);
-        }
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_value_at(std::size_t index,
-                                                              Visitor &&visitor,
-                                                              Vs &&... vs) {
-          return visit_alt_at(
-              index,
-              make_value_visitor(std::forward<Visitor>(visitor)),
-              std::forward<Vs>(vs)...);
-        }
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_value(Visitor &&visitor,
-                                                           Vs &&... vs) {
-          return visit_alt(make_value_visitor(std::forward<Visitor>(visitor)),
-                           std::forward<Vs>(vs)...);
-        }
-
-        private:
-        template <typename Visitor, typename... Values>
-        inline static constexpr void std_visit_exhaustive_visitor_check() {
-          static_assert(lib::is_callable<Visitor(Values...)>::value,
-                        "`std::visit` requires the visitor to be exhaustive.");
-        }
-
-        template <typename Visitor>
-        struct value_visitor {
-          template <typename... Alts>
-          inline constexpr decltype(auto) operator()(Alts &&... alts) const {
-            std_visit_exhaustive_visitor_check<
-                Visitor,
-                decltype(std::forward<Alts>(alts).value_)...>();
-            return lib::invoke(std::forward<Visitor>(visitor_),
-                               std::forward<Alts>(alts).value_...);
-          }
-          Visitor &&visitor_;
-        };
-
-        template <typename Visitor>
-        inline static constexpr auto make_value_visitor(Visitor &&visitor) {
-          return value_visitor<Visitor>{std::forward<Visitor>(visitor)};
-        }
-      };
-
-    }  // namespace visitation
-
-    template <std::size_t Index, typename T>
-    struct alt {
-      using value_type = T;
-
-      template <typename... Args>
-      inline explicit constexpr alt(in_place_t, Args &&... args)
-          : value_(std::forward<Args>(args)...) {}
-
-      value_type value_;
-    };
-
-    template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
-    union recursive_union;
-
-    template <Trait DestructibleTrait, std::size_t Index>
-    union recursive_union<DestructibleTrait, Index> {};
-
-#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)  \
-  template <std::size_t Index, typename T, typename... Ts>             \
-  union recursive_union<destructible_trait, Index, T, Ts...> {         \
-    public:                                                            \
-    inline explicit constexpr recursive_union(valueless_t) noexcept    \
-        : dummy_{} {}                                                  \
-                                                                       \
-    template <typename... Args>                                        \
-    inline explicit constexpr recursive_union(in_place_index_t<0>,     \
-                                              Args &&... args)         \
-        : head_(in_place, std::forward<Args>(args)...) {}              \
-                                                                       \
-    template <std::size_t I, typename... Args>                         \
-    inline explicit constexpr recursive_union(in_place_index_t<I>,     \
-                                              Args &&... args)         \
-        : tail_(in_place_index<I - 1>, std::forward<Args>(args)...) {} \
-                                                                       \
-    recursive_union(const recursive_union &) = default;                \
-    recursive_union(recursive_union &&) = default;                     \
-                                                                       \
-    destructor                                                         \
-                                                                       \
-    recursive_union &operator=(const recursive_union &) = default;     \
-    recursive_union &operator=(recursive_union &&) = default;          \
-                                                                       \
-    private:                                                           \
-    char dummy_;                                                       \
-    alt<Index, T> head_;                                               \
-    recursive_union<destructible_trait, Index + 1, Ts...> tail_;       \
-                                                                       \
-    friend struct access::recursive_union;                             \
-  }
-
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
-                                  ~recursive_union() = default;);
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
-                                  ~recursive_union() {});
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
-                                  ~recursive_union() = delete;);
-
-#undef _MPARK_VARIANT_UNION
-
-    template <Trait DestructibleTrait, typename... Ts>
-    class base {
-      public:
-      inline explicit constexpr base(valueless_t tag) noexcept
-          : data_(tag), index_(-1) {}
-
-      template <std::size_t I, typename... Args>
-      inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
-          : data_(in_place_index<I>, std::forward<Args>(args)...), index_(I) {}
-
-      inline constexpr bool valueless_by_exception() const noexcept {
-        return index() == variant_npos;
-      }
-
-      inline constexpr std::size_t index() const noexcept {
-        return index_ == static_cast<unsigned int>(-1) ? variant_npos : index_;
-      }
-
-      protected:
-      inline constexpr base &as_base() & { return *this; }
-      inline constexpr base &&as_base() && { return std::move(*this); }
-      inline constexpr const base &as_base() const & { return *this; }
-      inline constexpr const base &&as_base() const && { return std::move(*this); }
-
-      inline static constexpr std::size_t size() { return sizeof...(Ts); }
-
-      recursive_union<DestructibleTrait, 0, Ts...> data_;
-      unsigned int index_;
-
-      friend struct access::base;
-      friend struct visitation::base;
-    };
-
-    template <typename Traits, Trait = Traits::destructible_trait>
-    class destructor;
-
-#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
-  template <typename... Ts>                                               \
-  class destructor<traits<Ts...>, destructible_trait>                     \
-      : public base<destructible_trait, Ts...> {                          \
-    using super = base<destructible_trait, Ts...>;                        \
-                                                                          \
-    public:                                                               \
-    using super::super;                                                   \
-    using super::operator=;                                               \
-                                                                          \
-    destructor(const destructor &) = default;                             \
-    destructor(destructor &&) = default;                                  \
-    definition                                                            \
-    destructor &operator=(const destructor &) = default;                  \
-    destructor &operator=(destructor &&) = default;                       \
-                                                                          \
-    protected:                                                            \
-    inline destroy                                                        \
-  }
-
-    MPARK_VARIANT_DESTRUCTOR(Trait::TriviallyAvailable,
-                             ~destructor() = default;,
-                             void destroy() noexcept { this->index_ = -1; });
-
-    MPARK_VARIANT_DESTRUCTOR(Trait::Available,
-                             ~destructor() { destroy(); },
-                             void destroy() noexcept {
-                               if (!this->valueless_by_exception()) {
-                                 visitation::base::visit_alt(
-                                     [](auto &alt) noexcept {
-                                       using alt_type =
-                                           std::decay_t<decltype(alt)>;
-                                       alt.~alt_type();
-                                     },
-                                     *this);
-                               }
-                               this->index_ = -1;
-                             });
-
-    MPARK_VARIANT_DESTRUCTOR(Trait::Unavailable,
-                             ~destructor() = delete;,
-                             void destroy() noexcept = delete;);
-
-#undef MPARK_VARIANT_DESTRUCTOR
-
-    template <typename Traits>
-    class constructor : public destructor<Traits> {
-      using super = destructor<Traits>;
-
-      public:
-      using super::super;
-      using super::operator=;
-
-      protected:
-      template <std::size_t I, typename T, typename... Args>
-      inline static void construct_alt(alt<I, T> &a, Args &&... args) {
-        ::new (static_cast<void *>(lib::addressof(a)))
-            alt<I, T>(in_place, std::forward<Args>(args)...);
-      }
-
-      template <typename Rhs>
-      inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
-        lhs.destroy();
-        if (!rhs.valueless_by_exception()) {
-          visitation::base::visit_alt_at(
-              rhs.index(),
-              [](auto &lhs_alt, auto &&rhs_alt) {
-                constructor::construct_alt(
-                    lhs_alt, std::forward<decltype(rhs_alt)>(rhs_alt).value_);
-              },
-              lhs,
-              std::forward<Rhs>(rhs));
-          lhs.index_ = rhs.index();
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_constructible_trait>
-    class move_constructor;
-
-#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class move_constructor<traits<Ts...>, move_constructible_trait>            \
-      : public constructor<traits<Ts...>> {                                  \
-    using super = constructor<traits<Ts...>>;                                \
-                                                                             \
-    public:                                                                  \
-    using super::super;                                                      \
-    using super::operator=;                                                  \
-                                                                             \
-    move_constructor(const move_constructor &) = default;                    \
-    definition                                                               \
-    ~move_constructor() = default;                                           \
-    move_constructor &operator=(const move_constructor &) = default;         \
-    move_constructor &operator=(move_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        move_constructor(move_constructor &&that) = default;);
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Available,
-        move_constructor(move_constructor &&that) noexcept(
-            all({std::is_nothrow_move_constructible<Ts>::value...}))
-            : move_constructor(valueless_t{}) {
-          this->generic_construct(*this, std::move(that));
-        });
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Unavailable,
-        move_constructor(move_constructor &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_CONSTRUCTOR
-
-    template <typename Traits, Trait = Traits::copy_constructible_trait>
-    class copy_constructor;
-
-#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
-      : public move_constructor<traits<Ts...>> {                             \
-    using super = move_constructor<traits<Ts...>>;                           \
-                                                                             \
-    public:                                                                  \
-    using super::super;                                                      \
-    using super::operator=;                                                  \
-                                                                             \
-    definition                                                               \
-    copy_constructor(copy_constructor &&) = default;                         \
-    ~copy_constructor() = default;                                           \
-    copy_constructor &operator=(const copy_constructor &) = default;         \
-    copy_constructor &operator=(copy_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        copy_constructor(const copy_constructor &that) = default;);
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Available,
-        copy_constructor(const copy_constructor &that)
-            : copy_constructor(valueless_t{}) {
-          this->generic_construct(*this, that);
-        });
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Unavailable,
-        copy_constructor(const copy_constructor &) = delete;);
-
-#undef MPARK_VARIANT_COPY_CONSTRUCTOR
-
-    template <typename Traits>
-    class assignment : public copy_constructor<Traits> {
-      using super = copy_constructor<Traits>;
-
-      public:
-      using super::super;
-      using super::operator=;
-
-      template <std::size_t I, typename... Args>
-      inline void emplace(Args &&... args) {
-        this->destroy();
-        this->construct_alt(access::base::get_alt<I>(*this),
-                            std::forward<Args>(args)...);
-        this->index_ = I;
-      }
-
-      protected:
-      template <bool CopyAssign, std::size_t I, typename T, typename Arg>
-      inline void assign_alt(alt<I, T> &a,
-                             Arg &&arg,
-                             lib::bool_constant<CopyAssign> tag) {
-        if (this->index() == I) {
-          a.value_ = std::forward<Arg>(arg);
-        } else {
-          struct {
-            void operator()(std::true_type) const {
-              this_->emplace<I>(T(std::forward<Arg>(arg_)));
-            }
-            void operator()(std::false_type) const {
-              this_->emplace<I>(std::forward<Arg>(arg_));
-            }
-            assignment *this_;
-            Arg &&arg_;
-          } impl{this, std::forward<Arg>(arg)};
-          impl(tag);
-        }
-      }
-
-      template <typename That>
-      inline void generic_assign(That &&that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (that.valueless_by_exception()) {
-          this->destroy();
-        } else {
-          visitation::base::visit_alt_at(
-              that.index(),
-              [this](auto &this_alt, auto &&that_alt) {
-                this->assign_alt(
-                    this_alt,
-                    std::forward<decltype(that_alt)>(that_alt).value_,
-                    std::is_lvalue_reference<That>{});
-              },
-              *this,
-              std::forward<That>(that));
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_assignable_trait>
-    class move_assignment;
-
-#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class move_assignment<traits<Ts...>, move_assignable_trait>            \
-      : public assignment<traits<Ts...>> {                               \
-    using super = assignment<traits<Ts...>>;                             \
-                                                                         \
-    public:                                                              \
-    using super::super;                                                  \
-    using super::operator=;                                              \
-                                                                         \
-    move_assignment(const move_assignment &) = default;                  \
-    move_assignment(move_assignment &&) = default;                       \
-    ~move_assignment() = default;                                        \
-    move_assignment &operator=(const move_assignment &) = default;       \
-    definition                                                           \
-  }
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        move_assignment &operator=(move_assignment &&that) = default;);
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Available,
-        move_assignment &
-        operator=(move_assignment &&that) noexcept(
-            all({std::is_nothrow_move_constructible<Ts>::value &&
-                 std::is_nothrow_move_assignable<Ts>::value...})) {
-          this->generic_assign(std::move(that));
-          return *this;
-        });
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Unavailable,
-        move_assignment &operator=(move_assignment &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_ASSIGNMENT
-
-    template <typename Traits, Trait = Traits::copy_assignable_trait>
-    class copy_assignment;
-
-#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
-      : public move_assignment<traits<Ts...>> {                          \
-    using super = move_assignment<traits<Ts...>>;                        \
-                                                                         \
-    public:                                                              \
-    using super::super;                                                  \
-    using super::operator=;                                              \
-                                                                         \
-    copy_assignment(const copy_assignment &) = default;                  \
-    copy_assignment(copy_assignment &&) = default;                       \
-    ~copy_assignment() = default;                                        \
-    definition                                                           \
-    copy_assignment &operator=(copy_assignment &&) = default;            \
-  }
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        copy_assignment &operator=(const copy_assignment &that) = default;);
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Available,
-        copy_assignment &operator=(const copy_assignment &that) {
-          this->generic_assign(that);
-          return *this;
-        });
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Unavailable,
-        copy_assignment &operator=(const copy_assignment &) = delete;);
-
-#undef MPARK_VARIANT_COPY_ASSIGNMENT
-
-    template <typename... Ts>
-    class impl : public copy_assignment<traits<Ts...>> {
-      using super = copy_assignment<traits<Ts...>>;
-
-      public:
-      using super::super;
-      using super::operator=;
-
-      template <std::size_t I, typename Arg>
-      inline void assign(Arg &&arg) {
-        this->assign_alt(access::base::get_alt<I>(*this),
-                         std::forward<Arg>(arg),
-                         std::false_type{});
-      }
-
-      inline void swap(impl &that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (this->index() == that.index()) {
-          visitation::base::visit_alt_at(this->index(),
-                                         [](auto &this_alt, auto &that_alt) {
-                                           using std::swap;
-                                           swap(this_alt.value_,
-                                                that_alt.value_);
-                                         },
-                                         *this,
-                                         that);
-        } else {
-          impl *lhs = this;
-          impl *rhs = lib::addressof(that);
-          if (lhs->move_nothrow() && !rhs->move_nothrow()) {
-            std::swap(lhs, rhs);
-          }
-          impl tmp(std::move(*rhs));
-          // EXTENSION: When the move construction of `lhs` into `rhs` throws
-          // and `tmp` is nothrow move constructible then we move `tmp` back
-          // into `rhs` and provide the strong exception safety guarentee.
-          try {
-            this->generic_construct(*rhs, std::move(*lhs));
-          } catch (...) {
-            if (tmp.move_nothrow()) {
-              this->generic_construct(*rhs, std::move(tmp));
-            }
-            throw;
-          }
-          this->generic_construct(*lhs, std::move(tmp));
-        }
-      }
-
-      private:
-      inline constexpr bool move_nothrow() const {
-        constexpr bool results[] = {
-            std::is_nothrow_move_constructible<Ts>::value...};
-        return this->valueless_by_exception() || results[this->index()];
-      }
-    };
-
-    template <typename... Ts>
-    struct overload;
-
-    template <>
-    struct overload<> {
-      void operator()() const;
-    };
-
-    template <typename T, typename... Ts>
-    struct overload<T, Ts...> : overload<Ts...> {
-      using overload<Ts...>::operator();
-      lib::identity<T> operator()(T) const;
-    };
-
-    template <typename T, typename... Ts>
-    using best_match_t =
-        typename std::result_of_t<overload<Ts...>(T &&)>::type;
-
-  }  // detail
-
-  template <typename... Ts>
-  class variant {
-    static_assert(0 < sizeof...(Ts),
-                  "variant must consist of at least one alternative.");
-
-    static_assert(detail::all({!std::is_array<Ts>::value...}),
-                  "variant can not have an array type as an alternative.");
-
-    static_assert(detail::all({!std::is_reference<Ts>::value...}),
-                  "variant can not have a reference type as an alternative.");
-
-    static_assert(detail::all({!std::is_void<Ts>::value...}),
-                  "variant can not have a void type as an alternative.");
-
-    public:
-    template <
-        typename Front = lib::type_pack_element_t<0, Ts...>,
-        std::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
-    inline constexpr variant() noexcept(
-        std::is_nothrow_default_constructible<Front>::value)
-        : impl_(in_place_index<0>) {}
-
-    variant(const variant &) = default;
-    variant(variant &&) = default;
-
-    template <typename Arg,
-              std::enable_if_t<!std::is_same<std::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              typename T = detail::best_match_t<Arg, Ts...>,
-              std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-              std::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
-    inline constexpr variant(Arg &&arg) noexcept(
-        std::is_nothrow_constructible<T, Arg>::value)
-        : impl_(in_place_index<I>, std::forward<Arg>(arg)) {}
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index<I>, std::forward<Args>(args)...) {}
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        std::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index<I>, il, std::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index<I>, std::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        std::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index<I>, il, std::forward<Args>(args)...) {}
-
-    ~variant() = default;
-
-    variant &operator=(const variant &) = default;
-    variant &operator=(variant &&) = default;
-
-    template <typename Arg,
-              std::enable_if_t<!std::is_same<std::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              typename T = detail::best_match_t<Arg, Ts...>,
-              std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-              std::enable_if_t<std::is_assignable<T &, Arg>::value &&
-                                   std::is_constructible<T, Arg>::value,
-                               int> = 0>
-    inline variant &operator=(Arg &&arg) noexcept(
-        (std::is_nothrow_assignable<T &, Arg>::value &&
-         std::is_nothrow_constructible<T, Arg>::value)) {
-      impl_.template assign<I>(std::forward<Arg>(arg));
-      return *this;
-    }
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline void emplace(Args &&... args) {
-      impl_.template emplace<I>(std::forward<Args>(args)...);
-    }
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        std::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline void emplace(std::initializer_list<Up> il, Args &&... args) {
-      impl_.template emplace<I>(il, std::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline void emplace(Args &&... args) {
-      impl_.template emplace<I>(std::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        std::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline void emplace(std::initializer_list<Up> il, Args &&... args) {
-      impl_.template emplace<I>(il, std::forward<Args>(args)...);
-    }
-
-    inline constexpr bool valueless_by_exception() const noexcept {
-      return impl_.valueless_by_exception();
-    }
-
-    inline constexpr std::size_t index() const noexcept {
-      return impl_.index();
-    }
-
-    template <
-        bool Dummy = true,
-        std::enable_if_t<detail::all({Dummy,
-                                      (std::is_move_constructible<Ts>::value &&
-                                       lib::is_swappable<Ts>::value)...}),
-                         int> = 0>
-    inline void swap(variant &that) noexcept(
-        detail::all({(std::is_nothrow_move_constructible<Ts>::value &&
-                      lib::is_nothrow_swappable<Ts>::value)...})) {
-      impl_.swap(that.impl_);
-    }
-
-    private:
-    detail::impl<Ts...> impl_;
-
-    friend struct detail::access::variant;
-    friend struct detail::visitation::variant;
-  };
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return v.index() == I;
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr auto &&generic_get(V &&v) {
-      return (holds_alternative<I>(v) ? (void)0 : throw bad_variant_access{}),
-             access::variant::get_alt<I>(std::forward<V>(v)).value_;
-    }
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
-      variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
-      variant<Ts...> &&v) {
-    return detail::generic_get<I>(std::move(v));
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
-      const variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
-      const variant<Ts...> &&v) {
-    return detail::generic_get<I>(std::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &get(variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &&get(variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(std::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &get(const variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &&get(const variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(std::move(v));
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr auto *generic_get_if(V *v) noexcept {
-      return v && holds_alternative<I>(*v)
-                 ? lib::addressof(access::variant::get_alt<I>(*v).value_)
-                 : nullptr;
-    }
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr std::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
-  get_if(variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr std::add_pointer_t<
-      const variant_alternative_t<I, variant<Ts...>>>
-  get_if(const variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr std::add_pointer_t<T>
-  get_if(variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr std::add_pointer_t<const T>
-  get_if(const variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator==(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (lhs.index() != rhs.index()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    return variant::visit_value_at(lhs.index(), std::equal_to<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator!=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (lhs.index() != rhs.index()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    return variant::visit_value_at(
-        lhs.index(), std::not_equal_to<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), std::less<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (lhs.valueless_by_exception()) return false;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), std::greater<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (lhs.valueless_by_exception()) return true;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), std::less_equal<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(
-        lhs.index(), std::greater_equal<>{}, lhs, rhs);
-  }
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
-    using detail::visitation::variant;
-    return (detail::all({!vs.valueless_by_exception()...})
-                ? (void)0
-                : throw bad_variant_access{}),
-           variant::visit_value(std::forward<Visitor>(visitor),
-                                std::forward<Vs>(vs)...);
-  }
-
-  struct monostate {};
-
-  inline constexpr bool operator<(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator>(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator<=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator>=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator==(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator!=(monostate, monostate) noexcept {
-    return false;
-  }
-
-  template <typename... Ts>
-  inline auto swap(variant<Ts...> &lhs,
-                   variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
-      -> decltype(lhs.swap(rhs)) {
-    lhs.swap(rhs);
-  }
-
-}  // namespace mpark
-
-namespace std {
-
-  template <typename... Ts>
-  struct hash<mpark::variant<Ts...>> {
-    using argument_type = mpark::variant<Ts...>;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &v) const {
-      using mpark::detail::visitation::variant;
-      std::size_t result =
-          v.valueless_by_exception()
-              ? 299792458  // Random value chosen by the universe upon creation
-              : variant::visit_alt(
-                    [](const auto &alt) {
-                      using alt_type = decay_t<decltype(alt)>;
-                      using value_type = typename alt_type::value_type;
-                      return hash<value_type>{}(alt.value_);
-                    },
-                    v);
-      return hash_combine(result, hash<std::size_t>{}(v.index()));
-    }
-
-    private:
-    static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
-      return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
-    }
-  };
-
-  template <>
-  struct hash<mpark::monostate> {
-    using argument_type = mpark::monostate;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &) const {
-      return 66740831;  // return a fundamentally attractive random value.
-    }
-  };
-
-}  // namespace std
-
-#endif  // MPARK_VARIANT_HPP

+ 0 - 1798
src/external/mpark-variant/v1.0.1/variant.hpp

@@ -1,1798 +0,0 @@
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2016
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANT_HPP
-#define MPARK_VARIANT_HPP
-
-/*
-   variant synopsis
-
-namespace std {
-
-  // 20.7.2, class template variant
-  template <class... Types>
-  class variant {
-  public:
-
-    // 20.7.2.1, constructors
-    constexpr variant() noexcept(see below);
-    variant(const variant&);
-    variant(variant&&) noexcept(see below);
-
-    template <class T> constexpr variant(T&&) noexcept(see below);
-
-    template <class T, class... Args>
-    constexpr explicit variant(in_place_type_t<T>, Args&&...);
-
-    template <class T, class U, class... Args>
-    constexpr explicit variant(
-        in_place_type_t<T>, initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    constexpr explicit variant(in_place_index_t<I>, Args&&...);
-
-    template <size_t I, class U, class... Args>
-    constexpr explicit variant(
-        in_place_index_t<I>, initializer_list<U>, Args&&...);
-
-    // 20.7.2.2, destructor
-    ~variant();
-
-    // 20.7.2.3, assignment
-    variant& operator=(const variant&);
-    variant& operator=(variant&&) noexcept(see below);
-
-    template <class T> variant& operator=(T&&) noexcept(see below);
-
-    // 20.7.2.4, modifiers
-    template <class T, class... Args>
-    T& emplace(Args&&...);
-
-    template <class T, class U, class... Args>
-    T& emplace(initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    variant_alternative<I, variant>& emplace(Args&&...);
-
-    template <size_t I, class U, class...  Args>
-    variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
-
-    // 20.7.2.5, value status
-    constexpr bool valueless_by_exception() const noexcept;
-    constexpr size_t index() const noexcept;
-
-    // 20.7.2.6, swap
-    void swap(variant&) noexcept(see below);
-  };
-
-  // 20.7.3, variant helper classes
-  template <class T> struct variant_size; // undefined
-
-  template <class T>
-  constexpr size_t variant_size_v = variant_size<T>::value;
-
-  template <class T> struct variant_size<const T>;
-  template <class T> struct variant_size<volatile T>;
-  template <class T> struct variant_size<const volatile T>;
-
-  template <class... Types>
-  struct variant_size<variant<Types...>>;
-
-  template <size_t I, class T> struct variant_alternative; // undefined
-
-  template <size_t I, class T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <size_t I, class T> struct variant_alternative<I, const T>;
-  template <size_t I, class T> struct variant_alternative<I, volatile T>;
-  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
-
-  template <size_t I, class... Types>
-  struct variant_alternative<I, variant<Types...>>;
-
-  constexpr size_t variant_npos = -1;
-
-  // 20.7.4, value access
-  template <class T, class... Types>
-  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&
-  get(variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&&
-  get(variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&
-  get(const variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&&
-  get(const variant<Types...>&&);
-
-  template <class T, class...  Types>
-  constexpr T& get(variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr T&& get(variant<Types...>&&);
-
-  template <class T, class... Types>
-  constexpr const T& get(const variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr const T&& get(const variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
-  get_if(variant<Types...>*) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
-  get_if(const variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<T>
-  get_if(variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<const T>
-  get_if(const variant<Types...>*) noexcept;
-
-  // 20.7.5, relational operators
-  template <class... Types>
-  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
-
-  // 20.7.6, visitation
-  template <class Visitor, class... Variants>
-  constexpr see below visit(Visitor&&, Variants&&...);
-
-  // 20.7.7, class monostate
-  struct monostate;
-
-  // 20.7.8, monostate relational operators
-  constexpr bool operator<(monostate, monostate) noexcept;
-  constexpr bool operator>(monostate, monostate) noexcept;
-  constexpr bool operator<=(monostate, monostate) noexcept;
-  constexpr bool operator>=(monostate, monostate) noexcept;
-  constexpr bool operator==(monostate, monostate) noexcept;
-  constexpr bool operator!=(monostate, monostate) noexcept;
-
-  // 20.7.9, specialized algorithms
-  template <class... Types>
-  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
-
-  // 20.7.10, class bad_variant_access
-  class bad_variant_access;
-
-  // 20.7.11, hash support
-  template <class T> struct hash;
-  template <class... Types> struct hash<variant<Types...>>;
-  template <> struct hash<monostate>;
-
-} // namespace std
-
-*/
-
-#include <array>
-#include <cstddef>
-#include <exception>
-#include <functional>
-#include <initializer_list>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2016
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_IN_PLACE_HPP
-#define MPARK_IN_PLACE_HPP
-
-#include <cstddef>
-
-namespace mpark {
-
-  struct in_place_t {
-    explicit in_place_t() = default;
-  };
-
-  constexpr in_place_t in_place{};
-
-  template <std::size_t I>
-  struct in_place_index_t {
-    explicit in_place_index_t() = default;
-  };
-
-  template <std::size_t I>
-  constexpr in_place_index_t<I> in_place_index{};
-
-  template <typename T>
-  struct in_place_type_t {
-    explicit in_place_type_t() = default;
-  };
-
-  template <typename T>
-  constexpr in_place_type_t<T> in_place_type{};
-
-}  // namespace mpark
-
-#endif  // MPARK_IN_PLACE_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2016
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_LIB_HPP
-#define MPARK_LIB_HPP
-
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2016
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_CONFIG_HPP
-#define MPARK_CONFIG_HPP
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#if __has_builtin(__builtin_addressof) || __GNUC__ >= 7
-#define MPARK_BUILTIN_ADDRESSOF
-#endif
-
-#if __has_builtin(__type_pack_element)
-#define MPARK_TYPE_PACK_ELEMENT
-#endif
-
-#endif  // MPARK_CONFIG_HPP
-
-
-namespace mpark {
-  namespace lib {
-
-    template <typename T>
-    struct identity { using type = T; };
-
-#ifdef MPARK_TYPE_PACK_ELEMENT
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = __type_pack_element<I, Ts...>;
-#else
-    template <std::size_t I, typename... Ts>
-    struct type_pack_element_impl {
-      private:
-      template <std::size_t, typename T>
-      struct indexed_type : identity<T> {};
-
-      template <std::size_t... Is>
-      inline static auto make_set(std::index_sequence<Is...>) {
-        struct set : indexed_type<Is, Ts>... {};
-        return set{};
-      }
-
-      template <typename T>
-      inline static std::enable_if<true, T> impl(indexed_type<I, T>);
-
-      inline static std::enable_if<false> impl(...);
-
-      public:
-      using type = decltype(impl(make_set(std::index_sequence_for<Ts...>{})));
-    };
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
-#endif
-
-    inline namespace cpp17 {
-
-      // <type_traits>
-      template <bool B>
-      using bool_constant = std::integral_constant<bool, B>;
-
-      template <typename...>
-      using void_t = void;
-
-      namespace detail {
-        namespace swappable {
-
-          using std::swap;
-
-          template <typename T>
-          struct is_swappable_impl {
-            private:
-            template <typename U,
-                      typename = decltype(swap(std::declval<U &>(),
-                                               std::declval<U &>()))>
-            inline static std::true_type test(int);
-
-            template <typename U>
-            inline static std::false_type test(...);
-
-            public:
-            using type = decltype(test<T>(0));
-          };
-
-          template <typename T>
-          using is_swappable = typename is_swappable_impl<T>::type;
-
-          template <typename T, bool = is_swappable<T>::value>
-          struct is_nothrow_swappable
-              : bool_constant<noexcept(
-                    swap(std::declval<T &>(), std::declval<T &>()))> {};
-
-          template <typename T>
-          struct is_nothrow_swappable<T, false> : std::false_type {};
-
-        }  // namespace swappable
-      }  // namespace detail
-
-      template <typename T>
-      using is_swappable = detail::swappable::is_swappable<T>;
-
-      template <typename T>
-      using is_nothrow_swappable = detail::swappable::is_nothrow_swappable<T>;
-
-      // <functional>
-#define RETURN(...) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-      template <typename F, typename... As>
-      inline constexpr auto invoke(F &&f, As &&... as)
-          RETURN(std::forward<F>(f)(std::forward<As>(as)...))
-
-      template <typename B, typename T, typename D>
-      inline constexpr auto invoke(T B::*pmv, D &&d)
-          RETURN(std::forward<D>(d).*pmv)
-
-      template <typename Pmv, typename Ptr>
-      inline constexpr auto invoke(Pmv pmv, Ptr &&ptr)
-          RETURN((*std::forward<Ptr>(ptr)).*pmv)
-
-      template <typename B, typename T, typename D, typename... As>
-      inline constexpr auto invoke(T B::*pmf, D &&d, As &&... as)
-          RETURN((std::forward<D>(d).*pmf)(std::forward<As>(as)...))
-
-      template <typename Pmf, typename Ptr, typename... As>
-      inline constexpr auto invoke(Pmf pmf, Ptr &&ptr, As &&... as)
-          RETURN(((*std::forward<Ptr>(ptr)).*pmf)(std::forward<As>(as)...))
-
-#undef RETURN
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct invoke_result {};
-
-        template <typename F, typename... Args>
-        struct invoke_result<void_t<decltype(lib::invoke(
-                                 std::declval<F>(), std::declval<Args>()...))>,
-                             F,
-                             Args...>
-            : identity<decltype(
-                  lib::invoke(std::declval<F>(), std::declval<Args>()...))> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using invoke_result = detail::invoke_result<void, F, Args...>;
-
-      template <typename F, typename... Args>
-      using invoke_result_t = typename invoke_result<F, Args...>::type;
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct is_invocable : std::false_type {};
-
-        template <typename F, typename... Args>
-        struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
-            : std::true_type {};
-
-        template <typename Void, typename, typename, typename...>
-        struct is_invocable_r : std::false_type {};
-
-        template <typename R, typename F, typename... Args>
-        struct is_invocable_r<void_t<invoke_result_t<F, Args...>>,
-                              R,
-                              F,
-                              Args...>
-            : std::is_convertible<invoke_result_t<F, Args...>, R> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using is_invocable = detail::is_invocable<void, F, Args...>;
-
-      template <typename R, typename F, typename... Args>
-      using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
-
-      // <memory>
-#ifdef MPARK_BUILTIN_ADDRESSOF
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return __builtin_addressof(arg);
-      }
-#else
-      namespace detail {
-
-        namespace has_addressof_impl {
-
-          struct fail;
-
-          template <typename T>
-          inline fail operator&(T &&);
-
-          template <typename T>
-          inline static constexpr bool impl() {
-            return (std::is_class<T>::value || std::is_union<T>::value) &&
-                   !std::is_same<decltype(&std::declval<T &>()), fail>::value;
-          }
-
-        }  // namespace has_addressof_impl
-
-        template <typename T>
-        using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
-
-      }  // namespace detail
-
-      template <typename T,
-                std::enable_if_t<detail::has_addressof<T>::value, int> = 0>
-      inline T *addressof(T &arg) {
-        return std::addressof(arg);
-      }
-
-      template <typename T,
-                std::enable_if_t<!detail::has_addressof<T>::value, int> = 0>
-      inline constexpr T *addressof(T &arg) {
-        return &arg;
-      }
-#endif
-
-      template <typename T>
-      inline const T *addressof(const T &&) = delete;
-
-    }  // namespace cpp17
-
-  }  // namespace lib
-}  // namespace mpark
-
-#endif  // MPARK_LIB_HPP
-
-
-namespace mpark {
-
-  class bad_variant_access : public std::exception {
-    public:
-    virtual const char *what() const noexcept { return "bad_variant_access"; }
-  };
-
-  template <typename... Ts>
-  class variant;
-
-  template <typename T>
-  struct variant_size;
-
-  template <typename T>
-  constexpr std::size_t variant_size_v = variant_size<T>::value;
-
-  template <typename T>
-  struct variant_size<const T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<volatile T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<const volatile T> : variant_size<T> {};
-
-  template <typename... Ts>
-  struct variant_size<variant<Ts...>>
-      : std::integral_constant<std::size_t, sizeof...(Ts)> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative;
-
-  template <std::size_t I, typename T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const T>
-      : std::add_const<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, volatile T>
-      : std::add_volatile<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const volatile T>
-      : std::add_cv<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename... Ts>
-  struct variant_alternative<I, variant<Ts...>>
-      : lib::identity<lib::type_pack_element_t<I, Ts...>> {
-    static_assert(I < sizeof...(Ts),
-                  "`variant_alternative` index out of range.");
-  };
-
-  constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
-
-  namespace detail {
-
-    inline constexpr bool all(std::initializer_list<bool> bs) {
-      for (bool b : bs) {
-        if (!b) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    constexpr std::size_t not_found = static_cast<std::size_t>(-1);
-    constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
-
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      constexpr bool matches[] = {std::is_same<T, Ts>::value...};
-      std::size_t result = not_found;
-      for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
-        if (matches[i]) {
-          if (result != not_found) {
-            return ambiguous;
-          }
-          result = i;
-        }
-      }
-      return result;
-    }
-
-    template <std::size_t I>
-    using find_index_sfinae_impl =
-        std::enable_if_t<I != not_found && I != ambiguous,
-                         std::integral_constant<std::size_t, I>>;
-
-    template <typename T, typename... Ts>
-    using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
-
-    template <std::size_t I>
-    struct find_index_checked_impl : std::integral_constant<std::size_t, I> {
-      static_assert(I != not_found, "the specified type is not found.");
-      static_assert(I != ambiguous, "the specified type is ambiguous.");
-    };
-
-    template <typename T, typename... Ts>
-    using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
-
-    struct valueless_t {};
-
-    enum class Trait { TriviallyAvailable, Available, Unavailable };
-
-    template <typename T,
-              template <typename> class IsTriviallyAvailable,
-              template <typename> class IsAvailable>
-    inline constexpr Trait trait() {
-      return IsTriviallyAvailable<T>::value
-                 ? Trait::TriviallyAvailable
-                 : IsAvailable<T>::value ? Trait::Available
-                                         : Trait::Unavailable;
-    }
-
-    inline constexpr Trait common_trait(std::initializer_list<Trait> traits) {
-      Trait result = Trait::TriviallyAvailable;
-      for (Trait t : traits) {
-        if (static_cast<int>(t) > static_cast<int>(result)) {
-          result = t;
-        }
-      }
-      return result;
-    }
-
-    template <typename... Ts>
-    struct traits {
-      static constexpr Trait copy_constructible_trait =
-          common_trait({trait<Ts,
-                              std::is_trivially_copy_constructible,
-                              std::is_copy_constructible>()...});
-
-      static constexpr Trait move_constructible_trait =
-          common_trait({trait<Ts,
-                              std::is_trivially_move_constructible,
-                              std::is_move_constructible>()...});
-
-      static constexpr Trait copy_assignable_trait =
-          common_trait({copy_constructible_trait,
-                        move_constructible_trait,
-                        trait<Ts,
-                              std::is_trivially_copy_assignable,
-                              std::is_copy_assignable>()...});
-
-      static constexpr Trait move_assignable_trait =
-          common_trait({move_constructible_trait,
-                        trait<Ts,
-                              std::is_trivially_move_assignable,
-                              std::is_move_assignable>()...});
-
-      static constexpr Trait destructible_trait =
-          common_trait({trait<Ts,
-                              std::is_trivially_destructible,
-                              std::is_destructible>()...});
-    };
-
-    namespace access {
-
-      struct recursive_union {
-        template <typename V>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
-          return std::forward<V>(v).head_;
-        }
-
-        template <typename V, std::size_t I>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
-          return get_alt(std::forward<V>(v).tail_, in_place_index<I - 1>);
-        }
-      };
-
-      struct base {
-        template <std::size_t I, typename V>
-        inline static constexpr auto &&get_alt(V &&v) {
-          return recursive_union::get_alt(std::forward<V>(v).data_,
-                                          in_place_index<I>);
-        }
-      };
-
-      struct variant {
-        template <std::size_t I, typename V>
-        inline static constexpr auto &&get_alt(V &&v) {
-          return base::get_alt<I>(std::forward<V>(v).impl_);
-        }
-      };
-
-    }  // namespace access
-
-    namespace visitation {
-
-      struct base {
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_alt_at(std::size_t index,
-                                                            Visitor &&visitor,
-                                                            Vs &&... vs) {
-          constexpr auto fdiagonal =
-              make_fdiagonal<Visitor &&,
-                             decltype(std::forward<Vs>(vs).as_base())...>();
-          return fdiagonal[index](std::forward<Visitor>(visitor),
-                                  std::forward<Vs>(vs).as_base()...);
-        }
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_alt(Visitor &&visitor,
-                                                         Vs &&... vs) {
-          constexpr auto fmatrix =
-              make_fmatrix<Visitor &&,
-                           decltype(std::forward<Vs>(vs).as_base())...>();
-          return at(fmatrix, vs.index()...)(std::forward<Visitor>(visitor),
-                                            std::forward<Vs>(vs).as_base()...);
-        }
-
-        private:
-        template <typename T>
-        inline static constexpr const T &at(const T &elem) {
-          return elem;
-        }
-
-        template <typename T, std::size_t N, typename... Is>
-        inline static constexpr auto &&at(const std::array<T, N> &elems,
-                                          std::size_t i,
-                                          Is... is) {
-          return at(elems[i], is...);
-        }
-
-        template <typename F, typename... Fs>
-        inline static constexpr void visit_visitor_return_type_check() {
-          static_assert(all({std::is_same<F, Fs>::value...}),
-                        "`mpark::visit` requires the visitor to have a single "
-                        "return type.");
-        }
-
-        template <typename... Fs>
-        inline static constexpr auto make_farray(Fs &&... fs) {
-          visit_visitor_return_type_check<std::decay_t<Fs>...>();
-          using result = std::array<std::common_type_t<std::decay_t<Fs>...>,
-                                    sizeof...(Fs)>;
-          return result{{std::forward<Fs>(fs)...}};
-        }
-
-        template <std::size_t... Is>
-        struct dispatcher {
-          template <typename F, typename... Vs>
-          inline static constexpr decltype(auto) dispatch(F f, Vs... vs) {
-            return lib::invoke(
-                static_cast<F>(f),
-                access::base::get_alt<Is>(static_cast<Vs>(vs))...);
-          }
-        };
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_dispatch(std::index_sequence<Is...>) {
-          return &dispatcher<Is...>::template dispatch<F, Vs...>;
-        }
-
-        template <std::size_t I, typename F, typename... Vs>
-        inline static constexpr auto make_fdiagonal_impl() {
-          return make_dispatch<F, Vs...>(
-              std::index_sequence<(lib::identity<Vs>{}, I)...>{});
-        }
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_fdiagonal_impl(
-            std::index_sequence<Is...>) {
-          return base::make_farray(make_fdiagonal_impl<Is, F, Vs...>()...);
-        }
-
-        template <typename F, typename V, typename... Vs>
-        inline static constexpr auto make_fdiagonal() {
-          constexpr std::size_t N = std::decay_t<V>::size();
-          static_assert(all({(N == std::decay_t<Vs>::size())...}),
-                        "all of the variants must be the same size.");
-          return make_fdiagonal_impl<F, V, Vs...>(
-              std::make_index_sequence<N>{});
-        }
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_fmatrix_impl(
-            std::index_sequence<Is...> is) {
-          return make_dispatch<F, Vs...>(is);
-        }
-
-        template <typename F,
-                  typename... Vs,
-                  std::size_t... Is,
-                  std::size_t... Js,
-                  typename... Ls>
-        inline static constexpr auto make_fmatrix_impl(
-            std::index_sequence<Is...>, std::index_sequence<Js...>, Ls... ls) {
-          return base::make_farray(make_fmatrix_impl<F, Vs...>(
-              std::index_sequence<Is..., Js>{}, ls...)...);
-        }
-
-        template <typename F, typename... Vs>
-        inline static constexpr auto make_fmatrix() {
-          return make_fmatrix_impl<F, Vs...>(
-              std::index_sequence<>{},
-              std::make_index_sequence<std::decay_t<Vs>::size()>{}...);
-        }
-      };
-
-      struct variant {
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_alt_at(std::size_t index,
-                                                            Visitor &&visitor,
-                                                            Vs &&... vs) {
-          return base::visit_alt_at(index,
-                                    std::forward<Visitor>(visitor),
-                                    std::forward<Vs>(vs).impl_...);
-        }
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_alt(Visitor &&visitor,
-                                                         Vs &&... vs) {
-          return base::visit_alt(std::forward<Visitor>(visitor),
-                                 std::forward<Vs>(vs).impl_...);
-        }
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_value_at(std::size_t index,
-                                                              Visitor &&visitor,
-                                                              Vs &&... vs) {
-          return visit_alt_at(
-              index,
-              make_value_visitor(std::forward<Visitor>(visitor)),
-              std::forward<Vs>(vs)...);
-        }
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr decltype(auto) visit_value(Visitor &&visitor,
-                                                           Vs &&... vs) {
-          return visit_alt(make_value_visitor(std::forward<Visitor>(visitor)),
-                           std::forward<Vs>(vs)...);
-        }
-
-        private:
-        template <typename Visitor, typename... Values>
-        inline static constexpr void visit_exhaustive_visitor_check() {
-          static_assert(
-              lib::is_invocable<Visitor, Values...>::value,
-              "`mpark::visit` requires the visitor to be exhaustive.");
-        }
-
-        template <typename Visitor>
-        struct value_visitor {
-          template <typename... Alts>
-          inline constexpr decltype(auto) operator()(Alts &&... alts) const {
-            visit_exhaustive_visitor_check<
-                Visitor,
-                decltype((std::forward<Alts>(alts).value_))...>();
-            return lib::invoke(std::forward<Visitor>(visitor_),
-                               std::forward<Alts>(alts).value_...);
-          }
-          Visitor &&visitor_;
-        };
-
-        template <typename Visitor>
-        inline static constexpr auto make_value_visitor(Visitor &&visitor) {
-          return value_visitor<Visitor>{std::forward<Visitor>(visitor)};
-        }
-      };
-
-    }  // namespace visitation
-
-    template <std::size_t Index, typename T>
-    struct alt {
-      using value_type = T;
-
-      template <typename... Args>
-      inline explicit constexpr alt(in_place_t, Args &&... args)
-          : value_(std::forward<Args>(args)...) {}
-
-      value_type value_;
-    };
-
-    template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
-    union recursive_union;
-
-    template <Trait DestructibleTrait, std::size_t Index>
-    union recursive_union<DestructibleTrait, Index> {};
-
-#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)  \
-  template <std::size_t Index, typename T, typename... Ts>             \
-  union recursive_union<destructible_trait, Index, T, Ts...> {         \
-    public:                                                            \
-    inline explicit constexpr recursive_union(valueless_t) noexcept    \
-        : dummy_{} {}                                                  \
-                                                                       \
-    template <typename... Args>                                        \
-    inline explicit constexpr recursive_union(in_place_index_t<0>,     \
-                                              Args &&... args)         \
-        : head_(in_place, std::forward<Args>(args)...) {}              \
-                                                                       \
-    template <std::size_t I, typename... Args>                         \
-    inline explicit constexpr recursive_union(in_place_index_t<I>,     \
-                                              Args &&... args)         \
-        : tail_(in_place_index<I - 1>, std::forward<Args>(args)...) {} \
-                                                                       \
-    recursive_union(const recursive_union &) = default;                \
-    recursive_union(recursive_union &&) = default;                     \
-                                                                       \
-    destructor                                                         \
-                                                                       \
-    recursive_union &operator=(const recursive_union &) = default;     \
-    recursive_union &operator=(recursive_union &&) = default;          \
-                                                                       \
-    private:                                                           \
-    char dummy_;                                                       \
-    alt<Index, T> head_;                                               \
-    recursive_union<destructible_trait, Index + 1, Ts...> tail_;       \
-                                                                       \
-    friend struct access::recursive_union;                             \
-  }
-
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
-                                  ~recursive_union() = default;);
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
-                                  ~recursive_union() {});
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
-                                  ~recursive_union() = delete;);
-
-#undef _MPARK_VARIANT_UNION
-
-    using index_t = unsigned int;
-
-    template <Trait DestructibleTrait, typename... Ts>
-    class base {
-      public:
-      inline explicit constexpr base(valueless_t tag) noexcept
-          : data_(tag), index_(static_cast<index_t>(-1)) {}
-
-      template <std::size_t I, typename... Args>
-      inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
-          : data_(in_place_index<I>, std::forward<Args>(args)...), index_(I) {}
-
-      inline constexpr bool valueless_by_exception() const noexcept {
-        return index_ == static_cast<index_t>(-1);
-      }
-
-      inline constexpr std::size_t index() const noexcept {
-        return valueless_by_exception() ? variant_npos : index_;
-      }
-
-      protected:
-      inline constexpr base &as_base() & { return *this; }
-      inline constexpr base &&as_base() && { return std::move(*this); }
-      inline constexpr const base &as_base() const & { return *this; }
-      inline constexpr const base &&as_base() const && { return std::move(*this); }
-
-      inline static constexpr std::size_t size() { return sizeof...(Ts); }
-
-      recursive_union<DestructibleTrait, 0, Ts...> data_;
-      index_t index_;
-
-      friend struct access::base;
-      friend struct visitation::base;
-    };
-
-    template <typename Traits, Trait = Traits::destructible_trait>
-    class destructor;
-
-#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
-  template <typename... Ts>                                               \
-  class destructor<traits<Ts...>, destructible_trait>                     \
-      : public base<destructible_trait, Ts...> {                          \
-    using super = base<destructible_trait, Ts...>;                        \
-                                                                          \
-    public:                                                               \
-    using super::super;                                                   \
-    using super::operator=;                                               \
-                                                                          \
-    destructor(const destructor &) = default;                             \
-    destructor(destructor &&) = default;                                  \
-    definition                                                            \
-    destructor &operator=(const destructor &) = default;                  \
-    destructor &operator=(destructor &&) = default;                       \
-                                                                          \
-    protected:                                                            \
-    inline destroy                                                        \
-  }
-
-    MPARK_VARIANT_DESTRUCTOR(Trait::TriviallyAvailable,
-                             ~destructor() = default;,
-                             void destroy() noexcept {
-                               this->index_ = static_cast<index_t>(-1);
-                             });
-
-    MPARK_VARIANT_DESTRUCTOR(Trait::Available,
-                             ~destructor() { destroy(); },
-                             void destroy() noexcept {
-                               if (!this->valueless_by_exception()) {
-                                 visitation::base::visit_alt(
-                                     [](auto &alt) noexcept {
-                                       using alt_type =
-                                           std::decay_t<decltype(alt)>;
-                                       alt.~alt_type();
-                                     },
-                                     *this);
-                               }
-                               this->index_ = static_cast<index_t>(-1);
-                             });
-
-    MPARK_VARIANT_DESTRUCTOR(Trait::Unavailable,
-                             ~destructor() = delete;,
-                             void destroy() noexcept = delete;);
-
-#undef MPARK_VARIANT_DESTRUCTOR
-
-    template <typename Traits>
-    class constructor : public destructor<Traits> {
-      using super = destructor<Traits>;
-
-      public:
-      using super::super;
-      using super::operator=;
-
-      protected:
-      template <std::size_t I, typename T, typename... Args>
-      inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
-        ::new (static_cast<void *>(lib::addressof(a)))
-            alt<I, T>(in_place, std::forward<Args>(args)...);
-        return a.value_;
-      }
-
-      template <typename Rhs>
-      inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
-        lhs.destroy();
-        if (!rhs.valueless_by_exception()) {
-          visitation::base::visit_alt_at(
-              rhs.index(),
-              [](auto &lhs_alt, auto &&rhs_alt) {
-                constructor::construct_alt(
-                    lhs_alt, std::forward<decltype(rhs_alt)>(rhs_alt).value_);
-              },
-              lhs,
-              std::forward<Rhs>(rhs));
-          lhs.index_ = rhs.index_;
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_constructible_trait>
-    class move_constructor;
-
-#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class move_constructor<traits<Ts...>, move_constructible_trait>            \
-      : public constructor<traits<Ts...>> {                                  \
-    using super = constructor<traits<Ts...>>;                                \
-                                                                             \
-    public:                                                                  \
-    using super::super;                                                      \
-    using super::operator=;                                                  \
-                                                                             \
-    move_constructor(const move_constructor &) = default;                    \
-    definition                                                               \
-    ~move_constructor() = default;                                           \
-    move_constructor &operator=(const move_constructor &) = default;         \
-    move_constructor &operator=(move_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        move_constructor(move_constructor &&that) = default;);
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Available,
-        move_constructor(move_constructor &&that) noexcept(
-            all({std::is_nothrow_move_constructible<Ts>::value...}))
-            : move_constructor(valueless_t{}) {
-          this->generic_construct(*this, std::move(that));
-        });
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Unavailable,
-        move_constructor(move_constructor &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_CONSTRUCTOR
-
-    template <typename Traits, Trait = Traits::copy_constructible_trait>
-    class copy_constructor;
-
-#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
-      : public move_constructor<traits<Ts...>> {                             \
-    using super = move_constructor<traits<Ts...>>;                           \
-                                                                             \
-    public:                                                                  \
-    using super::super;                                                      \
-    using super::operator=;                                                  \
-                                                                             \
-    definition                                                               \
-    copy_constructor(copy_constructor &&) = default;                         \
-    ~copy_constructor() = default;                                           \
-    copy_constructor &operator=(const copy_constructor &) = default;         \
-    copy_constructor &operator=(copy_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        copy_constructor(const copy_constructor &that) = default;);
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Available,
-        copy_constructor(const copy_constructor &that)
-            : copy_constructor(valueless_t{}) {
-          this->generic_construct(*this, that);
-        });
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Unavailable,
-        copy_constructor(const copy_constructor &) = delete;);
-
-#undef MPARK_VARIANT_COPY_CONSTRUCTOR
-
-    template <typename Traits>
-    class assignment : public copy_constructor<Traits> {
-      using super = copy_constructor<Traits>;
-
-      public:
-      using super::super;
-      using super::operator=;
-
-      template <std::size_t I, typename... Args>
-      inline auto &emplace(Args &&... args) {
-        this->destroy();
-        auto &result = this->construct_alt(access::base::get_alt<I>(*this),
-                                           std::forward<Args>(args)...);
-        this->index_ = I;
-        return result;
-      }
-
-      protected:
-      template <bool CopyAssign, std::size_t I, typename T, typename Arg>
-      inline void assign_alt(alt<I, T> &a,
-                             Arg &&arg,
-                             lib::bool_constant<CopyAssign> tag) {
-        if (this->index() == I) {
-          a.value_ = std::forward<Arg>(arg);
-        } else {
-          struct {
-            void operator()(std::true_type) const {
-              this_->emplace<I>(T(std::forward<Arg>(arg_)));
-            }
-            void operator()(std::false_type) const {
-              this_->emplace<I>(std::forward<Arg>(arg_));
-            }
-            assignment *this_;
-            Arg &&arg_;
-          } impl{this, std::forward<Arg>(arg)};
-          impl(tag);
-        }
-      }
-
-      template <typename That>
-      inline void generic_assign(That &&that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (that.valueless_by_exception()) {
-          this->destroy();
-        } else {
-          visitation::base::visit_alt_at(
-              that.index(),
-              [this](auto &this_alt, auto &&that_alt) {
-                this->assign_alt(
-                    this_alt,
-                    std::forward<decltype(that_alt)>(that_alt).value_,
-                    std::is_lvalue_reference<That>{});
-              },
-              *this,
-              std::forward<That>(that));
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_assignable_trait>
-    class move_assignment;
-
-#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class move_assignment<traits<Ts...>, move_assignable_trait>            \
-      : public assignment<traits<Ts...>> {                               \
-    using super = assignment<traits<Ts...>>;                             \
-                                                                         \
-    public:                                                              \
-    using super::super;                                                  \
-    using super::operator=;                                              \
-                                                                         \
-    move_assignment(const move_assignment &) = default;                  \
-    move_assignment(move_assignment &&) = default;                       \
-    ~move_assignment() = default;                                        \
-    move_assignment &operator=(const move_assignment &) = default;       \
-    definition                                                           \
-  }
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        move_assignment &operator=(move_assignment &&that) = default;);
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Available,
-        move_assignment &
-        operator=(move_assignment &&that) noexcept(
-            all({std::is_nothrow_move_constructible<Ts>::value &&
-                 std::is_nothrow_move_assignable<Ts>::value...})) {
-          this->generic_assign(std::move(that));
-          return *this;
-        });
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Unavailable,
-        move_assignment &operator=(move_assignment &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_ASSIGNMENT
-
-    template <typename Traits, Trait = Traits::copy_assignable_trait>
-    class copy_assignment;
-
-#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
-      : public move_assignment<traits<Ts...>> {                          \
-    using super = move_assignment<traits<Ts...>>;                        \
-                                                                         \
-    public:                                                              \
-    using super::super;                                                  \
-    using super::operator=;                                              \
-                                                                         \
-    copy_assignment(const copy_assignment &) = default;                  \
-    copy_assignment(copy_assignment &&) = default;                       \
-    ~copy_assignment() = default;                                        \
-    definition                                                           \
-    copy_assignment &operator=(copy_assignment &&) = default;            \
-  }
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        copy_assignment &operator=(const copy_assignment &that) = default;);
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Available,
-        copy_assignment &operator=(const copy_assignment &that) {
-          this->generic_assign(that);
-          return *this;
-        });
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Unavailable,
-        copy_assignment &operator=(const copy_assignment &) = delete;);
-
-#undef MPARK_VARIANT_COPY_ASSIGNMENT
-
-    template <typename... Ts>
-    class impl : public copy_assignment<traits<Ts...>> {
-      using super = copy_assignment<traits<Ts...>>;
-
-      public:
-      using super::super;
-      using super::operator=;
-
-      template <std::size_t I, typename Arg>
-      inline void assign(Arg &&arg) {
-        this->assign_alt(access::base::get_alt<I>(*this),
-                         std::forward<Arg>(arg),
-                         std::false_type{});
-      }
-
-      inline void swap(impl &that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (this->index() == that.index()) {
-          visitation::base::visit_alt_at(this->index(),
-                                         [](auto &this_alt, auto &that_alt) {
-                                           using std::swap;
-                                           swap(this_alt.value_,
-                                                that_alt.value_);
-                                         },
-                                         *this,
-                                         that);
-        } else {
-          impl *lhs = this;
-          impl *rhs = lib::addressof(that);
-          if (lhs->move_nothrow() && !rhs->move_nothrow()) {
-            std::swap(lhs, rhs);
-          }
-          impl tmp(std::move(*rhs));
-          // EXTENSION: When the move construction of `lhs` into `rhs` throws
-          // and `tmp` is nothrow move constructible then we move `tmp` back
-          // into `rhs` and provide the strong exception safety guarentee.
-          try {
-            this->generic_construct(*rhs, std::move(*lhs));
-          } catch (...) {
-            if (tmp.move_nothrow()) {
-              this->generic_construct(*rhs, std::move(tmp));
-            }
-            throw;
-          }
-          this->generic_construct(*lhs, std::move(tmp));
-        }
-      }
-
-      private:
-      inline constexpr bool move_nothrow() const {
-        constexpr bool results[] = {
-            std::is_nothrow_move_constructible<Ts>::value...};
-        return this->valueless_by_exception() || results[this->index()];
-      }
-    };
-
-    template <typename... Ts>
-    struct overload;
-
-    template <>
-    struct overload<> {
-      void operator()() const;
-    };
-
-    template <typename T, typename... Ts>
-    struct overload<T, Ts...> : overload<Ts...> {
-      using overload<Ts...>::operator();
-      lib::identity<T> operator()(T) const;
-    };
-
-    template <typename T, typename... Ts>
-    using best_match_t =
-        typename lib::invoke_result_t<overload<Ts...>, T &&>::type;
-
-  }  // detail
-
-  template <typename... Ts>
-  class variant {
-    static_assert(0 < sizeof...(Ts),
-                  "variant must consist of at least one alternative.");
-
-    static_assert(detail::all({!std::is_array<Ts>::value...}),
-                  "variant can not have an array type as an alternative.");
-
-    static_assert(detail::all({!std::is_reference<Ts>::value...}),
-                  "variant can not have a reference type as an alternative.");
-
-    static_assert(detail::all({!std::is_void<Ts>::value...}),
-                  "variant can not have a void type as an alternative.");
-
-    public:
-    template <
-        typename Front = lib::type_pack_element_t<0, Ts...>,
-        std::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
-    inline constexpr variant() noexcept(
-        std::is_nothrow_default_constructible<Front>::value)
-        : impl_(in_place_index<0>) {}
-
-    variant(const variant &) = default;
-    variant(variant &&) = default;
-
-    template <typename Arg,
-              std::enable_if_t<!std::is_same<std::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              typename T = detail::best_match_t<Arg, Ts...>,
-              std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-              std::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
-    inline constexpr variant(Arg &&arg) noexcept(
-        std::is_nothrow_constructible<T, Arg>::value)
-        : impl_(in_place_index<I>, std::forward<Arg>(arg)) {}
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index<I>, std::forward<Args>(args)...) {}
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        std::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index<I>, il, std::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index<I>, std::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        std::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index<I>, il, std::forward<Args>(args)...) {}
-
-    ~variant() = default;
-
-    variant &operator=(const variant &) = default;
-    variant &operator=(variant &&) = default;
-
-    template <typename Arg,
-              std::enable_if_t<!std::is_same<std::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              typename T = detail::best_match_t<Arg, Ts...>,
-              std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-              std::enable_if_t<std::is_assignable<T &, Arg>::value &&
-                                   std::is_constructible<T, Arg>::value,
-                               int> = 0>
-    inline variant &operator=(Arg &&arg) noexcept(
-        (std::is_nothrow_assignable<T &, Arg>::value &&
-         std::is_nothrow_constructible<T, Arg>::value)) {
-      impl_.template assign<I>(std::forward<Arg>(arg));
-      return *this;
-    }
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(std::forward<Args>(args)...);
-    }
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        std::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, std::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        std::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(std::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        std::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, std::forward<Args>(args)...);
-    }
-
-    inline constexpr bool valueless_by_exception() const noexcept {
-      return impl_.valueless_by_exception();
-    }
-
-    inline constexpr std::size_t index() const noexcept {
-      return impl_.index();
-    }
-
-    template <
-        bool Dummy = true,
-        std::enable_if_t<detail::all({Dummy,
-                                      (std::is_move_constructible<Ts>::value &&
-                                       lib::is_swappable<Ts>::value)...}),
-                         int> = 0>
-    inline void swap(variant &that) noexcept(
-        detail::all({(std::is_nothrow_move_constructible<Ts>::value &&
-                      lib::is_nothrow_swappable<Ts>::value)...})) {
-      impl_.swap(that.impl_);
-    }
-
-    private:
-    detail::impl<Ts...> impl_;
-
-    friend struct detail::access::variant;
-    friend struct detail::visitation::variant;
-  };
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return v.index() == I;
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr auto &&generic_get(V &&v) {
-      return (holds_alternative<I>(v) ? (void)0 : throw bad_variant_access{}),
-             access::variant::get_alt<I>(std::forward<V>(v)).value_;
-    }
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
-      variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
-      variant<Ts...> &&v) {
-    return detail::generic_get<I>(std::move(v));
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
-      const variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
-      const variant<Ts...> &&v) {
-    return detail::generic_get<I>(std::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &get(variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &&get(variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(std::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &get(const variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &&get(const variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(std::move(v));
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr auto *generic_get_if(V *v) noexcept {
-      return v && holds_alternative<I>(*v)
-                 ? lib::addressof(access::variant::get_alt<I>(*v).value_)
-                 : nullptr;
-    }
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr std::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
-  get_if(variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr std::add_pointer_t<
-      const variant_alternative_t<I, variant<Ts...>>>
-  get_if(const variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr std::add_pointer_t<T>
-  get_if(variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr std::add_pointer_t<const T>
-  get_if(const variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator==(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (lhs.index() != rhs.index()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    return variant::visit_value_at(lhs.index(), std::equal_to<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator!=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (lhs.index() != rhs.index()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    return variant::visit_value_at(
-        lhs.index(), std::not_equal_to<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), std::less<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (lhs.valueless_by_exception()) return false;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), std::greater<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (lhs.valueless_by_exception()) return true;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), std::less_equal<>{}, lhs, rhs);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(
-        lhs.index(), std::greater_equal<>{}, lhs, rhs);
-  }
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
-    using detail::visitation::variant;
-    return (detail::all({!vs.valueless_by_exception()...})
-                ? (void)0
-                : throw bad_variant_access{}),
-           variant::visit_value(std::forward<Visitor>(visitor),
-                                std::forward<Vs>(vs)...);
-  }
-
-  struct monostate {};
-
-  inline constexpr bool operator<(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator>(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator<=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator>=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator==(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator!=(monostate, monostate) noexcept {
-    return false;
-  }
-
-  template <typename... Ts>
-  inline auto swap(variant<Ts...> &lhs,
-                   variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
-      -> decltype(lhs.swap(rhs)) {
-    lhs.swap(rhs);
-  }
-
-  namespace detail {
-
-    template <typename T, typename...>
-    using enabled_type = T;
-
-    namespace hash {
-
-      template <typename Hash, typename Key>
-      constexpr bool meets_requirements() {
-        return std::is_copy_constructible<Hash>::value &&
-               std::is_move_constructible<Hash>::value &&
-               lib::is_invocable_r<std::size_t, Hash, const Key &>::value;
-      }
-
-      template <typename Key>
-      constexpr bool is_enabled() {
-        using Hash = std::hash<Key>;
-        return meets_requirements<Hash, Key>() &&
-               std::is_default_constructible<Hash>::value &&
-               std::is_copy_assignable<Hash>::value &&
-               std::is_move_assignable<Hash>::value;
-      }
-
-    }  // namespace hash
-
-  }  // namespace detail
-
-}  // namespace mpark
-
-namespace std {
-
-  template <typename... Ts>
-  struct hash<mpark::detail::enabled_type<
-      mpark::variant<Ts...>,
-      std::enable_if_t<mpark::detail::all(
-          {mpark::detail::hash::is_enabled<std::remove_const_t<Ts>>()...})>>> {
-    using argument_type = mpark::variant<Ts...>;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &v) const {
-      using mpark::detail::visitation::variant;
-      std::size_t result =
-          v.valueless_by_exception()
-              ? 299792458  // Random value chosen by the universe upon creation
-              : variant::visit_alt(
-                    [](const auto &alt) {
-                      using alt_type = decay_t<decltype(alt)>;
-                      using value_type =
-                          std::remove_const_t<typename alt_type::value_type>;
-                      return hash<value_type>{}(alt.value_);
-                    },
-                    v);
-      return hash_combine(result, hash<std::size_t>{}(v.index()));
-    }
-
-    private:
-    static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
-      return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
-    }
-  };
-
-  template <>
-  struct hash<mpark::monostate> {
-    using argument_type = mpark::monostate;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &) const noexcept {
-      return 66740831;  // return a fundamentally attractive random value.
-    }
-  };
-
-}  // namespace std
-
-#endif  // MPARK_VARIANT_HPP

+ 0 - 2360
src/external/mpark-variant/v1.1.0/variant.hpp

@@ -1,2360 +0,0 @@
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANT_HPP
-#define MPARK_VARIANT_HPP
-
-/*
-   variant synopsis
-
-namespace std {
-
-  // 20.7.2, class template variant
-  template <class... Types>
-  class variant {
-  public:
-
-    // 20.7.2.1, constructors
-    constexpr variant() noexcept(see below);
-    variant(const variant&);
-    variant(variant&&) noexcept(see below);
-
-    template <class T> constexpr variant(T&&) noexcept(see below);
-
-    template <class T, class... Args>
-    constexpr explicit variant(in_place_type_t<T>, Args&&...);
-
-    template <class T, class U, class... Args>
-    constexpr explicit variant(
-        in_place_type_t<T>, initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    constexpr explicit variant(in_place_index_t<I>, Args&&...);
-
-    template <size_t I, class U, class... Args>
-    constexpr explicit variant(
-        in_place_index_t<I>, initializer_list<U>, Args&&...);
-
-    // 20.7.2.2, destructor
-    ~variant();
-
-    // 20.7.2.3, assignment
-    variant& operator=(const variant&);
-    variant& operator=(variant&&) noexcept(see below);
-
-    template <class T> variant& operator=(T&&) noexcept(see below);
-
-    // 20.7.2.4, modifiers
-    template <class T, class... Args>
-    T& emplace(Args&&...);
-
-    template <class T, class U, class... Args>
-    T& emplace(initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    variant_alternative<I, variant>& emplace(Args&&...);
-
-    template <size_t I, class U, class...  Args>
-    variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
-
-    // 20.7.2.5, value status
-    constexpr bool valueless_by_exception() const noexcept;
-    constexpr size_t index() const noexcept;
-
-    // 20.7.2.6, swap
-    void swap(variant&) noexcept(see below);
-  };
-
-  // 20.7.3, variant helper classes
-  template <class T> struct variant_size; // undefined
-
-  template <class T>
-  constexpr size_t variant_size_v = variant_size<T>::value;
-
-  template <class T> struct variant_size<const T>;
-  template <class T> struct variant_size<volatile T>;
-  template <class T> struct variant_size<const volatile T>;
-
-  template <class... Types>
-  struct variant_size<variant<Types...>>;
-
-  template <size_t I, class T> struct variant_alternative; // undefined
-
-  template <size_t I, class T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <size_t I, class T> struct variant_alternative<I, const T>;
-  template <size_t I, class T> struct variant_alternative<I, volatile T>;
-  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
-
-  template <size_t I, class... Types>
-  struct variant_alternative<I, variant<Types...>>;
-
-  constexpr size_t variant_npos = -1;
-
-  // 20.7.4, value access
-  template <class T, class... Types>
-  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&
-  get(variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&&
-  get(variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&
-  get(const variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&&
-  get(const variant<Types...>&&);
-
-  template <class T, class...  Types>
-  constexpr T& get(variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr T&& get(variant<Types...>&&);
-
-  template <class T, class... Types>
-  constexpr const T& get(const variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr const T&& get(const variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
-  get_if(variant<Types...>*) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
-  get_if(const variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<T>
-  get_if(variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<const T>
-  get_if(const variant<Types...>*) noexcept;
-
-  // 20.7.5, relational operators
-  template <class... Types>
-  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
-
-  // 20.7.6, visitation
-  template <class Visitor, class... Variants>
-  constexpr see below visit(Visitor&&, Variants&&...);
-
-  // 20.7.7, class monostate
-  struct monostate;
-
-  // 20.7.8, monostate relational operators
-  constexpr bool operator<(monostate, monostate) noexcept;
-  constexpr bool operator>(monostate, monostate) noexcept;
-  constexpr bool operator<=(monostate, monostate) noexcept;
-  constexpr bool operator>=(monostate, monostate) noexcept;
-  constexpr bool operator==(monostate, monostate) noexcept;
-  constexpr bool operator!=(monostate, monostate) noexcept;
-
-  // 20.7.9, specialized algorithms
-  template <class... Types>
-  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
-
-  // 20.7.10, class bad_variant_access
-  class bad_variant_access;
-
-  // 20.7.11, hash support
-  template <class T> struct hash;
-  template <class... Types> struct hash<variant<Types...>>;
-  template <> struct hash<monostate>;
-
-} // namespace std
-
-*/
-
-#include <cstddef>
-#include <exception>
-#include <functional>
-#include <initializer_list>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_IN_PLACE_HPP
-#define MPARK_IN_PLACE_HPP
-
-#include <cstddef>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANTS_CONFIG_HPP
-#define MPARK_VARIANTS_CONFIG_HPP
-
-// MSVC 2015 Update 3.
-#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024215)
-#error "MPark.Variant requires C++11 support."
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#if __has_builtin(__builtin_addressof) || __GNUC__ >= 7 || defined(_MSC_VER)
-#define MPARK_BUILTIN_ADDRESSOF
-#endif
-
-#if __has_builtin(__type_pack_element)
-#define MPARK_TYPE_PACK_ELEMENT
-#endif
-
-#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
-#define MPARK_CPP14_CONSTEXPR
-#endif
-
-#if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
-#define MPARK_GENERIC_LAMBDAS
-#endif
-
-#if defined(__cpp_lib_integer_sequence)
-#define MPARK_INTEGER_SEQUENCE
-#endif
-
-#if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
-#define MPARK_RETURN_TYPE_DEDUCTION
-#endif
-
-#if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
-#define MPARK_TRANSPARENT_OPERATORS
-#endif
-
-#if defined(__cpp_variable_templates) || defined(_MSC_VER)
-#define MPARK_VARIABLE_TEMPLATES
-#endif
-
-#endif  // MPARK_VARIANTS_CONFIG_HPP
-
-
-namespace mpark {
-
-  struct in_place_t { explicit in_place_t() = default; };
-
-  template <std::size_t I>
-  struct in_place_index_t { explicit in_place_index_t() = default; };
-
-  template <typename T>
-  struct in_place_type_t { explicit in_place_type_t() = default; };
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  constexpr in_place_t in_place{};
-
-  template <std::size_t I> constexpr in_place_index_t<I> in_place_index{};
-
-  template <typename T> constexpr in_place_type_t<T> in_place_type{};
-#endif
-
-}  // namespace mpark
-
-#endif  // MPARK_IN_PLACE_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANTS_LIB_HPP
-#define MPARK_VARIANTS_LIB_HPP
-
-#include <memory>
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-
-#define RETURN(...)                                          \
-  noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { \
-    return __VA_ARGS__;                                      \
-  }
-
-namespace mpark {
-  namespace variants {
-    namespace lib {
-
-      template <typename T>
-      struct identity { using type = T; };
-
-      inline namespace cpp14 {
-        template <typename T, std::size_t N>
-        struct array {
-          constexpr const T &operator[](std::size_t index) const {
-            return data[index];
-          }
-
-          T data[N == 0 ? 1 : N];
-        };
-
-        template <typename T>
-        using add_pointer_t = typename std::add_pointer<T>::type;
-
-        template <typename... Ts>
-        using common_type_t = typename std::common_type<Ts...>::type;
-
-        template <typename T>
-        using decay_t = typename std::decay<T>::type;
-
-        template <bool B, typename T = void>
-        using enable_if_t = typename std::enable_if<B, T>::type;
-
-        template <typename T>
-        using remove_const_t = typename std::remove_const<T>::type;
-
-        template <typename T>
-        using remove_reference_t = typename std::remove_reference<T>::type;
-
-        template <typename T>
-        inline constexpr T &&forward(remove_reference_t<T> &t) noexcept {
-          return static_cast<T &&>(t);
-        }
-
-        template <typename T>
-        inline constexpr T &&forward(remove_reference_t<T> &&t) noexcept {
-          static_assert(!std::is_lvalue_reference<T>::value,
-                        "can not forward an rvalue as an lvalue");
-          return static_cast<T &&>(t);
-        }
-
-        template <typename T>
-        constexpr remove_reference_t<T> &&move(T &&t) noexcept {
-          return static_cast<remove_reference_t<T> &&>(t);
-        }
-
-#ifdef MPARK_INTEGER_SEQUENCE
-        template <typename T, T... Is>
-        using integer_sequence = std::integer_sequence<T, Is...>;
-
-        template <std::size_t... Is>
-        using index_sequence = std::index_sequence<Is...>;
-
-        template <std::size_t N>
-        using make_index_sequence = std::make_index_sequence<N>;
-
-        template <typename... Ts>
-        using index_sequence_for = std::index_sequence_for<Ts...>;
-#else
-        template <typename T, T... Is>
-        struct integer_sequence {
-          using value_type = T;
-          static constexpr std::size_t size() noexcept { return sizeof...(Is); }
-        };
-
-        template <std::size_t... Is>
-        using index_sequence = integer_sequence<std::size_t, Is...>;
-
-        template <typename Lhs, typename Rhs>
-        struct make_index_sequence_concat;
-
-        template <std::size_t... Lhs, std::size_t... Rhs>
-        struct make_index_sequence_concat<index_sequence<Lhs...>,
-                                          index_sequence<Rhs...>>
-            : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
-
-        template <std::size_t N>
-        struct make_index_sequence_impl;
-
-        template <std::size_t N>
-        using make_index_sequence = typename make_index_sequence_impl<N>::type;
-
-        template <std::size_t N>
-        struct make_index_sequence_impl
-            : make_index_sequence_concat<make_index_sequence<N / 2>,
-                                         make_index_sequence<N - (N / 2)>> {};
-
-        template <>
-        struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
-
-        template <>
-        struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
-
-        template <typename... Ts>
-        using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
-#endif
-
-        // <functional>
-#ifdef MPARK_TRANSPARENT_OPERATORS
-        using equal_to = std::equal_to<>;
-#else
-        struct equal_to {
-          template <typename Lhs, typename Rhs>
-          inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-            RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
-        };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-        using not_equal_to = std::not_equal_to<>;
-#else
-        struct not_equal_to {
-          template <typename Lhs, typename Rhs>
-          inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-            RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
-        };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-        using less = std::less<>;
-#else
-        struct less {
-          template <typename Lhs, typename Rhs>
-          inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-            RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
-        };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-        using greater = std::greater<>;
-#else
-        struct greater {
-          template <typename Lhs, typename Rhs>
-          inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-            RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
-        };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-        using less_equal = std::less_equal<>;
-#else
-        struct less_equal {
-          template <typename Lhs, typename Rhs>
-          inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-            RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
-        };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-        using greater_equal = std::greater_equal<>;
-#else
-        struct greater_equal {
-          template <typename Lhs, typename Rhs>
-          inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-            RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
-        };
-#endif
-      }  // namespace cpp14
-
-      inline namespace cpp17 {
-
-        // <type_traits>
-        template <bool B>
-        using bool_constant = std::integral_constant<bool, B>;
-
-        template <typename...>
-        using void_t = void;
-
-        namespace detail {
-          namespace swappable {
-
-            using std::swap;
-
-            template <typename T>
-            struct is_swappable_impl {
-              private:
-              template <typename U,
-                        typename = decltype(swap(std::declval<U &>(),
-                                                 std::declval<U &>()))>
-              inline static std::true_type test(int);
-
-              template <typename U>
-              inline static std::false_type test(...);
-
-              public:
-              using type = decltype(test<T>(0));
-            };
-
-            template <typename T>
-            using is_swappable = typename is_swappable_impl<T>::type;
-
-            template <typename T, bool = is_swappable<T>::value>
-            struct is_nothrow_swappable {
-              static constexpr bool value =
-                  noexcept(swap(std::declval<T &>(), std::declval<T &>()));
-            };
-
-            template <typename T>
-            struct is_nothrow_swappable<T, false> : std::false_type {};
-
-          }  // namespace swappable
-        }  // namespace detail
-
-        template <typename T>
-        using is_swappable = detail::swappable::is_swappable<T>;
-
-        template <typename T>
-        using is_nothrow_swappable = detail::swappable::is_nothrow_swappable<T>;
-
-        // <functional>
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-        template <typename F, typename... As>
-        inline constexpr auto invoke(F &&f, As &&... as)
-            RETURN(lib::forward<F>(f)(lib::forward<As>(as)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-        template <typename B, typename T, typename D>
-        inline constexpr auto invoke(T B::*pmv, D &&d)
-            RETURN(lib::forward<D>(d).*pmv)
-
-        template <typename Pmv, typename Ptr>
-        inline constexpr auto invoke(Pmv pmv, Ptr &&ptr)
-            RETURN((*lib::forward<Ptr>(ptr)).*pmv)
-
-        template <typename B, typename T, typename D, typename... As>
-        inline constexpr auto invoke(T B::*pmf, D &&d, As &&... as)
-            RETURN((lib::forward<D>(d).*pmf)(lib::forward<As>(as)...))
-
-        template <typename Pmf, typename Ptr, typename... As>
-        inline constexpr auto invoke(Pmf pmf, Ptr &&ptr, As &&... as)
-            RETURN(((*lib::forward<Ptr>(ptr)).*pmf)(lib::forward<As>(as)...))
-
-        namespace detail {
-
-          template <typename Void, typename, typename...>
-          struct invoke_result {};
-
-          template <typename F, typename... Args>
-          struct invoke_result<void_t<decltype(lib::invoke(
-                                   std::declval<F>(), std::declval<Args>()...))>,
-                               F,
-                               Args...>
-              : identity<decltype(
-                    lib::invoke(std::declval<F>(), std::declval<Args>()...))> {};
-
-        }  // namespace detail
-
-        template <typename F, typename... Args>
-        using invoke_result = detail::invoke_result<void, F, Args...>;
-
-        template <typename F, typename... Args>
-        using invoke_result_t = typename invoke_result<F, Args...>::type;
-
-        namespace detail {
-
-          template <typename Void, typename, typename...>
-          struct is_invocable : std::false_type {};
-
-          template <typename F, typename... Args>
-          struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
-              : std::true_type {};
-
-          template <typename Void, typename, typename, typename...>
-          struct is_invocable_r : std::false_type {};
-
-          template <typename R, typename F, typename... Args>
-          struct is_invocable_r<void_t<invoke_result_t<F, Args...>>,
-                                R,
-                                F,
-                                Args...>
-              : std::is_convertible<invoke_result_t<F, Args...>, R> {};
-
-        }  // namespace detail
-
-        template <typename F, typename... Args>
-        using is_invocable = detail::is_invocable<void, F, Args...>;
-
-        template <typename R, typename F, typename... Args>
-        using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
-
-        // <memory>
-#ifdef MPARK_BUILTIN_ADDRESSOF
-        template <typename T>
-        inline constexpr T *addressof(T &arg) {
-          return __builtin_addressof(arg);
-        }
-#else
-        namespace detail {
-
-          namespace has_addressof_impl {
-
-            struct fail;
-
-            template <typename T>
-            inline fail operator&(T &&);
-
-            template <typename T>
-            inline static constexpr bool impl() {
-              return (std::is_class<T>::value || std::is_union<T>::value) &&
-                     !std::is_same<decltype(&std::declval<T &>()), fail>::value;
-            }
-
-          }  // namespace has_addressof_impl
-
-          template <typename T>
-          using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
-
-          template <typename T>
-          inline constexpr T *addressof(T &arg, std::true_type) {
-            return std::addressof(arg);
-          }
-
-          template <typename T>
-          inline constexpr T *addressof(T &arg, std::false_type) {
-            return &arg;
-          }
-
-        }  // namespace detail
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg) {
-          return detail::addressof(arg, detail::has_addressof<T>{});
-        }
-#endif
-
-        template <typename T>
-        inline constexpr T *addressof(const T &&) = delete;
-
-      }  // namespace cpp17
-
-      template <typename T>
-      struct remove_all_extents : identity<T> {};
-
-      template <typename T, std::size_t N>
-      struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
-
-      template <typename T>
-      using remove_all_extents_t = typename remove_all_extents<T>::type;
-
-      template <std::size_t N>
-      using size_constant = std::integral_constant<std::size_t, N>;
-
-      template <bool... Bs>
-      using bool_sequence = integer_sequence<bool, Bs...>;
-
-      template <std::size_t I, typename T>
-      struct indexed_type : size_constant<I>, identity<T> {};
-
-      template <bool... Bs>
-      using all =
-          std::is_same<bool_sequence<true, Bs...>, bool_sequence<Bs..., true>>;
-
-#ifdef MPARK_TYPE_PACK_ELEMENT
-      template <std::size_t I, typename... Ts>
-      using type_pack_element_t = __type_pack_element<I, Ts...>;
-#else
-      template <std::size_t I, typename... Ts>
-      struct type_pack_element_impl {
-        private:
-        template <typename>
-        struct set;
-
-        template <std::size_t... Is>
-        struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
-
-        template <typename T>
-        inline static std::enable_if<true, T> impl(indexed_type<I, T>);
-
-        inline static std::enable_if<false> impl(...);
-
-        public:
-        using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
-      };
-
-      template <std::size_t I, typename... Ts>
-      using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
-
-      template <std::size_t I, typename... Ts>
-      using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
-#endif
-
-    }  // namespace lib
-  }  // namespace variants
-}  // namespace mpark
-
-#undef RETURN
-
-#endif  // MPARK_VARIANTS_LIB_HPP
-
-
-namespace mpark {
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-
-#define AUTO auto
-#define AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto &&
-#define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; }
-
-#define DECLTYPE_AUTO decltype(auto)
-#define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#else
-
-#define AUTO auto
-#define AUTO_RETURN(...)                                    \
-  -> mpark::variants::lib::decay_t<decltype(__VA_ARGS__)> { \
-    return __VA_ARGS__;                                     \
-  }
-
-#define AUTO_REFREF auto
-#define AUTO_REFREF_RETURN(...)                                           \
-  -> decltype((__VA_ARGS__)) {                                            \
-    static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
-    return __VA_ARGS__;                                                   \
-  }
-
-#define DECLTYPE_AUTO auto
-#define DECLTYPE_AUTO_RETURN(...) \
-  -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-#endif
-
-  class bad_variant_access : public std::exception {
-    public:
-    virtual const char *what() const noexcept { return "bad_variant_access"; }
-  };
-
-  template <typename... Ts>
-  class variant;
-
-  template <typename T>
-  struct variant_size;
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  template <typename T>
-  constexpr std::size_t variant_size_v = variant_size<T>::value;
-#endif
-
-  template <typename T>
-  struct variant_size<const T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<volatile T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<const volatile T> : variant_size<T> {};
-
-  template <typename... Ts>
-  struct variant_size<variant<Ts...>>
-      : variants::lib::size_constant<sizeof...(Ts)> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative;
-
-  template <std::size_t I, typename T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const T>
-      : std::add_const<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, volatile T>
-      : std::add_volatile<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const volatile T>
-      : std::add_cv<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename... Ts>
-  struct variant_alternative<I, variant<Ts...>>
-      : variants::lib::identity<variants::lib::type_pack_element_t<I, Ts...>> {
-    static_assert(I < sizeof...(Ts),
-                  "`variant_alternative` index out of range.");
-  };
-
-  constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
-
-  namespace detail {
-
-    inline constexpr bool all() { return true; }
-
-    template <typename... Bs>
-    inline constexpr bool all(bool b, Bs... bs) {
-      return b && all(bs...);
-    }
-
-    constexpr std::size_t not_found = static_cast<std::size_t>(-1);
-    constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      constexpr variants::lib::array<bool, sizeof...(Ts)> matches = {
-          {std::is_same<T, Ts>::value...}
-      };
-      std::size_t result = not_found;
-      for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
-        if (matches[i]) {
-          if (result != not_found) {
-            return ambiguous;
-          }
-          result = i;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t) {
-      return result;
-    }
-
-    template <typename... Bs>
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t idx,
-                                                 bool b,
-                                                 Bs... bs) {
-      return b ? (result != not_found ? ambiguous
-                                      : find_index_impl(idx, idx + 1, bs...))
-               : find_index_impl(result, idx + 1, bs...);
-    }
-
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
-    }
-#endif
-
-    template <std::size_t I>
-    using find_index_sfinae_impl =
-        variants::lib::enable_if_t<I != not_found && I != ambiguous,
-                                   variants::lib::size_constant<I>>;
-
-    template <typename T, typename... Ts>
-    using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
-
-    template <std::size_t I>
-    struct find_index_checked_impl : variants::lib::size_constant<I> {
-      static_assert(I != not_found, "the specified type is not found.");
-      static_assert(I != ambiguous, "the specified type is ambiguous.");
-    };
-
-    template <typename T, typename... Ts>
-    using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
-
-    struct valueless_t {};
-
-    enum class Trait { TriviallyAvailable, Available, Unavailable };
-
-    template <typename T,
-              template <typename> class IsTriviallyAvailable,
-              template <typename> class IsAvailable>
-    inline constexpr Trait trait() {
-      return IsTriviallyAvailable<T>::value
-                 ? Trait::TriviallyAvailable
-                 : IsAvailable<T>::value ? Trait::Available
-                                         : Trait::Unavailable;
-    }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... traits) {
-      Trait result = Trait::TriviallyAvailable;
-      for (Trait t : {traits...}) {
-        if (static_cast<int>(t) > static_cast<int>(result)) {
-          result = t;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr Trait common_trait_impl(Trait result) { return result; }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait_impl(Trait result,
-                                             Trait t,
-                                             Traits... ts) {
-      return static_cast<int>(t) > static_cast<int>(result)
-                 ? common_trait_impl(t, ts...)
-                 : common_trait_impl(result, ts...);
-    }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... ts) {
-      return common_trait_impl(Trait::TriviallyAvailable, ts...);
-    }
-#endif
-
-    template <typename... Ts>
-    struct traits {
-      static constexpr Trait copy_constructible_trait =
-          common_trait(trait<Ts,
-                             std::is_trivially_copy_constructible,
-                             std::is_copy_constructible>()...);
-
-      static constexpr Trait move_constructible_trait =
-          common_trait(trait<Ts,
-                             std::is_trivially_move_constructible,
-                             std::is_move_constructible>()...);
-
-      static constexpr Trait copy_assignable_trait =
-          common_trait(copy_constructible_trait,
-                       move_constructible_trait,
-                       trait<Ts,
-                             std::is_trivially_copy_assignable,
-                             std::is_copy_assignable>()...);
-
-      static constexpr Trait move_assignable_trait =
-          common_trait(move_constructible_trait,
-                       trait<Ts,
-                             std::is_trivially_move_assignable,
-                             std::is_move_assignable>()...);
-
-      static constexpr Trait destructible_trait =
-          common_trait(trait<Ts,
-                             std::is_trivially_destructible,
-                             std::is_destructible>()...);
-    };
-
-    namespace access {
-
-      struct recursive_union {
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename V>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
-          return variants::lib::forward<V>(v).head_;
-        }
-
-        template <typename V, std::size_t I>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
-          return get_alt(variants::lib::forward<V>(v).tail_,
-                         in_place_index_t<I - 1>{});
-        }
-#else
-        template <std::size_t I, bool Dummy = true>
-        struct get_alt_impl {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(
-                get_alt_impl<I - 1>{}(variants::lib::forward<V>(v).tail_))
-        };
-
-        template <bool Dummy>
-        struct get_alt_impl<0, Dummy> {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(variants::lib::forward<V>(v).head_)
-        };
-
-        template <typename V, std::size_t I>
-        inline static constexpr AUTO_REFREF get_alt(V &&v,
-                                                    in_place_index_t<I>)
-          AUTO_REFREF_RETURN(get_alt_impl<I>{}(variants::lib::forward<V>(v)))
-#endif
-      };
-
-      struct base {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(recursive_union::get_alt(
-              variants::lib::forward<V>(v).data_, in_place_index_t<I>{}))
-      };
-
-      struct variant {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(
-              base::get_alt<I>(variants::lib::forward<V>(v).impl_))
-      };
-
-    }  // namespace access
-
-    namespace visitation {
-
-      struct base {
-        private:
-        template <typename T>
-        inline static constexpr const T &at(const T &elem) {
-          return elem;
-        }
-
-        template <typename T, std::size_t N, typename... Is>
-        inline static constexpr const variants::lib::remove_all_extents_t<T> &
-        at(const variants::lib::array<T, N> &elems, std::size_t i, Is... is) {
-          return at(elems[i], is...);
-        }
-
-        template <typename F, typename... Fs>
-        inline static constexpr int visit_visitor_return_type_check() {
-          static_assert(all(std::is_same<F, Fs>::value...),
-                        "`mpark::visit` requires the visitor to have a single "
-                        "return type.");
-          return 0;
-        }
-
-        template <typename... Fs>
-        inline static constexpr variants::lib::array<
-            variants::lib::common_type_t<variants::lib::decay_t<Fs>...>,
-            sizeof...(Fs)>
-        make_farray(Fs &&... fs) {
-          using result = variants::lib::array<
-              variants::lib::common_type_t<variants::lib::decay_t<Fs>...>,
-              sizeof...(Fs)>;
-          return visit_visitor_return_type_check<
-                     variants::lib::decay_t<Fs>...>(),
-                 result{{variants::lib::forward<Fs>(fs)...}};
-        }
-
-        template <std::size_t... Is>
-        struct dispatcher {
-          template <typename F, typename... Vs>
-          struct impl {
-            inline static constexpr DECLTYPE_AUTO dispatch(F f, Vs... vs)
-              DECLTYPE_AUTO_RETURN(variants::lib::invoke(
-                  static_cast<F>(f),
-                  access::base::get_alt<Is>(static_cast<Vs>(vs))...))
-          };
-        };
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_dispatch(
-            variants::lib::index_sequence<Is...>)
-          AUTO_RETURN(&dispatcher<Is...>::template impl<F, Vs...>::dispatch)
-
-        template <std::size_t I, typename F, typename... Vs>
-        inline static constexpr AUTO make_fdiagonal_impl()
-          AUTO_RETURN(make_dispatch<F, Vs...>(
-              variants::lib::index_sequence<
-                  variants::lib::indexed_type<I, Vs>::value...>{}))
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_fdiagonal_impl(
-            variants::lib::index_sequence<Is...>)
-          AUTO_RETURN(make_farray(make_fdiagonal_impl<Is, F, Vs...>()...))
-
-        template <typename F, typename V, typename... Vs>
-        inline static constexpr /* auto * */ auto make_fdiagonal()
-            -> decltype(make_fdiagonal_impl<F, V, Vs...>(
-                variants::lib::make_index_sequence<
-                    variants::lib::decay_t<V>::size()>{})) {
-          static_assert(all((variants::lib::decay_t<V>::size() ==
-                             variants::lib::decay_t<Vs>::size())...),
-                        "all of the variants must be the same size.");
-          return make_fdiagonal_impl<F, V, Vs...>(
-              variants::lib::make_index_sequence<
-                  variants::lib::decay_t<V>::size()>{});
-        }
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_fmatrix_impl(
-            variants::lib::index_sequence<Is...> is) {
-          return make_dispatch<F, Vs...>(is);
-        }
-
-        template <typename F,
-                  typename... Vs,
-                  std::size_t... Is,
-                  std::size_t... Js,
-                  typename... Ls>
-        inline static constexpr auto make_fmatrix_impl(
-            variants::lib::index_sequence<Is...>,
-            variants::lib::index_sequence<Js...>,
-            Ls... ls) {
-          return make_farray(make_fmatrix_impl<F, Vs...>(
-              variants::lib::index_sequence<Is..., Js>{}, ls...)...);
-        }
-
-        template <typename F, typename... Vs>
-        inline static constexpr auto make_fmatrix() {
-          return make_fmatrix_impl<F, Vs...>(
-              variants::lib::index_sequence<>{},
-              variants::lib::make_index_sequence<
-                  variants::lib::decay_t<Vs>::size()>{}...);
-        }
-#else
-        template <typename F, typename... Vs>
-        struct make_fmatrix_impl {
-          template <typename...>
-          struct impl;
-
-          template <std::size_t... Is>
-          struct impl<variants::lib::index_sequence<Is...>> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(make_dispatch<F, Vs...>(
-                  variants::lib::index_sequence<Is...>{}))
-          };
-
-          template <std::size_t... Is, std::size_t... Js, typename... Ls>
-          struct impl<variants::lib::index_sequence<Is...>,
-                      variants::lib::index_sequence<Js...>,
-                      Ls...> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(
-                  make_farray(impl<variants::lib::index_sequence<Is..., Js>,
-                                   Ls...>{}()...))
-          };
-        };
-
-        template <typename F, typename... Vs>
-        inline static constexpr AUTO make_fmatrix()
-          AUTO_RETURN(typename make_fmatrix_impl<F, Vs...>::template impl<
-                      variants::lib::index_sequence<>,
-                      variants::lib::make_index_sequence<
-                          variants::lib::decay_t<Vs>::size()>...>{}())
-#endif
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(at(
-              make_fdiagonal<Visitor &&,
-                             decltype(
-                                 as_base(variants::lib::forward<Vs>(vs)))...>(),
-              index)(variants::lib::forward<Visitor>(visitor),
-                     as_base(variants::lib::forward<Vs>(vs))...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(at(
-              make_fmatrix<Visitor &&,
-                           decltype(
-                               as_base(variants::lib::forward<Vs>(vs)))...>(),
-              vs.index()...)(variants::lib::forward<Visitor>(visitor),
-                             as_base(variants::lib::forward<Vs>(vs))...))
-      };
-
-      struct variant {
-        private:
-        template <typename Visitor, typename... Values>
-        struct visit_exhaustive_visitor_check {
-          static_assert(
-              variants::lib::is_invocable<Visitor, Values...>::value,
-              "`mpark::visit` requires the visitor to be exhaustive.");
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-          inline constexpr DECLTYPE_AUTO operator()(Visitor &&visitor,
-                                                    Values &&... values) const
-            DECLTYPE_AUTO_RETURN(variants::lib::invoke(
-                variants::lib::forward<Visitor>(visitor),
-                variants::lib::forward<Values>(values)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        };
-
-        template <typename Visitor>
-        struct value_visitor {
-          Visitor &&visitor_;
-
-          template <typename... Alts>
-          inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const
-            DECLTYPE_AUTO_RETURN(
-                visit_exhaustive_visitor_check<
-                    Visitor,
-                    decltype((variants::lib::forward<Alts>(alts).value))...>{}(
-                    variants::lib::forward<Visitor>(visitor_),
-                    variants::lib::forward<Alts>(alts).value...))
-        };
-
-        template <typename Visitor>
-        inline static constexpr AUTO make_value_visitor(Visitor &&visitor)
-          AUTO_RETURN(
-              value_visitor<Visitor>{variants::lib::forward<Visitor>(visitor)})
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              base::visit_alt_at(index,
-                                 variants::lib::forward<Visitor>(visitor),
-                                 variants::lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              base::visit_alt(variants::lib::forward<Visitor>(visitor),
-                              variants::lib::forward<Vs>(vs).impl_...));
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index,
-                                                             Visitor &&visitor,
-                                                             Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(visit_alt_at(
-              index,
-              make_value_visitor(variants::lib::forward<Visitor>(visitor)),
-              variants::lib::forward<Vs>(vs)...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor,
-                                                          Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(visit_alt(
-              make_value_visitor(variants::lib::forward<Visitor>(visitor)),
-              variants::lib::forward<Vs>(vs)...))
-      };
-
-    }  // namespace visitation
-
-    template <std::size_t Index, typename T>
-    struct alt {
-      using value_type = T;
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-      template <typename... Args>
-      inline explicit constexpr alt(in_place_t, Args &&... args)
-          : value(variants::lib::forward<Args>(args)...) {}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      T value;
-    };
-
-    template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
-    union recursive_union;
-
-    template <Trait DestructibleTrait, std::size_t Index>
-    union recursive_union<DestructibleTrait, Index> {};
-
-#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)   \
-  template <std::size_t Index, typename T, typename... Ts>              \
-  union recursive_union<destructible_trait, Index, T, Ts...> {          \
-    public:                                                             \
-    inline explicit constexpr recursive_union(valueless_t) noexcept     \
-        : dummy_{} {}                                                   \
-                                                                        \
-    template <typename... Args>                                         \
-    inline explicit constexpr recursive_union(in_place_index_t<0>,      \
-                                              Args &&... args)          \
-        : head_(in_place_t{}, variants::lib::forward<Args>(args)...) {} \
-                                                                        \
-    template <std::size_t I, typename... Args>                          \
-    inline explicit constexpr recursive_union(in_place_index_t<I>,      \
-                                              Args &&... args)          \
-        : tail_(in_place_index_t<I - 1>{},                              \
-                variants::lib::forward<Args>(args)...) {}               \
-                                                                        \
-    recursive_union(const recursive_union &) = default;                 \
-    recursive_union(recursive_union &&) = default;                      \
-                                                                        \
-    destructor                                                          \
-                                                                        \
-    recursive_union &operator=(const recursive_union &) = default;      \
-    recursive_union &operator=(recursive_union &&) = default;           \
-                                                                        \
-    private:                                                            \
-    char dummy_;                                                        \
-    alt<Index, T> head_;                                                \
-    recursive_union<destructible_trait, Index + 1, Ts...> tail_;        \
-                                                                        \
-    friend struct access::recursive_union;                              \
-  }
-
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
-                                  ~recursive_union() = default;);
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
-                                  ~recursive_union() {});
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
-                                  ~recursive_union() = delete;);
-
-#undef MPARK_VARIANT_RECURSIVE_UNION
-
-    using index_t = unsigned int;
-
-    template <Trait DestructibleTrait, typename... Ts>
-    class base {
-      public:
-      inline explicit constexpr base(valueless_t tag) noexcept
-          : data_(tag), index_(static_cast<index_t>(-1)) {}
-
-      template <std::size_t I, typename... Args>
-      inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
-          : data_(in_place_index_t<I>{}, variants::lib::forward<Args>(args)...),
-            index_(I) {}
-
-      inline constexpr bool valueless_by_exception() const noexcept {
-        return index_ == static_cast<index_t>(-1);
-      }
-
-      inline constexpr std::size_t index() const noexcept {
-        return valueless_by_exception() ? variant_npos : index_;
-      }
-
-      protected:
-      friend inline constexpr base &as_base(base &b) { return b; }
-      friend inline constexpr const base &as_base(const base &b) { return b; }
-      friend inline constexpr base &&as_base(base &&b) {
-        return variants::lib::move(b);
-      }
-      friend inline constexpr const base &&as_base(const base &&b) {
-        return variants::lib::move(b);
-      }
-
-      inline static constexpr std::size_t size() { return sizeof...(Ts); }
-
-      recursive_union<DestructibleTrait, 0, Ts...> data_;
-      index_t index_;
-
-      friend struct access::base;
-      friend struct visitation::base;
-    };
-
-    struct dtor {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename Alt>
-      inline void operator()(Alt &alt) const noexcept { alt.~Alt(); }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-    };
-
-#if defined(_MSC_VER) && _MSC_VER < 1910
-#define INHERITING_CTOR(type, base)               \
-  template <typename... Args>                     \
-  inline explicit constexpr type(Args &&... args) \
-      : base(variants::lib::forward<Args>(args)...) {}
-#else
-#define INHERITING_CTOR(type, base) using base::base;
-#endif
-
-    template <typename Traits, Trait = Traits::destructible_trait>
-    class destructor;
-
-#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
-  template <typename... Ts>                                               \
-  class destructor<traits<Ts...>, destructible_trait>                     \
-      : public base<destructible_trait, Ts...> {                          \
-    using super = base<destructible_trait, Ts...>;                        \
-                                                                          \
-    public:                                                               \
-    INHERITING_CTOR(destructor, super)                                    \
-    using super::operator=;                                               \
-                                                                          \
-    destructor(const destructor &) = default;                             \
-    destructor(destructor &&) = default;                                  \
-    definition                                                            \
-    destructor &operator=(const destructor &) = default;                  \
-    destructor &operator=(destructor &&) = default;                       \
-                                                                          \
-    protected:                                                            \
-    destroy                                                               \
-  }
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::TriviallyAvailable,
-        ~destructor() = default;,
-        inline void destroy() noexcept {
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Available,
-        ~destructor() { destroy(); },
-        inline void destroy() noexcept {
-          if (!this->valueless_by_exception()) {
-            visitation::base::visit_alt(dtor{}, *this);
-          }
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Unavailable,
-        ~destructor() = delete;,
-        inline void destroy() noexcept = delete;);
-
-#undef MPARK_VARIANT_DESTRUCTOR
-
-    template <typename Traits>
-    class constructor : public destructor<Traits> {
-      using super = destructor<Traits>;
-
-      public:
-      INHERITING_CTOR(constructor, super)
-      using super::operator=;
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct ctor {
-        template <typename LhsAlt, typename RhsAlt>
-        inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const {
-          constructor::construct_alt(
-              lhs_alt, variants::lib::forward<RhsAlt>(rhs_alt).value);
-        }
-      };
-#endif
-
-      template <std::size_t I, typename T, typename... Args>
-      inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
-        ::new (static_cast<void *>(variants::lib::addressof(a)))
-            alt<I, T>(in_place_t{}, variants::lib::forward<Args>(args)...);
-        return a.value;
-      }
-
-      template <typename Rhs>
-      inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
-        lhs.destroy();
-        if (!rhs.valueless_by_exception()) {
-          visitation::base::visit_alt_at(
-              rhs.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [](auto &lhs_alt, auto &&rhs_alt) {
-                constructor::construct_alt(
-                    lhs_alt,
-                    variants::lib::forward<decltype(rhs_alt)>(rhs_alt).value);
-              }
-#else
-              ctor{}
-#endif
-              ,
-              lhs,
-              variants::lib::forward<Rhs>(rhs));
-          lhs.index_ = rhs.index_;
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_constructible_trait>
-    class move_constructor;
-
-#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class move_constructor<traits<Ts...>, move_constructible_trait>            \
-      : public constructor<traits<Ts...>> {                                  \
-    using super = constructor<traits<Ts...>>;                                \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(move_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    move_constructor(const move_constructor &) = default;                    \
-    definition                                                               \
-    ~move_constructor() = default;                                           \
-    move_constructor &operator=(const move_constructor &) = default;         \
-    move_constructor &operator=(move_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        move_constructor(move_constructor &&that) = default;);
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Available,
-        move_constructor(move_constructor &&that) noexcept(
-            all(std::is_nothrow_move_constructible<Ts>::value...))
-            : move_constructor(valueless_t{}) {
-          this->generic_construct(*this, variants::lib::move(that));
-        });
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Unavailable,
-        move_constructor(move_constructor &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_CONSTRUCTOR
-
-    template <typename Traits, Trait = Traits::copy_constructible_trait>
-    class copy_constructor;
-
-#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
-      : public move_constructor<traits<Ts...>> {                             \
-    using super = move_constructor<traits<Ts...>>;                           \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(copy_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    definition                                                               \
-    copy_constructor(copy_constructor &&) = default;                         \
-    ~copy_constructor() = default;                                           \
-    copy_constructor &operator=(const copy_constructor &) = default;         \
-    copy_constructor &operator=(copy_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        copy_constructor(const copy_constructor &that) = default;);
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Available,
-        copy_constructor(const copy_constructor &that)
-            : copy_constructor(valueless_t{}) {
-          this->generic_construct(*this, that);
-        });
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Unavailable,
-        copy_constructor(const copy_constructor &) = delete;);
-
-#undef MPARK_VARIANT_COPY_CONSTRUCTOR
-
-    template <typename Traits>
-    class assignment : public copy_constructor<Traits> {
-      using super = copy_constructor<Traits>;
-
-      public:
-      INHERITING_CTOR(assignment, super)
-      using super::operator=;
-
-      template <std::size_t I, typename... Args>
-      inline /* auto & */ auto emplace(Args &&... args) -> decltype(
-          this->construct_alt(access::base::get_alt<I>(*this),
-                              variants::lib::forward<Args>(args)...)) {
-        this->destroy();
-        auto &result =
-            this->construct_alt(access::base::get_alt<I>(*this),
-                                variants::lib::forward<Args>(args)...);
-        this->index_ = I;
-        return result;
-      }
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      template <typename That>
-      struct assigner {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const {
-          self->assign_alt(this_alt,
-                           variants::lib::forward<ThatAlt>(that_alt).value,
-                           std::is_lvalue_reference<That>{});
-        }
-        assignment *self;
-      };
-#endif
-
-      template <bool CopyAssign, std::size_t I, typename T, typename Arg>
-      inline void assign_alt(alt<I, T> &a,
-                             Arg &&arg,
-                             variants::lib::bool_constant<CopyAssign> tag) {
-        if (this->index() == I) {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-          a.value = variants::lib::forward<Arg>(arg);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        } else {
-          struct {
-            void operator()(std::true_type) const {
-              this_->emplace<I>(T(variants::lib::forward<Arg>(arg_)));
-            }
-            void operator()(std::false_type) const {
-              this_->emplace<I>(variants::lib::forward<Arg>(arg_));
-            }
-            assignment *this_;
-            Arg &&arg_;
-          } impl{this, variants::lib::forward<Arg>(arg)};
-          impl(tag);
-        }
-      }
-
-      template <typename That>
-      inline void generic_assign(That &&that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (that.valueless_by_exception()) {
-          this->destroy();
-        } else {
-          visitation::base::visit_alt_at(
-              that.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [this](auto &this_alt, auto &&that_alt) {
-                this->assign_alt(
-                    this_alt,
-                    variants::lib::forward<decltype(that_alt)>(that_alt).value,
-                    std::is_lvalue_reference<That>{});
-              }
-#else
-              assigner<That>{this}
-#endif
-              ,
-              *this,
-              variants::lib::forward<That>(that));
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_assignable_trait>
-    class move_assignment;
-
-#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class move_assignment<traits<Ts...>, move_assignable_trait>            \
-      : public assignment<traits<Ts...>> {                               \
-    using super = assignment<traits<Ts...>>;                             \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(move_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    move_assignment(const move_assignment &) = default;                  \
-    move_assignment(move_assignment &&) = default;                       \
-    ~move_assignment() = default;                                        \
-    move_assignment &operator=(const move_assignment &) = default;       \
-    definition                                                           \
-  }
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        move_assignment &operator=(move_assignment &&that) = default;);
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Available,
-        move_assignment &
-        operator=(move_assignment &&that) noexcept(
-            all((std::is_nothrow_move_constructible<Ts>::value &&
-                 std::is_nothrow_move_assignable<Ts>::value)...)) {
-          this->generic_assign(variants::lib::move(that));
-          return *this;
-        });
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Unavailable,
-        move_assignment &operator=(move_assignment &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_ASSIGNMENT
-
-    template <typename Traits, Trait = Traits::copy_assignable_trait>
-    class copy_assignment;
-
-#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
-      : public move_assignment<traits<Ts...>> {                          \
-    using super = move_assignment<traits<Ts...>>;                        \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(copy_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    copy_assignment(const copy_assignment &) = default;                  \
-    copy_assignment(copy_assignment &&) = default;                       \
-    ~copy_assignment() = default;                                        \
-    definition                                                           \
-    copy_assignment &operator=(copy_assignment &&) = default;            \
-  }
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        copy_assignment &operator=(const copy_assignment &that) = default;);
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Available,
-        copy_assignment &operator=(const copy_assignment &that) {
-          this->generic_assign(that);
-          return *this;
-        });
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Unavailable,
-        copy_assignment &operator=(const copy_assignment &) = delete;);
-
-#undef MPARK_VARIANT_COPY_ASSIGNMENT
-
-    template <typename... Ts>
-    class impl : public copy_assignment<traits<Ts...>> {
-      using super = copy_assignment<traits<Ts...>>;
-
-      public:
-      INHERITING_CTOR(impl, super)
-      using super::operator=;
-
-      template <std::size_t I, typename Arg>
-      inline void assign(Arg &&arg) {
-        this->assign_alt(access::base::get_alt<I>(*this),
-                         variants::lib::forward<Arg>(arg),
-                         std::false_type{});
-      }
-
-      inline void swap(impl &that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (this->index() == that.index()) {
-          visitation::base::visit_alt_at(this->index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-                                         [](auto &this_alt, auto &that_alt) {
-                                           using std::swap;
-                                           swap(this_alt.value,
-                                                that_alt.value);
-                                         }
-#else
-                                         swapper{}
-#endif
-                                         ,
-                                         *this,
-                                         that);
-        } else {
-          impl *lhs = this;
-          impl *rhs = variants::lib::addressof(that);
-          if (lhs->move_nothrow() && !rhs->move_nothrow()) {
-            std::swap(lhs, rhs);
-          }
-          impl tmp(variants::lib::move(*rhs));
-          // EXTENSION: When the move construction of `lhs` into `rhs` throws
-          // and `tmp` is nothrow move constructible then we move `tmp` back
-          // into `rhs` and provide the strong exception safety guarentee.
-          try {
-            this->generic_construct(*rhs, variants::lib::move(*lhs));
-          } catch (...) {
-            if (tmp.move_nothrow()) {
-              this->generic_construct(*rhs, variants::lib::move(tmp));
-            }
-            throw;
-          }
-          this->generic_construct(*lhs, variants::lib::move(tmp));
-        }
-      }
-
-      private:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct swapper {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const {
-          using std::swap;
-          swap(this_alt.value, that_alt.value);
-        }
-      };
-#endif
-
-      inline constexpr bool move_nothrow() const {
-        return this->valueless_by_exception() ||
-               variants::lib::array<bool, sizeof...(Ts)>{
-                   {std::is_nothrow_move_constructible<Ts>::value...}
-               }[this->index()];
-      }
-    };
-
-    template <typename... Ts>
-    struct overload;
-
-    template <>
-    struct overload<> { void operator()() const {} };
-
-    template <typename T, typename... Ts>
-    struct overload<T, Ts...> : overload<Ts...> {
-      using overload<Ts...>::operator();
-      variants::lib::identity<T> operator()(T) const { return {}; }
-    };
-
-    template <typename T, typename... Ts>
-    using best_match_t =
-        typename variants::lib::invoke_result_t<overload<Ts...>, T &&>::type;
-
-  }  // detail
-
-  template <typename... Ts>
-  class variant {
-    static_assert(0 < sizeof...(Ts),
-                  "variant must consist of at least one alternative.");
-
-    static_assert(variants::lib::all<!std::is_array<Ts>::value...>::value,
-                  "variant can not have an array type as an alternative.");
-
-    static_assert(variants::lib::all<!std::is_reference<Ts>::value...>::value,
-                  "variant can not have a reference type as an alternative.");
-
-    static_assert(variants::lib::all<!std::is_void<Ts>::value...>::value,
-                  "variant can not have a void type as an alternative.");
-
-    public:
-    template <
-        typename Front = variants::lib::type_pack_element_t<0, Ts...>,
-        variants::lib::enable_if_t<std::is_default_constructible<Front>::value,
-                                   int> = 0>
-    inline constexpr variant() noexcept(
-        std::is_nothrow_default_constructible<Front>::value)
-        : impl_(in_place_index_t<0>{}) {}
-
-    variant(const variant &) = default;
-    variant(variant &&) = default;
-
-    template <typename Arg,
-              variants::lib::enable_if_t<
-                  !std::is_same<variants::lib::decay_t<Arg>, variant>::value,
-                  int> = 0,
-              typename T = detail::best_match_t<Arg, Ts...>,
-              std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-              variants::lib::enable_if_t<std::is_constructible<T, Arg>::value,
-                                         int> = 0>
-    inline constexpr variant(Arg &&arg) noexcept(
-        std::is_nothrow_constructible<T, Arg>::value)
-        : impl_(in_place_index_t<I>{}, variants::lib::forward<Arg>(arg)) {}
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = variants::lib::type_pack_element_t<I, Ts...>,
-        variants::lib::enable_if_t<std::is_constructible<T, Args...>::value,
-                                   int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, variants::lib::forward<Args>(args)...) {}
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = variants::lib::type_pack_element_t<I, Ts...>,
-        variants::lib::enable_if_t<
-            std::is_constructible<T, std::initializer_list<Up> &, Args...>::
-                value,
-            int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{},
-                il,
-                variants::lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        variants::lib::enable_if_t<std::is_constructible<T, Args...>::value,
-                                   int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, variants::lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        variants::lib::enable_if_t<
-            std::is_constructible<T, std::initializer_list<Up> &, Args...>::
-                value,
-            int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{},
-                il,
-                variants::lib::forward<Args>(args)...) {}
-
-    ~variant() = default;
-
-    variant &operator=(const variant &) = default;
-    variant &operator=(variant &&) = default;
-
-    template <typename Arg,
-              variants::lib::enable_if_t<
-                  !std::is_same<variants::lib::decay_t<Arg>, variant>::value,
-                  int> = 0,
-              typename T = detail::best_match_t<Arg, Ts...>,
-              std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-              variants::lib::enable_if_t<(std::is_assignable<T &, Arg>::value &&
-                                          std::is_constructible<T, Arg>::value),
-                                         int> = 0>
-    inline variant &operator=(Arg &&arg) noexcept(
-        (std::is_nothrow_assignable<T &, Arg>::value &&
-         std::is_nothrow_constructible<T, Arg>::value)) {
-      impl_.template assign<I>(variants::lib::forward<Arg>(arg));
-      return *this;
-    }
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = variants::lib::type_pack_element_t<I, Ts...>,
-        variants::lib::enable_if_t<std::is_constructible<T, Args...>::value,
-                                   int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(variants::lib::forward<Args>(args)...);
-    }
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = variants::lib::type_pack_element_t<I, Ts...>,
-        variants::lib::enable_if_t<
-            std::is_constructible<T, std::initializer_list<Up> &, Args...>::
-                value,
-            int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il,
-                                       variants::lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        variants::lib::enable_if_t<std::is_constructible<T, Args...>::value,
-                                   int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(variants::lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        variants::lib::enable_if_t<
-            std::is_constructible<T, std::initializer_list<Up> &, Args...>::
-                value,
-            int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il,
-                                       variants::lib::forward<Args>(args)...);
-    }
-
-    inline constexpr bool valueless_by_exception() const noexcept {
-      return impl_.valueless_by_exception();
-    }
-
-    inline constexpr std::size_t index() const noexcept {
-      return impl_.index();
-    }
-
-    template <bool Dummy = true,
-              variants::lib::enable_if_t<
-                  variants::lib::all<
-                      Dummy,
-                      (std::is_move_constructible<Ts>::value &&
-                       variants::lib::is_swappable<Ts>::value)...>::value,
-                  int> = 0>
-    inline void swap(variant &that) noexcept(
-        variants::lib::all<
-            (std::is_nothrow_move_constructible<Ts>::value &&
-             variants::lib::is_nothrow_swappable<Ts>::value)...>::value) {
-      impl_.swap(that.impl_);
-    }
-
-    private:
-    detail::impl<Ts...> impl_;
-
-    friend struct detail::access::variant;
-    friend struct detail::visitation::variant;
-  };
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return v.index() == I;
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-    template <std::size_t I, typename V>
-    struct generic_get_impl {
-      constexpr generic_get_impl(int) {}
-
-      constexpr AUTO_REFREF operator()(V &&v) const
-        AUTO_REFREF_RETURN(
-            access::variant::get_alt<I>(variants::lib::forward<V>(v)).value)
-    };
-
-    template <std::size_t I, typename V>
-    inline constexpr AUTO_REFREF generic_get(V &&v)
-      AUTO_REFREF_RETURN(generic_get_impl<I, V>(
-          holds_alternative<I>(v) ? 0 : throw bad_variant_access{})(
-          variants::lib::forward<V>(v)))
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
-      variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
-      variant<Ts...> &&v) {
-    return detail::generic_get<I>(variants::lib::move(v));
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
-      const variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
-      const variant<Ts...> &&v) {
-    return detail::generic_get<I>(variants::lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &get(variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &&get(variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(
-        variants::lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &get(const variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &&get(const variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(
-        variants::lib::move(v));
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept
-      AUTO_RETURN(
-          v && holds_alternative<I>(*v)
-              ? variants::lib::addressof(access::variant::get_alt<I>(*v).value)
-              : nullptr)
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variants::lib::add_pointer_t<
-      variant_alternative_t<I, variant<Ts...>>>
-  get_if(variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variants::lib::add_pointer_t<
-      const variant_alternative_t<I, variant<Ts...>>>
-  get_if(const variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr variants::lib::add_pointer_t<T>
-  get_if(variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr variants::lib::add_pointer_t<const T>
-  get_if(const variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator==(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using variants::lib::equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
-#else
-    return lhs.index() == rhs.index() &&
-           (lhs.valueless_by_exception() ||
-            variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator!=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using variants::lib::not_equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
-#else
-    return lhs.index() != rhs.index() ||
-           (!lhs.valueless_by_exception() &&
-            variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using variants::lib::less;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
-#else
-    return !rhs.valueless_by_exception() &&
-           (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using variants::lib::greater;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return false;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
-#else
-    return !lhs.valueless_by_exception() &&
-           (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using variants::lib::less_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return true;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
-#else
-    return lhs.valueless_by_exception() ||
-           (!rhs.valueless_by_exception() &&
-            (lhs.index() < rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using variants::lib::greater_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
-#else
-    return rhs.valueless_by_exception() ||
-           (!lhs.valueless_by_exception() &&
-            (lhs.index() > rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(
-                  lhs.index(), greater_equal{}, lhs, rhs))));
-#endif
-  }
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs)
-    DECLTYPE_AUTO_RETURN((detail::all(!vs.valueless_by_exception()...)
-                              ? (void)0
-                              : throw bad_variant_access{}),
-                         detail::visitation::variant::visit_value(
-                             variants::lib::forward<Visitor>(visitor),
-                             variants::lib::forward<Vs>(vs)...))
-
-  struct monostate {};
-
-  inline constexpr bool operator<(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator>(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator<=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator>=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator==(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator!=(monostate, monostate) noexcept {
-    return false;
-  }
-
-  template <typename... Ts>
-  inline auto swap(variant<Ts...> &lhs,
-                   variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
-      -> decltype(lhs.swap(rhs)) {
-    lhs.swap(rhs);
-  }
-
-  namespace detail {
-
-    template <typename T, typename...>
-    using enabled_type = T;
-
-    namespace hash {
-
-      template <typename H, typename K>
-      constexpr bool meets_requirements() {
-        return std::is_copy_constructible<H>::value &&
-               std::is_move_constructible<H>::value &&
-               variants::lib::is_invocable_r<std::size_t, H, const K &>::value;
-      }
-
-      template <typename K>
-      constexpr bool is_enabled() {
-        using H = std::hash<K>;
-        return meets_requirements<H, K>() &&
-               std::is_default_constructible<H>::value &&
-               std::is_copy_assignable<H>::value &&
-               std::is_move_assignable<H>::value;
-      }
-
-    }  // namespace hash
-
-  }  // namespace detail
-
-#undef AUTO
-#undef AUTO_RETURN
-
-#undef AUTO_REFREF
-#undef AUTO_REFREF_RETURN
-
-#undef DECLTYPE_AUTO
-#undef DECLTYPE_AUTO_RETURN
-
-}  // namespace mpark
-
-namespace std {
-
-  template <typename... Ts>
-  struct hash<mpark::detail::enabled_type<
-      mpark::variant<Ts...>,
-      mpark::variants::lib::enable_if_t<
-          mpark::variants::lib::all<mpark::detail::hash::is_enabled<
-              mpark::variants::lib::remove_const_t<Ts>>()...>::value>>> {
-    using argument_type = mpark::variant<Ts...>;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &v) const {
-      using mpark::detail::visitation::variant;
-      std::size_t result =
-          v.valueless_by_exception()
-              ? 299792458  // Random value chosen by the universe upon creation
-              : variant::visit_alt(
-#ifdef MPARK_GENERIC_LAMBDAS
-                    [](const auto &alt) {
-                      using alt_type =
-                          mpark::variants::lib::decay_t<decltype(alt)>;
-                      using value_type = mpark::variants::lib::remove_const_t<
-                          typename alt_type::value_type>;
-                      return hash<value_type>{}(alt.value);
-                    }
-#else
-                    hasher{}
-#endif
-                    ,
-                    v);
-      return hash_combine(result, hash<std::size_t>{}(v.index()));
-    }
-
-    private:
-#ifndef MPARK_GENERIC_LAMBDAS
-    struct hasher {
-      template <typename Alt>
-      inline std::size_t operator()(const Alt &alt) const {
-        using alt_type = mpark::variants::lib::decay_t<Alt>;
-        using value_type =
-            mpark::variants::lib::remove_const_t<typename alt_type::value_type>;
-        return hash<value_type>{}(alt.value);
-      }
-    };
-#endif
-
-    static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
-      return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
-    }
-  };
-
-  template <>
-  struct hash<mpark::monostate> {
-    using argument_type = mpark::monostate;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &) const noexcept {
-      return 66740831;  // return a fundamentally attractive random value.
-    }
-  };
-
-}  // namespace std
-
-#endif  // MPARK_VARIANT_HPP

+ 0 - 2365
src/external/mpark-variant/v1.2.0/variant.hpp

@@ -1,2365 +0,0 @@
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANT_HPP
-#define MPARK_VARIANT_HPP
-
-/*
-   variant synopsis
-
-namespace std {
-
-  // 20.7.2, class template variant
-  template <class... Types>
-  class variant {
-  public:
-
-    // 20.7.2.1, constructors
-    constexpr variant() noexcept(see below);
-    variant(const variant&);
-    variant(variant&&) noexcept(see below);
-
-    template <class T> constexpr variant(T&&) noexcept(see below);
-
-    template <class T, class... Args>
-    constexpr explicit variant(in_place_type_t<T>, Args&&...);
-
-    template <class T, class U, class... Args>
-    constexpr explicit variant(
-        in_place_type_t<T>, initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    constexpr explicit variant(in_place_index_t<I>, Args&&...);
-
-    template <size_t I, class U, class... Args>
-    constexpr explicit variant(
-        in_place_index_t<I>, initializer_list<U>, Args&&...);
-
-    // 20.7.2.2, destructor
-    ~variant();
-
-    // 20.7.2.3, assignment
-    variant& operator=(const variant&);
-    variant& operator=(variant&&) noexcept(see below);
-
-    template <class T> variant& operator=(T&&) noexcept(see below);
-
-    // 20.7.2.4, modifiers
-    template <class T, class... Args>
-    T& emplace(Args&&...);
-
-    template <class T, class U, class... Args>
-    T& emplace(initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    variant_alternative<I, variant>& emplace(Args&&...);
-
-    template <size_t I, class U, class...  Args>
-    variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
-
-    // 20.7.2.5, value status
-    constexpr bool valueless_by_exception() const noexcept;
-    constexpr size_t index() const noexcept;
-
-    // 20.7.2.6, swap
-    void swap(variant&) noexcept(see below);
-  };
-
-  // 20.7.3, variant helper classes
-  template <class T> struct variant_size; // undefined
-
-  template <class T>
-  constexpr size_t variant_size_v = variant_size<T>::value;
-
-  template <class T> struct variant_size<const T>;
-  template <class T> struct variant_size<volatile T>;
-  template <class T> struct variant_size<const volatile T>;
-
-  template <class... Types>
-  struct variant_size<variant<Types...>>;
-
-  template <size_t I, class T> struct variant_alternative; // undefined
-
-  template <size_t I, class T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <size_t I, class T> struct variant_alternative<I, const T>;
-  template <size_t I, class T> struct variant_alternative<I, volatile T>;
-  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
-
-  template <size_t I, class... Types>
-  struct variant_alternative<I, variant<Types...>>;
-
-  constexpr size_t variant_npos = -1;
-
-  // 20.7.4, value access
-  template <class T, class... Types>
-  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&
-  get(variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&&
-  get(variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&
-  get(const variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&&
-  get(const variant<Types...>&&);
-
-  template <class T, class...  Types>
-  constexpr T& get(variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr T&& get(variant<Types...>&&);
-
-  template <class T, class... Types>
-  constexpr const T& get(const variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr const T&& get(const variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
-  get_if(variant<Types...>*) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
-  get_if(const variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<T>
-  get_if(variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<const T>
-  get_if(const variant<Types...>*) noexcept;
-
-  // 20.7.5, relational operators
-  template <class... Types>
-  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
-
-  // 20.7.6, visitation
-  template <class Visitor, class... Variants>
-  constexpr see below visit(Visitor&&, Variants&&...);
-
-  // 20.7.7, class monostate
-  struct monostate;
-
-  // 20.7.8, monostate relational operators
-  constexpr bool operator<(monostate, monostate) noexcept;
-  constexpr bool operator>(monostate, monostate) noexcept;
-  constexpr bool operator<=(monostate, monostate) noexcept;
-  constexpr bool operator>=(monostate, monostate) noexcept;
-  constexpr bool operator==(monostate, monostate) noexcept;
-  constexpr bool operator!=(monostate, monostate) noexcept;
-
-  // 20.7.9, specialized algorithms
-  template <class... Types>
-  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
-
-  // 20.7.10, class bad_variant_access
-  class bad_variant_access;
-
-  // 20.7.11, hash support
-  template <class T> struct hash;
-  template <class... Types> struct hash<variant<Types...>>;
-  template <> struct hash<monostate>;
-
-} // namespace std
-
-*/
-
-#include <cstddef>
-#include <exception>
-#include <functional>
-#include <initializer_list>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_CONFIG_HPP
-#define MPARK_CONFIG_HPP
-
-// MSVC 2015 Update 3.
-#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024215)
-#error "MPark.Variant requires C++11 support."
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-
-#if __has_builtin(__builtin_addressof) || \
-    (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
-#define MPARK_BUILTIN_ADDRESSOF
-#endif
-
-#if __has_builtin(__type_pack_element)
-#define MPARK_TYPE_PACK_ELEMENT
-#endif
-
-#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
-#define MPARK_CPP14_CONSTEXPR
-#endif
-
-#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions)
-#define MPARK_EXCEPTIONS
-#endif
-
-#if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
-#define MPARK_GENERIC_LAMBDAS
-#endif
-
-#if defined(__cpp_lib_integer_sequence)
-#define MPARK_INTEGER_SEQUENCE
-#endif
-
-#if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
-#define MPARK_RETURN_TYPE_DEDUCTION
-#endif
-
-#if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
-#define MPARK_TRANSPARENT_OPERATORS
-#endif
-
-#if defined(__cpp_variable_templates) || defined(_MSC_VER)
-#define MPARK_VARIABLE_TEMPLATES
-#endif
-
-#if !defined(__GLIBCXX__)
-#define MPARK_TRIVIALITY_TYPE_TRAITS
-#elif defined(__has_include) && __has_include(<codecvt>)  // >= libstdc++-5
-#define MPARK_TRIVIALITY_TYPE_TRAITS
-#endif
-
-#endif  // MPARK_CONFIG_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_IN_PLACE_HPP
-#define MPARK_IN_PLACE_HPP
-
-#include <cstddef>
-
-
-namespace mpark {
-
-  struct in_place_t { explicit in_place_t() = default; };
-
-  template <std::size_t I>
-  struct in_place_index_t { explicit in_place_index_t() = default; };
-
-  template <typename T>
-  struct in_place_type_t { explicit in_place_type_t() = default; };
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  constexpr in_place_t in_place{};
-
-  template <std::size_t I> constexpr in_place_index_t<I> in_place_index{};
-
-  template <typename T> constexpr in_place_type_t<T> in_place_type{};
-#endif
-
-}  // namespace mpark
-
-#endif  // MPARK_IN_PLACE_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_LIB_HPP
-#define MPARK_LIB_HPP
-
-#include <memory>
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-
-#define RETURN(...)                                          \
-  noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { \
-    return __VA_ARGS__;                                      \
-  }
-
-namespace mpark {
-  namespace lib {
-    template <typename T>
-    struct identity { using type = T; };
-
-    inline namespace cpp14 {
-      template <typename T, std::size_t N>
-      struct array {
-        constexpr const T &operator[](std::size_t index) const {
-          return data[index];
-        }
-
-        T data[N == 0 ? 1 : N];
-      };
-
-      template <typename T>
-      using add_pointer_t = typename std::add_pointer<T>::type;
-
-      template <typename... Ts>
-      using common_type_t = typename std::common_type<Ts...>::type;
-
-      template <typename T>
-      using decay_t = typename std::decay<T>::type;
-
-      template <bool B, typename T = void>
-      using enable_if_t = typename std::enable_if<B, T>::type;
-
-      template <typename T>
-      using remove_const_t = typename std::remove_const<T>::type;
-
-      template <typename T>
-      using remove_reference_t = typename std::remove_reference<T>::type;
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &t) noexcept {
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &&t) noexcept {
-        static_assert(!std::is_lvalue_reference<T>::value,
-                      "can not forward an rvalue as an lvalue");
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr remove_reference_t<T> &&move(T &&t) noexcept {
-        return static_cast<remove_reference_t<T> &&>(t);
-      }
-
-#ifdef MPARK_INTEGER_SEQUENCE
-      template <typename T, T... Is>
-      using integer_sequence = std::integer_sequence<T, Is...>;
-
-      template <std::size_t... Is>
-      using index_sequence = std::index_sequence<Is...>;
-
-      template <std::size_t N>
-      using make_index_sequence = std::make_index_sequence<N>;
-
-      template <typename... Ts>
-      using index_sequence_for = std::index_sequence_for<Ts...>;
-#else
-      template <typename T, T... Is>
-      struct integer_sequence {
-        using value_type = T;
-        static constexpr std::size_t size() noexcept { return sizeof...(Is); }
-      };
-
-      template <std::size_t... Is>
-      using index_sequence = integer_sequence<std::size_t, Is...>;
-
-      template <typename Lhs, typename Rhs>
-      struct make_index_sequence_concat;
-
-      template <std::size_t... Lhs, std::size_t... Rhs>
-      struct make_index_sequence_concat<index_sequence<Lhs...>,
-                                        index_sequence<Rhs...>>
-          : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
-
-      template <std::size_t N>
-      struct make_index_sequence_impl;
-
-      template <std::size_t N>
-      using make_index_sequence = typename make_index_sequence_impl<N>::type;
-
-      template <std::size_t N>
-      struct make_index_sequence_impl
-          : make_index_sequence_concat<make_index_sequence<N / 2>,
-                                       make_index_sequence<N - (N / 2)>> {};
-
-      template <>
-      struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
-
-      template <>
-      struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
-
-      template <typename... Ts>
-      using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
-#endif
-
-      // <functional>
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using equal_to = std::equal_to<>;
-#else
-      struct equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using not_equal_to = std::not_equal_to<>;
-#else
-      struct not_equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less = std::less<>;
-#else
-      struct less {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater = std::greater<>;
-#else
-      struct greater {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less_equal = std::less_equal<>;
-#else
-      struct less_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater_equal = std::greater_equal<>;
-#else
-      struct greater_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
-      };
-#endif
-    }  // namespace cpp14
-
-    inline namespace cpp17 {
-
-      // <type_traits>
-      template <bool B>
-      using bool_constant = std::integral_constant<bool, B>;
-
-      template <typename...>
-      struct voider : identity<void> {};
-
-      template <typename... Ts>
-      using void_t = typename voider<Ts...>::type;
-
-      namespace detail {
-        namespace swappable {
-
-          using std::swap;
-
-          template <typename T>
-          struct is_swappable_impl {
-            private:
-            template <typename U,
-                      typename = decltype(swap(std::declval<U &>(),
-                                               std::declval<U &>()))>
-            inline static std::true_type test(int);
-
-            template <typename U>
-            inline static std::false_type test(...);
-
-            public:
-            using type = decltype(test<T>(0));
-          };
-
-          template <typename T>
-          using is_swappable = typename is_swappable_impl<T>::type;
-
-          template <typename T, bool = is_swappable<T>::value>
-          struct is_nothrow_swappable {
-            static constexpr bool value =
-                noexcept(swap(std::declval<T &>(), std::declval<T &>()));
-          };
-
-          template <typename T>
-          struct is_nothrow_swappable<T, false> : std::false_type {};
-
-        }  // namespace swappable
-      }  // namespace detail
-
-      template <typename T>
-      using is_swappable = detail::swappable::is_swappable<T>;
-
-      template <typename T>
-      using is_nothrow_swappable = detail::swappable::is_nothrow_swappable<T>;
-
-      // <functional>
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename F, typename... As>
-      inline constexpr auto invoke(F &&f, As &&... as)
-          RETURN(lib::forward<F>(f)(lib::forward<As>(as)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      template <typename B, typename T, typename D>
-      inline constexpr auto invoke(T B::*pmv, D &&d)
-          RETURN(lib::forward<D>(d).*pmv)
-
-      template <typename Pmv, typename Ptr>
-      inline constexpr auto invoke(Pmv pmv, Ptr &&ptr)
-          RETURN((*lib::forward<Ptr>(ptr)).*pmv)
-
-      template <typename B, typename T, typename D, typename... As>
-      inline constexpr auto invoke(T B::*pmf, D &&d, As &&... as)
-          RETURN((lib::forward<D>(d).*pmf)(lib::forward<As>(as)...))
-
-      template <typename Pmf, typename Ptr, typename... As>
-      inline constexpr auto invoke(Pmf pmf, Ptr &&ptr, As &&... as)
-          RETURN(((*lib::forward<Ptr>(ptr)).*pmf)(lib::forward<As>(as)...))
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct invoke_result {};
-
-        template <typename F, typename... Args>
-        struct invoke_result<void_t<decltype(lib::invoke(
-                                 std::declval<F>(), std::declval<Args>()...))>,
-                             F,
-                             Args...>
-            : identity<decltype(
-                  lib::invoke(std::declval<F>(), std::declval<Args>()...))> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using invoke_result = detail::invoke_result<void, F, Args...>;
-
-      template <typename F, typename... Args>
-      using invoke_result_t = typename invoke_result<F, Args...>::type;
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct is_invocable : std::false_type {};
-
-        template <typename F, typename... Args>
-        struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
-            : std::true_type {};
-
-        template <typename Void, typename, typename, typename...>
-        struct is_invocable_r : std::false_type {};
-
-        template <typename R, typename F, typename... Args>
-        struct is_invocable_r<void_t<invoke_result_t<F, Args...>>,
-                              R,
-                              F,
-                              Args...>
-            : std::is_convertible<invoke_result_t<F, Args...>, R> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using is_invocable = detail::is_invocable<void, F, Args...>;
-
-      template <typename R, typename F, typename... Args>
-      using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
-
-      // <memory>
-#ifdef MPARK_BUILTIN_ADDRESSOF
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return __builtin_addressof(arg);
-      }
-#else
-      namespace detail {
-
-        namespace has_addressof_impl {
-
-          struct fail;
-
-          template <typename T>
-          inline fail operator&(T &&);
-
-          template <typename T>
-          inline static constexpr bool impl() {
-            return (std::is_class<T>::value || std::is_union<T>::value) &&
-                   !std::is_same<decltype(&std::declval<T &>()), fail>::value;
-          }
-
-        }  // namespace has_addressof_impl
-
-        template <typename T>
-        using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::true_type) {
-          return std::addressof(arg);
-        }
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::false_type) {
-          return &arg;
-        }
-
-      }  // namespace detail
-
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return detail::addressof(arg, detail::has_addressof<T>{});
-      }
-#endif
-
-      template <typename T>
-      inline constexpr T *addressof(const T &&) = delete;
-
-    }  // namespace cpp17
-
-    template <typename T>
-    struct remove_all_extents : identity<T> {};
-
-    template <typename T, std::size_t N>
-    struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
-
-    template <typename T>
-    using remove_all_extents_t = typename remove_all_extents<T>::type;
-
-    template <std::size_t N>
-    using size_constant = std::integral_constant<std::size_t, N>;
-
-    template <bool... Bs>
-    using bool_sequence = integer_sequence<bool, Bs...>;
-
-    template <std::size_t I, typename T>
-    struct indexed_type : size_constant<I>, identity<T> {};
-
-    template <bool... Bs>
-    using all =
-        std::is_same<bool_sequence<true, Bs...>, bool_sequence<Bs..., true>>;
-
-#ifdef MPARK_TYPE_PACK_ELEMENT
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = __type_pack_element<I, Ts...>;
-#else
-    template <std::size_t I, typename... Ts>
-    struct type_pack_element_impl {
-      private:
-      template <typename>
-      struct set;
-
-      template <std::size_t... Is>
-      struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
-
-      template <typename T>
-      inline static std::enable_if<true, T> impl(indexed_type<I, T>);
-
-      inline static std::enable_if<false> impl(...);
-
-      public:
-      using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
-    };
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
-#endif
-
-#ifdef MPARK_TRIVIALITY_TYPE_TRAITS
-    template <typename T>
-    using is_trivially_copy_constructible =
-        std::is_trivially_copy_constructible<T>;
-
-    template <typename T>
-    using is_trivially_move_constructible =
-        std::is_trivially_move_constructible<T>;
-
-    template <typename T>
-    using is_trivially_copy_assignable = std::is_trivially_copy_assignable<T>;
-
-    template <typename T>
-    using is_trivially_move_assignable = std::is_trivially_move_assignable<T>;
-#else
-    template <typename T>
-    struct is_trivially_copy_constructible
-        : bool_constant<
-              std::is_copy_constructible<T>::value && __has_trivial_copy(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {};
-
-    template <typename T>
-    struct is_trivially_copy_assignable
-        : bool_constant<
-              std::is_copy_assignable<T>::value && __has_trivial_assign(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {};
-#endif
-
-  }  // namespace lib
-}  // namespace mpark
-
-#undef RETURN
-
-#endif  // MPARK_LIB_HPP
-
-
-namespace mpark {
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-
-#define AUTO auto
-#define AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto &&
-#define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; }
-
-#define DECLTYPE_AUTO decltype(auto)
-#define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#else
-
-#define AUTO auto
-#define AUTO_RETURN(...) \
-  -> lib::decay_t<decltype(__VA_ARGS__)> { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto
-#define AUTO_REFREF_RETURN(...)                                           \
-  -> decltype((__VA_ARGS__)) {                                            \
-    static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
-    return __VA_ARGS__;                                                   \
-  }
-
-#define DECLTYPE_AUTO auto
-#define DECLTYPE_AUTO_RETURN(...) \
-  -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-#endif
-
-  class bad_variant_access : public std::exception {
-    public:
-    virtual const char *what() const noexcept { return "bad_variant_access"; }
-  };
-
-  [[noreturn]] inline void throw_bad_variant_access() {
-#ifdef MPARK_EXCEPTIONS
-    throw bad_variant_access{};
-#else
-    std::terminate();
-#endif
-  }
-
-  template <typename... Ts>
-  class variant;
-
-  template <typename T>
-  struct variant_size;
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  template <typename T>
-  constexpr std::size_t variant_size_v = variant_size<T>::value;
-#endif
-
-  template <typename T>
-  struct variant_size<const T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<volatile T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<const volatile T> : variant_size<T> {};
-
-  template <typename... Ts>
-  struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative;
-
-  template <std::size_t I, typename T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const T>
-      : std::add_const<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, volatile T>
-      : std::add_volatile<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const volatile T>
-      : std::add_cv<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename... Ts>
-  struct variant_alternative<I, variant<Ts...>>
-      : lib::identity<lib::type_pack_element_t<I, Ts...>> {
-    static_assert(I < sizeof...(Ts),
-                  "`variant_alternative` index out of range.");
-  };
-
-  constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
-
-  namespace detail {
-
-    inline constexpr bool all() { return true; }
-
-    template <typename... Bs>
-    inline constexpr bool all(bool b, Bs... bs) {
-      return b && all(bs...);
-    }
-
-    constexpr std::size_t not_found = static_cast<std::size_t>(-1);
-    constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      constexpr lib::array<bool, sizeof...(Ts)> matches = {
-          {std::is_same<T, Ts>::value...}
-      };
-      std::size_t result = not_found;
-      for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
-        if (matches[i]) {
-          if (result != not_found) {
-            return ambiguous;
-          }
-          result = i;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t) {
-      return result;
-    }
-
-    template <typename... Bs>
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t idx,
-                                                 bool b,
-                                                 Bs... bs) {
-      return b ? (result != not_found ? ambiguous
-                                      : find_index_impl(idx, idx + 1, bs...))
-               : find_index_impl(result, idx + 1, bs...);
-    }
-
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
-    }
-#endif
-
-    template <std::size_t I>
-    using find_index_sfinae_impl =
-        lib::enable_if_t<I != not_found && I != ambiguous,
-                         lib::size_constant<I>>;
-
-    template <typename T, typename... Ts>
-    using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
-
-    template <std::size_t I>
-    struct find_index_checked_impl : lib::size_constant<I> {
-      static_assert(I != not_found, "the specified type is not found.");
-      static_assert(I != ambiguous, "the specified type is ambiguous.");
-    };
-
-    template <typename T, typename... Ts>
-    using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
-
-    struct valueless_t {};
-
-    enum class Trait { TriviallyAvailable, Available, Unavailable };
-
-    template <typename T,
-              template <typename> class IsTriviallyAvailable,
-              template <typename> class IsAvailable>
-    inline constexpr Trait trait() {
-      return IsTriviallyAvailable<T>::value
-                 ? Trait::TriviallyAvailable
-                 : IsAvailable<T>::value ? Trait::Available
-                                         : Trait::Unavailable;
-    }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... traits) {
-      Trait result = Trait::TriviallyAvailable;
-      for (Trait t : {traits...}) {
-        if (static_cast<int>(t) > static_cast<int>(result)) {
-          result = t;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr Trait common_trait_impl(Trait result) { return result; }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait_impl(Trait result,
-                                             Trait t,
-                                             Traits... ts) {
-      return static_cast<int>(t) > static_cast<int>(result)
-                 ? common_trait_impl(t, ts...)
-                 : common_trait_impl(result, ts...);
-    }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... ts) {
-      return common_trait_impl(Trait::TriviallyAvailable, ts...);
-    }
-#endif
-
-    template <typename... Ts>
-    struct traits {
-      static constexpr Trait copy_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_copy_constructible,
-                             std::is_copy_constructible>()...);
-
-      static constexpr Trait move_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_move_constructible,
-                             std::is_move_constructible>()...);
-
-      static constexpr Trait copy_assignable_trait =
-          common_trait(copy_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_copy_assignable,
-                             std::is_copy_assignable>()...);
-
-      static constexpr Trait move_assignable_trait =
-          common_trait(move_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_move_assignable,
-                             std::is_move_assignable>()...);
-
-      static constexpr Trait destructible_trait =
-          common_trait(trait<Ts,
-                             std::is_trivially_destructible,
-                             std::is_destructible>()...);
-    };
-
-    namespace access {
-
-      struct recursive_union {
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename V>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
-          return lib::forward<V>(v).head_;
-        }
-
-        template <typename V, std::size_t I>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
-          return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
-        }
-#else
-        template <std::size_t I, bool Dummy = true>
-        struct get_alt_impl {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
-        };
-
-        template <bool Dummy>
-        struct get_alt_impl<0, Dummy> {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
-        };
-
-        template <typename V, std::size_t I>
-        inline static constexpr AUTO_REFREF get_alt(V &&v, in_place_index_t<I>)
-          AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
-#endif
-      };
-
-      struct base {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(recursive_union::get_alt(
-              data(lib::forward<V>(v)), in_place_index_t<I>{}))
-      };
-
-      struct variant {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
-      };
-
-    }  // namespace access
-
-    namespace visitation {
-
-      struct base {
-        private:
-        template <typename T>
-        inline static constexpr const T &at(const T &elem) {
-          return elem;
-        }
-
-        template <typename T, std::size_t N, typename... Is>
-        inline static constexpr const lib::remove_all_extents_t<T> &at(
-            const lib::array<T, N> &elems, std::size_t i, Is... is) {
-          return at(elems[i], is...);
-        }
-
-        template <typename F, typename... Fs>
-        inline static constexpr int visit_visitor_return_type_check() {
-          static_assert(all(std::is_same<F, Fs>::value...),
-                        "`mpark::visit` requires the visitor to have a single "
-                        "return type.");
-          return 0;
-        }
-
-        template <typename... Fs>
-        inline static constexpr lib::array<
-            lib::common_type_t<lib::decay_t<Fs>...>,
-            sizeof...(Fs)>
-        make_farray(Fs &&... fs) {
-          using result = lib::array<lib::common_type_t<lib::decay_t<Fs>...>,
-                                    sizeof...(Fs)>;
-          return visit_visitor_return_type_check<lib::decay_t<Fs>...>(),
-                 result{{lib::forward<Fs>(fs)...}};
-        }
-
-        template <std::size_t... Is>
-        struct dispatcher {
-          template <typename F, typename... Vs>
-          struct impl {
-            inline static constexpr DECLTYPE_AUTO dispatch(F f, Vs... vs)
-              DECLTYPE_AUTO_RETURN(lib::invoke(
-                  static_cast<F>(f),
-                  access::base::get_alt<Is>(static_cast<Vs>(vs))...))
-          };
-        };
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_dispatch(lib::index_sequence<Is...>)
-          AUTO_RETURN(&dispatcher<Is...>::template impl<F, Vs...>::dispatch)
-
-        template <std::size_t I, typename F, typename... Vs>
-        inline static constexpr AUTO make_fdiagonal_impl()
-          AUTO_RETURN(make_dispatch<F, Vs...>(
-              lib::index_sequence<lib::indexed_type<I, Vs>::value...>{}))
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_fdiagonal_impl(
-            lib::index_sequence<Is...>)
-          AUTO_RETURN(make_farray(make_fdiagonal_impl<Is, F, Vs...>()...))
-
-        template <typename F, typename V, typename... Vs>
-        inline static constexpr /* auto * */ auto make_fdiagonal()
-            -> decltype(make_fdiagonal_impl<F, V, Vs...>(
-                lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
-          static_assert(
-              all((lib::decay_t<V>::size() == lib::decay_t<Vs>::size())...),
-              "all of the variants must be the same size.");
-          return make_fdiagonal_impl<F, V, Vs...>(
-              lib::make_index_sequence<lib::decay_t<V>::size()>{});
-        }
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_fmatrix_impl(
-            lib::index_sequence<Is...> is) {
-          return make_dispatch<F, Vs...>(is);
-        }
-
-        template <typename F,
-                  typename... Vs,
-                  std::size_t... Is,
-                  std::size_t... Js,
-                  typename... Ls>
-        inline static constexpr auto make_fmatrix_impl(
-            lib::index_sequence<Is...>, lib::index_sequence<Js...>, Ls... ls) {
-          return make_farray(make_fmatrix_impl<F, Vs...>(
-              lib::index_sequence<Is..., Js>{}, ls...)...);
-        }
-
-        template <typename F, typename... Vs>
-        inline static constexpr auto make_fmatrix() {
-          return make_fmatrix_impl<F, Vs...>(
-              lib::index_sequence<>{},
-              lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
-        }
-#else
-        template <typename F, typename... Vs>
-        struct make_fmatrix_impl {
-          template <typename...>
-          struct impl;
-
-          template <std::size_t... Is>
-          struct impl<lib::index_sequence<Is...>> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(
-                  make_dispatch<F, Vs...>(lib::index_sequence<Is...>{}))
-          };
-
-          template <std::size_t... Is, std::size_t... Js, typename... Ls>
-          struct impl<lib::index_sequence<Is...>,
-                      lib::index_sequence<Js...>,
-                      Ls...> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(make_farray(
-                  impl<lib::index_sequence<Is..., Js>, Ls...>{}()...))
-          };
-        };
-
-        template <typename F, typename... Vs>
-        inline static constexpr AUTO make_fmatrix()
-          AUTO_RETURN(
-              typename make_fmatrix_impl<F, Vs...>::template impl<
-                  lib::index_sequence<>,
-                  lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
-#endif
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              at(make_fdiagonal<Visitor &&,
-                                decltype(as_base(lib::forward<Vs>(vs)))...>(),
-                 index)(lib::forward<Visitor>(visitor),
-                        as_base(lib::forward<Vs>(vs))...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              at(make_fmatrix<Visitor &&,
-                              decltype(as_base(lib::forward<Vs>(vs)))...>(),
-                 vs.index()...)(lib::forward<Visitor>(visitor),
-                                as_base(lib::forward<Vs>(vs))...))
-      };
-
-      struct variant {
-        private:
-        template <typename Visitor, typename... Values>
-        struct visit_exhaustive_visitor_check {
-          static_assert(
-              lib::is_invocable<Visitor, Values...>::value,
-              "`mpark::visit` requires the visitor to be exhaustive.");
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-          inline constexpr DECLTYPE_AUTO operator()(Visitor &&visitor,
-                                                    Values &&... values) const
-            DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
-                                             lib::forward<Values>(values)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        };
-
-        template <typename Visitor>
-        struct value_visitor {
-          Visitor &&visitor_;
-
-          template <typename... Alts>
-          inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const
-            DECLTYPE_AUTO_RETURN(
-                visit_exhaustive_visitor_check<
-                    Visitor,
-                    decltype((lib::forward<Alts>(alts).value))...>{}(
-                    lib::forward<Visitor>(visitor_),
-                    lib::forward<Alts>(alts).value...))
-        };
-
-        template <typename Visitor>
-        inline static constexpr AUTO make_value_visitor(Visitor &&visitor)
-          AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              base::visit_alt_at(index,
-                                 lib::forward<Visitor>(visitor),
-                                 lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(base::visit_alt(lib::forward<Visitor>(visitor),
-                                               lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index,
-                                                             Visitor &&visitor,
-                                                             Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt_at(index,
-                           make_value_visitor(lib::forward<Visitor>(visitor)),
-                           lib::forward<Vs>(vs)...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor,
-                                                          Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt(make_value_visitor(lib::forward<Visitor>(visitor)),
-                        lib::forward<Vs>(vs)...))
-      };
-
-    }  // namespace visitation
-
-    template <std::size_t Index, typename T>
-    struct alt {
-      using value_type = T;
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-      template <typename... Args>
-      inline explicit constexpr alt(in_place_t, Args &&... args)
-          : value(lib::forward<Args>(args)...) {}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      T value;
-    };
-
-    template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
-    union recursive_union;
-
-    template <Trait DestructibleTrait, std::size_t Index>
-    union recursive_union<DestructibleTrait, Index> {};
-
-#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)      \
-  template <std::size_t Index, typename T, typename... Ts>                 \
-  union recursive_union<destructible_trait, Index, T, Ts...> {             \
-    public:                                                                \
-    inline explicit constexpr recursive_union(valueless_t) noexcept        \
-        : dummy_{} {}                                                      \
-                                                                           \
-    template <typename... Args>                                            \
-    inline explicit constexpr recursive_union(in_place_index_t<0>,         \
-                                              Args &&... args)             \
-        : head_(in_place_t{}, lib::forward<Args>(args)...) {}              \
-                                                                           \
-    template <std::size_t I, typename... Args>                             \
-    inline explicit constexpr recursive_union(in_place_index_t<I>,         \
-                                              Args &&... args)             \
-        : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
-                                                                           \
-    recursive_union(const recursive_union &) = default;                    \
-    recursive_union(recursive_union &&) = default;                         \
-                                                                           \
-    destructor                                                             \
-                                                                           \
-    recursive_union &operator=(const recursive_union &) = default;         \
-    recursive_union &operator=(recursive_union &&) = default;              \
-                                                                           \
-    private:                                                               \
-    char dummy_;                                                           \
-    alt<Index, T> head_;                                                   \
-    recursive_union<destructible_trait, Index + 1, Ts...> tail_;           \
-                                                                           \
-    friend struct access::recursive_union;                                 \
-  }
-
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
-                                  ~recursive_union() = default;);
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
-                                  ~recursive_union() {});
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
-                                  ~recursive_union() = delete;);
-
-#undef MPARK_VARIANT_RECURSIVE_UNION
-
-    using index_t = unsigned int;
-
-    template <Trait DestructibleTrait, typename... Ts>
-    class base {
-      public:
-      inline explicit constexpr base(valueless_t tag) noexcept
-          : data_(tag), index_(static_cast<index_t>(-1)) {}
-
-      template <std::size_t I, typename... Args>
-      inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
-          : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...),
-            index_(I) {}
-
-      inline constexpr bool valueless_by_exception() const noexcept {
-        return index_ == static_cast<index_t>(-1);
-      }
-
-      inline constexpr std::size_t index() const noexcept {
-        return valueless_by_exception() ? variant_npos : index_;
-      }
-
-      protected:
-      using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
-
-      friend inline constexpr base &as_base(base &b) { return b; }
-      friend inline constexpr const base &as_base(const base &b) { return b; }
-      friend inline constexpr base &&as_base(base &&b) { return lib::move(b); }
-      friend inline constexpr const base &&as_base(const base &&b) { return lib::move(b); }
-
-      friend inline constexpr data_t &data(base &b) { return b.data_; }
-      friend inline constexpr const data_t &data(const base &b) { return b.data_; }
-      friend inline constexpr data_t &&data(base &&b) { return lib::move(b).data_; }
-      friend inline constexpr const data_t &&data(const base &&b) { return lib::move(b).data_; }
-
-      inline static constexpr std::size_t size() { return sizeof...(Ts); }
-
-      data_t data_;
-      index_t index_;
-
-      friend struct access::base;
-      friend struct visitation::base;
-    };
-
-    struct dtor {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename Alt>
-      inline void operator()(Alt &alt) const noexcept { alt.~Alt(); }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-    };
-
-#if defined(_MSC_VER) && _MSC_VER < 1910
-#define INHERITING_CTOR(type, base)               \
-  template <typename... Args>                     \
-  inline explicit constexpr type(Args &&... args) \
-      : base(lib::forward<Args>(args)...) {}
-#else
-#define INHERITING_CTOR(type, base) using base::base;
-#endif
-
-    template <typename Traits, Trait = Traits::destructible_trait>
-    class destructor;
-
-#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
-  template <typename... Ts>                                               \
-  class destructor<traits<Ts...>, destructible_trait>                     \
-      : public base<destructible_trait, Ts...> {                          \
-    using super = base<destructible_trait, Ts...>;                        \
-                                                                          \
-    public:                                                               \
-    INHERITING_CTOR(destructor, super)                                    \
-    using super::operator=;                                               \
-                                                                          \
-    destructor(const destructor &) = default;                             \
-    destructor(destructor &&) = default;                                  \
-    definition                                                            \
-    destructor &operator=(const destructor &) = default;                  \
-    destructor &operator=(destructor &&) = default;                       \
-                                                                          \
-    protected:                                                            \
-    destroy                                                               \
-  }
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::TriviallyAvailable,
-        ~destructor() = default;,
-        inline void destroy() noexcept {
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Available,
-        ~destructor() { destroy(); },
-        inline void destroy() noexcept {
-          if (!this->valueless_by_exception()) {
-            visitation::base::visit_alt(dtor{}, *this);
-          }
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Unavailable,
-        ~destructor() = delete;,
-        inline void destroy() noexcept = delete;);
-
-#undef MPARK_VARIANT_DESTRUCTOR
-
-    template <typename Traits>
-    class constructor : public destructor<Traits> {
-      using super = destructor<Traits>;
-
-      public:
-      INHERITING_CTOR(constructor, super)
-      using super::operator=;
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct ctor {
-        template <typename LhsAlt, typename RhsAlt>
-        inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const {
-          constructor::construct_alt(lhs_alt,
-                                     lib::forward<RhsAlt>(rhs_alt).value);
-        }
-      };
-#endif
-
-      template <std::size_t I, typename T, typename... Args>
-      inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
-        ::new (static_cast<void *>(lib::addressof(a)))
-            alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
-        return a.value;
-      }
-
-      template <typename Rhs>
-      inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
-        lhs.destroy();
-        if (!rhs.valueless_by_exception()) {
-          visitation::base::visit_alt_at(
-              rhs.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [](auto &lhs_alt, auto &&rhs_alt) {
-                constructor::construct_alt(
-                    lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
-              }
-#else
-              ctor{}
-#endif
-              ,
-              lhs,
-              lib::forward<Rhs>(rhs));
-          lhs.index_ = rhs.index_;
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_constructible_trait>
-    class move_constructor;
-
-#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class move_constructor<traits<Ts...>, move_constructible_trait>            \
-      : public constructor<traits<Ts...>> {                                  \
-    using super = constructor<traits<Ts...>>;                                \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(move_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    move_constructor(const move_constructor &) = default;                    \
-    definition                                                               \
-    ~move_constructor() = default;                                           \
-    move_constructor &operator=(const move_constructor &) = default;         \
-    move_constructor &operator=(move_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        move_constructor(move_constructor &&that) = default;);
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Available,
-        move_constructor(move_constructor &&that) noexcept(
-            all(std::is_nothrow_move_constructible<Ts>::value...))
-            : move_constructor(valueless_t{}) {
-          this->generic_construct(*this, lib::move(that));
-        });
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Unavailable,
-        move_constructor(move_constructor &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_CONSTRUCTOR
-
-    template <typename Traits, Trait = Traits::copy_constructible_trait>
-    class copy_constructor;
-
-#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
-      : public move_constructor<traits<Ts...>> {                             \
-    using super = move_constructor<traits<Ts...>>;                           \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(copy_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    definition                                                               \
-    copy_constructor(copy_constructor &&) = default;                         \
-    ~copy_constructor() = default;                                           \
-    copy_constructor &operator=(const copy_constructor &) = default;         \
-    copy_constructor &operator=(copy_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        copy_constructor(const copy_constructor &that) = default;);
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Available,
-        copy_constructor(const copy_constructor &that)
-            : copy_constructor(valueless_t{}) {
-          this->generic_construct(*this, that);
-        });
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Unavailable,
-        copy_constructor(const copy_constructor &) = delete;);
-
-#undef MPARK_VARIANT_COPY_CONSTRUCTOR
-
-    template <typename Traits>
-    class assignment : public copy_constructor<Traits> {
-      using super = copy_constructor<Traits>;
-
-      public:
-      INHERITING_CTOR(assignment, super)
-      using super::operator=;
-
-      template <std::size_t I, typename... Args>
-      inline /* auto & */ auto emplace(Args &&... args)
-          -> decltype(this->construct_alt(access::base::get_alt<I>(*this),
-                                          lib::forward<Args>(args)...)) {
-        this->destroy();
-        auto &result = this->construct_alt(access::base::get_alt<I>(*this),
-                                           lib::forward<Args>(args)...);
-        this->index_ = I;
-        return result;
-      }
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      template <typename That>
-      struct assigner {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const {
-          self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
-        }
-        assignment *self;
-      };
-#endif
-
-      template <std::size_t I, typename T, typename Arg>
-      inline void assign_alt(alt<I, T> &a, Arg &&arg) {
-        if (this->index() == I) {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-          a.value = lib::forward<Arg>(arg);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        } else {
-          struct {
-            void operator()(std::true_type) const {
-              this_->emplace<I>(lib::forward<Arg>(arg_));
-            }
-            void operator()(std::false_type) const {
-              this_->emplace<I>(T(lib::forward<Arg>(arg_)));
-            }
-            assignment *this_;
-            Arg &&arg_;
-          } impl{this, lib::forward<Arg>(arg)};
-          impl(lib::bool_constant<
-                   std::is_nothrow_constructible<T, Arg>::value ||
-                   !std::is_nothrow_move_constructible<T>::value>{});
-        }
-      }
-
-      template <typename That>
-      inline void generic_assign(That &&that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (that.valueless_by_exception()) {
-          this->destroy();
-        } else {
-          visitation::base::visit_alt_at(
-              that.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [this](auto &this_alt, auto &&that_alt) {
-                this->assign_alt(
-                    this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
-              }
-#else
-              assigner<That>{this}
-#endif
-              ,
-              *this,
-              lib::forward<That>(that));
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_assignable_trait>
-    class move_assignment;
-
-#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class move_assignment<traits<Ts...>, move_assignable_trait>            \
-      : public assignment<traits<Ts...>> {                               \
-    using super = assignment<traits<Ts...>>;                             \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(move_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    move_assignment(const move_assignment &) = default;                  \
-    move_assignment(move_assignment &&) = default;                       \
-    ~move_assignment() = default;                                        \
-    move_assignment &operator=(const move_assignment &) = default;       \
-    definition                                                           \
-  }
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        move_assignment &operator=(move_assignment &&that) = default;);
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Available,
-        move_assignment &
-        operator=(move_assignment &&that) noexcept(
-            all((std::is_nothrow_move_constructible<Ts>::value &&
-                 std::is_nothrow_move_assignable<Ts>::value)...)) {
-          this->generic_assign(lib::move(that));
-          return *this;
-        });
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Unavailable,
-        move_assignment &operator=(move_assignment &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_ASSIGNMENT
-
-    template <typename Traits, Trait = Traits::copy_assignable_trait>
-    class copy_assignment;
-
-#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
-      : public move_assignment<traits<Ts...>> {                          \
-    using super = move_assignment<traits<Ts...>>;                        \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(copy_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    copy_assignment(const copy_assignment &) = default;                  \
-    copy_assignment(copy_assignment &&) = default;                       \
-    ~copy_assignment() = default;                                        \
-    definition                                                           \
-    copy_assignment &operator=(copy_assignment &&) = default;            \
-  }
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        copy_assignment &operator=(const copy_assignment &that) = default;);
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Available,
-        copy_assignment &operator=(const copy_assignment &that) {
-          this->generic_assign(that);
-          return *this;
-        });
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Unavailable,
-        copy_assignment &operator=(const copy_assignment &) = delete;);
-
-#undef MPARK_VARIANT_COPY_ASSIGNMENT
-
-    template <typename... Ts>
-    class impl : public copy_assignment<traits<Ts...>> {
-      using super = copy_assignment<traits<Ts...>>;
-
-      public:
-      INHERITING_CTOR(impl, super)
-      using super::operator=;
-
-      template <std::size_t I, typename Arg>
-      inline void assign(Arg &&arg) {
-        this->assign_alt(access::base::get_alt<I>(*this),
-                         lib::forward<Arg>(arg));
-      }
-
-      inline void swap(impl &that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (this->index() == that.index()) {
-          visitation::base::visit_alt_at(this->index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-                                         [](auto &this_alt, auto &that_alt) {
-                                           using std::swap;
-                                           swap(this_alt.value,
-                                                that_alt.value);
-                                         }
-#else
-                                         swapper{}
-#endif
-                                         ,
-                                         *this,
-                                         that);
-        } else {
-          impl *lhs = this;
-          impl *rhs = lib::addressof(that);
-          if (lhs->move_nothrow() && !rhs->move_nothrow()) {
-            std::swap(lhs, rhs);
-          }
-          impl tmp(lib::move(*rhs));
-#ifdef MPARK_EXCEPTIONS
-          // EXTENSION: When the move construction of `lhs` into `rhs` throws
-          // and `tmp` is nothrow move constructible then we move `tmp` back
-          // into `rhs` and provide the strong exception safety guarantee.
-          try {
-            this->generic_construct(*rhs, lib::move(*lhs));
-          } catch (...) {
-            if (tmp.move_nothrow()) {
-              this->generic_construct(*rhs, lib::move(tmp));
-            }
-            throw;
-          }
-#else
-          this->generic_construct(*rhs, lib::move(*lhs));
-#endif
-          this->generic_construct(*lhs, lib::move(tmp));
-        }
-      }
-
-      private:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct swapper {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const {
-          using std::swap;
-          swap(this_alt.value, that_alt.value);
-        }
-      };
-#endif
-
-      inline constexpr bool move_nothrow() const {
-        return this->valueless_by_exception() ||
-               lib::array<bool, sizeof...(Ts)>{
-                   {std::is_nothrow_move_constructible<Ts>::value...}
-               }[this->index()];
-      }
-    };
-
-    template <typename... Ts>
-    struct overload;
-
-    template <>
-    struct overload<> { void operator()() const {} };
-
-    template <typename T, typename... Ts>
-    struct overload<T, Ts...> : overload<Ts...> {
-      using overload<Ts...>::operator();
-      lib::identity<T> operator()(T) const { return {}; }
-    };
-
-    template <typename T, typename... Ts>
-    using best_match_t =
-        typename lib::invoke_result_t<overload<Ts...>, T &&>::type;
-
-  }  // detail
-
-  template <typename... Ts>
-  class variant {
-    static_assert(0 < sizeof...(Ts),
-                  "variant must consist of at least one alternative.");
-
-    static_assert(lib::all<!std::is_array<Ts>::value...>::value,
-                  "variant can not have an array type as an alternative.");
-
-    static_assert(lib::all<!std::is_reference<Ts>::value...>::value,
-                  "variant can not have a reference type as an alternative.");
-
-    static_assert(lib::all<!std::is_void<Ts>::value...>::value,
-                  "variant can not have a void type as an alternative.");
-
-    public:
-    template <
-        typename Front = lib::type_pack_element_t<0, Ts...>,
-        lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
-    inline constexpr variant() noexcept(
-        std::is_nothrow_default_constructible<Front>::value)
-        : impl_(in_place_index_t<0>{}) {}
-
-    variant(const variant &) = default;
-    variant(variant &&) = default;
-
-    template <typename Arg,
-              lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              typename T = detail::best_match_t<Arg, Ts...>,
-              std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-              lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
-    inline constexpr variant(Arg &&arg) noexcept(
-        std::is_nothrow_constructible<T, Arg>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {}
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    ~variant() = default;
-
-    variant &operator=(const variant &) = default;
-    variant &operator=(variant &&) = default;
-
-    template <typename Arg,
-              lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              typename T = detail::best_match_t<Arg, Ts...>,
-              std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-              lib::enable_if_t<(std::is_assignable<T &, Arg>::value &&
-                                std::is_constructible<T, Arg>::value),
-                               int> = 0>
-    inline variant &operator=(Arg &&arg) noexcept(
-        (std::is_nothrow_assignable<T &, Arg>::value &&
-         std::is_nothrow_constructible<T, Arg>::value)) {
-      impl_.template assign<I>(lib::forward<Arg>(arg));
-      return *this;
-    }
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    inline constexpr bool valueless_by_exception() const noexcept {
-      return impl_.valueless_by_exception();
-    }
-
-    inline constexpr std::size_t index() const noexcept {
-      return impl_.index();
-    }
-
-    template <
-        bool Dummy = true,
-        lib::enable_if_t<lib::all<Dummy,
-                                  (std::is_move_constructible<Ts>::value &&
-                                   lib::is_swappable<Ts>::value)...>::value,
-                         int> = 0>
-    inline void swap(variant &that) noexcept(
-        lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                  lib::is_nothrow_swappable<Ts>::value)...>::value) {
-      impl_.swap(that.impl_);
-    }
-
-    private:
-    detail::impl<Ts...> impl_;
-
-    friend struct detail::access::variant;
-    friend struct detail::visitation::variant;
-  };
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return v.index() == I;
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-    template <std::size_t I, typename V>
-    struct generic_get_impl {
-      constexpr generic_get_impl(int) {}
-
-      constexpr AUTO_REFREF operator()(V &&v) const
-        AUTO_REFREF_RETURN(
-            access::variant::get_alt<I>(lib::forward<V>(v)).value)
-    };
-
-    template <std::size_t I, typename V>
-    inline constexpr AUTO_REFREF generic_get(V &&v)
-      AUTO_REFREF_RETURN(generic_get_impl<I, V>(
-          holds_alternative<I>(v) ? 0 : (throw_bad_variant_access(), 0))(
-          lib::forward<V>(v)))
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
-      variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
-      variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
-      const variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
-      const variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &get(variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &&get(variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &get(const variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &&get(const variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept
-      AUTO_RETURN(v && holds_alternative<I>(*v)
-                      ? lib::addressof(access::variant::get_alt<I>(*v).value)
-                      : nullptr)
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
-  get_if(variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<
-      const variant_alternative_t<I, variant<Ts...>>>
-  get_if(const variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<T>
-  get_if(variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<const T>
-  get_if(const variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator==(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
-#else
-    return lhs.index() == rhs.index() &&
-           (lhs.valueless_by_exception() ||
-            variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator!=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::not_equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
-#else
-    return lhs.index() != rhs.index() ||
-           (!lhs.valueless_by_exception() &&
-            variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::less;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
-#else
-    return !rhs.valueless_by_exception() &&
-           (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::greater;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return false;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
-#else
-    return !lhs.valueless_by_exception() &&
-           (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::less_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return true;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
-#else
-    return lhs.valueless_by_exception() ||
-           (!rhs.valueless_by_exception() &&
-            (lhs.index() < rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::greater_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
-#else
-    return rhs.valueless_by_exception() ||
-           (!lhs.valueless_by_exception() &&
-            (lhs.index() > rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(
-                  lhs.index(), greater_equal{}, lhs, rhs))));
-#endif
-  }
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs)
-    DECLTYPE_AUTO_RETURN(
-        (detail::all(!vs.valueless_by_exception()...)
-             ? (void)0
-             : throw_bad_variant_access()),
-        detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
-                                                 lib::forward<Vs>(vs)...))
-
-  struct monostate {};
-
-  inline constexpr bool operator<(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator>(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator<=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator>=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator==(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator!=(monostate, monostate) noexcept {
-    return false;
-  }
-
-  template <typename... Ts>
-  inline auto swap(variant<Ts...> &lhs,
-                   variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
-      -> decltype(lhs.swap(rhs)) {
-    lhs.swap(rhs);
-  }
-
-  namespace detail {
-
-    template <typename T, typename...>
-    using enabled_type = T;
-
-    namespace hash {
-
-      template <typename H, typename K>
-      constexpr bool meets_requirements() {
-        return std::is_copy_constructible<H>::value &&
-               std::is_move_constructible<H>::value &&
-               lib::is_invocable_r<std::size_t, H, const K &>::value;
-      }
-
-      template <typename K>
-      constexpr bool is_enabled() {
-        using H = std::hash<K>;
-        return meets_requirements<H, K>() &&
-               std::is_default_constructible<H>::value &&
-               std::is_copy_assignable<H>::value &&
-               std::is_move_assignable<H>::value;
-      }
-
-    }  // namespace hash
-
-  }  // namespace detail
-
-#undef AUTO
-#undef AUTO_RETURN
-
-#undef AUTO_REFREF
-#undef AUTO_REFREF_RETURN
-
-#undef DECLTYPE_AUTO
-#undef DECLTYPE_AUTO_RETURN
-
-}  // namespace mpark
-
-namespace std {
-
-  template <typename... Ts>
-  struct hash<mpark::detail::enabled_type<
-      mpark::variant<Ts...>,
-      mpark::lib::enable_if_t<mpark::lib::all<mpark::detail::hash::is_enabled<
-          mpark::lib::remove_const_t<Ts>>()...>::value>>> {
-    using argument_type = mpark::variant<Ts...>;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &v) const {
-      using mpark::detail::visitation::variant;
-      std::size_t result =
-          v.valueless_by_exception()
-              ? 299792458  // Random value chosen by the universe upon creation
-              : variant::visit_alt(
-#ifdef MPARK_GENERIC_LAMBDAS
-                    [](const auto &alt) {
-                      using alt_type = mpark::lib::decay_t<decltype(alt)>;
-                      using value_type = mpark::lib::remove_const_t<
-                          typename alt_type::value_type>;
-                      return hash<value_type>{}(alt.value);
-                    }
-#else
-                    hasher{}
-#endif
-                    ,
-                    v);
-      return hash_combine(result, hash<std::size_t>{}(v.index()));
-    }
-
-    private:
-#ifndef MPARK_GENERIC_LAMBDAS
-    struct hasher {
-      template <typename Alt>
-      inline std::size_t operator()(const Alt &alt) const {
-        using alt_type = mpark::lib::decay_t<Alt>;
-        using value_type =
-            mpark::lib::remove_const_t<typename alt_type::value_type>;
-        return hash<value_type>{}(alt.value);
-      }
-    };
-#endif
-
-    static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
-      return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
-    }
-  };
-
-  template <>
-  struct hash<mpark::monostate> {
-    using argument_type = mpark::monostate;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &) const noexcept {
-      return 66740831;  // return a fundamentally attractive random value.
-    }
-  };
-
-}  // namespace std
-
-#endif  // MPARK_VARIANT_HPP

+ 0 - 2424
src/external/mpark-variant/v1.2.1/variant.hpp

@@ -1,2424 +0,0 @@
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANT_HPP
-#define MPARK_VARIANT_HPP
-
-/*
-   variant synopsis
-
-namespace std {
-
-  // 20.7.2, class template variant
-  template <class... Types>
-  class variant {
-  public:
-
-    // 20.7.2.1, constructors
-    constexpr variant() noexcept(see below);
-    variant(const variant&);
-    variant(variant&&) noexcept(see below);
-
-    template <class T> constexpr variant(T&&) noexcept(see below);
-
-    template <class T, class... Args>
-    constexpr explicit variant(in_place_type_t<T>, Args&&...);
-
-    template <class T, class U, class... Args>
-    constexpr explicit variant(
-        in_place_type_t<T>, initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    constexpr explicit variant(in_place_index_t<I>, Args&&...);
-
-    template <size_t I, class U, class... Args>
-    constexpr explicit variant(
-        in_place_index_t<I>, initializer_list<U>, Args&&...);
-
-    // 20.7.2.2, destructor
-    ~variant();
-
-    // 20.7.2.3, assignment
-    variant& operator=(const variant&);
-    variant& operator=(variant&&) noexcept(see below);
-
-    template <class T> variant& operator=(T&&) noexcept(see below);
-
-    // 20.7.2.4, modifiers
-    template <class T, class... Args>
-    T& emplace(Args&&...);
-
-    template <class T, class U, class... Args>
-    T& emplace(initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    variant_alternative<I, variant>& emplace(Args&&...);
-
-    template <size_t I, class U, class...  Args>
-    variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
-
-    // 20.7.2.5, value status
-    constexpr bool valueless_by_exception() const noexcept;
-    constexpr size_t index() const noexcept;
-
-    // 20.7.2.6, swap
-    void swap(variant&) noexcept(see below);
-  };
-
-  // 20.7.3, variant helper classes
-  template <class T> struct variant_size; // undefined
-
-  template <class T>
-  constexpr size_t variant_size_v = variant_size<T>::value;
-
-  template <class T> struct variant_size<const T>;
-  template <class T> struct variant_size<volatile T>;
-  template <class T> struct variant_size<const volatile T>;
-
-  template <class... Types>
-  struct variant_size<variant<Types...>>;
-
-  template <size_t I, class T> struct variant_alternative; // undefined
-
-  template <size_t I, class T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <size_t I, class T> struct variant_alternative<I, const T>;
-  template <size_t I, class T> struct variant_alternative<I, volatile T>;
-  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
-
-  template <size_t I, class... Types>
-  struct variant_alternative<I, variant<Types...>>;
-
-  constexpr size_t variant_npos = -1;
-
-  // 20.7.4, value access
-  template <class T, class... Types>
-  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&
-  get(variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&&
-  get(variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&
-  get(const variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&&
-  get(const variant<Types...>&&);
-
-  template <class T, class...  Types>
-  constexpr T& get(variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr T&& get(variant<Types...>&&);
-
-  template <class T, class... Types>
-  constexpr const T& get(const variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr const T&& get(const variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
-  get_if(variant<Types...>*) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
-  get_if(const variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<T>
-  get_if(variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<const T>
-  get_if(const variant<Types...>*) noexcept;
-
-  // 20.7.5, relational operators
-  template <class... Types>
-  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
-
-  // 20.7.6, visitation
-  template <class Visitor, class... Variants>
-  constexpr see below visit(Visitor&&, Variants&&...);
-
-  // 20.7.7, class monostate
-  struct monostate;
-
-  // 20.7.8, monostate relational operators
-  constexpr bool operator<(monostate, monostate) noexcept;
-  constexpr bool operator>(monostate, monostate) noexcept;
-  constexpr bool operator<=(monostate, monostate) noexcept;
-  constexpr bool operator>=(monostate, monostate) noexcept;
-  constexpr bool operator==(monostate, monostate) noexcept;
-  constexpr bool operator!=(monostate, monostate) noexcept;
-
-  // 20.7.9, specialized algorithms
-  template <class... Types>
-  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
-
-  // 20.7.10, class bad_variant_access
-  class bad_variant_access;
-
-  // 20.7.11, hash support
-  template <class T> struct hash;
-  template <class... Types> struct hash<variant<Types...>>;
-  template <> struct hash<monostate>;
-
-} // namespace std
-
-*/
-
-#include <cstddef>
-#include <exception>
-#include <functional>
-#include <initializer_list>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_CONFIG_HPP
-#define MPARK_CONFIG_HPP
-
-// MSVC 2015 Update 3.
-#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024215)
-#error "MPark.Variant requires C++11 support."
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#ifndef __has_include
-#define __has_include(x) 0
-#endif
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-
-#if __has_builtin(__builtin_addressof) || \
-    (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
-#define MPARK_BUILTIN_ADDRESSOF
-#endif
-
-#if __has_builtin(__type_pack_element)
-#define MPARK_TYPE_PACK_ELEMENT
-#endif
-
-#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
-#define MPARK_CPP14_CONSTEXPR
-#endif
-
-#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions)
-#define MPARK_EXCEPTIONS
-#endif
-
-#if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
-#define MPARK_GENERIC_LAMBDAS
-#endif
-
-#if defined(__cpp_lib_integer_sequence)
-#define MPARK_INTEGER_SEQUENCE
-#endif
-
-#if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
-#define MPARK_RETURN_TYPE_DEDUCTION
-#endif
-
-#if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
-#define MPARK_TRANSPARENT_OPERATORS
-#endif
-
-#if defined(__cpp_variable_templates) || defined(_MSC_VER)
-#define MPARK_VARIABLE_TEMPLATES
-#endif
-
-#if !defined(__GLIBCXX__) || __has_include(<codecvt>)  // >= libstdc++-5
-#define MPARK_TRIVIALITY_TYPE_TRAITS
-#endif
-
-#endif  // MPARK_CONFIG_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_IN_PLACE_HPP
-#define MPARK_IN_PLACE_HPP
-
-#include <cstddef>
-
-
-namespace mpark {
-
-  struct in_place_t { explicit in_place_t() = default; };
-
-  template <std::size_t I>
-  struct in_place_index_t { explicit in_place_index_t() = default; };
-
-  template <typename T>
-  struct in_place_type_t { explicit in_place_type_t() = default; };
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  constexpr in_place_t in_place{};
-
-  template <std::size_t I> constexpr in_place_index_t<I> in_place_index{};
-
-  template <typename T> constexpr in_place_type_t<T> in_place_type{};
-#endif
-
-}  // namespace mpark
-
-#endif  // MPARK_IN_PLACE_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_LIB_HPP
-#define MPARK_LIB_HPP
-
-#include <memory>
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-
-#define RETURN(...)                                          \
-  noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { \
-    return __VA_ARGS__;                                      \
-  }
-
-namespace mpark {
-  namespace lib {
-    template <typename T>
-    struct identity { using type = T; };
-
-    inline namespace cpp14 {
-      template <typename T, std::size_t N>
-      struct array {
-        constexpr const T &operator[](std::size_t index) const {
-          return data[index];
-        }
-
-        T data[N == 0 ? 1 : N];
-      };
-
-      template <typename T>
-      using add_pointer_t = typename std::add_pointer<T>::type;
-
-      template <typename... Ts>
-      using common_type_t = typename std::common_type<Ts...>::type;
-
-      template <typename T>
-      using decay_t = typename std::decay<T>::type;
-
-      template <bool B, typename T = void>
-      using enable_if_t = typename std::enable_if<B, T>::type;
-
-      template <typename T>
-      using remove_const_t = typename std::remove_const<T>::type;
-
-      template <typename T>
-      using remove_reference_t = typename std::remove_reference<T>::type;
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &t) noexcept {
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &&t) noexcept {
-        static_assert(!std::is_lvalue_reference<T>::value,
-                      "can not forward an rvalue as an lvalue");
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr remove_reference_t<T> &&move(T &&t) noexcept {
-        return static_cast<remove_reference_t<T> &&>(t);
-      }
-
-#ifdef MPARK_INTEGER_SEQUENCE
-      template <typename T, T... Is>
-      using integer_sequence = std::integer_sequence<T, Is...>;
-
-      template <std::size_t... Is>
-      using index_sequence = std::index_sequence<Is...>;
-
-      template <std::size_t N>
-      using make_index_sequence = std::make_index_sequence<N>;
-
-      template <typename... Ts>
-      using index_sequence_for = std::index_sequence_for<Ts...>;
-#else
-      template <typename T, T... Is>
-      struct integer_sequence {
-        using value_type = T;
-        static constexpr std::size_t size() noexcept { return sizeof...(Is); }
-      };
-
-      template <std::size_t... Is>
-      using index_sequence = integer_sequence<std::size_t, Is...>;
-
-      template <typename Lhs, typename Rhs>
-      struct make_index_sequence_concat;
-
-      template <std::size_t... Lhs, std::size_t... Rhs>
-      struct make_index_sequence_concat<index_sequence<Lhs...>,
-                                        index_sequence<Rhs...>>
-          : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
-
-      template <std::size_t N>
-      struct make_index_sequence_impl;
-
-      template <std::size_t N>
-      using make_index_sequence = typename make_index_sequence_impl<N>::type;
-
-      template <std::size_t N>
-      struct make_index_sequence_impl
-          : make_index_sequence_concat<make_index_sequence<N / 2>,
-                                       make_index_sequence<N - (N / 2)>> {};
-
-      template <>
-      struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
-
-      template <>
-      struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
-
-      template <typename... Ts>
-      using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
-#endif
-
-      // <functional>
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using equal_to = std::equal_to<>;
-#else
-      struct equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using not_equal_to = std::not_equal_to<>;
-#else
-      struct not_equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less = std::less<>;
-#else
-      struct less {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater = std::greater<>;
-#else
-      struct greater {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less_equal = std::less_equal<>;
-#else
-      struct less_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater_equal = std::greater_equal<>;
-#else
-      struct greater_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
-      };
-#endif
-    }  // namespace cpp14
-
-    inline namespace cpp17 {
-
-      // <type_traits>
-      template <bool B>
-      using bool_constant = std::integral_constant<bool, B>;
-
-      template <typename...>
-      struct voider : identity<void> {};
-
-      template <typename... Ts>
-      using void_t = typename voider<Ts...>::type;
-
-      namespace detail {
-        namespace swappable {
-
-          using std::swap;
-
-          template <typename T>
-          struct is_swappable_impl {
-            private:
-            template <typename U,
-                      typename = decltype(swap(std::declval<U &>(),
-                                               std::declval<U &>()))>
-            inline static std::true_type test(int);
-
-            template <typename U>
-            inline static std::false_type test(...);
-
-            public:
-            using type = decltype(test<T>(0));
-          };
-
-          template <typename T>
-          using is_swappable = typename is_swappable_impl<T>::type;
-
-          template <typename T, bool = is_swappable<T>::value>
-          struct is_nothrow_swappable {
-            static constexpr bool value =
-                noexcept(swap(std::declval<T &>(), std::declval<T &>()));
-          };
-
-          template <typename T>
-          struct is_nothrow_swappable<T, false> : std::false_type {};
-
-        }  // namespace swappable
-      }  // namespace detail
-
-      template <typename T>
-      using is_swappable = detail::swappable::is_swappable<T>;
-
-      template <typename T>
-      using is_nothrow_swappable = detail::swappable::is_nothrow_swappable<T>;
-
-      // <functional>
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename F, typename... As>
-      inline constexpr auto invoke(F &&f, As &&... as)
-          RETURN(lib::forward<F>(f)(lib::forward<As>(as)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      template <typename B, typename T, typename D>
-      inline constexpr auto invoke(T B::*pmv, D &&d)
-          RETURN(lib::forward<D>(d).*pmv)
-
-      template <typename Pmv, typename Ptr>
-      inline constexpr auto invoke(Pmv pmv, Ptr &&ptr)
-          RETURN((*lib::forward<Ptr>(ptr)).*pmv)
-
-      template <typename B, typename T, typename D, typename... As>
-      inline constexpr auto invoke(T B::*pmf, D &&d, As &&... as)
-          RETURN((lib::forward<D>(d).*pmf)(lib::forward<As>(as)...))
-
-      template <typename Pmf, typename Ptr, typename... As>
-      inline constexpr auto invoke(Pmf pmf, Ptr &&ptr, As &&... as)
-          RETURN(((*lib::forward<Ptr>(ptr)).*pmf)(lib::forward<As>(as)...))
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct invoke_result {};
-
-        template <typename F, typename... Args>
-        struct invoke_result<void_t<decltype(lib::invoke(
-                                 std::declval<F>(), std::declval<Args>()...))>,
-                             F,
-                             Args...>
-            : identity<decltype(
-                  lib::invoke(std::declval<F>(), std::declval<Args>()...))> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using invoke_result = detail::invoke_result<void, F, Args...>;
-
-      template <typename F, typename... Args>
-      using invoke_result_t = typename invoke_result<F, Args...>::type;
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct is_invocable : std::false_type {};
-
-        template <typename F, typename... Args>
-        struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
-            : std::true_type {};
-
-        template <typename Void, typename, typename, typename...>
-        struct is_invocable_r : std::false_type {};
-
-        template <typename R, typename F, typename... Args>
-        struct is_invocable_r<void_t<invoke_result_t<F, Args...>>,
-                              R,
-                              F,
-                              Args...>
-            : std::is_convertible<invoke_result_t<F, Args...>, R> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using is_invocable = detail::is_invocable<void, F, Args...>;
-
-      template <typename R, typename F, typename... Args>
-      using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
-
-      // <memory>
-#ifdef MPARK_BUILTIN_ADDRESSOF
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return __builtin_addressof(arg);
-      }
-#else
-      namespace detail {
-
-        namespace has_addressof_impl {
-
-          struct fail;
-
-          template <typename T>
-          inline fail operator&(T &&);
-
-          template <typename T>
-          inline static constexpr bool impl() {
-            return (std::is_class<T>::value || std::is_union<T>::value) &&
-                   !std::is_same<decltype(&std::declval<T &>()), fail>::value;
-          }
-
-        }  // namespace has_addressof_impl
-
-        template <typename T>
-        using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::true_type) {
-          return std::addressof(arg);
-        }
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::false_type) {
-          return &arg;
-        }
-
-      }  // namespace detail
-
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return detail::addressof(arg, detail::has_addressof<T>{});
-      }
-#endif
-
-      template <typename T>
-      inline constexpr T *addressof(const T &&) = delete;
-
-    }  // namespace cpp17
-
-    template <typename T>
-    struct remove_all_extents : identity<T> {};
-
-    template <typename T, std::size_t N>
-    struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
-
-    template <typename T>
-    using remove_all_extents_t = typename remove_all_extents<T>::type;
-
-    template <std::size_t N>
-    using size_constant = std::integral_constant<std::size_t, N>;
-
-    template <bool... Bs>
-    using bool_sequence = integer_sequence<bool, Bs...>;
-
-    template <std::size_t I, typename T>
-    struct indexed_type : size_constant<I>, identity<T> {};
-
-    template <bool... Bs>
-    using all =
-        std::is_same<bool_sequence<true, Bs...>, bool_sequence<Bs..., true>>;
-
-#ifdef MPARK_TYPE_PACK_ELEMENT
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = __type_pack_element<I, Ts...>;
-#else
-    template <std::size_t I, typename... Ts>
-    struct type_pack_element_impl {
-      private:
-      template <typename>
-      struct set;
-
-      template <std::size_t... Is>
-      struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
-
-      template <typename T>
-      inline static std::enable_if<true, T> impl(indexed_type<I, T>);
-
-      inline static std::enable_if<false> impl(...);
-
-      public:
-      using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
-    };
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
-#endif
-
-#ifdef MPARK_TRIVIALITY_TYPE_TRAITS
-    template <typename T>
-    using is_trivially_copy_constructible =
-        std::is_trivially_copy_constructible<T>;
-
-    template <typename T>
-    using is_trivially_move_constructible =
-        std::is_trivially_move_constructible<T>;
-
-    template <typename T>
-    using is_trivially_copy_assignable = std::is_trivially_copy_assignable<T>;
-
-    template <typename T>
-    using is_trivially_move_assignable = std::is_trivially_move_assignable<T>;
-#else
-    template <typename T>
-    struct is_trivially_copy_constructible
-        : bool_constant<
-              std::is_copy_constructible<T>::value && __has_trivial_copy(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {};
-
-    template <typename T>
-    struct is_trivially_copy_assignable
-        : bool_constant<
-              std::is_copy_assignable<T>::value && __has_trivial_assign(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {};
-#endif
-
-  }  // namespace lib
-}  // namespace mpark
-
-#undef RETURN
-
-#endif  // MPARK_LIB_HPP
-
-
-namespace mpark {
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-
-#define AUTO auto
-#define AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto &&
-#define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; }
-
-#define DECLTYPE_AUTO decltype(auto)
-#define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#else
-
-#define AUTO auto
-#define AUTO_RETURN(...) \
-  -> lib::decay_t<decltype(__VA_ARGS__)> { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto
-#define AUTO_REFREF_RETURN(...)                                           \
-  -> decltype((__VA_ARGS__)) {                                            \
-    static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
-    return __VA_ARGS__;                                                   \
-  }
-
-#define DECLTYPE_AUTO auto
-#define DECLTYPE_AUTO_RETURN(...) \
-  -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-#endif
-
-  class bad_variant_access : public std::exception {
-    public:
-    virtual const char *what() const noexcept { return "bad_variant_access"; }
-  };
-
-  [[noreturn]] inline void throw_bad_variant_access() {
-#ifdef MPARK_EXCEPTIONS
-    throw bad_variant_access{};
-#else
-    std::terminate();
-#endif
-  }
-
-  template <typename... Ts>
-  class variant;
-
-  template <typename T>
-  struct variant_size;
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  template <typename T>
-  constexpr std::size_t variant_size_v = variant_size<T>::value;
-#endif
-
-  template <typename T>
-  struct variant_size<const T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<volatile T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<const volatile T> : variant_size<T> {};
-
-  template <typename... Ts>
-  struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative;
-
-  template <std::size_t I, typename T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const T>
-      : std::add_const<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, volatile T>
-      : std::add_volatile<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const volatile T>
-      : std::add_cv<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename... Ts>
-  struct variant_alternative<I, variant<Ts...>> {
-    static_assert(I < sizeof...(Ts),
-                  "Index out of bounds in std::variant_alternative<>");
-    using type = lib::type_pack_element_t<I, Ts...>;
-  };
-
-  constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
-
-  namespace detail {
-
-    constexpr std::size_t not_found = static_cast<std::size_t>(-1);
-    constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      constexpr lib::array<bool, sizeof...(Ts)> matches = {
-          {std::is_same<T, Ts>::value...}
-      };
-      std::size_t result = not_found;
-      for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
-        if (matches[i]) {
-          if (result != not_found) {
-            return ambiguous;
-          }
-          result = i;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t) {
-      return result;
-    }
-
-    template <typename... Bs>
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t idx,
-                                                 bool b,
-                                                 Bs... bs) {
-      return b ? (result != not_found ? ambiguous
-                                      : find_index_impl(idx, idx + 1, bs...))
-               : find_index_impl(result, idx + 1, bs...);
-    }
-
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
-    }
-#endif
-
-    template <std::size_t I>
-    using find_index_sfinae_impl =
-        lib::enable_if_t<I != not_found && I != ambiguous,
-                         lib::size_constant<I>>;
-
-    template <typename T, typename... Ts>
-    using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
-
-    template <std::size_t I>
-    struct find_index_checked_impl : lib::size_constant<I> {
-      static_assert(I != not_found, "the specified type is not found.");
-      static_assert(I != ambiguous, "the specified type is ambiguous.");
-    };
-
-    template <typename T, typename... Ts>
-    using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
-
-    struct valueless_t {};
-
-    enum class Trait { TriviallyAvailable, Available, Unavailable };
-
-    template <typename T,
-              template <typename> class IsTriviallyAvailable,
-              template <typename> class IsAvailable>
-    inline constexpr Trait trait() {
-      return IsTriviallyAvailable<T>::value
-                 ? Trait::TriviallyAvailable
-                 : IsAvailable<T>::value ? Trait::Available
-                                         : Trait::Unavailable;
-    }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... traits) {
-      Trait result = Trait::TriviallyAvailable;
-      for (Trait t : {traits...}) {
-        if (static_cast<int>(t) > static_cast<int>(result)) {
-          result = t;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr Trait common_trait_impl(Trait result) { return result; }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait_impl(Trait result,
-                                             Trait t,
-                                             Traits... ts) {
-      return static_cast<int>(t) > static_cast<int>(result)
-                 ? common_trait_impl(t, ts...)
-                 : common_trait_impl(result, ts...);
-    }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... ts) {
-      return common_trait_impl(Trait::TriviallyAvailable, ts...);
-    }
-#endif
-
-    template <typename... Ts>
-    struct traits {
-      static constexpr Trait copy_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_copy_constructible,
-                             std::is_copy_constructible>()...);
-
-      static constexpr Trait move_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_move_constructible,
-                             std::is_move_constructible>()...);
-
-      static constexpr Trait copy_assignable_trait =
-          common_trait(copy_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_copy_assignable,
-                             std::is_copy_assignable>()...);
-
-      static constexpr Trait move_assignable_trait =
-          common_trait(move_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_move_assignable,
-                             std::is_move_assignable>()...);
-
-      static constexpr Trait destructible_trait =
-          common_trait(trait<Ts,
-                             std::is_trivially_destructible,
-                             std::is_destructible>()...);
-    };
-
-    namespace access {
-
-      struct recursive_union {
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename V>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
-          return lib::forward<V>(v).head_;
-        }
-
-        template <typename V, std::size_t I>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
-          return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
-        }
-#else
-        template <std::size_t I, bool Dummy = true>
-        struct get_alt_impl {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
-        };
-
-        template <bool Dummy>
-        struct get_alt_impl<0, Dummy> {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
-        };
-
-        template <typename V, std::size_t I>
-        inline static constexpr AUTO_REFREF get_alt(V &&v, in_place_index_t<I>)
-          AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
-#endif
-      };
-
-      struct base {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(recursive_union::get_alt(
-              data(lib::forward<V>(v)), in_place_index_t<I>{}))
-      };
-
-      struct variant {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
-      };
-
-    }  // namespace access
-
-    namespace visitation {
-
-      struct base {
-        private:
-        template <typename T>
-        inline static constexpr const T &at(const T &elem) {
-          return elem;
-        }
-
-        template <typename T, std::size_t N, typename... Is>
-        inline static constexpr const lib::remove_all_extents_t<T> &at(
-            const lib::array<T, N> &elems, std::size_t i, Is... is) {
-          return at(elems[i], is...);
-        }
-
-        template <typename F, typename... Fs>
-        inline static constexpr int visit_visitor_return_type_check() {
-          static_assert(lib::all<std::is_same<F, Fs>::value...>::value,
-                        "`mpark::visit` requires the visitor to have a single "
-                        "return type.");
-          return 0;
-        }
-
-        template <typename... Fs>
-        inline static constexpr lib::array<
-            lib::common_type_t<lib::decay_t<Fs>...>,
-            sizeof...(Fs)>
-        make_farray(Fs &&... fs) {
-          using result = lib::array<lib::common_type_t<lib::decay_t<Fs>...>,
-                                    sizeof...(Fs)>;
-          return visit_visitor_return_type_check<lib::decay_t<Fs>...>(),
-                 result{{lib::forward<Fs>(fs)...}};
-        }
-
-        template <std::size_t... Is>
-        struct dispatcher {
-          template <typename F, typename... Vs>
-          struct impl {
-            inline static constexpr DECLTYPE_AUTO dispatch(F f, Vs... vs)
-              DECLTYPE_AUTO_RETURN(lib::invoke(
-                  static_cast<F>(f),
-                  access::base::get_alt<Is>(static_cast<Vs>(vs))...))
-          };
-        };
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_dispatch(lib::index_sequence<Is...>)
-          AUTO_RETURN(&dispatcher<Is...>::template impl<F, Vs...>::dispatch)
-
-        template <std::size_t I, typename F, typename... Vs>
-        inline static constexpr AUTO make_fdiagonal_impl()
-          AUTO_RETURN(make_dispatch<F, Vs...>(
-              lib::index_sequence<lib::indexed_type<I, Vs>::value...>{}))
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_fdiagonal_impl(
-            lib::index_sequence<Is...>)
-          AUTO_RETURN(make_farray(make_fdiagonal_impl<Is, F, Vs...>()...))
-
-        template <typename F, typename V, typename... Vs>
-        inline static constexpr /* auto * */ auto make_fdiagonal()
-            -> decltype(make_fdiagonal_impl<F, V, Vs...>(
-                lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
-          static_assert(lib::all<(lib::decay_t<V>::size() ==
-                                  lib::decay_t<Vs>::size())...>::value,
-                        "all of the variants must be the same size.");
-          return make_fdiagonal_impl<F, V, Vs...>(
-              lib::make_index_sequence<lib::decay_t<V>::size()>{});
-        }
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_fmatrix_impl(
-            lib::index_sequence<Is...> is) {
-          return make_dispatch<F, Vs...>(is);
-        }
-
-        template <typename F,
-                  typename... Vs,
-                  std::size_t... Is,
-                  std::size_t... Js,
-                  typename... Ls>
-        inline static constexpr auto make_fmatrix_impl(
-            lib::index_sequence<Is...>, lib::index_sequence<Js...>, Ls... ls) {
-          return make_farray(make_fmatrix_impl<F, Vs...>(
-              lib::index_sequence<Is..., Js>{}, ls...)...);
-        }
-
-        template <typename F, typename... Vs>
-        inline static constexpr auto make_fmatrix() {
-          return make_fmatrix_impl<F, Vs...>(
-              lib::index_sequence<>{},
-              lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
-        }
-#else
-        template <typename F, typename... Vs>
-        struct make_fmatrix_impl {
-          template <typename...>
-          struct impl;
-
-          template <std::size_t... Is>
-          struct impl<lib::index_sequence<Is...>> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(
-                  make_dispatch<F, Vs...>(lib::index_sequence<Is...>{}))
-          };
-
-          template <std::size_t... Is, std::size_t... Js, typename... Ls>
-          struct impl<lib::index_sequence<Is...>,
-                      lib::index_sequence<Js...>,
-                      Ls...> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(make_farray(
-                  impl<lib::index_sequence<Is..., Js>, Ls...>{}()...))
-          };
-        };
-
-        template <typename F, typename... Vs>
-        inline static constexpr AUTO make_fmatrix()
-          AUTO_RETURN(
-              typename make_fmatrix_impl<F, Vs...>::template impl<
-                  lib::index_sequence<>,
-                  lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
-#endif
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              at(make_fdiagonal<Visitor &&,
-                                decltype(as_base(lib::forward<Vs>(vs)))...>(),
-                 index)(lib::forward<Visitor>(visitor),
-                        as_base(lib::forward<Vs>(vs))...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              at(make_fmatrix<Visitor &&,
-                              decltype(as_base(lib::forward<Vs>(vs)))...>(),
-                 vs.index()...)(lib::forward<Visitor>(visitor),
-                                as_base(lib::forward<Vs>(vs))...))
-      };
-
-      struct variant {
-        private:
-        template <typename Visitor, typename... Values>
-        struct visit_exhaustive_visitor_check {
-          static_assert(
-              lib::is_invocable<Visitor, Values...>::value,
-              "`mpark::visit` requires the visitor to be exhaustive.");
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-          inline constexpr DECLTYPE_AUTO operator()(Visitor &&visitor,
-                                                    Values &&... values) const
-            DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
-                                             lib::forward<Values>(values)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        };
-
-        template <typename Visitor>
-        struct value_visitor {
-          Visitor &&visitor_;
-
-          template <typename... Alts>
-          inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const
-            DECLTYPE_AUTO_RETURN(
-                visit_exhaustive_visitor_check<
-                    Visitor,
-                    decltype((lib::forward<Alts>(alts).value))...>{}(
-                    lib::forward<Visitor>(visitor_),
-                    lib::forward<Alts>(alts).value...))
-        };
-
-        template <typename Visitor>
-        inline static constexpr AUTO make_value_visitor(Visitor &&visitor)
-          AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              base::visit_alt_at(index,
-                                 lib::forward<Visitor>(visitor),
-                                 lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(base::visit_alt(lib::forward<Visitor>(visitor),
-                                               lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index,
-                                                             Visitor &&visitor,
-                                                             Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt_at(index,
-                           make_value_visitor(lib::forward<Visitor>(visitor)),
-                           lib::forward<Vs>(vs)...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor,
-                                                          Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt(make_value_visitor(lib::forward<Visitor>(visitor)),
-                        lib::forward<Vs>(vs)...))
-      };
-
-    }  // namespace visitation
-
-    template <std::size_t Index, typename T>
-    struct alt {
-      using value_type = T;
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-      template <typename... Args>
-      inline explicit constexpr alt(in_place_t, Args &&... args)
-          : value(lib::forward<Args>(args)...) {}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      T value;
-    };
-
-    template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
-    union recursive_union;
-
-    template <Trait DestructibleTrait, std::size_t Index>
-    union recursive_union<DestructibleTrait, Index> {};
-
-#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)      \
-  template <std::size_t Index, typename T, typename... Ts>                 \
-  union recursive_union<destructible_trait, Index, T, Ts...> {             \
-    public:                                                                \
-    inline explicit constexpr recursive_union(valueless_t) noexcept        \
-        : dummy_{} {}                                                      \
-                                                                           \
-    template <typename... Args>                                            \
-    inline explicit constexpr recursive_union(in_place_index_t<0>,         \
-                                              Args &&... args)             \
-        : head_(in_place_t{}, lib::forward<Args>(args)...) {}              \
-                                                                           \
-    template <std::size_t I, typename... Args>                             \
-    inline explicit constexpr recursive_union(in_place_index_t<I>,         \
-                                              Args &&... args)             \
-        : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
-                                                                           \
-    recursive_union(const recursive_union &) = default;                    \
-    recursive_union(recursive_union &&) = default;                         \
-                                                                           \
-    destructor                                                             \
-                                                                           \
-    recursive_union &operator=(const recursive_union &) = default;         \
-    recursive_union &operator=(recursive_union &&) = default;              \
-                                                                           \
-    private:                                                               \
-    char dummy_;                                                           \
-    alt<Index, T> head_;                                                   \
-    recursive_union<destructible_trait, Index + 1, Ts...> tail_;           \
-                                                                           \
-    friend struct access::recursive_union;                                 \
-  }
-
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
-                                  ~recursive_union() = default;);
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
-                                  ~recursive_union() {});
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
-                                  ~recursive_union() = delete;);
-
-#undef MPARK_VARIANT_RECURSIVE_UNION
-
-    using index_t = unsigned int;
-
-    template <Trait DestructibleTrait, typename... Ts>
-    class base {
-      public:
-      inline explicit constexpr base(valueless_t tag) noexcept
-          : data_(tag), index_(static_cast<index_t>(-1)) {}
-
-      template <std::size_t I, typename... Args>
-      inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
-          : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...),
-            index_(I) {}
-
-      inline constexpr bool valueless_by_exception() const noexcept {
-        return index_ == static_cast<index_t>(-1);
-      }
-
-      inline constexpr std::size_t index() const noexcept {
-        return valueless_by_exception() ? variant_npos : index_;
-      }
-
-      protected:
-      using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
-
-      friend inline constexpr base &as_base(base &b) { return b; }
-      friend inline constexpr const base &as_base(const base &b) { return b; }
-      friend inline constexpr base &&as_base(base &&b) { return lib::move(b); }
-      friend inline constexpr const base &&as_base(const base &&b) { return lib::move(b); }
-
-      friend inline constexpr data_t &data(base &b) { return b.data_; }
-      friend inline constexpr const data_t &data(const base &b) { return b.data_; }
-      friend inline constexpr data_t &&data(base &&b) { return lib::move(b).data_; }
-      friend inline constexpr const data_t &&data(const base &&b) { return lib::move(b).data_; }
-
-      inline static constexpr std::size_t size() { return sizeof...(Ts); }
-
-      data_t data_;
-      index_t index_;
-
-      friend struct access::base;
-      friend struct visitation::base;
-    };
-
-    struct dtor {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename Alt>
-      inline void operator()(Alt &alt) const noexcept { alt.~Alt(); }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-    };
-
-#if defined(_MSC_VER) && _MSC_VER < 1910
-#define INHERITING_CTOR(type, base)               \
-  template <typename... Args>                     \
-  inline explicit constexpr type(Args &&... args) \
-      : base(lib::forward<Args>(args)...) {}
-#else
-#define INHERITING_CTOR(type, base) using base::base;
-#endif
-
-    template <typename Traits, Trait = Traits::destructible_trait>
-    class destructor;
-
-#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
-  template <typename... Ts>                                               \
-  class destructor<traits<Ts...>, destructible_trait>                     \
-      : public base<destructible_trait, Ts...> {                          \
-    using super = base<destructible_trait, Ts...>;                        \
-                                                                          \
-    public:                                                               \
-    INHERITING_CTOR(destructor, super)                                    \
-    using super::operator=;                                               \
-                                                                          \
-    destructor(const destructor &) = default;                             \
-    destructor(destructor &&) = default;                                  \
-    definition                                                            \
-    destructor &operator=(const destructor &) = default;                  \
-    destructor &operator=(destructor &&) = default;                       \
-                                                                          \
-    protected:                                                            \
-    destroy                                                               \
-  }
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::TriviallyAvailable,
-        ~destructor() = default;,
-        inline void destroy() noexcept {
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Available,
-        ~destructor() { destroy(); },
-        inline void destroy() noexcept {
-          if (!this->valueless_by_exception()) {
-            visitation::base::visit_alt(dtor{}, *this);
-          }
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Unavailable,
-        ~destructor() = delete;,
-        inline void destroy() noexcept = delete;);
-
-#undef MPARK_VARIANT_DESTRUCTOR
-
-    template <typename Traits>
-    class constructor : public destructor<Traits> {
-      using super = destructor<Traits>;
-
-      public:
-      INHERITING_CTOR(constructor, super)
-      using super::operator=;
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct ctor {
-        template <typename LhsAlt, typename RhsAlt>
-        inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const {
-          constructor::construct_alt(lhs_alt,
-                                     lib::forward<RhsAlt>(rhs_alt).value);
-        }
-      };
-#endif
-
-      template <std::size_t I, typename T, typename... Args>
-      inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
-        ::new (static_cast<void *>(lib::addressof(a)))
-            alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
-        return a.value;
-      }
-
-      template <typename Rhs>
-      inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
-        lhs.destroy();
-        if (!rhs.valueless_by_exception()) {
-          visitation::base::visit_alt_at(
-              rhs.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [](auto &lhs_alt, auto &&rhs_alt) {
-                constructor::construct_alt(
-                    lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
-              }
-#else
-              ctor{}
-#endif
-              ,
-              lhs,
-              lib::forward<Rhs>(rhs));
-          lhs.index_ = rhs.index_;
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_constructible_trait>
-    class move_constructor;
-
-#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class move_constructor<traits<Ts...>, move_constructible_trait>            \
-      : public constructor<traits<Ts...>> {                                  \
-    using super = constructor<traits<Ts...>>;                                \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(move_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    move_constructor(const move_constructor &) = default;                    \
-    definition                                                               \
-    ~move_constructor() = default;                                           \
-    move_constructor &operator=(const move_constructor &) = default;         \
-    move_constructor &operator=(move_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        move_constructor(move_constructor &&that) = default;);
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Available,
-        move_constructor(move_constructor &&that) noexcept(
-            lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
-            : move_constructor(valueless_t{}) {
-          this->generic_construct(*this, lib::move(that));
-        });
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Unavailable,
-        move_constructor(move_constructor &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_CONSTRUCTOR
-
-    template <typename Traits, Trait = Traits::copy_constructible_trait>
-    class copy_constructor;
-
-#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
-      : public move_constructor<traits<Ts...>> {                             \
-    using super = move_constructor<traits<Ts...>>;                           \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(copy_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    definition                                                               \
-    copy_constructor(copy_constructor &&) = default;                         \
-    ~copy_constructor() = default;                                           \
-    copy_constructor &operator=(const copy_constructor &) = default;         \
-    copy_constructor &operator=(copy_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        copy_constructor(const copy_constructor &that) = default;);
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Available,
-        copy_constructor(const copy_constructor &that)
-            : copy_constructor(valueless_t{}) {
-          this->generic_construct(*this, that);
-        });
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Unavailable,
-        copy_constructor(const copy_constructor &) = delete;);
-
-#undef MPARK_VARIANT_COPY_CONSTRUCTOR
-
-    template <typename Traits>
-    class assignment : public copy_constructor<Traits> {
-      using super = copy_constructor<Traits>;
-
-      public:
-      INHERITING_CTOR(assignment, super)
-      using super::operator=;
-
-      template <std::size_t I, typename... Args>
-      inline /* auto & */ auto emplace(Args &&... args)
-          -> decltype(this->construct_alt(access::base::get_alt<I>(*this),
-                                          lib::forward<Args>(args)...)) {
-        this->destroy();
-        auto &result = this->construct_alt(access::base::get_alt<I>(*this),
-                                           lib::forward<Args>(args)...);
-        this->index_ = I;
-        return result;
-      }
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      template <typename That>
-      struct assigner {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const {
-          self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
-        }
-        assignment *self;
-      };
-#endif
-
-      template <std::size_t I, typename T, typename Arg>
-      inline void assign_alt(alt<I, T> &a, Arg &&arg) {
-        if (this->index() == I) {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-          a.value = lib::forward<Arg>(arg);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        } else {
-          struct {
-            void operator()(std::true_type) const {
-              this_->emplace<I>(lib::forward<Arg>(arg_));
-            }
-            void operator()(std::false_type) const {
-              this_->emplace<I>(T(lib::forward<Arg>(arg_)));
-            }
-            assignment *this_;
-            Arg &&arg_;
-          } impl{this, lib::forward<Arg>(arg)};
-          impl(lib::bool_constant<
-                   std::is_nothrow_constructible<T, Arg>::value ||
-                   !std::is_nothrow_move_constructible<T>::value>{});
-        }
-      }
-
-      template <typename That>
-      inline void generic_assign(That &&that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (that.valueless_by_exception()) {
-          this->destroy();
-        } else {
-          visitation::base::visit_alt_at(
-              that.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [this](auto &this_alt, auto &&that_alt) {
-                this->assign_alt(
-                    this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
-              }
-#else
-              assigner<That>{this}
-#endif
-              ,
-              *this,
-              lib::forward<That>(that));
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_assignable_trait>
-    class move_assignment;
-
-#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class move_assignment<traits<Ts...>, move_assignable_trait>            \
-      : public assignment<traits<Ts...>> {                               \
-    using super = assignment<traits<Ts...>>;                             \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(move_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    move_assignment(const move_assignment &) = default;                  \
-    move_assignment(move_assignment &&) = default;                       \
-    ~move_assignment() = default;                                        \
-    move_assignment &operator=(const move_assignment &) = default;       \
-    definition                                                           \
-  }
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        move_assignment &operator=(move_assignment &&that) = default;);
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Available,
-        move_assignment &
-        operator=(move_assignment &&that) noexcept(
-            lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                      std::is_nothrow_move_assignable<Ts>::value)...>::value) {
-          this->generic_assign(lib::move(that));
-          return *this;
-        });
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Unavailable,
-        move_assignment &operator=(move_assignment &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_ASSIGNMENT
-
-    template <typename Traits, Trait = Traits::copy_assignable_trait>
-    class copy_assignment;
-
-#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
-      : public move_assignment<traits<Ts...>> {                          \
-    using super = move_assignment<traits<Ts...>>;                        \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(copy_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    copy_assignment(const copy_assignment &) = default;                  \
-    copy_assignment(copy_assignment &&) = default;                       \
-    ~copy_assignment() = default;                                        \
-    definition                                                           \
-    copy_assignment &operator=(copy_assignment &&) = default;            \
-  }
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        copy_assignment &operator=(const copy_assignment &that) = default;);
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Available,
-        copy_assignment &operator=(const copy_assignment &that) {
-          this->generic_assign(that);
-          return *this;
-        });
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Unavailable,
-        copy_assignment &operator=(const copy_assignment &) = delete;);
-
-#undef MPARK_VARIANT_COPY_ASSIGNMENT
-
-    template <typename... Ts>
-    class impl : public copy_assignment<traits<Ts...>> {
-      using super = copy_assignment<traits<Ts...>>;
-
-      public:
-      INHERITING_CTOR(impl, super)
-      using super::operator=;
-
-      template <std::size_t I, typename Arg>
-      inline void assign(Arg &&arg) {
-        this->assign_alt(access::base::get_alt<I>(*this),
-                         lib::forward<Arg>(arg));
-      }
-
-      inline void swap(impl &that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (this->index() == that.index()) {
-          visitation::base::visit_alt_at(this->index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-                                         [](auto &this_alt, auto &that_alt) {
-                                           using std::swap;
-                                           swap(this_alt.value,
-                                                that_alt.value);
-                                         }
-#else
-                                         swapper{}
-#endif
-                                         ,
-                                         *this,
-                                         that);
-        } else {
-          impl *lhs = this;
-          impl *rhs = lib::addressof(that);
-          if (lhs->move_nothrow() && !rhs->move_nothrow()) {
-            std::swap(lhs, rhs);
-          }
-          impl tmp(lib::move(*rhs));
-#ifdef MPARK_EXCEPTIONS
-          // EXTENSION: When the move construction of `lhs` into `rhs` throws
-          // and `tmp` is nothrow move constructible then we move `tmp` back
-          // into `rhs` and provide the strong exception safety guarantee.
-          try {
-            this->generic_construct(*rhs, lib::move(*lhs));
-          } catch (...) {
-            if (tmp.move_nothrow()) {
-              this->generic_construct(*rhs, lib::move(tmp));
-            }
-            throw;
-          }
-#else
-          this->generic_construct(*rhs, lib::move(*lhs));
-#endif
-          this->generic_construct(*lhs, lib::move(tmp));
-        }
-      }
-
-      private:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct swapper {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const {
-          using std::swap;
-          swap(this_alt.value, that_alt.value);
-        }
-      };
-#endif
-
-      inline constexpr bool move_nothrow() const {
-        return this->valueless_by_exception() ||
-               lib::array<bool, sizeof...(Ts)>{
-                   {std::is_nothrow_move_constructible<Ts>::value...}
-               }[this->index()];
-      }
-    };
-
-    template <std::size_t I, typename T>
-    struct overload_leaf {
-      using F = lib::size_constant<I> (*)(T);
-      operator F() const { return nullptr; }
-    };
-
-    template <typename... Ts>
-    struct overload_impl {
-      private:
-      template <typename>
-      struct impl;
-
-      template <std::size_t... Is>
-      struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>... {};
-
-      public:
-      using type = impl<lib::index_sequence_for<Ts...>>;
-    };
-
-    template <typename... Ts>
-    using overload = typename overload_impl<Ts...>::type;
-
-    template <typename T, typename... Ts>
-    using best_match = lib::invoke_result_t<overload<Ts...>, T &&>;
-
-    template <typename T>
-    struct is_in_place_index : std::false_type {};
-
-    template <std::size_t I>
-    struct is_in_place_index<in_place_index_t<I>> : std::true_type {};
-
-    template <typename T>
-    struct is_in_place_type : std::false_type {};
-
-    template <typename T>
-    struct is_in_place_type<in_place_type_t<T>> : std::true_type {};
-
-  }  // detail
-
-  template <typename... Ts>
-  class variant {
-    static_assert(0 < sizeof...(Ts),
-                  "variant must consist of at least one alternative.");
-
-    static_assert(lib::all<!std::is_array<Ts>::value...>::value,
-                  "variant can not have an array type as an alternative.");
-
-    static_assert(lib::all<!std::is_reference<Ts>::value...>::value,
-                  "variant can not have a reference type as an alternative.");
-
-    static_assert(lib::all<!std::is_void<Ts>::value...>::value,
-                  "variant can not have a void type as an alternative.");
-
-    public:
-    template <
-        typename Front = lib::type_pack_element_t<0, Ts...>,
-        lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
-    inline constexpr variant() noexcept(
-        std::is_nothrow_default_constructible<Front>::value)
-        : impl_(in_place_index_t<0>{}) {}
-
-    variant(const variant &) = default;
-    variant(variant &&) = default;
-
-    template <
-        typename Arg,
-        typename Decayed = lib::decay_t<Arg>,
-        lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_index<Decayed>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_type<Decayed>::value, int> = 0,
-        std::size_t I = detail::best_match<Arg, Ts...>::value,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
-    inline constexpr variant(Arg &&arg) noexcept(
-        std::is_nothrow_constructible<T, Arg>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {}
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    ~variant() = default;
-
-    variant &operator=(const variant &) = default;
-    variant &operator=(variant &&) = default;
-
-    template <typename Arg,
-              lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              std::size_t I = detail::best_match<Arg, Ts...>::value,
-              typename T = lib::type_pack_element_t<I, Ts...>,
-              lib::enable_if_t<(std::is_assignable<T &, Arg>::value &&
-                                std::is_constructible<T, Arg>::value),
-                               int> = 0>
-    inline variant &operator=(Arg &&arg) noexcept(
-        (std::is_nothrow_assignable<T &, Arg>::value &&
-         std::is_nothrow_constructible<T, Arg>::value)) {
-      impl_.template assign<I>(lib::forward<Arg>(arg));
-      return *this;
-    }
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    inline constexpr bool valueless_by_exception() const noexcept {
-      return impl_.valueless_by_exception();
-    }
-
-    inline constexpr std::size_t index() const noexcept {
-      return impl_.index();
-    }
-
-    template <
-        bool Dummy = true,
-        lib::enable_if_t<lib::all<Dummy,
-                                  (std::is_move_constructible<Ts>::value &&
-                                   lib::is_swappable<Ts>::value)...>::value,
-                         int> = 0>
-    inline void swap(variant &that) noexcept(
-        lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                  lib::is_nothrow_swappable<Ts>::value)...>::value) {
-      impl_.swap(that.impl_);
-    }
-
-    private:
-    detail::impl<Ts...> impl_;
-
-    friend struct detail::access::variant;
-    friend struct detail::visitation::variant;
-  };
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return v.index() == I;
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-    template <std::size_t I, typename V>
-    struct generic_get_impl {
-      constexpr generic_get_impl(int) {}
-
-      constexpr AUTO_REFREF operator()(V &&v) const
-        AUTO_REFREF_RETURN(
-            access::variant::get_alt<I>(lib::forward<V>(v)).value)
-    };
-
-    template <std::size_t I, typename V>
-    inline constexpr AUTO_REFREF generic_get(V &&v)
-      AUTO_REFREF_RETURN(generic_get_impl<I, V>(
-          holds_alternative<I>(v) ? 0 : (throw_bad_variant_access(), 0))(
-          lib::forward<V>(v)))
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
-      variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
-      variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
-      const variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
-      const variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &get(variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &&get(variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &get(const variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &&get(const variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept
-      AUTO_RETURN(v && holds_alternative<I>(*v)
-                      ? lib::addressof(access::variant::get_alt<I>(*v).value)
-                      : nullptr)
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
-  get_if(variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<
-      const variant_alternative_t<I, variant<Ts...>>>
-  get_if(const variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<T>
-  get_if(variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<const T>
-  get_if(const variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator==(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
-#else
-    return lhs.index() == rhs.index() &&
-           (lhs.valueless_by_exception() ||
-            variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator!=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::not_equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
-#else
-    return lhs.index() != rhs.index() ||
-           (!lhs.valueless_by_exception() &&
-            variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::less;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
-#else
-    return !rhs.valueless_by_exception() &&
-           (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::greater;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return false;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
-#else
-    return !lhs.valueless_by_exception() &&
-           (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::less_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return true;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
-#else
-    return lhs.valueless_by_exception() ||
-           (!rhs.valueless_by_exception() &&
-            (lhs.index() < rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::greater_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
-#else
-    return rhs.valueless_by_exception() ||
-           (!lhs.valueless_by_exception() &&
-            (lhs.index() > rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(
-                  lhs.index(), greater_equal{}, lhs, rhs))));
-#endif
-  }
-
-  struct monostate {};
-
-  inline constexpr bool operator<(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator>(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator<=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator>=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator==(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator!=(monostate, monostate) noexcept {
-    return false;
-  }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-  namespace detail {
-
-    inline constexpr bool all(std::initializer_list<bool> bs) {
-      for (bool b : bs) {
-        if (!b) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
-    return (detail::all({!vs.valueless_by_exception()...})
-                ? (void)0
-                : throw_bad_variant_access()),
-           detail::visitation::variant::visit_value(
-               lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
-  }
-#else
-  namespace detail {
-
-    template <std::size_t N>
-    inline constexpr bool all_impl(const lib::array<bool, N> &bs,
-                                   std::size_t idx) {
-      return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
-    }
-
-    template <std::size_t N>
-    inline constexpr bool all(const lib::array<bool, N> &bs) {
-      return all_impl(bs, 0);
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs)
-    DECLTYPE_AUTO_RETURN(
-        (detail::all(
-             lib::array<bool, sizeof...(Vs)>{{!vs.valueless_by_exception()...}})
-             ? (void)0
-             : throw_bad_variant_access()),
-        detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
-                                                 lib::forward<Vs>(vs)...))
-#endif
-
-  template <typename... Ts>
-  inline auto swap(variant<Ts...> &lhs,
-                   variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
-      -> decltype(lhs.swap(rhs)) {
-    lhs.swap(rhs);
-  }
-
-  namespace detail {
-
-    template <typename T, typename...>
-    using enabled_type = T;
-
-    namespace hash {
-
-      template <typename H, typename K>
-      constexpr bool meets_requirements() {
-        return std::is_copy_constructible<H>::value &&
-               std::is_move_constructible<H>::value &&
-               lib::is_invocable_r<std::size_t, H, const K &>::value;
-      }
-
-      template <typename K>
-      constexpr bool is_enabled() {
-        using H = std::hash<K>;
-        return meets_requirements<H, K>() &&
-               std::is_default_constructible<H>::value &&
-               std::is_copy_assignable<H>::value &&
-               std::is_move_assignable<H>::value;
-      }
-
-    }  // namespace hash
-
-  }  // namespace detail
-
-#undef AUTO
-#undef AUTO_RETURN
-
-#undef AUTO_REFREF
-#undef AUTO_REFREF_RETURN
-
-#undef DECLTYPE_AUTO
-#undef DECLTYPE_AUTO_RETURN
-
-}  // namespace mpark
-
-namespace std {
-
-  template <typename... Ts>
-  struct hash<mpark::detail::enabled_type<
-      mpark::variant<Ts...>,
-      mpark::lib::enable_if_t<mpark::lib::all<mpark::detail::hash::is_enabled<
-          mpark::lib::remove_const_t<Ts>>()...>::value>>> {
-    using argument_type = mpark::variant<Ts...>;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &v) const {
-      using mpark::detail::visitation::variant;
-      std::size_t result =
-          v.valueless_by_exception()
-              ? 299792458  // Random value chosen by the universe upon creation
-              : variant::visit_alt(
-#ifdef MPARK_GENERIC_LAMBDAS
-                    [](const auto &alt) {
-                      using alt_type = mpark::lib::decay_t<decltype(alt)>;
-                      using value_type = mpark::lib::remove_const_t<
-                          typename alt_type::value_type>;
-                      return hash<value_type>{}(alt.value);
-                    }
-#else
-                    hasher{}
-#endif
-                    ,
-                    v);
-      return hash_combine(result, hash<std::size_t>{}(v.index()));
-    }
-
-    private:
-#ifndef MPARK_GENERIC_LAMBDAS
-    struct hasher {
-      template <typename Alt>
-      inline std::size_t operator()(const Alt &alt) const {
-        using alt_type = mpark::lib::decay_t<Alt>;
-        using value_type =
-            mpark::lib::remove_const_t<typename alt_type::value_type>;
-        return hash<value_type>{}(alt.value);
-      }
-    };
-#endif
-
-    static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
-      return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
-    }
-  };
-
-  template <>
-  struct hash<mpark::monostate> {
-    using argument_type = mpark::monostate;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &) const noexcept {
-      return 66740831;  // return a fundamentally attractive random value.
-    }
-  };
-
-}  // namespace std
-
-#endif  // MPARK_VARIANT_HPP

+ 0 - 2416
src/external/mpark-variant/v1.2.2/variant.hpp

@@ -1,2416 +0,0 @@
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANT_HPP
-#define MPARK_VARIANT_HPP
-
-/*
-   variant synopsis
-
-namespace std {
-
-  // 20.7.2, class template variant
-  template <class... Types>
-  class variant {
-  public:
-
-    // 20.7.2.1, constructors
-    constexpr variant() noexcept(see below);
-    variant(const variant&);
-    variant(variant&&) noexcept(see below);
-
-    template <class T> constexpr variant(T&&) noexcept(see below);
-
-    template <class T, class... Args>
-    constexpr explicit variant(in_place_type_t<T>, Args&&...);
-
-    template <class T, class U, class... Args>
-    constexpr explicit variant(
-        in_place_type_t<T>, initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    constexpr explicit variant(in_place_index_t<I>, Args&&...);
-
-    template <size_t I, class U, class... Args>
-    constexpr explicit variant(
-        in_place_index_t<I>, initializer_list<U>, Args&&...);
-
-    // 20.7.2.2, destructor
-    ~variant();
-
-    // 20.7.2.3, assignment
-    variant& operator=(const variant&);
-    variant& operator=(variant&&) noexcept(see below);
-
-    template <class T> variant& operator=(T&&) noexcept(see below);
-
-    // 20.7.2.4, modifiers
-    template <class T, class... Args>
-    T& emplace(Args&&...);
-
-    template <class T, class U, class... Args>
-    T& emplace(initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    variant_alternative<I, variant>& emplace(Args&&...);
-
-    template <size_t I, class U, class...  Args>
-    variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
-
-    // 20.7.2.5, value status
-    constexpr bool valueless_by_exception() const noexcept;
-    constexpr size_t index() const noexcept;
-
-    // 20.7.2.6, swap
-    void swap(variant&) noexcept(see below);
-  };
-
-  // 20.7.3, variant helper classes
-  template <class T> struct variant_size; // undefined
-
-  template <class T>
-  constexpr size_t variant_size_v = variant_size<T>::value;
-
-  template <class T> struct variant_size<const T>;
-  template <class T> struct variant_size<volatile T>;
-  template <class T> struct variant_size<const volatile T>;
-
-  template <class... Types>
-  struct variant_size<variant<Types...>>;
-
-  template <size_t I, class T> struct variant_alternative; // undefined
-
-  template <size_t I, class T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <size_t I, class T> struct variant_alternative<I, const T>;
-  template <size_t I, class T> struct variant_alternative<I, volatile T>;
-  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
-
-  template <size_t I, class... Types>
-  struct variant_alternative<I, variant<Types...>>;
-
-  constexpr size_t variant_npos = -1;
-
-  // 20.7.4, value access
-  template <class T, class... Types>
-  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&
-  get(variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&&
-  get(variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&
-  get(const variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&&
-  get(const variant<Types...>&&);
-
-  template <class T, class...  Types>
-  constexpr T& get(variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr T&& get(variant<Types...>&&);
-
-  template <class T, class... Types>
-  constexpr const T& get(const variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr const T&& get(const variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
-  get_if(variant<Types...>*) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
-  get_if(const variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<T>
-  get_if(variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<const T>
-  get_if(const variant<Types...>*) noexcept;
-
-  // 20.7.5, relational operators
-  template <class... Types>
-  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
-
-  // 20.7.6, visitation
-  template <class Visitor, class... Variants>
-  constexpr see below visit(Visitor&&, Variants&&...);
-
-  // 20.7.7, class monostate
-  struct monostate;
-
-  // 20.7.8, monostate relational operators
-  constexpr bool operator<(monostate, monostate) noexcept;
-  constexpr bool operator>(monostate, monostate) noexcept;
-  constexpr bool operator<=(monostate, monostate) noexcept;
-  constexpr bool operator>=(monostate, monostate) noexcept;
-  constexpr bool operator==(monostate, monostate) noexcept;
-  constexpr bool operator!=(monostate, monostate) noexcept;
-
-  // 20.7.9, specialized algorithms
-  template <class... Types>
-  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
-
-  // 20.7.10, class bad_variant_access
-  class bad_variant_access;
-
-  // 20.7.11, hash support
-  template <class T> struct hash;
-  template <class... Types> struct hash<variant<Types...>>;
-  template <> struct hash<monostate>;
-
-} // namespace std
-
-*/
-
-#include <cstddef>
-#include <exception>
-#include <functional>
-#include <initializer_list>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_CONFIG_HPP
-#define MPARK_CONFIG_HPP
-
-// MSVC 2015 Update 3.
-#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024215)
-#error "MPark.Variant requires C++11 support."
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#ifndef __has_include
-#define __has_include(x) 0
-#endif
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-
-#if __has_builtin(__builtin_addressof) || \
-    (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
-#define MPARK_BUILTIN_ADDRESSOF
-#endif
-
-#if __has_builtin(__builtin_unreachable)
-#define MPARK_BUILTIN_UNREACHABLE
-#endif
-
-#if __has_builtin(__type_pack_element)
-#define MPARK_TYPE_PACK_ELEMENT
-#endif
-
-#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
-#define MPARK_CPP14_CONSTEXPR
-#endif
-
-#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \
-    (defined(_MSC_VER) && defined(_CPPUNWIND))
-#define MPARK_EXCEPTIONS
-#endif
-
-#if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
-#define MPARK_GENERIC_LAMBDAS
-#endif
-
-#if defined(__cpp_lib_integer_sequence)
-#define MPARK_INTEGER_SEQUENCE
-#endif
-
-#if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
-#define MPARK_RETURN_TYPE_DEDUCTION
-#endif
-
-#if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
-#define MPARK_TRANSPARENT_OPERATORS
-#endif
-
-#if defined(__cpp_variable_templates) || defined(_MSC_VER)
-#define MPARK_VARIABLE_TEMPLATES
-#endif
-
-#if !defined(__GLIBCXX__) || __has_include(<codecvt>)  // >= libstdc++-5
-#define MPARK_TRIVIALITY_TYPE_TRAITS
-#endif
-
-#endif  // MPARK_CONFIG_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_IN_PLACE_HPP
-#define MPARK_IN_PLACE_HPP
-
-#include <cstddef>
-
-
-namespace mpark {
-
-  struct in_place_t { explicit in_place_t() = default; };
-
-  template <std::size_t I>
-  struct in_place_index_t { explicit in_place_index_t() = default; };
-
-  template <typename T>
-  struct in_place_type_t { explicit in_place_type_t() = default; };
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  constexpr in_place_t in_place{};
-
-  template <std::size_t I> constexpr in_place_index_t<I> in_place_index{};
-
-  template <typename T> constexpr in_place_type_t<T> in_place_type{};
-#endif
-
-}  // namespace mpark
-
-#endif  // MPARK_IN_PLACE_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_LIB_HPP
-#define MPARK_LIB_HPP
-
-#include <memory>
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-
-#define RETURN(...)                                          \
-  noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { \
-    return __VA_ARGS__;                                      \
-  }
-
-namespace mpark {
-  namespace lib {
-    template <typename T>
-    struct identity { using type = T; };
-
-    inline namespace cpp14 {
-      template <typename T, std::size_t N>
-      struct array {
-        constexpr const T &operator[](std::size_t index) const {
-          return data[index];
-        }
-
-        T data[N == 0 ? 1 : N];
-      };
-
-      template <typename T>
-      using add_pointer_t = typename std::add_pointer<T>::type;
-
-      template <typename... Ts>
-      using common_type_t = typename std::common_type<Ts...>::type;
-
-      template <typename T>
-      using decay_t = typename std::decay<T>::type;
-
-      template <bool B, typename T = void>
-      using enable_if_t = typename std::enable_if<B, T>::type;
-
-      template <typename T>
-      using remove_const_t = typename std::remove_const<T>::type;
-
-      template <typename T>
-      using remove_reference_t = typename std::remove_reference<T>::type;
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &t) noexcept {
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &&t) noexcept {
-        static_assert(!std::is_lvalue_reference<T>::value,
-                      "can not forward an rvalue as an lvalue");
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr remove_reference_t<T> &&move(T &&t) noexcept {
-        return static_cast<remove_reference_t<T> &&>(t);
-      }
-
-#ifdef MPARK_INTEGER_SEQUENCE
-      using std::integer_sequence;
-      using std::index_sequence;
-      using std::make_index_sequence;
-      using std::index_sequence_for;
-#else
-      template <typename T, T... Is>
-      struct integer_sequence {
-        using value_type = T;
-        static constexpr std::size_t size() noexcept { return sizeof...(Is); }
-      };
-
-      template <std::size_t... Is>
-      using index_sequence = integer_sequence<std::size_t, Is...>;
-
-      template <typename Lhs, typename Rhs>
-      struct make_index_sequence_concat;
-
-      template <std::size_t... Lhs, std::size_t... Rhs>
-      struct make_index_sequence_concat<index_sequence<Lhs...>,
-                                        index_sequence<Rhs...>>
-          : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
-
-      template <std::size_t N>
-      struct make_index_sequence_impl;
-
-      template <std::size_t N>
-      using make_index_sequence = typename make_index_sequence_impl<N>::type;
-
-      template <std::size_t N>
-      struct make_index_sequence_impl
-          : make_index_sequence_concat<make_index_sequence<N / 2>,
-                                       make_index_sequence<N - (N / 2)>> {};
-
-      template <>
-      struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
-
-      template <>
-      struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
-
-      template <typename... Ts>
-      using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
-#endif
-
-      // <functional>
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using equal_to = std::equal_to<>;
-#else
-      struct equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using not_equal_to = std::not_equal_to<>;
-#else
-      struct not_equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less = std::less<>;
-#else
-      struct less {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater = std::greater<>;
-#else
-      struct greater {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less_equal = std::less_equal<>;
-#else
-      struct less_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater_equal = std::greater_equal<>;
-#else
-      struct greater_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
-      };
-#endif
-    }  // namespace cpp14
-
-    inline namespace cpp17 {
-
-      // <type_traits>
-      template <bool B>
-      using bool_constant = std::integral_constant<bool, B>;
-
-      template <typename...>
-      struct voider : identity<void> {};
-
-      template <typename... Ts>
-      using void_t = typename voider<Ts...>::type;
-
-      namespace detail {
-        namespace swappable {
-
-          using std::swap;
-
-          template <typename T>
-          struct is_swappable_impl {
-            private:
-            template <typename U,
-                      typename = decltype(swap(std::declval<U &>(),
-                                               std::declval<U &>()))>
-            inline static std::true_type test(int);
-
-            template <typename U>
-            inline static std::false_type test(...);
-
-            public:
-            using type = decltype(test<T>(0));
-          };
-
-          template <typename T>
-          using is_swappable = typename is_swappable_impl<T>::type;
-
-          template <typename T, bool = is_swappable<T>::value>
-          struct is_nothrow_swappable {
-            static constexpr bool value =
-                noexcept(swap(std::declval<T &>(), std::declval<T &>()));
-          };
-
-          template <typename T>
-          struct is_nothrow_swappable<T, false> : std::false_type {};
-
-        }  // namespace swappable
-      }  // namespace detail
-
-      template <typename T>
-      using is_swappable = detail::swappable::is_swappable<T>;
-
-      template <typename T>
-      using is_nothrow_swappable = detail::swappable::is_nothrow_swappable<T>;
-
-      // <functional>
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename F, typename... As>
-      inline constexpr auto invoke(F &&f, As &&... as)
-          RETURN(lib::forward<F>(f)(lib::forward<As>(as)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      template <typename B, typename T, typename D>
-      inline constexpr auto invoke(T B::*pmv, D &&d)
-          RETURN(lib::forward<D>(d).*pmv)
-
-      template <typename Pmv, typename Ptr>
-      inline constexpr auto invoke(Pmv pmv, Ptr &&ptr)
-          RETURN((*lib::forward<Ptr>(ptr)).*pmv)
-
-      template <typename B, typename T, typename D, typename... As>
-      inline constexpr auto invoke(T B::*pmf, D &&d, As &&... as)
-          RETURN((lib::forward<D>(d).*pmf)(lib::forward<As>(as)...))
-
-      template <typename Pmf, typename Ptr, typename... As>
-      inline constexpr auto invoke(Pmf pmf, Ptr &&ptr, As &&... as)
-          RETURN(((*lib::forward<Ptr>(ptr)).*pmf)(lib::forward<As>(as)...))
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct invoke_result {};
-
-        template <typename F, typename... Args>
-        struct invoke_result<void_t<decltype(lib::invoke(
-                                 std::declval<F>(), std::declval<Args>()...))>,
-                             F,
-                             Args...>
-            : identity<decltype(
-                  lib::invoke(std::declval<F>(), std::declval<Args>()...))> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using invoke_result = detail::invoke_result<void, F, Args...>;
-
-      template <typename F, typename... Args>
-      using invoke_result_t = typename invoke_result<F, Args...>::type;
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct is_invocable : std::false_type {};
-
-        template <typename F, typename... Args>
-        struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
-            : std::true_type {};
-
-        template <typename Void, typename, typename, typename...>
-        struct is_invocable_r : std::false_type {};
-
-        template <typename R, typename F, typename... Args>
-        struct is_invocable_r<void_t<invoke_result_t<F, Args...>>,
-                              R,
-                              F,
-                              Args...>
-            : std::is_convertible<invoke_result_t<F, Args...>, R> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using is_invocable = detail::is_invocable<void, F, Args...>;
-
-      template <typename R, typename F, typename... Args>
-      using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
-
-      // <memory>
-#ifdef MPARK_BUILTIN_ADDRESSOF
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return __builtin_addressof(arg);
-      }
-#else
-      namespace detail {
-
-        namespace has_addressof_impl {
-
-          struct fail;
-
-          template <typename T>
-          inline fail operator&(T &&);
-
-          template <typename T>
-          inline static constexpr bool impl() {
-            return (std::is_class<T>::value || std::is_union<T>::value) &&
-                   !std::is_same<decltype(&std::declval<T &>()), fail>::value;
-          }
-
-        }  // namespace has_addressof_impl
-
-        template <typename T>
-        using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::true_type) {
-          return std::addressof(arg);
-        }
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::false_type) {
-          return &arg;
-        }
-
-      }  // namespace detail
-
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return detail::addressof(arg, detail::has_addressof<T>{});
-      }
-#endif
-
-      template <typename T>
-      inline constexpr T *addressof(const T &&) = delete;
-
-    }  // namespace cpp17
-
-    template <typename T>
-    struct remove_all_extents : identity<T> {};
-
-    template <typename T, std::size_t N>
-    struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
-
-    template <typename T>
-    using remove_all_extents_t = typename remove_all_extents<T>::type;
-
-    template <std::size_t N>
-    using size_constant = std::integral_constant<std::size_t, N>;
-
-    template <bool... Bs>
-    using bool_sequence = integer_sequence<bool, Bs...>;
-
-    template <std::size_t I, typename T>
-    struct indexed_type : size_constant<I>, identity<T> {};
-
-    template <bool... Bs>
-    using all =
-        std::is_same<bool_sequence<true, Bs...>, bool_sequence<Bs..., true>>;
-
-#ifdef MPARK_TYPE_PACK_ELEMENT
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = __type_pack_element<I, Ts...>;
-#else
-    template <std::size_t I, typename... Ts>
-    struct type_pack_element_impl {
-      private:
-      template <typename>
-      struct set;
-
-      template <std::size_t... Is>
-      struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
-
-      template <typename T>
-      inline static std::enable_if<true, T> impl(indexed_type<I, T>);
-
-      inline static std::enable_if<false> impl(...);
-
-      public:
-      using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
-    };
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
-#endif
-
-#ifdef MPARK_TRIVIALITY_TYPE_TRAITS
-    using std::is_trivially_copy_constructible;
-    using std::is_trivially_move_constructible;
-    using std::is_trivially_copy_assignable;
-    using std::is_trivially_move_assignable;
-#else
-    template <typename T>
-    struct is_trivially_copy_constructible
-        : bool_constant<
-              std::is_copy_constructible<T>::value && __has_trivial_copy(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {};
-
-    template <typename T>
-    struct is_trivially_copy_assignable
-        : bool_constant<
-              std::is_copy_assignable<T>::value && __has_trivial_assign(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {};
-#endif
-
-  }  // namespace lib
-}  // namespace mpark
-
-#undef RETURN
-
-#endif  // MPARK_LIB_HPP
-
-
-namespace mpark {
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-
-#define AUTO auto
-#define AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto &&
-#define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; }
-
-#define DECLTYPE_AUTO decltype(auto)
-#define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#else
-
-#define AUTO auto
-#define AUTO_RETURN(...) \
-  -> lib::decay_t<decltype(__VA_ARGS__)> { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto
-#define AUTO_REFREF_RETURN(...)                                           \
-  -> decltype((__VA_ARGS__)) {                                            \
-    static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
-    return __VA_ARGS__;                                                   \
-  }
-
-#define DECLTYPE_AUTO auto
-#define DECLTYPE_AUTO_RETURN(...) \
-  -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-#endif
-
-  class bad_variant_access : public std::exception {
-    public:
-    virtual const char *what() const noexcept { return "bad_variant_access"; }
-  };
-
-  [[noreturn]] inline void throw_bad_variant_access() {
-#ifdef MPARK_EXCEPTIONS
-    throw bad_variant_access{};
-#else
-    std::terminate();
-#ifdef MPARK_BUILTIN_UNREACHABLE
-    __builtin_unreachable();
-#endif
-#endif
-  }
-
-  template <typename... Ts>
-  class variant;
-
-  template <typename T>
-  struct variant_size;
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  template <typename T>
-  constexpr std::size_t variant_size_v = variant_size<T>::value;
-#endif
-
-  template <typename T>
-  struct variant_size<const T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<volatile T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<const volatile T> : variant_size<T> {};
-
-  template <typename... Ts>
-  struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative;
-
-  template <std::size_t I, typename T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const T>
-      : std::add_const<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, volatile T>
-      : std::add_volatile<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const volatile T>
-      : std::add_cv<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename... Ts>
-  struct variant_alternative<I, variant<Ts...>> {
-    static_assert(I < sizeof...(Ts),
-                  "Index out of bounds in std::variant_alternative<>");
-    using type = lib::type_pack_element_t<I, Ts...>;
-  };
-
-  constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
-
-  namespace detail {
-
-    constexpr std::size_t not_found = static_cast<std::size_t>(-1);
-    constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      constexpr lib::array<bool, sizeof...(Ts)> matches = {
-          {std::is_same<T, Ts>::value...}
-      };
-      std::size_t result = not_found;
-      for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
-        if (matches[i]) {
-          if (result != not_found) {
-            return ambiguous;
-          }
-          result = i;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t) {
-      return result;
-    }
-
-    template <typename... Bs>
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t idx,
-                                                 bool b,
-                                                 Bs... bs) {
-      return b ? (result != not_found ? ambiguous
-                                      : find_index_impl(idx, idx + 1, bs...))
-               : find_index_impl(result, idx + 1, bs...);
-    }
-
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
-    }
-#endif
-
-    template <std::size_t I>
-    using find_index_sfinae_impl =
-        lib::enable_if_t<I != not_found && I != ambiguous,
-                         lib::size_constant<I>>;
-
-    template <typename T, typename... Ts>
-    using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
-
-    template <std::size_t I>
-    struct find_index_checked_impl : lib::size_constant<I> {
-      static_assert(I != not_found, "the specified type is not found.");
-      static_assert(I != ambiguous, "the specified type is ambiguous.");
-    };
-
-    template <typename T, typename... Ts>
-    using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
-
-    struct valueless_t {};
-
-    enum class Trait { TriviallyAvailable, Available, Unavailable };
-
-    template <typename T,
-              template <typename> class IsTriviallyAvailable,
-              template <typename> class IsAvailable>
-    inline constexpr Trait trait() {
-      return IsTriviallyAvailable<T>::value
-                 ? Trait::TriviallyAvailable
-                 : IsAvailable<T>::value ? Trait::Available
-                                         : Trait::Unavailable;
-    }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... traits) {
-      Trait result = Trait::TriviallyAvailable;
-      for (Trait t : {traits...}) {
-        if (static_cast<int>(t) > static_cast<int>(result)) {
-          result = t;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr Trait common_trait_impl(Trait result) { return result; }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait_impl(Trait result,
-                                             Trait t,
-                                             Traits... ts) {
-      return static_cast<int>(t) > static_cast<int>(result)
-                 ? common_trait_impl(t, ts...)
-                 : common_trait_impl(result, ts...);
-    }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... ts) {
-      return common_trait_impl(Trait::TriviallyAvailable, ts...);
-    }
-#endif
-
-    template <typename... Ts>
-    struct traits {
-      static constexpr Trait copy_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_copy_constructible,
-                             std::is_copy_constructible>()...);
-
-      static constexpr Trait move_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_move_constructible,
-                             std::is_move_constructible>()...);
-
-      static constexpr Trait copy_assignable_trait =
-          common_trait(copy_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_copy_assignable,
-                             std::is_copy_assignable>()...);
-
-      static constexpr Trait move_assignable_trait =
-          common_trait(move_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_move_assignable,
-                             std::is_move_assignable>()...);
-
-      static constexpr Trait destructible_trait =
-          common_trait(trait<Ts,
-                             std::is_trivially_destructible,
-                             std::is_destructible>()...);
-    };
-
-    namespace access {
-
-      struct recursive_union {
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename V>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
-          return lib::forward<V>(v).head_;
-        }
-
-        template <typename V, std::size_t I>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
-          return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
-        }
-#else
-        template <std::size_t I, bool Dummy = true>
-        struct get_alt_impl {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
-        };
-
-        template <bool Dummy>
-        struct get_alt_impl<0, Dummy> {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
-        };
-
-        template <typename V, std::size_t I>
-        inline static constexpr AUTO_REFREF get_alt(V &&v, in_place_index_t<I>)
-          AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
-#endif
-      };
-
-      struct base {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(recursive_union::get_alt(
-              data(lib::forward<V>(v)), in_place_index_t<I>{}))
-      };
-
-      struct variant {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
-      };
-
-    }  // namespace access
-
-    namespace visitation {
-
-      struct base {
-        private:
-        template <typename T>
-        inline static constexpr const T &at(const T &elem) {
-          return elem;
-        }
-
-        template <typename T, std::size_t N, typename... Is>
-        inline static constexpr const lib::remove_all_extents_t<T> &at(
-            const lib::array<T, N> &elems, std::size_t i, Is... is) {
-          return at(elems[i], is...);
-        }
-
-        template <typename F, typename... Fs>
-        inline static constexpr int visit_visitor_return_type_check() {
-          static_assert(lib::all<std::is_same<F, Fs>::value...>::value,
-                        "`mpark::visit` requires the visitor to have a single "
-                        "return type.");
-          return 0;
-        }
-
-        template <typename... Fs>
-        inline static constexpr lib::array<
-            lib::common_type_t<lib::decay_t<Fs>...>,
-            sizeof...(Fs)>
-        make_farray(Fs &&... fs) {
-          using result = lib::array<lib::common_type_t<lib::decay_t<Fs>...>,
-                                    sizeof...(Fs)>;
-          return visit_visitor_return_type_check<lib::decay_t<Fs>...>(),
-                 result{{lib::forward<Fs>(fs)...}};
-        }
-
-        template <std::size_t... Is>
-        struct dispatcher {
-          template <typename F, typename... Vs>
-          struct impl {
-            inline static constexpr DECLTYPE_AUTO dispatch(F f, Vs... vs)
-              DECLTYPE_AUTO_RETURN(lib::invoke(
-                  static_cast<F>(f),
-                  access::base::get_alt<Is>(static_cast<Vs>(vs))...))
-          };
-        };
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_dispatch(lib::index_sequence<Is...>)
-          AUTO_RETURN(&dispatcher<Is...>::template impl<F, Vs...>::dispatch)
-
-        template <std::size_t I, typename F, typename... Vs>
-        inline static constexpr AUTO make_fdiagonal_impl()
-          AUTO_RETURN(make_dispatch<F, Vs...>(
-              lib::index_sequence<lib::indexed_type<I, Vs>::value...>{}))
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_fdiagonal_impl(
-            lib::index_sequence<Is...>)
-          AUTO_RETURN(make_farray(make_fdiagonal_impl<Is, F, Vs...>()...))
-
-        template <typename F, typename V, typename... Vs>
-        inline static constexpr /* auto * */ auto make_fdiagonal()
-            -> decltype(make_fdiagonal_impl<F, V, Vs...>(
-                lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
-          static_assert(lib::all<(lib::decay_t<V>::size() ==
-                                  lib::decay_t<Vs>::size())...>::value,
-                        "all of the variants must be the same size.");
-          return make_fdiagonal_impl<F, V, Vs...>(
-              lib::make_index_sequence<lib::decay_t<V>::size()>{});
-        }
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr auto make_fmatrix_impl(
-            lib::index_sequence<Is...> is) {
-          return make_dispatch<F, Vs...>(is);
-        }
-
-        template <typename F,
-                  typename... Vs,
-                  std::size_t... Is,
-                  std::size_t... Js,
-                  typename... Ls>
-        inline static constexpr auto make_fmatrix_impl(
-            lib::index_sequence<Is...>, lib::index_sequence<Js...>, Ls... ls) {
-          return make_farray(make_fmatrix_impl<F, Vs...>(
-              lib::index_sequence<Is..., Js>{}, ls...)...);
-        }
-
-        template <typename F, typename... Vs>
-        inline static constexpr auto make_fmatrix() {
-          return make_fmatrix_impl<F, Vs...>(
-              lib::index_sequence<>{},
-              lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
-        }
-#else
-        template <typename F, typename... Vs>
-        struct make_fmatrix_impl {
-          template <typename...>
-          struct impl;
-
-          template <std::size_t... Is>
-          struct impl<lib::index_sequence<Is...>> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(
-                  make_dispatch<F, Vs...>(lib::index_sequence<Is...>{}))
-          };
-
-          template <std::size_t... Is, std::size_t... Js, typename... Ls>
-          struct impl<lib::index_sequence<Is...>,
-                      lib::index_sequence<Js...>,
-                      Ls...> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(make_farray(
-                  impl<lib::index_sequence<Is..., Js>, Ls...>{}()...))
-          };
-        };
-
-        template <typename F, typename... Vs>
-        inline static constexpr AUTO make_fmatrix()
-          AUTO_RETURN(
-              typename make_fmatrix_impl<F, Vs...>::template impl<
-                  lib::index_sequence<>,
-                  lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
-#endif
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              at(make_fdiagonal<Visitor &&,
-                                decltype(as_base(lib::forward<Vs>(vs)))...>(),
-                 index)(lib::forward<Visitor>(visitor),
-                        as_base(lib::forward<Vs>(vs))...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              at(make_fmatrix<Visitor &&,
-                              decltype(as_base(lib::forward<Vs>(vs)))...>(),
-                 vs.index()...)(lib::forward<Visitor>(visitor),
-                                as_base(lib::forward<Vs>(vs))...))
-      };
-
-      struct variant {
-        private:
-        template <typename Visitor, typename... Values>
-        struct visit_exhaustive_visitor_check {
-          static_assert(
-              lib::is_invocable<Visitor, Values...>::value,
-              "`mpark::visit` requires the visitor to be exhaustive.");
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-          inline constexpr DECLTYPE_AUTO operator()(Visitor &&visitor,
-                                                    Values &&... values) const
-            DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
-                                             lib::forward<Values>(values)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        };
-
-        template <typename Visitor>
-        struct value_visitor {
-          Visitor &&visitor_;
-
-          template <typename... Alts>
-          inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const
-            DECLTYPE_AUTO_RETURN(
-                visit_exhaustive_visitor_check<
-                    Visitor,
-                    decltype((lib::forward<Alts>(alts).value))...>{}(
-                    lib::forward<Visitor>(visitor_),
-                    lib::forward<Alts>(alts).value...))
-        };
-
-        template <typename Visitor>
-        inline static constexpr AUTO make_value_visitor(Visitor &&visitor)
-          AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              base::visit_alt_at(index,
-                                 lib::forward<Visitor>(visitor),
-                                 lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(base::visit_alt(lib::forward<Visitor>(visitor),
-                                               lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index,
-                                                             Visitor &&visitor,
-                                                             Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt_at(index,
-                           make_value_visitor(lib::forward<Visitor>(visitor)),
-                           lib::forward<Vs>(vs)...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor,
-                                                          Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt(make_value_visitor(lib::forward<Visitor>(visitor)),
-                        lib::forward<Vs>(vs)...))
-      };
-
-    }  // namespace visitation
-
-    template <std::size_t Index, typename T>
-    struct alt {
-      using value_type = T;
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-      template <typename... Args>
-      inline explicit constexpr alt(in_place_t, Args &&... args)
-          : value(lib::forward<Args>(args)...) {}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      T value;
-    };
-
-    template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
-    union recursive_union;
-
-    template <Trait DestructibleTrait, std::size_t Index>
-    union recursive_union<DestructibleTrait, Index> {};
-
-#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)      \
-  template <std::size_t Index, typename T, typename... Ts>                 \
-  union recursive_union<destructible_trait, Index, T, Ts...> {             \
-    public:                                                                \
-    inline explicit constexpr recursive_union(valueless_t) noexcept        \
-        : dummy_{} {}                                                      \
-                                                                           \
-    template <typename... Args>                                            \
-    inline explicit constexpr recursive_union(in_place_index_t<0>,         \
-                                              Args &&... args)             \
-        : head_(in_place_t{}, lib::forward<Args>(args)...) {}              \
-                                                                           \
-    template <std::size_t I, typename... Args>                             \
-    inline explicit constexpr recursive_union(in_place_index_t<I>,         \
-                                              Args &&... args)             \
-        : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
-                                                                           \
-    recursive_union(const recursive_union &) = default;                    \
-    recursive_union(recursive_union &&) = default;                         \
-                                                                           \
-    destructor                                                             \
-                                                                           \
-    recursive_union &operator=(const recursive_union &) = default;         \
-    recursive_union &operator=(recursive_union &&) = default;              \
-                                                                           \
-    private:                                                               \
-    char dummy_;                                                           \
-    alt<Index, T> head_;                                                   \
-    recursive_union<destructible_trait, Index + 1, Ts...> tail_;           \
-                                                                           \
-    friend struct access::recursive_union;                                 \
-  }
-
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
-                                  ~recursive_union() = default;);
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
-                                  ~recursive_union() {});
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
-                                  ~recursive_union() = delete;);
-
-#undef MPARK_VARIANT_RECURSIVE_UNION
-
-    using index_t = unsigned int;
-
-    template <Trait DestructibleTrait, typename... Ts>
-    class base {
-      public:
-      inline explicit constexpr base(valueless_t tag) noexcept
-          : data_(tag), index_(static_cast<index_t>(-1)) {}
-
-      template <std::size_t I, typename... Args>
-      inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
-          : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...),
-            index_(I) {}
-
-      inline constexpr bool valueless_by_exception() const noexcept {
-        return index_ == static_cast<index_t>(-1);
-      }
-
-      inline constexpr std::size_t index() const noexcept {
-        return valueless_by_exception() ? variant_npos : index_;
-      }
-
-      protected:
-      using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
-
-      friend inline constexpr base &as_base(base &b) { return b; }
-      friend inline constexpr const base &as_base(const base &b) { return b; }
-      friend inline constexpr base &&as_base(base &&b) { return lib::move(b); }
-      friend inline constexpr const base &&as_base(const base &&b) { return lib::move(b); }
-
-      friend inline constexpr data_t &data(base &b) { return b.data_; }
-      friend inline constexpr const data_t &data(const base &b) { return b.data_; }
-      friend inline constexpr data_t &&data(base &&b) { return lib::move(b).data_; }
-      friend inline constexpr const data_t &&data(const base &&b) { return lib::move(b).data_; }
-
-      inline static constexpr std::size_t size() { return sizeof...(Ts); }
-
-      data_t data_;
-      index_t index_;
-
-      friend struct access::base;
-      friend struct visitation::base;
-    };
-
-    struct dtor {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename Alt>
-      inline void operator()(Alt &alt) const noexcept { alt.~Alt(); }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-    };
-
-#if defined(_MSC_VER) && _MSC_VER < 1910
-#define INHERITING_CTOR(type, base)               \
-  template <typename... Args>                     \
-  inline explicit constexpr type(Args &&... args) \
-      : base(lib::forward<Args>(args)...) {}
-#else
-#define INHERITING_CTOR(type, base) using base::base;
-#endif
-
-    template <typename Traits, Trait = Traits::destructible_trait>
-    class destructor;
-
-#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
-  template <typename... Ts>                                               \
-  class destructor<traits<Ts...>, destructible_trait>                     \
-      : public base<destructible_trait, Ts...> {                          \
-    using super = base<destructible_trait, Ts...>;                        \
-                                                                          \
-    public:                                                               \
-    INHERITING_CTOR(destructor, super)                                    \
-    using super::operator=;                                               \
-                                                                          \
-    destructor(const destructor &) = default;                             \
-    destructor(destructor &&) = default;                                  \
-    definition                                                            \
-    destructor &operator=(const destructor &) = default;                  \
-    destructor &operator=(destructor &&) = default;                       \
-                                                                          \
-    protected:                                                            \
-    destroy                                                               \
-  }
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::TriviallyAvailable,
-        ~destructor() = default;,
-        inline void destroy() noexcept {
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Available,
-        ~destructor() { destroy(); },
-        inline void destroy() noexcept {
-          if (!this->valueless_by_exception()) {
-            visitation::base::visit_alt(dtor{}, *this);
-          }
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Unavailable,
-        ~destructor() = delete;,
-        inline void destroy() noexcept = delete;);
-
-#undef MPARK_VARIANT_DESTRUCTOR
-
-    template <typename Traits>
-    class constructor : public destructor<Traits> {
-      using super = destructor<Traits>;
-
-      public:
-      INHERITING_CTOR(constructor, super)
-      using super::operator=;
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct ctor {
-        template <typename LhsAlt, typename RhsAlt>
-        inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const {
-          constructor::construct_alt(lhs_alt,
-                                     lib::forward<RhsAlt>(rhs_alt).value);
-        }
-      };
-#endif
-
-      template <std::size_t I, typename T, typename... Args>
-      inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
-        ::new (static_cast<void *>(lib::addressof(a)))
-            alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
-        return a.value;
-      }
-
-      template <typename Rhs>
-      inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
-        lhs.destroy();
-        if (!rhs.valueless_by_exception()) {
-          visitation::base::visit_alt_at(
-              rhs.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [](auto &lhs_alt, auto &&rhs_alt) {
-                constructor::construct_alt(
-                    lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
-              }
-#else
-              ctor{}
-#endif
-              ,
-              lhs,
-              lib::forward<Rhs>(rhs));
-          lhs.index_ = rhs.index_;
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_constructible_trait>
-    class move_constructor;
-
-#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class move_constructor<traits<Ts...>, move_constructible_trait>            \
-      : public constructor<traits<Ts...>> {                                  \
-    using super = constructor<traits<Ts...>>;                                \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(move_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    move_constructor(const move_constructor &) = default;                    \
-    definition                                                               \
-    ~move_constructor() = default;                                           \
-    move_constructor &operator=(const move_constructor &) = default;         \
-    move_constructor &operator=(move_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        move_constructor(move_constructor &&that) = default;);
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Available,
-        move_constructor(move_constructor &&that) noexcept(
-            lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
-            : move_constructor(valueless_t{}) {
-          this->generic_construct(*this, lib::move(that));
-        });
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Unavailable,
-        move_constructor(move_constructor &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_CONSTRUCTOR
-
-    template <typename Traits, Trait = Traits::copy_constructible_trait>
-    class copy_constructor;
-
-#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
-      : public move_constructor<traits<Ts...>> {                             \
-    using super = move_constructor<traits<Ts...>>;                           \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(copy_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    definition                                                               \
-    copy_constructor(copy_constructor &&) = default;                         \
-    ~copy_constructor() = default;                                           \
-    copy_constructor &operator=(const copy_constructor &) = default;         \
-    copy_constructor &operator=(copy_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        copy_constructor(const copy_constructor &that) = default;);
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Available,
-        copy_constructor(const copy_constructor &that)
-            : copy_constructor(valueless_t{}) {
-          this->generic_construct(*this, that);
-        });
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Unavailable,
-        copy_constructor(const copy_constructor &) = delete;);
-
-#undef MPARK_VARIANT_COPY_CONSTRUCTOR
-
-    template <typename Traits>
-    class assignment : public copy_constructor<Traits> {
-      using super = copy_constructor<Traits>;
-
-      public:
-      INHERITING_CTOR(assignment, super)
-      using super::operator=;
-
-      template <std::size_t I, typename... Args>
-      inline /* auto & */ auto emplace(Args &&... args)
-          -> decltype(this->construct_alt(access::base::get_alt<I>(*this),
-                                          lib::forward<Args>(args)...)) {
-        this->destroy();
-        auto &result = this->construct_alt(access::base::get_alt<I>(*this),
-                                           lib::forward<Args>(args)...);
-        this->index_ = I;
-        return result;
-      }
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      template <typename That>
-      struct assigner {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const {
-          self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
-        }
-        assignment *self;
-      };
-#endif
-
-      template <std::size_t I, typename T, typename Arg>
-      inline void assign_alt(alt<I, T> &a, Arg &&arg) {
-        if (this->index() == I) {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-          a.value = lib::forward<Arg>(arg);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        } else {
-          struct {
-            void operator()(std::true_type) const {
-              this_->emplace<I>(lib::forward<Arg>(arg_));
-            }
-            void operator()(std::false_type) const {
-              this_->emplace<I>(T(lib::forward<Arg>(arg_)));
-            }
-            assignment *this_;
-            Arg &&arg_;
-          } impl{this, lib::forward<Arg>(arg)};
-          impl(lib::bool_constant<
-                   std::is_nothrow_constructible<T, Arg>::value ||
-                   !std::is_nothrow_move_constructible<T>::value>{});
-        }
-      }
-
-      template <typename That>
-      inline void generic_assign(That &&that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (that.valueless_by_exception()) {
-          this->destroy();
-        } else {
-          visitation::base::visit_alt_at(
-              that.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [this](auto &this_alt, auto &&that_alt) {
-                this->assign_alt(
-                    this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
-              }
-#else
-              assigner<That>{this}
-#endif
-              ,
-              *this,
-              lib::forward<That>(that));
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_assignable_trait>
-    class move_assignment;
-
-#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class move_assignment<traits<Ts...>, move_assignable_trait>            \
-      : public assignment<traits<Ts...>> {                               \
-    using super = assignment<traits<Ts...>>;                             \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(move_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    move_assignment(const move_assignment &) = default;                  \
-    move_assignment(move_assignment &&) = default;                       \
-    ~move_assignment() = default;                                        \
-    move_assignment &operator=(const move_assignment &) = default;       \
-    definition                                                           \
-  }
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        move_assignment &operator=(move_assignment &&that) = default;);
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Available,
-        move_assignment &
-        operator=(move_assignment &&that) noexcept(
-            lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                      std::is_nothrow_move_assignable<Ts>::value)...>::value) {
-          this->generic_assign(lib::move(that));
-          return *this;
-        });
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Unavailable,
-        move_assignment &operator=(move_assignment &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_ASSIGNMENT
-
-    template <typename Traits, Trait = Traits::copy_assignable_trait>
-    class copy_assignment;
-
-#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
-      : public move_assignment<traits<Ts...>> {                          \
-    using super = move_assignment<traits<Ts...>>;                        \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(copy_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    copy_assignment(const copy_assignment &) = default;                  \
-    copy_assignment(copy_assignment &&) = default;                       \
-    ~copy_assignment() = default;                                        \
-    definition                                                           \
-    copy_assignment &operator=(copy_assignment &&) = default;            \
-  }
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        copy_assignment &operator=(const copy_assignment &that) = default;);
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Available,
-        copy_assignment &operator=(const copy_assignment &that) {
-          this->generic_assign(that);
-          return *this;
-        });
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Unavailable,
-        copy_assignment &operator=(const copy_assignment &) = delete;);
-
-#undef MPARK_VARIANT_COPY_ASSIGNMENT
-
-    template <typename... Ts>
-    class impl : public copy_assignment<traits<Ts...>> {
-      using super = copy_assignment<traits<Ts...>>;
-
-      public:
-      INHERITING_CTOR(impl, super)
-      using super::operator=;
-
-      template <std::size_t I, typename Arg>
-      inline void assign(Arg &&arg) {
-        this->assign_alt(access::base::get_alt<I>(*this),
-                         lib::forward<Arg>(arg));
-      }
-
-      inline void swap(impl &that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (this->index() == that.index()) {
-          visitation::base::visit_alt_at(this->index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-                                         [](auto &this_alt, auto &that_alt) {
-                                           using std::swap;
-                                           swap(this_alt.value,
-                                                that_alt.value);
-                                         }
-#else
-                                         swapper{}
-#endif
-                                         ,
-                                         *this,
-                                         that);
-        } else {
-          impl *lhs = this;
-          impl *rhs = lib::addressof(that);
-          if (lhs->move_nothrow() && !rhs->move_nothrow()) {
-            std::swap(lhs, rhs);
-          }
-          impl tmp(lib::move(*rhs));
-#ifdef MPARK_EXCEPTIONS
-          // EXTENSION: When the move construction of `lhs` into `rhs` throws
-          // and `tmp` is nothrow move constructible then we move `tmp` back
-          // into `rhs` and provide the strong exception safety guarantee.
-          try {
-            this->generic_construct(*rhs, lib::move(*lhs));
-          } catch (...) {
-            if (tmp.move_nothrow()) {
-              this->generic_construct(*rhs, lib::move(tmp));
-            }
-            throw;
-          }
-#else
-          this->generic_construct(*rhs, lib::move(*lhs));
-#endif
-          this->generic_construct(*lhs, lib::move(tmp));
-        }
-      }
-
-      private:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct swapper {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const {
-          using std::swap;
-          swap(this_alt.value, that_alt.value);
-        }
-      };
-#endif
-
-      inline constexpr bool move_nothrow() const {
-        return this->valueless_by_exception() ||
-               lib::array<bool, sizeof...(Ts)>{
-                   {std::is_nothrow_move_constructible<Ts>::value...}
-               }[this->index()];
-      }
-    };
-
-    template <std::size_t I, typename T>
-    struct overload_leaf {
-      using F = lib::size_constant<I> (*)(T);
-      operator F() const { return nullptr; }
-    };
-
-    template <typename... Ts>
-    struct overload_impl {
-      private:
-      template <typename>
-      struct impl;
-
-      template <std::size_t... Is>
-      struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>... {};
-
-      public:
-      using type = impl<lib::index_sequence_for<Ts...>>;
-    };
-
-    template <typename... Ts>
-    using overload = typename overload_impl<Ts...>::type;
-
-    template <typename T, typename... Ts>
-    using best_match = lib::invoke_result_t<overload<Ts...>, T &&>;
-
-    template <typename T>
-    struct is_in_place_index : std::false_type {};
-
-    template <std::size_t I>
-    struct is_in_place_index<in_place_index_t<I>> : std::true_type {};
-
-    template <typename T>
-    struct is_in_place_type : std::false_type {};
-
-    template <typename T>
-    struct is_in_place_type<in_place_type_t<T>> : std::true_type {};
-
-  }  // detail
-
-  template <typename... Ts>
-  class variant {
-    static_assert(0 < sizeof...(Ts),
-                  "variant must consist of at least one alternative.");
-
-    static_assert(lib::all<!std::is_array<Ts>::value...>::value,
-                  "variant can not have an array type as an alternative.");
-
-    static_assert(lib::all<!std::is_reference<Ts>::value...>::value,
-                  "variant can not have a reference type as an alternative.");
-
-    static_assert(lib::all<!std::is_void<Ts>::value...>::value,
-                  "variant can not have a void type as an alternative.");
-
-    public:
-    template <
-        typename Front = lib::type_pack_element_t<0, Ts...>,
-        lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
-    inline constexpr variant() noexcept(
-        std::is_nothrow_default_constructible<Front>::value)
-        : impl_(in_place_index_t<0>{}) {}
-
-    variant(const variant &) = default;
-    variant(variant &&) = default;
-
-    template <
-        typename Arg,
-        typename Decayed = lib::decay_t<Arg>,
-        lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_index<Decayed>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_type<Decayed>::value, int> = 0,
-        std::size_t I = detail::best_match<Arg, Ts...>::value,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
-    inline constexpr variant(Arg &&arg) noexcept(
-        std::is_nothrow_constructible<T, Arg>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {}
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    ~variant() = default;
-
-    variant &operator=(const variant &) = default;
-    variant &operator=(variant &&) = default;
-
-    template <typename Arg,
-              lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              std::size_t I = detail::best_match<Arg, Ts...>::value,
-              typename T = lib::type_pack_element_t<I, Ts...>,
-              lib::enable_if_t<(std::is_assignable<T &, Arg>::value &&
-                                std::is_constructible<T, Arg>::value),
-                               int> = 0>
-    inline variant &operator=(Arg &&arg) noexcept(
-        (std::is_nothrow_assignable<T &, Arg>::value &&
-         std::is_nothrow_constructible<T, Arg>::value)) {
-      impl_.template assign<I>(lib::forward<Arg>(arg));
-      return *this;
-    }
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    inline constexpr bool valueless_by_exception() const noexcept {
-      return impl_.valueless_by_exception();
-    }
-
-    inline constexpr std::size_t index() const noexcept {
-      return impl_.index();
-    }
-
-    template <
-        bool Dummy = true,
-        lib::enable_if_t<lib::all<Dummy,
-                                  (std::is_move_constructible<Ts>::value &&
-                                   lib::is_swappable<Ts>::value)...>::value,
-                         int> = 0>
-    inline void swap(variant &that) noexcept(
-        lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                  lib::is_nothrow_swappable<Ts>::value)...>::value) {
-      impl_.swap(that.impl_);
-    }
-
-    private:
-    detail::impl<Ts...> impl_;
-
-    friend struct detail::access::variant;
-    friend struct detail::visitation::variant;
-  };
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return v.index() == I;
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-    template <std::size_t I, typename V>
-    struct generic_get_impl {
-      constexpr generic_get_impl(int) {}
-
-      constexpr AUTO_REFREF operator()(V &&v) const
-        AUTO_REFREF_RETURN(
-            access::variant::get_alt<I>(lib::forward<V>(v)).value)
-    };
-
-    template <std::size_t I, typename V>
-    inline constexpr AUTO_REFREF generic_get(V &&v)
-      AUTO_REFREF_RETURN(generic_get_impl<I, V>(
-          holds_alternative<I>(v) ? 0 : (throw_bad_variant_access(), 0))(
-          lib::forward<V>(v)))
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
-      variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
-      variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
-      const variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
-      const variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &get(variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &&get(variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &get(const variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &&get(const variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept
-      AUTO_RETURN(v && holds_alternative<I>(*v)
-                      ? lib::addressof(access::variant::get_alt<I>(*v).value)
-                      : nullptr)
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
-  get_if(variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<
-      const variant_alternative_t<I, variant<Ts...>>>
-  get_if(const variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<T>
-  get_if(variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<const T>
-  get_if(const variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator==(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
-#else
-    return lhs.index() == rhs.index() &&
-           (lhs.valueless_by_exception() ||
-            variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator!=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::not_equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
-#else
-    return lhs.index() != rhs.index() ||
-           (!lhs.valueless_by_exception() &&
-            variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::less;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
-#else
-    return !rhs.valueless_by_exception() &&
-           (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::greater;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return false;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
-#else
-    return !lhs.valueless_by_exception() &&
-           (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::less_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return true;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
-#else
-    return lhs.valueless_by_exception() ||
-           (!rhs.valueless_by_exception() &&
-            (lhs.index() < rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::greater_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
-#else
-    return rhs.valueless_by_exception() ||
-           (!lhs.valueless_by_exception() &&
-            (lhs.index() > rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(
-                  lhs.index(), greater_equal{}, lhs, rhs))));
-#endif
-  }
-
-  struct monostate {};
-
-  inline constexpr bool operator<(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator>(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator<=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator>=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator==(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator!=(monostate, monostate) noexcept {
-    return false;
-  }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-  namespace detail {
-
-    inline constexpr bool all(std::initializer_list<bool> bs) {
-      for (bool b : bs) {
-        if (!b) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
-    return (detail::all({!vs.valueless_by_exception()...})
-                ? (void)0
-                : throw_bad_variant_access()),
-           detail::visitation::variant::visit_value(
-               lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
-  }
-#else
-  namespace detail {
-
-    template <std::size_t N>
-    inline constexpr bool all_impl(const lib::array<bool, N> &bs,
-                                   std::size_t idx) {
-      return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
-    }
-
-    template <std::size_t N>
-    inline constexpr bool all(const lib::array<bool, N> &bs) {
-      return all_impl(bs, 0);
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs)
-    DECLTYPE_AUTO_RETURN(
-        (detail::all(
-             lib::array<bool, sizeof...(Vs)>{{!vs.valueless_by_exception()...}})
-             ? (void)0
-             : throw_bad_variant_access()),
-        detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
-                                                 lib::forward<Vs>(vs)...))
-#endif
-
-  template <typename... Ts>
-  inline auto swap(variant<Ts...> &lhs,
-                   variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
-      -> decltype(lhs.swap(rhs)) {
-    lhs.swap(rhs);
-  }
-
-  namespace detail {
-
-    template <typename T, typename...>
-    using enabled_type = T;
-
-    namespace hash {
-
-      template <typename H, typename K>
-      constexpr bool meets_requirements() {
-        return std::is_copy_constructible<H>::value &&
-               std::is_move_constructible<H>::value &&
-               lib::is_invocable_r<std::size_t, H, const K &>::value;
-      }
-
-      template <typename K>
-      constexpr bool is_enabled() {
-        using H = std::hash<K>;
-        return meets_requirements<H, K>() &&
-               std::is_default_constructible<H>::value &&
-               std::is_copy_assignable<H>::value &&
-               std::is_move_assignable<H>::value;
-      }
-
-    }  // namespace hash
-
-  }  // namespace detail
-
-#undef AUTO
-#undef AUTO_RETURN
-
-#undef AUTO_REFREF
-#undef AUTO_REFREF_RETURN
-
-#undef DECLTYPE_AUTO
-#undef DECLTYPE_AUTO_RETURN
-
-}  // namespace mpark
-
-namespace std {
-
-  template <typename... Ts>
-  struct hash<mpark::detail::enabled_type<
-      mpark::variant<Ts...>,
-      mpark::lib::enable_if_t<mpark::lib::all<mpark::detail::hash::is_enabled<
-          mpark::lib::remove_const_t<Ts>>()...>::value>>> {
-    using argument_type = mpark::variant<Ts...>;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &v) const {
-      using mpark::detail::visitation::variant;
-      std::size_t result =
-          v.valueless_by_exception()
-              ? 299792458  // Random value chosen by the universe upon creation
-              : variant::visit_alt(
-#ifdef MPARK_GENERIC_LAMBDAS
-                    [](const auto &alt) {
-                      using alt_type = mpark::lib::decay_t<decltype(alt)>;
-                      using value_type = mpark::lib::remove_const_t<
-                          typename alt_type::value_type>;
-                      return hash<value_type>{}(alt.value);
-                    }
-#else
-                    hasher{}
-#endif
-                    ,
-                    v);
-      return hash_combine(result, hash<std::size_t>{}(v.index()));
-    }
-
-    private:
-#ifndef MPARK_GENERIC_LAMBDAS
-    struct hasher {
-      template <typename Alt>
-      inline std::size_t operator()(const Alt &alt) const {
-        using alt_type = mpark::lib::decay_t<Alt>;
-        using value_type =
-            mpark::lib::remove_const_t<typename alt_type::value_type>;
-        return hash<value_type>{}(alt.value);
-      }
-    };
-#endif
-
-    static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
-      return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
-    }
-  };
-
-  template <>
-  struct hash<mpark::monostate> {
-    using argument_type = mpark::monostate;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &) const noexcept {
-      return 66740831;  // return a fundamentally attractive random value.
-    }
-  };
-
-}  // namespace std
-
-#endif  // MPARK_VARIANT_HPP

+ 0 - 2457
src/external/mpark-variant/v1.3.0/variant.hpp

@@ -1,2457 +0,0 @@
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANT_HPP
-#define MPARK_VARIANT_HPP
-
-/*
-   variant synopsis
-
-namespace std {
-
-  // 20.7.2, class template variant
-  template <class... Types>
-  class variant {
-  public:
-
-    // 20.7.2.1, constructors
-    constexpr variant() noexcept(see below);
-    variant(const variant&);
-    variant(variant&&) noexcept(see below);
-
-    template <class T> constexpr variant(T&&) noexcept(see below);
-
-    template <class T, class... Args>
-    constexpr explicit variant(in_place_type_t<T>, Args&&...);
-
-    template <class T, class U, class... Args>
-    constexpr explicit variant(
-        in_place_type_t<T>, initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    constexpr explicit variant(in_place_index_t<I>, Args&&...);
-
-    template <size_t I, class U, class... Args>
-    constexpr explicit variant(
-        in_place_index_t<I>, initializer_list<U>, Args&&...);
-
-    // 20.7.2.2, destructor
-    ~variant();
-
-    // 20.7.2.3, assignment
-    variant& operator=(const variant&);
-    variant& operator=(variant&&) noexcept(see below);
-
-    template <class T> variant& operator=(T&&) noexcept(see below);
-
-    // 20.7.2.4, modifiers
-    template <class T, class... Args>
-    T& emplace(Args&&...);
-
-    template <class T, class U, class... Args>
-    T& emplace(initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    variant_alternative<I, variant>& emplace(Args&&...);
-
-    template <size_t I, class U, class...  Args>
-    variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
-
-    // 20.7.2.5, value status
-    constexpr bool valueless_by_exception() const noexcept;
-    constexpr size_t index() const noexcept;
-
-    // 20.7.2.6, swap
-    void swap(variant&) noexcept(see below);
-  };
-
-  // 20.7.3, variant helper classes
-  template <class T> struct variant_size; // undefined
-
-  template <class T>
-  constexpr size_t variant_size_v = variant_size<T>::value;
-
-  template <class T> struct variant_size<const T>;
-  template <class T> struct variant_size<volatile T>;
-  template <class T> struct variant_size<const volatile T>;
-
-  template <class... Types>
-  struct variant_size<variant<Types...>>;
-
-  template <size_t I, class T> struct variant_alternative; // undefined
-
-  template <size_t I, class T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <size_t I, class T> struct variant_alternative<I, const T>;
-  template <size_t I, class T> struct variant_alternative<I, volatile T>;
-  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
-
-  template <size_t I, class... Types>
-  struct variant_alternative<I, variant<Types...>>;
-
-  constexpr size_t variant_npos = -1;
-
-  // 20.7.4, value access
-  template <class T, class... Types>
-  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&
-  get(variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&&
-  get(variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&
-  get(const variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&&
-  get(const variant<Types...>&&);
-
-  template <class T, class...  Types>
-  constexpr T& get(variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr T&& get(variant<Types...>&&);
-
-  template <class T, class... Types>
-  constexpr const T& get(const variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr const T&& get(const variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
-  get_if(variant<Types...>*) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
-  get_if(const variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<T>
-  get_if(variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<const T>
-  get_if(const variant<Types...>*) noexcept;
-
-  // 20.7.5, relational operators
-  template <class... Types>
-  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
-
-  // 20.7.6, visitation
-  template <class Visitor, class... Variants>
-  constexpr see below visit(Visitor&&, Variants&&...);
-
-  // 20.7.7, class monostate
-  struct monostate;
-
-  // 20.7.8, monostate relational operators
-  constexpr bool operator<(monostate, monostate) noexcept;
-  constexpr bool operator>(monostate, monostate) noexcept;
-  constexpr bool operator<=(monostate, monostate) noexcept;
-  constexpr bool operator>=(monostate, monostate) noexcept;
-  constexpr bool operator==(monostate, monostate) noexcept;
-  constexpr bool operator!=(monostate, monostate) noexcept;
-
-  // 20.7.9, specialized algorithms
-  template <class... Types>
-  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
-
-  // 20.7.10, class bad_variant_access
-  class bad_variant_access;
-
-  // 20.7.11, hash support
-  template <class T> struct hash;
-  template <class... Types> struct hash<variant<Types...>>;
-  template <> struct hash<monostate>;
-
-} // namespace std
-
-*/
-
-#include <cstddef>
-#include <exception>
-#include <functional>
-#include <initializer_list>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_CONFIG_HPP
-#define MPARK_CONFIG_HPP
-
-// MSVC 2015 Update 3.
-#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024210)
-#error "MPark.Variant requires C++11 support."
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#ifndef __has_include
-#define __has_include(x) 0
-#endif
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-
-#if __has_builtin(__builtin_addressof) || \
-    (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
-#define MPARK_BUILTIN_ADDRESSOF
-#endif
-
-#if __has_builtin(__builtin_unreachable)
-#define MPARK_BUILTIN_UNREACHABLE
-#endif
-
-#if __has_builtin(__type_pack_element)
-#define MPARK_TYPE_PACK_ELEMENT
-#endif
-
-#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
-#define MPARK_CPP14_CONSTEXPR
-#endif
-
-#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \
-    (defined(_MSC_VER) && defined(_CPPUNWIND))
-#define MPARK_EXCEPTIONS
-#endif
-
-#if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
-#define MPARK_GENERIC_LAMBDAS
-#endif
-
-#if defined(__cpp_lib_integer_sequence)
-#define MPARK_INTEGER_SEQUENCE
-#endif
-
-#if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
-#define MPARK_RETURN_TYPE_DEDUCTION
-#endif
-
-#if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
-#define MPARK_TRANSPARENT_OPERATORS
-#endif
-
-#if defined(__cpp_variable_templates) || defined(_MSC_VER)
-#define MPARK_VARIABLE_TEMPLATES
-#endif
-
-#if !defined(__GLIBCXX__) || __has_include(<codecvt>)  // >= libstdc++-5
-#define MPARK_TRIVIALITY_TYPE_TRAITS
-#endif
-
-#endif  // MPARK_CONFIG_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_IN_PLACE_HPP
-#define MPARK_IN_PLACE_HPP
-
-#include <cstddef>
-
-
-namespace mpark {
-
-  struct in_place_t { explicit in_place_t() = default; };
-
-  template <std::size_t I>
-  struct in_place_index_t { explicit in_place_index_t() = default; };
-
-  template <typename T>
-  struct in_place_type_t { explicit in_place_type_t() = default; };
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  constexpr in_place_t in_place{};
-
-  template <std::size_t I> constexpr in_place_index_t<I> in_place_index{};
-
-  template <typename T> constexpr in_place_type_t<T> in_place_type{};
-#endif
-
-}  // namespace mpark
-
-#endif  // MPARK_IN_PLACE_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_LIB_HPP
-#define MPARK_LIB_HPP
-
-#include <memory>
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-
-#define RETURN(...)                                          \
-  noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { \
-    return __VA_ARGS__;                                      \
-  }
-
-namespace mpark {
-  namespace lib {
-    template <typename T>
-    struct identity { using type = T; };
-
-    inline namespace cpp14 {
-      template <typename T, std::size_t N>
-      struct array {
-        constexpr const T &operator[](std::size_t index) const {
-          return data[index];
-        }
-
-        T data[N == 0 ? 1 : N];
-      };
-
-      template <typename T>
-      using add_pointer_t = typename std::add_pointer<T>::type;
-
-      template <typename... Ts>
-      using common_type_t = typename std::common_type<Ts...>::type;
-
-      template <typename T>
-      using decay_t = typename std::decay<T>::type;
-
-      template <bool B, typename T = void>
-      using enable_if_t = typename std::enable_if<B, T>::type;
-
-      template <typename T>
-      using remove_const_t = typename std::remove_const<T>::type;
-
-      template <typename T>
-      using remove_reference_t = typename std::remove_reference<T>::type;
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &t) noexcept {
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &&t) noexcept {
-        static_assert(!std::is_lvalue_reference<T>::value,
-                      "can not forward an rvalue as an lvalue");
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr remove_reference_t<T> &&move(T &&t) noexcept {
-        return static_cast<remove_reference_t<T> &&>(t);
-      }
-
-#ifdef MPARK_INTEGER_SEQUENCE
-      using std::integer_sequence;
-      using std::index_sequence;
-      using std::make_index_sequence;
-      using std::index_sequence_for;
-#else
-      template <typename T, T... Is>
-      struct integer_sequence {
-        using value_type = T;
-        static constexpr std::size_t size() noexcept { return sizeof...(Is); }
-      };
-
-      template <std::size_t... Is>
-      using index_sequence = integer_sequence<std::size_t, Is...>;
-
-      template <typename Lhs, typename Rhs>
-      struct make_index_sequence_concat;
-
-      template <std::size_t... Lhs, std::size_t... Rhs>
-      struct make_index_sequence_concat<index_sequence<Lhs...>,
-                                        index_sequence<Rhs...>>
-          : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
-
-      template <std::size_t N>
-      struct make_index_sequence_impl;
-
-      template <std::size_t N>
-      using make_index_sequence = typename make_index_sequence_impl<N>::type;
-
-      template <std::size_t N>
-      struct make_index_sequence_impl
-          : make_index_sequence_concat<make_index_sequence<N / 2>,
-                                       make_index_sequence<N - (N / 2)>> {};
-
-      template <>
-      struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
-
-      template <>
-      struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
-
-      template <typename... Ts>
-      using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
-#endif
-
-      // <functional>
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using equal_to = std::equal_to<>;
-#else
-      struct equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using not_equal_to = std::not_equal_to<>;
-#else
-      struct not_equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less = std::less<>;
-#else
-      struct less {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater = std::greater<>;
-#else
-      struct greater {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less_equal = std::less_equal<>;
-#else
-      struct less_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater_equal = std::greater_equal<>;
-#else
-      struct greater_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
-      };
-#endif
-    }  // namespace cpp14
-
-    inline namespace cpp17 {
-
-      // <type_traits>
-      template <bool B>
-      using bool_constant = std::integral_constant<bool, B>;
-
-      template <typename...>
-      struct voider : identity<void> {};
-
-      template <typename... Ts>
-      using void_t = typename voider<Ts...>::type;
-
-      namespace detail {
-        namespace swappable {
-
-          using std::swap;
-
-          template <typename T>
-          struct is_swappable {
-            private:
-            template <typename U,
-                      typename = decltype(swap(std::declval<U &>(),
-                                               std::declval<U &>()))>
-            inline static std::true_type test(int);
-
-            template <typename U>
-            inline static std::false_type test(...);
-
-            public:
-            static constexpr bool value = decltype(test<T>(0))::value;
-          };
-
-          template <typename T, bool = is_swappable<T>::value>
-          struct is_nothrow_swappable {
-            static constexpr bool value =
-                noexcept(swap(std::declval<T &>(), std::declval<T &>()));
-          };
-
-          template <typename T>
-          struct is_nothrow_swappable<T, false> : std::false_type {};
-
-        }  // namespace swappable
-      }  // namespace detail
-
-      using detail::swappable::is_swappable;
-      using detail::swappable::is_nothrow_swappable;
-
-      // <functional>
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename F, typename... As>
-      inline constexpr auto invoke(F &&f, As &&... as)
-          RETURN(lib::forward<F>(f)(lib::forward<As>(as)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      template <typename B, typename T, typename D>
-      inline constexpr auto invoke(T B::*pmv, D &&d)
-          RETURN(lib::forward<D>(d).*pmv)
-
-      template <typename Pmv, typename Ptr>
-      inline constexpr auto invoke(Pmv pmv, Ptr &&ptr)
-          RETURN((*lib::forward<Ptr>(ptr)).*pmv)
-
-      template <typename B, typename T, typename D, typename... As>
-      inline constexpr auto invoke(T B::*pmf, D &&d, As &&... as)
-          RETURN((lib::forward<D>(d).*pmf)(lib::forward<As>(as)...))
-
-      template <typename Pmf, typename Ptr, typename... As>
-      inline constexpr auto invoke(Pmf pmf, Ptr &&ptr, As &&... as)
-          RETURN(((*lib::forward<Ptr>(ptr)).*pmf)(lib::forward<As>(as)...))
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct invoke_result {};
-
-        template <typename F, typename... Args>
-        struct invoke_result<void_t<decltype(lib::invoke(
-                                 std::declval<F>(), std::declval<Args>()...))>,
-                             F,
-                             Args...>
-            : identity<decltype(
-                  lib::invoke(std::declval<F>(), std::declval<Args>()...))> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using invoke_result = detail::invoke_result<void, F, Args...>;
-
-      template <typename F, typename... Args>
-      using invoke_result_t = typename invoke_result<F, Args...>::type;
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct is_invocable : std::false_type {};
-
-        template <typename F, typename... Args>
-        struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
-            : std::true_type {};
-
-        template <typename Void, typename, typename, typename...>
-        struct is_invocable_r : std::false_type {};
-
-        template <typename R, typename F, typename... Args>
-        struct is_invocable_r<void_t<invoke_result_t<F, Args...>>,
-                              R,
-                              F,
-                              Args...>
-            : std::is_convertible<invoke_result_t<F, Args...>, R> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using is_invocable = detail::is_invocable<void, F, Args...>;
-
-      template <typename R, typename F, typename... Args>
-      using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
-
-      // <memory>
-#ifdef MPARK_BUILTIN_ADDRESSOF
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return __builtin_addressof(arg);
-      }
-#else
-      namespace detail {
-
-        namespace has_addressof_impl {
-
-          struct fail;
-
-          template <typename T>
-          inline fail operator&(T &&);
-
-          template <typename T>
-          inline static constexpr bool impl() {
-            return (std::is_class<T>::value || std::is_union<T>::value) &&
-                   !std::is_same<decltype(&std::declval<T &>()), fail>::value;
-          }
-
-        }  // namespace has_addressof_impl
-
-        template <typename T>
-        using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::true_type) {
-          return std::addressof(arg);
-        }
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::false_type) {
-          return &arg;
-        }
-
-      }  // namespace detail
-
-      template <typename T>
-      inline constexpr T *addressof(T &arg) {
-        return detail::addressof(arg, detail::has_addressof<T>{});
-      }
-#endif
-
-      template <typename T>
-      inline constexpr T *addressof(const T &&) = delete;
-
-    }  // namespace cpp17
-
-    template <typename T>
-    struct remove_all_extents : identity<T> {};
-
-    template <typename T, std::size_t N>
-    struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
-
-    template <typename T>
-    using remove_all_extents_t = typename remove_all_extents<T>::type;
-
-    template <std::size_t N>
-    using size_constant = std::integral_constant<std::size_t, N>;
-
-    template <std::size_t I, typename T>
-    struct indexed_type : size_constant<I>, identity<T> {};
-
-    template <bool... Bs>
-    using all = std::is_same<integer_sequence<bool, true, Bs...>,
-                             integer_sequence<bool, Bs..., true>>;
-
-#ifdef MPARK_TYPE_PACK_ELEMENT
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = __type_pack_element<I, Ts...>;
-#else
-    template <std::size_t I, typename... Ts>
-    struct type_pack_element_impl {
-      private:
-      template <typename>
-      struct set;
-
-      template <std::size_t... Is>
-      struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
-
-      template <typename T>
-      inline static std::enable_if<true, T> impl(indexed_type<I, T>);
-
-      inline static std::enable_if<false> impl(...);
-
-      public:
-      using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
-    };
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
-#endif
-
-#ifdef MPARK_TRIVIALITY_TYPE_TRAITS
-    using std::is_trivially_copy_constructible;
-    using std::is_trivially_move_constructible;
-    using std::is_trivially_copy_assignable;
-    using std::is_trivially_move_assignable;
-#else
-    template <typename T>
-    struct is_trivially_copy_constructible
-        : bool_constant<
-              std::is_copy_constructible<T>::value && __has_trivial_copy(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {};
-
-    template <typename T>
-    struct is_trivially_copy_assignable
-        : bool_constant<
-              std::is_copy_assignable<T>::value && __has_trivial_assign(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {};
-#endif
-
-    template <typename T, bool>
-    struct dependent_type : T {};
-
-    template <typename Is, std::size_t J>
-    struct push_back;
-
-    template <typename Is, std::size_t J>
-    using push_back_t = typename push_back<Is, J>::type;
-
-    template <std::size_t... Is, std::size_t J>
-    struct push_back<index_sequence<Is...>, J> {
-      using type = index_sequence<Is..., J>;
-    };
-
-  }  // namespace lib
-}  // namespace mpark
-
-#undef RETURN
-
-#endif  // MPARK_LIB_HPP
-
-
-namespace mpark {
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-
-#define AUTO auto
-#define AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto &&
-#define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; }
-
-#define DECLTYPE_AUTO decltype(auto)
-#define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#else
-
-#define AUTO auto
-#define AUTO_RETURN(...) \
-  -> lib::decay_t<decltype(__VA_ARGS__)> { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto
-#define AUTO_REFREF_RETURN(...)                                           \
-  -> decltype((__VA_ARGS__)) {                                            \
-    static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
-    return __VA_ARGS__;                                                   \
-  }
-
-#define DECLTYPE_AUTO auto
-#define DECLTYPE_AUTO_RETURN(...) \
-  -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-#endif
-
-  class bad_variant_access : public std::exception {
-    public:
-    virtual const char *what() const noexcept { return "bad_variant_access"; }
-  };
-
-  [[noreturn]] inline void throw_bad_variant_access() {
-#ifdef MPARK_EXCEPTIONS
-    throw bad_variant_access{};
-#else
-    std::terminate();
-#ifdef MPARK_BUILTIN_UNREACHABLE
-    __builtin_unreachable();
-#endif
-#endif
-  }
-
-  template <typename... Ts>
-  class variant;
-
-  template <typename T>
-  struct variant_size;
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  template <typename T>
-  constexpr std::size_t variant_size_v = variant_size<T>::value;
-#endif
-
-  template <typename T>
-  struct variant_size<const T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<volatile T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<const volatile T> : variant_size<T> {};
-
-  template <typename... Ts>
-  struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative;
-
-  template <std::size_t I, typename T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const T>
-      : std::add_const<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, volatile T>
-      : std::add_volatile<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const volatile T>
-      : std::add_cv<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename... Ts>
-  struct variant_alternative<I, variant<Ts...>> {
-    static_assert(I < sizeof...(Ts),
-                  "Index out of bounds in std::variant_alternative<>");
-    using type = lib::type_pack_element_t<I, Ts...>;
-  };
-
-  constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
-
-  namespace detail {
-
-    constexpr std::size_t not_found = static_cast<std::size_t>(-1);
-    constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      constexpr lib::array<bool, sizeof...(Ts)> matches = {
-          {std::is_same<T, Ts>::value...}
-      };
-      std::size_t result = not_found;
-      for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
-        if (matches[i]) {
-          if (result != not_found) {
-            return ambiguous;
-          }
-          result = i;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t) {
-      return result;
-    }
-
-    template <typename... Bs>
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t idx,
-                                                 bool b,
-                                                 Bs... bs) {
-      return b ? (result != not_found ? ambiguous
-                                      : find_index_impl(idx, idx + 1, bs...))
-               : find_index_impl(result, idx + 1, bs...);
-    }
-
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
-    }
-#endif
-
-    template <std::size_t I>
-    using find_index_sfinae_impl =
-        lib::enable_if_t<I != not_found && I != ambiguous,
-                         lib::size_constant<I>>;
-
-    template <typename T, typename... Ts>
-    using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
-
-    template <std::size_t I>
-    struct find_index_checked_impl : lib::size_constant<I> {
-      static_assert(I != not_found, "the specified type is not found.");
-      static_assert(I != ambiguous, "the specified type is ambiguous.");
-    };
-
-    template <typename T, typename... Ts>
-    using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
-
-    struct valueless_t {};
-
-    enum class Trait { TriviallyAvailable, Available, Unavailable };
-
-    template <typename T,
-              template <typename> class IsTriviallyAvailable,
-              template <typename> class IsAvailable>
-    inline constexpr Trait trait() {
-      return IsTriviallyAvailable<T>::value
-                 ? Trait::TriviallyAvailable
-                 : IsAvailable<T>::value ? Trait::Available
-                                         : Trait::Unavailable;
-    }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... traits) {
-      Trait result = Trait::TriviallyAvailable;
-      for (Trait t : {traits...}) {
-        if (static_cast<int>(t) > static_cast<int>(result)) {
-          result = t;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr Trait common_trait_impl(Trait result) { return result; }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait_impl(Trait result,
-                                             Trait t,
-                                             Traits... ts) {
-      return static_cast<int>(t) > static_cast<int>(result)
-                 ? common_trait_impl(t, ts...)
-                 : common_trait_impl(result, ts...);
-    }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... ts) {
-      return common_trait_impl(Trait::TriviallyAvailable, ts...);
-    }
-#endif
-
-    template <typename... Ts>
-    struct traits {
-      static constexpr Trait copy_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_copy_constructible,
-                             std::is_copy_constructible>()...);
-
-      static constexpr Trait move_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_move_constructible,
-                             std::is_move_constructible>()...);
-
-      static constexpr Trait copy_assignable_trait =
-          common_trait(copy_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_copy_assignable,
-                             std::is_copy_assignable>()...);
-
-      static constexpr Trait move_assignable_trait =
-          common_trait(move_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_move_assignable,
-                             std::is_move_assignable>()...);
-
-      static constexpr Trait destructible_trait =
-          common_trait(trait<Ts,
-                             std::is_trivially_destructible,
-                             std::is_destructible>()...);
-    };
-
-    namespace access {
-
-      struct recursive_union {
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename V>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
-          return lib::forward<V>(v).head_;
-        }
-
-        template <typename V, std::size_t I>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
-          return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
-        }
-#else
-        template <std::size_t I, bool Dummy = true>
-        struct get_alt_impl {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
-        };
-
-        template <bool Dummy>
-        struct get_alt_impl<0, Dummy> {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
-        };
-
-        template <typename V, std::size_t I>
-        inline static constexpr AUTO_REFREF get_alt(V &&v, in_place_index_t<I>)
-          AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
-#endif
-      };
-
-      struct base {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(recursive_union::get_alt(
-              data(lib::forward<V>(v)), in_place_index_t<I>{}))
-      };
-
-      struct variant {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
-      };
-
-    }  // namespace access
-
-    namespace visitation {
-
-      struct base {
-        template <typename T>
-        inline static constexpr const T &at(const T &elem) {
-          return elem;
-        }
-
-        template <typename T, std::size_t N, typename... Is>
-        inline static constexpr const lib::remove_all_extents_t<T> &at(
-            const lib::array<T, N> &elems, std::size_t i, Is... is) {
-          return at(elems[i], is...);
-        }
-
-        template <typename F, typename... Fs>
-        inline static constexpr int visit_visitor_return_type_check() {
-          static_assert(lib::all<std::is_same<F, Fs>::value...>::value,
-                        "`mpark::visit` requires the visitor to have a single "
-                        "return type.");
-          return 0;
-        }
-
-        template <typename... Fs>
-        inline static constexpr lib::array<
-            lib::common_type_t<lib::decay_t<Fs>...>,
-            sizeof...(Fs)>
-        make_farray(Fs &&... fs) {
-          using result = lib::array<lib::common_type_t<lib::decay_t<Fs>...>,
-                                    sizeof...(Fs)>;
-          return visit_visitor_return_type_check<lib::decay_t<Fs>...>(),
-                 result{{lib::forward<Fs>(fs)...}};
-        }
-
-        template <std::size_t... Is>
-        struct dispatcher {
-          template <typename F, typename... Vs>
-          struct impl {
-            inline static constexpr DECLTYPE_AUTO dispatch(F f, Vs... vs)
-              DECLTYPE_AUTO_RETURN(lib::invoke(
-                  static_cast<F>(f),
-                  access::base::get_alt<Is>(static_cast<Vs>(vs))...))
-          };
-        };
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_dispatch(lib::index_sequence<Is...>)
-          AUTO_RETURN(&dispatcher<Is...>::template impl<F, Vs...>::dispatch)
-
-        template <std::size_t I, typename F, typename... Vs>
-        inline static constexpr AUTO make_fdiagonal_impl()
-          AUTO_RETURN(make_dispatch<F, Vs...>(
-              lib::index_sequence<lib::indexed_type<I, Vs>::value...>{}))
-
-        template <typename F, typename... Vs, std::size_t... Is>
-        inline static constexpr AUTO make_fdiagonal_impl(
-            lib::index_sequence<Is...>)
-          AUTO_RETURN(make_farray(make_fdiagonal_impl<Is, F, Vs...>()...))
-
-        template <typename F, typename V, typename... Vs>
-        inline static constexpr /* auto * */ auto make_fdiagonal()
-            -> decltype(make_fdiagonal_impl<F, V, Vs...>(
-                lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
-          static_assert(lib::all<(lib::decay_t<V>::size() ==
-                                  lib::decay_t<Vs>::size())...>::value,
-                        "all of the variants must be the same size.");
-          return make_fdiagonal_impl<F, V, Vs...>(
-              lib::make_index_sequence<lib::decay_t<V>::size()>{});
-        }
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename F, typename... Vs, typename Is>
-        inline static constexpr auto make_fmatrix_impl(Is is) {
-          return make_dispatch<F, Vs...>(is);
-        }
-
-        template <typename F,
-                  typename... Vs,
-                  typename Is,
-                  std::size_t... Js,
-                  typename... Ls>
-        inline static constexpr auto make_fmatrix_impl(
-            Is, lib::index_sequence<Js...>, Ls... ls) {
-          return make_farray(make_fmatrix_impl<F, Vs...>(
-              lib::push_back_t<Is, Js>{}, ls...)...);
-        }
-
-        template <typename F, typename... Vs>
-        inline static constexpr auto make_fmatrix() {
-          return make_fmatrix_impl<F, Vs...>(
-              lib::index_sequence<>{},
-              lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
-        }
-#else
-        template <typename F, typename... Vs>
-        struct make_fmatrix_impl {
-          template <typename...>
-          struct impl;
-
-          template <typename Is>
-          struct impl<Is> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(make_dispatch<F, Vs...>(Is{}))
-          };
-
-          template <typename Is, std::size_t... Js, typename... Ls>
-          struct impl<Is, lib::index_sequence<Js...>, Ls...> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(
-                  make_farray(impl<lib::push_back_t<Is, Js>, Ls...>{}()...))
-          };
-        };
-
-        template <typename F, typename... Vs>
-        inline static constexpr AUTO make_fmatrix()
-          AUTO_RETURN(
-              typename make_fmatrix_impl<F, Vs...>::template impl<
-                  lib::index_sequence<>,
-                  lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
-#endif
-      };  // namespace base
-
-      template <typename F, typename... Vs>
-      using FDiagonal = decltype(base::make_fdiagonal<F, Vs...>());
-
-      template <typename F, typename... Vs>
-      struct fdiagonal {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4268)
-#endif
-        static constexpr FDiagonal<F, Vs...> value =
-            base::make_fdiagonal<F, Vs...>();
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-      };
-
-      template <typename F, typename... Vs>
-      constexpr FDiagonal<F, Vs...> fdiagonal<F, Vs...>::value;
-
-      template <typename F, typename... Vs>
-      using FMatrix = decltype(base::make_fmatrix<F, Vs...>());
-
-      template <typename F, typename... Vs>
-      struct fmatrix {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4268)
-#endif
-        static constexpr FMatrix<F, Vs...> value =
-            base::make_fmatrix<F, Vs...>();
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-      };
-
-      template <typename F, typename... Vs>
-      constexpr FMatrix<F, Vs...> fmatrix<F, Vs...>::value;
-
-      struct alt {
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(base::at(
-              fdiagonal<Visitor &&,
-                        decltype(as_base(lib::forward<Vs>(vs)))...>::value,
-              index)(lib::forward<Visitor>(visitor),
-                     as_base(lib::forward<Vs>(vs))...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(base::at(
-              fmatrix<Visitor &&,
-                      decltype(as_base(lib::forward<Vs>(vs)))...>::value,
-              vs.index()...)(lib::forward<Visitor>(visitor),
-                             as_base(lib::forward<Vs>(vs))...))
-      };
-
-      struct variant {
-        private:
-        template <typename Visitor, typename... Values>
-        struct visit_exhaustive_visitor_check {
-          static_assert(
-              lib::is_invocable<Visitor, Values...>::value,
-              "`mpark::visit` requires the visitor to be exhaustive.");
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-          inline constexpr DECLTYPE_AUTO operator()(Visitor &&visitor,
-                                                    Values &&... values) const
-            DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
-                                             lib::forward<Values>(values)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        };
-
-        template <typename Visitor>
-        struct value_visitor {
-          Visitor &&visitor_;
-
-          template <typename... Alts>
-          inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const
-            DECLTYPE_AUTO_RETURN(
-                visit_exhaustive_visitor_check<
-                    Visitor,
-                    decltype((lib::forward<Alts>(alts).value))...>{}(
-                    lib::forward<Visitor>(visitor_),
-                    lib::forward<Alts>(alts).value...))
-        };
-
-        template <typename Visitor>
-        inline static constexpr AUTO make_value_visitor(Visitor &&visitor)
-          AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              alt::visit_alt_at(index,
-                                lib::forward<Visitor>(visitor),
-                                lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(alt::visit_alt(lib::forward<Visitor>(visitor),
-                                              lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index,
-                                                             Visitor &&visitor,
-                                                             Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt_at(index,
-                           make_value_visitor(lib::forward<Visitor>(visitor)),
-                           lib::forward<Vs>(vs)...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor,
-                                                          Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt(make_value_visitor(lib::forward<Visitor>(visitor)),
-                        lib::forward<Vs>(vs)...))
-      };
-
-    }  // namespace visitation
-
-    template <std::size_t Index, typename T>
-    struct alt {
-      using value_type = T;
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-      template <typename... Args>
-      inline explicit constexpr alt(in_place_t, Args &&... args)
-          : value(lib::forward<Args>(args)...) {}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      T value;
-    };
-
-    template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
-    union recursive_union;
-
-    template <Trait DestructibleTrait, std::size_t Index>
-    union recursive_union<DestructibleTrait, Index> {};
-
-#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)      \
-  template <std::size_t Index, typename T, typename... Ts>                 \
-  union recursive_union<destructible_trait, Index, T, Ts...> {             \
-    public:                                                                \
-    inline explicit constexpr recursive_union(valueless_t) noexcept        \
-        : dummy_{} {}                                                      \
-                                                                           \
-    template <typename... Args>                                            \
-    inline explicit constexpr recursive_union(in_place_index_t<0>,         \
-                                              Args &&... args)             \
-        : head_(in_place_t{}, lib::forward<Args>(args)...) {}              \
-                                                                           \
-    template <std::size_t I, typename... Args>                             \
-    inline explicit constexpr recursive_union(in_place_index_t<I>,         \
-                                              Args &&... args)             \
-        : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
-                                                                           \
-    recursive_union(const recursive_union &) = default;                    \
-    recursive_union(recursive_union &&) = default;                         \
-                                                                           \
-    destructor                                                             \
-                                                                           \
-    recursive_union &operator=(const recursive_union &) = default;         \
-    recursive_union &operator=(recursive_union &&) = default;              \
-                                                                           \
-    private:                                                               \
-    char dummy_;                                                           \
-    alt<Index, T> head_;                                                   \
-    recursive_union<destructible_trait, Index + 1, Ts...> tail_;           \
-                                                                           \
-    friend struct access::recursive_union;                                 \
-  }
-
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
-                                  ~recursive_union() = default;);
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
-                                  ~recursive_union() {});
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
-                                  ~recursive_union() = delete;);
-
-#undef MPARK_VARIANT_RECURSIVE_UNION
-
-    using index_t = unsigned int;
-
-    template <Trait DestructibleTrait, typename... Ts>
-    class base {
-      public:
-      inline explicit constexpr base(valueless_t tag) noexcept
-          : data_(tag), index_(static_cast<index_t>(-1)) {}
-
-      template <std::size_t I, typename... Args>
-      inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
-          : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...),
-            index_(I) {}
-
-      inline constexpr bool valueless_by_exception() const noexcept {
-        return index_ == static_cast<index_t>(-1);
-      }
-
-      inline constexpr std::size_t index() const noexcept {
-        return valueless_by_exception() ? variant_npos : index_;
-      }
-
-      protected:
-      using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
-
-      friend inline constexpr base &as_base(base &b) { return b; }
-      friend inline constexpr const base &as_base(const base &b) { return b; }
-      friend inline constexpr base &&as_base(base &&b) { return lib::move(b); }
-      friend inline constexpr const base &&as_base(const base &&b) { return lib::move(b); }
-
-      friend inline constexpr data_t &data(base &b) { return b.data_; }
-      friend inline constexpr const data_t &data(const base &b) { return b.data_; }
-      friend inline constexpr data_t &&data(base &&b) { return lib::move(b).data_; }
-      friend inline constexpr const data_t &&data(const base &&b) { return lib::move(b).data_; }
-
-      inline static constexpr std::size_t size() { return sizeof...(Ts); }
-
-      data_t data_;
-      index_t index_;
-
-      friend struct access::base;
-      friend struct visitation::base;
-    };
-
-    struct dtor {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename Alt>
-      inline void operator()(Alt &alt) const noexcept { alt.~Alt(); }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-    };
-
-#if defined(_MSC_VER) && _MSC_VER < 1910
-#define INHERITING_CTOR(type, base)               \
-  template <typename... Args>                     \
-  inline explicit constexpr type(Args &&... args) \
-      : base(lib::forward<Args>(args)...) {}
-#else
-#define INHERITING_CTOR(type, base) using base::base;
-#endif
-
-    template <typename Traits, Trait = Traits::destructible_trait>
-    class destructor;
-
-#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
-  template <typename... Ts>                                               \
-  class destructor<traits<Ts...>, destructible_trait>                     \
-      : public base<destructible_trait, Ts...> {                          \
-    using super = base<destructible_trait, Ts...>;                        \
-                                                                          \
-    public:                                                               \
-    INHERITING_CTOR(destructor, super)                                    \
-    using super::operator=;                                               \
-                                                                          \
-    destructor(const destructor &) = default;                             \
-    destructor(destructor &&) = default;                                  \
-    definition                                                            \
-    destructor &operator=(const destructor &) = default;                  \
-    destructor &operator=(destructor &&) = default;                       \
-                                                                          \
-    protected:                                                            \
-    destroy                                                               \
-  }
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::TriviallyAvailable,
-        ~destructor() = default;,
-        inline void destroy() noexcept {
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Available,
-        ~destructor() { destroy(); },
-        inline void destroy() noexcept {
-          if (!this->valueless_by_exception()) {
-            visitation::alt::visit_alt(dtor{}, *this);
-          }
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Unavailable,
-        ~destructor() = delete;,
-        inline void destroy() noexcept = delete;);
-
-#undef MPARK_VARIANT_DESTRUCTOR
-
-    template <typename Traits>
-    class constructor : public destructor<Traits> {
-      using super = destructor<Traits>;
-
-      public:
-      INHERITING_CTOR(constructor, super)
-      using super::operator=;
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct ctor {
-        template <typename LhsAlt, typename RhsAlt>
-        inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const {
-          constructor::construct_alt(lhs_alt,
-                                     lib::forward<RhsAlt>(rhs_alt).value);
-        }
-      };
-#endif
-
-      template <std::size_t I, typename T, typename... Args>
-      inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
-        ::new (static_cast<void *>(lib::addressof(a)))
-            alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
-        return a.value;
-      }
-
-      template <typename Rhs>
-      inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
-        lhs.destroy();
-        if (!rhs.valueless_by_exception()) {
-          visitation::alt::visit_alt_at(
-              rhs.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [](auto &lhs_alt, auto &&rhs_alt) {
-                constructor::construct_alt(
-                    lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
-              }
-#else
-              ctor{}
-#endif
-              ,
-              lhs,
-              lib::forward<Rhs>(rhs));
-          lhs.index_ = rhs.index_;
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_constructible_trait>
-    class move_constructor;
-
-#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class move_constructor<traits<Ts...>, move_constructible_trait>            \
-      : public constructor<traits<Ts...>> {                                  \
-    using super = constructor<traits<Ts...>>;                                \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(move_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    move_constructor(const move_constructor &) = default;                    \
-    definition                                                               \
-    ~move_constructor() = default;                                           \
-    move_constructor &operator=(const move_constructor &) = default;         \
-    move_constructor &operator=(move_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        move_constructor(move_constructor &&that) = default;);
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Available,
-        move_constructor(move_constructor &&that) noexcept(
-            lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
-            : move_constructor(valueless_t{}) {
-          this->generic_construct(*this, lib::move(that));
-        });
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Unavailable,
-        move_constructor(move_constructor &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_CONSTRUCTOR
-
-    template <typename Traits, Trait = Traits::copy_constructible_trait>
-    class copy_constructor;
-
-#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
-      : public move_constructor<traits<Ts...>> {                             \
-    using super = move_constructor<traits<Ts...>>;                           \
-                                                                             \
-    public:                                                                  \
-    INHERITING_CTOR(copy_constructor, super)                                 \
-    using super::operator=;                                                  \
-                                                                             \
-    definition                                                               \
-    copy_constructor(copy_constructor &&) = default;                         \
-    ~copy_constructor() = default;                                           \
-    copy_constructor &operator=(const copy_constructor &) = default;         \
-    copy_constructor &operator=(copy_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        copy_constructor(const copy_constructor &that) = default;);
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Available,
-        copy_constructor(const copy_constructor &that)
-            : copy_constructor(valueless_t{}) {
-          this->generic_construct(*this, that);
-        });
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Unavailable,
-        copy_constructor(const copy_constructor &) = delete;);
-
-#undef MPARK_VARIANT_COPY_CONSTRUCTOR
-
-    template <typename Traits>
-    class assignment : public copy_constructor<Traits> {
-      using super = copy_constructor<Traits>;
-
-      public:
-      INHERITING_CTOR(assignment, super)
-      using super::operator=;
-
-      template <std::size_t I, typename... Args>
-      inline /* auto & */ auto emplace(Args &&... args)
-          -> decltype(this->construct_alt(access::base::get_alt<I>(*this),
-                                          lib::forward<Args>(args)...)) {
-        this->destroy();
-        auto &result = this->construct_alt(access::base::get_alt<I>(*this),
-                                           lib::forward<Args>(args)...);
-        this->index_ = I;
-        return result;
-      }
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      template <typename That>
-      struct assigner {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const {
-          self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
-        }
-        assignment *self;
-      };
-#endif
-
-      template <std::size_t I, typename T, typename Arg>
-      inline void assign_alt(alt<I, T> &a, Arg &&arg) {
-        if (this->index() == I) {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-          a.value = lib::forward<Arg>(arg);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        } else {
-          struct {
-            void operator()(std::true_type) const {
-              this_->emplace<I>(lib::forward<Arg>(arg_));
-            }
-            void operator()(std::false_type) const {
-              this_->emplace<I>(T(lib::forward<Arg>(arg_)));
-            }
-            assignment *this_;
-            Arg &&arg_;
-          } impl{this, lib::forward<Arg>(arg)};
-          impl(lib::bool_constant<
-                   std::is_nothrow_constructible<T, Arg>::value ||
-                   !std::is_nothrow_move_constructible<T>::value>{});
-        }
-      }
-
-      template <typename That>
-      inline void generic_assign(That &&that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (that.valueless_by_exception()) {
-          this->destroy();
-        } else {
-          visitation::alt::visit_alt_at(
-              that.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [this](auto &this_alt, auto &&that_alt) {
-                this->assign_alt(
-                    this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
-              }
-#else
-              assigner<That>{this}
-#endif
-              ,
-              *this,
-              lib::forward<That>(that));
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_assignable_trait>
-    class move_assignment;
-
-#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class move_assignment<traits<Ts...>, move_assignable_trait>            \
-      : public assignment<traits<Ts...>> {                               \
-    using super = assignment<traits<Ts...>>;                             \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(move_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    move_assignment(const move_assignment &) = default;                  \
-    move_assignment(move_assignment &&) = default;                       \
-    ~move_assignment() = default;                                        \
-    move_assignment &operator=(const move_assignment &) = default;       \
-    definition                                                           \
-  }
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        move_assignment &operator=(move_assignment &&that) = default;);
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Available,
-        move_assignment &
-        operator=(move_assignment &&that) noexcept(
-            lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                      std::is_nothrow_move_assignable<Ts>::value)...>::value) {
-          this->generic_assign(lib::move(that));
-          return *this;
-        });
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Unavailable,
-        move_assignment &operator=(move_assignment &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_ASSIGNMENT
-
-    template <typename Traits, Trait = Traits::copy_assignable_trait>
-    class copy_assignment;
-
-#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
-      : public move_assignment<traits<Ts...>> {                          \
-    using super = move_assignment<traits<Ts...>>;                        \
-                                                                         \
-    public:                                                              \
-    INHERITING_CTOR(copy_assignment, super)                              \
-    using super::operator=;                                              \
-                                                                         \
-    copy_assignment(const copy_assignment &) = default;                  \
-    copy_assignment(copy_assignment &&) = default;                       \
-    ~copy_assignment() = default;                                        \
-    definition                                                           \
-    copy_assignment &operator=(copy_assignment &&) = default;            \
-  }
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        copy_assignment &operator=(const copy_assignment &that) = default;);
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Available,
-        copy_assignment &operator=(const copy_assignment &that) {
-          this->generic_assign(that);
-          return *this;
-        });
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Unavailable,
-        copy_assignment &operator=(const copy_assignment &) = delete;);
-
-#undef MPARK_VARIANT_COPY_ASSIGNMENT
-
-    template <typename... Ts>
-    class impl : public copy_assignment<traits<Ts...>> {
-      using super = copy_assignment<traits<Ts...>>;
-
-      public:
-      INHERITING_CTOR(impl, super)
-      using super::operator=;
-
-      template <std::size_t I, typename Arg>
-      inline void assign(Arg &&arg) {
-        this->assign_alt(access::base::get_alt<I>(*this),
-                         lib::forward<Arg>(arg));
-      }
-
-      inline void swap(impl &that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (this->index() == that.index()) {
-          visitation::alt::visit_alt_at(this->index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-                                        [](auto &this_alt, auto &that_alt) {
-                                          using std::swap;
-                                          swap(this_alt.value,
-                                               that_alt.value);
-                                        }
-#else
-                                        swapper{}
-#endif
-                                        ,
-                                        *this,
-                                        that);
-        } else {
-          impl *lhs = this;
-          impl *rhs = lib::addressof(that);
-          if (lhs->move_nothrow() && !rhs->move_nothrow()) {
-            std::swap(lhs, rhs);
-          }
-          impl tmp(lib::move(*rhs));
-#ifdef MPARK_EXCEPTIONS
-          // EXTENSION: When the move construction of `lhs` into `rhs` throws
-          // and `tmp` is nothrow move constructible then we move `tmp` back
-          // into `rhs` and provide the strong exception safety guarantee.
-          try {
-            this->generic_construct(*rhs, lib::move(*lhs));
-          } catch (...) {
-            if (tmp.move_nothrow()) {
-              this->generic_construct(*rhs, lib::move(tmp));
-            }
-            throw;
-          }
-#else
-          this->generic_construct(*rhs, lib::move(*lhs));
-#endif
-          this->generic_construct(*lhs, lib::move(tmp));
-        }
-      }
-
-      private:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct swapper {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const {
-          using std::swap;
-          swap(this_alt.value, that_alt.value);
-        }
-      };
-#endif
-
-      inline constexpr bool move_nothrow() const {
-        return this->valueless_by_exception() ||
-               lib::array<bool, sizeof...(Ts)>{
-                   {std::is_nothrow_move_constructible<Ts>::value...}
-               }[this->index()];
-      }
-    };
-
-    template <std::size_t I, typename T>
-    struct overload_leaf {
-      using F = lib::size_constant<I> (*)(T);
-      operator F() const { return nullptr; }
-    };
-
-    template <typename... Ts>
-    struct overload_impl {
-      private:
-      template <typename>
-      struct impl;
-
-      template <std::size_t... Is>
-      struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>... {};
-
-      public:
-      using type = impl<lib::index_sequence_for<Ts...>>;
-    };
-
-    template <typename... Ts>
-    using overload = typename overload_impl<Ts...>::type;
-
-    template <typename T, typename... Ts>
-    using best_match = lib::invoke_result_t<overload<Ts...>, T &&>;
-
-    template <typename T>
-    struct is_in_place_index : std::false_type {};
-
-    template <std::size_t I>
-    struct is_in_place_index<in_place_index_t<I>> : std::true_type {};
-
-    template <typename T>
-    struct is_in_place_type : std::false_type {};
-
-    template <typename T>
-    struct is_in_place_type<in_place_type_t<T>> : std::true_type {};
-
-  }  // detail
-
-  template <typename... Ts>
-  class variant {
-    static_assert(0 < sizeof...(Ts),
-                  "variant must consist of at least one alternative.");
-
-    static_assert(lib::all<!std::is_array<Ts>::value...>::value,
-                  "variant can not have an array type as an alternative.");
-
-    static_assert(lib::all<!std::is_reference<Ts>::value...>::value,
-                  "variant can not have a reference type as an alternative.");
-
-    static_assert(lib::all<!std::is_void<Ts>::value...>::value,
-                  "variant can not have a void type as an alternative.");
-
-    public:
-    template <
-        typename Front = lib::type_pack_element_t<0, Ts...>,
-        lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
-    inline constexpr variant() noexcept(
-        std::is_nothrow_default_constructible<Front>::value)
-        : impl_(in_place_index_t<0>{}) {}
-
-    variant(const variant &) = default;
-    variant(variant &&) = default;
-
-    template <
-        typename Arg,
-        typename Decayed = lib::decay_t<Arg>,
-        lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_index<Decayed>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_type<Decayed>::value, int> = 0,
-        std::size_t I = detail::best_match<Arg, Ts...>::value,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
-    inline constexpr variant(Arg &&arg) noexcept(
-        std::is_nothrow_constructible<T, Arg>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {}
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    ~variant() = default;
-
-    variant &operator=(const variant &) = default;
-    variant &operator=(variant &&) = default;
-
-    template <typename Arg,
-              lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              std::size_t I = detail::best_match<Arg, Ts...>::value,
-              typename T = lib::type_pack_element_t<I, Ts...>,
-              lib::enable_if_t<(std::is_assignable<T &, Arg>::value &&
-                                std::is_constructible<T, Arg>::value),
-                               int> = 0>
-    inline variant &operator=(Arg &&arg) noexcept(
-        (std::is_nothrow_assignable<T &, Arg>::value &&
-         std::is_nothrow_constructible<T, Arg>::value)) {
-      impl_.template assign<I>(lib::forward<Arg>(arg));
-      return *this;
-    }
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    inline constexpr bool valueless_by_exception() const noexcept {
-      return impl_.valueless_by_exception();
-    }
-
-    inline constexpr std::size_t index() const noexcept {
-      return impl_.index();
-    }
-
-    template <bool Dummy = true,
-              lib::enable_if_t<
-                  lib::all<Dummy,
-                           (lib::dependent_type<std::is_move_constructible<Ts>,
-                                                Dummy>::value &&
-                            lib::dependent_type<lib::is_swappable<Ts>,
-                                                Dummy>::value)...>::value,
-                  int> = 0>
-    inline void swap(variant &that) noexcept(
-        lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                  lib::is_nothrow_swappable<Ts>::value)...>::value) {
-      impl_.swap(that.impl_);
-    }
-
-    private:
-    detail::impl<Ts...> impl_;
-
-    friend struct detail::access::variant;
-    friend struct detail::visitation::variant;
-  };
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return v.index() == I;
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-    template <std::size_t I, typename V>
-    struct generic_get_impl {
-      constexpr generic_get_impl(int) {}
-
-      constexpr AUTO_REFREF operator()(V &&v) const
-        AUTO_REFREF_RETURN(
-            access::variant::get_alt<I>(lib::forward<V>(v)).value)
-    };
-
-    template <std::size_t I, typename V>
-    inline constexpr AUTO_REFREF generic_get(V &&v)
-      AUTO_REFREF_RETURN(generic_get_impl<I, V>(
-          holds_alternative<I>(v) ? 0 : (throw_bad_variant_access(), 0))(
-          lib::forward<V>(v)))
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
-      variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
-      variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
-      const variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
-      const variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &get(variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &&get(variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &get(const variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &&get(const variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept
-      AUTO_RETURN(v && holds_alternative<I>(*v)
-                      ? lib::addressof(access::variant::get_alt<I>(*v).value)
-                      : nullptr)
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
-  get_if(variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<
-      const variant_alternative_t<I, variant<Ts...>>>
-  get_if(const variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<T>
-  get_if(variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<const T>
-  get_if(const variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator==(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
-#else
-    return lhs.index() == rhs.index() &&
-           (lhs.valueless_by_exception() ||
-            variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator!=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::not_equal_to;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
-#else
-    return lhs.index() != rhs.index() ||
-           (!lhs.valueless_by_exception() &&
-            variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::less;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
-#else
-    return !rhs.valueless_by_exception() &&
-           (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::greater;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return false;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
-#else
-    return !lhs.valueless_by_exception() &&
-           (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::less_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return true;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
-#else
-    return lhs.valueless_by_exception() ||
-           (!rhs.valueless_by_exception() &&
-            (lhs.index() < rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using lib::greater_equal;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
-#else
-    return rhs.valueless_by_exception() ||
-           (!lhs.valueless_by_exception() &&
-            (lhs.index() > rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(
-                  lhs.index(), greater_equal{}, lhs, rhs))));
-#endif
-  }
-
-  struct monostate {};
-
-  inline constexpr bool operator<(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator>(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator<=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator>=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator==(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator!=(monostate, monostate) noexcept {
-    return false;
-  }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-  namespace detail {
-
-    inline constexpr bool all(std::initializer_list<bool> bs) {
-      for (bool b : bs) {
-        if (!b) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
-    return (detail::all({!vs.valueless_by_exception()...})
-                ? (void)0
-                : throw_bad_variant_access()),
-           detail::visitation::variant::visit_value(
-               lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
-  }
-#else
-  namespace detail {
-
-    template <std::size_t N>
-    inline constexpr bool all_impl(const lib::array<bool, N> &bs,
-                                   std::size_t idx) {
-      return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
-    }
-
-    template <std::size_t N>
-    inline constexpr bool all(const lib::array<bool, N> &bs) {
-      return all_impl(bs, 0);
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs)
-    DECLTYPE_AUTO_RETURN(
-        (detail::all(
-             lib::array<bool, sizeof...(Vs)>{{!vs.valueless_by_exception()...}})
-             ? (void)0
-             : throw_bad_variant_access()),
-        detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
-                                                 lib::forward<Vs>(vs)...))
-#endif
-
-  template <typename... Ts>
-  inline auto swap(variant<Ts...> &lhs,
-                   variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
-      -> decltype(lhs.swap(rhs)) {
-    lhs.swap(rhs);
-  }
-
-  namespace detail {
-
-    template <typename T, typename...>
-    using enabled_type = T;
-
-    namespace hash {
-
-      template <typename H, typename K>
-      constexpr bool meets_requirements() {
-        return std::is_copy_constructible<H>::value &&
-               std::is_move_constructible<H>::value &&
-               lib::is_invocable_r<std::size_t, H, const K &>::value;
-      }
-
-      template <typename K>
-      constexpr bool is_enabled() {
-        using H = std::hash<K>;
-        return meets_requirements<H, K>() &&
-               std::is_default_constructible<H>::value &&
-               std::is_copy_assignable<H>::value &&
-               std::is_move_assignable<H>::value;
-      }
-
-    }  // namespace hash
-
-  }  // namespace detail
-
-#undef AUTO
-#undef AUTO_RETURN
-
-#undef AUTO_REFREF
-#undef AUTO_REFREF_RETURN
-
-#undef DECLTYPE_AUTO
-#undef DECLTYPE_AUTO_RETURN
-
-}  // namespace mpark
-
-namespace std {
-
-  template <typename... Ts>
-  struct hash<mpark::detail::enabled_type<
-      mpark::variant<Ts...>,
-      mpark::lib::enable_if_t<mpark::lib::all<mpark::detail::hash::is_enabled<
-          mpark::lib::remove_const_t<Ts>>()...>::value>>> {
-    using argument_type = mpark::variant<Ts...>;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &v) const {
-      using mpark::detail::visitation::variant;
-      std::size_t result =
-          v.valueless_by_exception()
-              ? 299792458  // Random value chosen by the universe upon creation
-              : variant::visit_alt(
-#ifdef MPARK_GENERIC_LAMBDAS
-                    [](const auto &alt) {
-                      using alt_type = mpark::lib::decay_t<decltype(alt)>;
-                      using value_type = mpark::lib::remove_const_t<
-                          typename alt_type::value_type>;
-                      return hash<value_type>{}(alt.value);
-                    }
-#else
-                    hasher{}
-#endif
-                    ,
-                    v);
-      return hash_combine(result, hash<std::size_t>{}(v.index()));
-    }
-
-    private:
-#ifndef MPARK_GENERIC_LAMBDAS
-    struct hasher {
-      template <typename Alt>
-      inline std::size_t operator()(const Alt &alt) const {
-        using alt_type = mpark::lib::decay_t<Alt>;
-        using value_type =
-            mpark::lib::remove_const_t<typename alt_type::value_type>;
-        return hash<value_type>{}(alt.value);
-      }
-    };
-#endif
-
-    static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
-      return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
-    }
-  };
-
-  template <>
-  struct hash<mpark::monostate> {
-    using argument_type = mpark::monostate;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &) const noexcept {
-      return 66740831;  // return a fundamentally attractive random value.
-    }
-  };
-
-}  // namespace std
-
-#endif  // MPARK_VARIANT_HPP

+ 0 - 2813
src/external/mpark-variant/v1.4.0/variant.hpp

@@ -1,2813 +0,0 @@
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_VARIANT_HPP
-#define MPARK_VARIANT_HPP
-
-/*
-   variant synopsis
-
-namespace std {
-
-  // 20.7.2, class template variant
-  template <class... Types>
-  class variant {
-  public:
-
-    // 20.7.2.1, constructors
-    constexpr variant() noexcept(see below);
-    variant(const variant&);
-    variant(variant&&) noexcept(see below);
-
-    template <class T> constexpr variant(T&&) noexcept(see below);
-
-    template <class T, class... Args>
-    constexpr explicit variant(in_place_type_t<T>, Args&&...);
-
-    template <class T, class U, class... Args>
-    constexpr explicit variant(
-        in_place_type_t<T>, initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    constexpr explicit variant(in_place_index_t<I>, Args&&...);
-
-    template <size_t I, class U, class... Args>
-    constexpr explicit variant(
-        in_place_index_t<I>, initializer_list<U>, Args&&...);
-
-    // 20.7.2.2, destructor
-    ~variant();
-
-    // 20.7.2.3, assignment
-    variant& operator=(const variant&);
-    variant& operator=(variant&&) noexcept(see below);
-
-    template <class T> variant& operator=(T&&) noexcept(see below);
-
-    // 20.7.2.4, modifiers
-    template <class T, class... Args>
-    T& emplace(Args&&...);
-
-    template <class T, class U, class... Args>
-    T& emplace(initializer_list<U>, Args&&...);
-
-    template <size_t I, class... Args>
-    variant_alternative<I, variant>& emplace(Args&&...);
-
-    template <size_t I, class U, class...  Args>
-    variant_alternative<I, variant>& emplace(initializer_list<U>, Args&&...);
-
-    // 20.7.2.5, value status
-    constexpr bool valueless_by_exception() const noexcept;
-    constexpr size_t index() const noexcept;
-
-    // 20.7.2.6, swap
-    void swap(variant&) noexcept(see below);
-  };
-
-  // 20.7.3, variant helper classes
-  template <class T> struct variant_size; // undefined
-
-  template <class T>
-  constexpr size_t variant_size_v = variant_size<T>::value;
-
-  template <class T> struct variant_size<const T>;
-  template <class T> struct variant_size<volatile T>;
-  template <class T> struct variant_size<const volatile T>;
-
-  template <class... Types>
-  struct variant_size<variant<Types...>>;
-
-  template <size_t I, class T> struct variant_alternative; // undefined
-
-  template <size_t I, class T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <size_t I, class T> struct variant_alternative<I, const T>;
-  template <size_t I, class T> struct variant_alternative<I, volatile T>;
-  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
-
-  template <size_t I, class... Types>
-  struct variant_alternative<I, variant<Types...>>;
-
-  constexpr size_t variant_npos = -1;
-
-  // 20.7.4, value access
-  template <class T, class... Types>
-  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&
-  get(variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>>&&
-  get(variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&
-  get(const variant<Types...>&);
-
-  template <size_t I, class... Types>
-  constexpr variant_alternative_t<I, variant<Types...>> const&&
-  get(const variant<Types...>&&);
-
-  template <class T, class...  Types>
-  constexpr T& get(variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr T&& get(variant<Types...>&&);
-
-  template <class T, class... Types>
-  constexpr const T& get(const variant<Types...>&);
-
-  template <class T, class... Types>
-  constexpr const T&& get(const variant<Types...>&&);
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
-  get_if(variant<Types...>*) noexcept;
-
-  template <size_t I, class... Types>
-  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
-  get_if(const variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<T>
-  get_if(variant<Types...>*) noexcept;
-
-  template <class T, class... Types>
-  constexpr add_pointer_t<const T>
-  get_if(const variant<Types...>*) noexcept;
-
-  // 20.7.5, relational operators
-  template <class... Types>
-  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
-
-  template <class... Types>
-  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
-
-  // 20.7.6, visitation
-  template <class Visitor, class... Variants>
-  constexpr see below visit(Visitor&&, Variants&&...);
-
-  // 20.7.7, class monostate
-  struct monostate;
-
-  // 20.7.8, monostate relational operators
-  constexpr bool operator<(monostate, monostate) noexcept;
-  constexpr bool operator>(monostate, monostate) noexcept;
-  constexpr bool operator<=(monostate, monostate) noexcept;
-  constexpr bool operator>=(monostate, monostate) noexcept;
-  constexpr bool operator==(monostate, monostate) noexcept;
-  constexpr bool operator!=(monostate, monostate) noexcept;
-
-  // 20.7.9, specialized algorithms
-  template <class... Types>
-  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
-
-  // 20.7.10, class bad_variant_access
-  class bad_variant_access;
-
-  // 20.7.11, hash support
-  template <class T> struct hash;
-  template <class... Types> struct hash<variant<Types...>>;
-  template <> struct hash<monostate>;
-
-} // namespace std
-
-*/
-
-#include <cstddef>
-#include <exception>
-#include <functional>
-#include <initializer_list>
-#include <new>
-#include <type_traits>
-#include <utility>
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_CONFIG_HPP
-#define MPARK_CONFIG_HPP
-
-// MSVC 2015 Update 3.
-#if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024210)
-#error "MPark.Variant requires C++11 support."
-#endif
-
-#ifndef __has_attribute
-#define __has_attribute(x) 0
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#ifndef __has_include
-#define __has_include(x) 0
-#endif
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-
-#if __has_attribute(always_inline) || defined(__GNUC__)
-#define MPARK_ALWAYS_INLINE __attribute__((__always_inline__)) inline
-#elif defined(_MSC_VER)
-#define MPARK_ALWAYS_INLINE __forceinline
-#else
-#define MPARK_ALWAYS_INLINE inline
-#endif
-
-#if __has_builtin(__builtin_addressof) || \
-    (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER)
-#define MPARK_BUILTIN_ADDRESSOF
-#endif
-
-#if __has_builtin(__builtin_unreachable) || defined(__GNUC__)
-#define MPARK_BUILTIN_UNREACHABLE __builtin_unreachable()
-#elif defined(_MSC_VER)
-#define MPARK_BUILTIN_UNREACHABLE __assume(false)
-#else
-#define MPARK_BUILTIN_UNREACHABLE
-#endif
-
-#if __has_builtin(__type_pack_element)
-#define MPARK_TYPE_PACK_ELEMENT
-#endif
-
-#if defined(__cpp_constexpr) && __cpp_constexpr >= 200704 && \
-    !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 9)
-#define MPARK_CPP11_CONSTEXPR
-#endif
-
-#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
-#define MPARK_CPP14_CONSTEXPR
-#endif
-
-#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \
-    (defined(_MSC_VER) && defined(_CPPUNWIND))
-#define MPARK_EXCEPTIONS
-#endif
-
-#if defined(__cpp_generic_lambdas) || defined(_MSC_VER)
-#define MPARK_GENERIC_LAMBDAS
-#endif
-
-#if defined(__cpp_lib_integer_sequence)
-#define MPARK_INTEGER_SEQUENCE
-#endif
-
-#if defined(__cpp_return_type_deduction) || defined(_MSC_VER)
-#define MPARK_RETURN_TYPE_DEDUCTION
-#endif
-
-#if defined(__cpp_lib_transparent_operators) || defined(_MSC_VER)
-#define MPARK_TRANSPARENT_OPERATORS
-#endif
-
-#if defined(__cpp_variable_templates) || defined(_MSC_VER)
-#define MPARK_VARIABLE_TEMPLATES
-#endif
-
-#if !defined(__GLIBCXX__) || __has_include(<codecvt>)  // >= libstdc++-5
-#define MPARK_TRIVIALITY_TYPE_TRAITS
-#define MPARK_INCOMPLETE_TYPE_TRAITS
-#endif
-
-#endif  // MPARK_CONFIG_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_IN_PLACE_HPP
-#define MPARK_IN_PLACE_HPP
-
-#include <cstddef>
-
-
-namespace mpark {
-
-  struct in_place_t { explicit in_place_t() = default; };
-
-  template <std::size_t I>
-  struct in_place_index_t { explicit in_place_index_t() = default; };
-
-  template <typename T>
-  struct in_place_type_t { explicit in_place_type_t() = default; };
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  constexpr in_place_t in_place{};
-
-  template <std::size_t I> constexpr in_place_index_t<I> in_place_index{};
-
-  template <typename T> constexpr in_place_type_t<T> in_place_type{};
-#endif
-
-}  // namespace mpark
-
-#endif  // MPARK_IN_PLACE_HPP
-
-// MPark.Variant
-//
-// Copyright Michael Park, 2015-2017
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-
-#ifndef MPARK_LIB_HPP
-#define MPARK_LIB_HPP
-
-#include <memory>
-#include <functional>
-#include <type_traits>
-#include <utility>
-
-
-#define MPARK_RETURN(...) \
-  noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-namespace mpark {
-  namespace lib {
-    template <typename T>
-    struct identity { using type = T; };
-
-    inline namespace cpp14 {
-      template <typename T, std::size_t N>
-      struct array {
-        constexpr const T &operator[](std::size_t index) const {
-          return data[index];
-        }
-
-        T data[N == 0 ? 1 : N];
-      };
-
-      template <typename T>
-      using add_pointer_t = typename std::add_pointer<T>::type;
-
-      template <typename... Ts>
-      using common_type_t = typename std::common_type<Ts...>::type;
-
-      template <typename T>
-      using decay_t = typename std::decay<T>::type;
-
-      template <bool B, typename T = void>
-      using enable_if_t = typename std::enable_if<B, T>::type;
-
-      template <typename T>
-      using remove_const_t = typename std::remove_const<T>::type;
-
-      template <typename T>
-      using remove_reference_t = typename std::remove_reference<T>::type;
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &t) noexcept {
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr T &&forward(remove_reference_t<T> &&t) noexcept {
-        static_assert(!std::is_lvalue_reference<T>::value,
-                      "can not forward an rvalue as an lvalue");
-        return static_cast<T &&>(t);
-      }
-
-      template <typename T>
-      inline constexpr remove_reference_t<T> &&move(T &&t) noexcept {
-        return static_cast<remove_reference_t<T> &&>(t);
-      }
-
-#ifdef MPARK_INTEGER_SEQUENCE
-      using std::integer_sequence;
-      using std::index_sequence;
-      using std::make_index_sequence;
-      using std::index_sequence_for;
-#else
-      template <typename T, T... Is>
-      struct integer_sequence {
-        using value_type = T;
-        static constexpr std::size_t size() noexcept { return sizeof...(Is); }
-      };
-
-      template <std::size_t... Is>
-      using index_sequence = integer_sequence<std::size_t, Is...>;
-
-      template <typename Lhs, typename Rhs>
-      struct make_index_sequence_concat;
-
-      template <std::size_t... Lhs, std::size_t... Rhs>
-      struct make_index_sequence_concat<index_sequence<Lhs...>,
-                                        index_sequence<Rhs...>>
-          : identity<index_sequence<Lhs..., (sizeof...(Lhs) + Rhs)...>> {};
-
-      template <std::size_t N>
-      struct make_index_sequence_impl;
-
-      template <std::size_t N>
-      using make_index_sequence = typename make_index_sequence_impl<N>::type;
-
-      template <std::size_t N>
-      struct make_index_sequence_impl
-          : make_index_sequence_concat<make_index_sequence<N / 2>,
-                                       make_index_sequence<N - (N / 2)>> {};
-
-      template <>
-      struct make_index_sequence_impl<0> : identity<index_sequence<>> {};
-
-      template <>
-      struct make_index_sequence_impl<1> : identity<index_sequence<0>> {};
-
-      template <typename... Ts>
-      using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
-#endif
-
-      // <functional>
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using equal_to = std::equal_to<>;
-#else
-      struct equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) == lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using not_equal_to = std::not_equal_to<>;
-#else
-      struct not_equal_to {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) != lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less = std::less<>;
-#else
-      struct less {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) < lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater = std::greater<>;
-#else
-      struct greater {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) > lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using less_equal = std::less_equal<>;
-#else
-      struct less_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) <= lib::forward<Rhs>(rhs))
-      };
-#endif
-
-#ifdef MPARK_TRANSPARENT_OPERATORS
-      using greater_equal = std::greater_equal<>;
-#else
-      struct greater_equal {
-        template <typename Lhs, typename Rhs>
-        inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const
-          MPARK_RETURN(lib::forward<Lhs>(lhs) >= lib::forward<Rhs>(rhs))
-      };
-#endif
-    }  // namespace cpp14
-
-    inline namespace cpp17 {
-
-      // <type_traits>
-      template <bool B>
-      using bool_constant = std::integral_constant<bool, B>;
-
-      template <typename...>
-      struct voider : identity<void> {};
-
-      template <typename... Ts>
-      using void_t = typename voider<Ts...>::type;
-
-      namespace detail {
-        namespace swappable {
-
-          using std::swap;
-
-          template <typename T>
-          struct is_swappable {
-            private:
-            template <typename U,
-                      typename = decltype(swap(std::declval<U &>(),
-                                               std::declval<U &>()))>
-            inline static std::true_type test(int);
-
-            template <typename U>
-            inline static std::false_type test(...);
-
-            public:
-            static constexpr bool value = decltype(test<T>(0))::value;
-          };
-
-          template <bool IsSwappable, typename T>
-          struct is_nothrow_swappable {
-            static constexpr bool value =
-                noexcept(swap(std::declval<T &>(), std::declval<T &>()));
-          };
-
-          template <typename T>
-          struct is_nothrow_swappable<false, T> : std::false_type {};
-
-        }  // namespace swappable
-      }  // namespace detail
-
-      using detail::swappable::is_swappable;
-
-      template <typename T>
-      using is_nothrow_swappable =
-          detail::swappable::is_nothrow_swappable<is_swappable<T>::value, T>;
-
-      // <functional>
-      namespace detail {
-
-        template <typename T>
-        struct is_reference_wrapper : std::false_type {};
-
-        template <typename T>
-        struct is_reference_wrapper<std::reference_wrapper<T>>
-            : std::true_type {};
-
-        template <bool, int>
-        struct Invoke;
-
-        template <>
-        struct Invoke<true /* pmf */, 0 /* is_base_of */> {
-          template <typename R, typename T, typename Arg, typename... Args>
-          inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&... args)
-            MPARK_RETURN((lib::forward<Arg>(arg).*pmf)(lib::forward<Args>(args)...))
-        };
-
-        template <>
-        struct Invoke<true /* pmf */, 1 /* is_reference_wrapper */> {
-          template <typename R, typename T, typename Arg, typename... Args>
-          inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&... args)
-            MPARK_RETURN((lib::forward<Arg>(arg).get().*pmf)(lib::forward<Args>(args)...))
-        };
-
-        template <>
-        struct Invoke<true /* pmf */, 2 /* otherwise */> {
-          template <typename R, typename T, typename Arg, typename... Args>
-          inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&... args)
-            MPARK_RETURN(((*lib::forward<Arg>(arg)).*pmf)(lib::forward<Args>(args)...))
-        };
-
-        template <>
-        struct Invoke<false /* pmo */, 0 /* is_base_of */> {
-          template <typename R, typename T, typename Arg>
-          inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
-            MPARK_RETURN(lib::forward<Arg>(arg).*pmo)
-        };
-
-        template <>
-        struct Invoke<false /* pmo */, 1 /* is_reference_wrapper */> {
-          template <typename R, typename T, typename Arg>
-          inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
-            MPARK_RETURN(lib::forward<Arg>(arg).get().*pmo)
-        };
-
-        template <>
-        struct Invoke<false /* pmo */, 2 /* otherwise */> {
-          template <typename R, typename T, typename Arg>
-          inline static constexpr auto invoke(R T::*pmo, Arg &&arg)
-              MPARK_RETURN((*lib::forward<Arg>(arg)).*pmo)
-        };
-
-        template <typename R, typename T, typename Arg, typename... Args>
-        inline constexpr auto invoke(R T::*f, Arg &&arg, Args &&... args)
-          MPARK_RETURN(
-              Invoke<std::is_function<R>::value,
-                     (std::is_base_of<T, lib::decay_t<Arg>>::value
-                          ? 0
-                          : is_reference_wrapper<lib::decay_t<Arg>>::value
-                                ? 1
-                                : 2)>::invoke(f,
-                                              lib::forward<Arg>(arg),
-                                              lib::forward<Args>(args)...))
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-        template <typename F, typename... Args>
-        inline constexpr auto invoke(F &&f, Args &&... args)
-          MPARK_RETURN(lib::forward<F>(f)(lib::forward<Args>(args)...))
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      inline constexpr auto invoke(F &&f, Args &&... args)
-        MPARK_RETURN(detail::invoke(lib::forward<F>(f),
-                                    lib::forward<Args>(args)...))
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct invoke_result {};
-
-        template <typename F, typename... Args>
-        struct invoke_result<void_t<decltype(lib::invoke(
-                                 std::declval<F>(), std::declval<Args>()...))>,
-                             F,
-                             Args...>
-            : identity<decltype(
-                  lib::invoke(std::declval<F>(), std::declval<Args>()...))> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using invoke_result = detail::invoke_result<void, F, Args...>;
-
-      template <typename F, typename... Args>
-      using invoke_result_t = typename invoke_result<F, Args...>::type;
-
-      namespace detail {
-
-        template <typename Void, typename, typename...>
-        struct is_invocable : std::false_type {};
-
-        template <typename F, typename... Args>
-        struct is_invocable<void_t<invoke_result_t<F, Args...>>, F, Args...>
-            : std::true_type {};
-
-        template <typename Void, typename, typename, typename...>
-        struct is_invocable_r : std::false_type {};
-
-        template <typename R, typename F, typename... Args>
-        struct is_invocable_r<void_t<invoke_result_t<F, Args...>>,
-                              R,
-                              F,
-                              Args...>
-            : std::is_convertible<invoke_result_t<F, Args...>, R> {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using is_invocable = detail::is_invocable<void, F, Args...>;
-
-      template <typename R, typename F, typename... Args>
-      using is_invocable_r = detail::is_invocable_r<void, R, F, Args...>;
-
-      namespace detail {
-
-        template <bool Invocable, typename F, typename... Args>
-        struct is_nothrow_invocable {
-          static constexpr bool value =
-              noexcept(lib::invoke(std::declval<F>(), std::declval<Args>()...));
-        };
-
-        template <typename F, typename... Args>
-        struct is_nothrow_invocable<false, F, Args...> : std::false_type {};
-
-        template <bool Invocable, typename R, typename F, typename... Args>
-        struct is_nothrow_invocable_r {
-          private:
-          inline static R impl() {
-            return lib::invoke(std::declval<F>(), std::declval<Args>()...);
-          }
-
-          public:
-          static constexpr bool value = noexcept(impl());
-        };
-
-        template <typename R, typename F, typename... Args>
-        struct is_nothrow_invocable_r<false, R, F, Args...> : std::false_type {};
-
-      }  // namespace detail
-
-      template <typename F, typename... Args>
-      using is_nothrow_invocable = detail::
-          is_nothrow_invocable<is_invocable<F, Args...>::value, F, Args...>;
-
-      template <typename R, typename F, typename... Args>
-      using is_nothrow_invocable_r =
-          detail::is_nothrow_invocable_r<is_invocable_r<R, F, Args...>::value,
-                                         R,
-                                         F,
-                                         Args...>;
-
-      // <memory>
-#ifdef MPARK_BUILTIN_ADDRESSOF
-      template <typename T>
-      inline constexpr T *addressof(T &arg) noexcept {
-        return __builtin_addressof(arg);
-      }
-#else
-      namespace detail {
-
-        namespace has_addressof_impl {
-
-          struct fail;
-
-          template <typename T>
-          inline fail operator&(T &&);
-
-          template <typename T>
-          inline static constexpr bool impl() {
-            return (std::is_class<T>::value || std::is_union<T>::value) &&
-                   !std::is_same<decltype(&std::declval<T &>()), fail>::value;
-          }
-
-        }  // namespace has_addressof_impl
-
-        template <typename T>
-        using has_addressof = bool_constant<has_addressof_impl::impl<T>()>;
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::true_type) noexcept {
-          return std::addressof(arg);
-        }
-
-        template <typename T>
-        inline constexpr T *addressof(T &arg, std::false_type) noexcept {
-          return &arg;
-        }
-
-      }  // namespace detail
-
-      template <typename T>
-      inline constexpr T *addressof(T &arg) noexcept {
-        return detail::addressof(arg, detail::has_addressof<T>{});
-      }
-#endif
-
-      template <typename T>
-      inline constexpr T *addressof(const T &&) = delete;
-
-    }  // namespace cpp17
-
-    template <typename T>
-    struct remove_all_extents : identity<T> {};
-
-    template <typename T, std::size_t N>
-    struct remove_all_extents<array<T, N>> : remove_all_extents<T> {};
-
-    template <typename T>
-    using remove_all_extents_t = typename remove_all_extents<T>::type;
-
-    template <std::size_t N>
-    using size_constant = std::integral_constant<std::size_t, N>;
-
-    template <std::size_t I, typename T>
-    struct indexed_type : size_constant<I> { using type = T; };
-
-    template <bool... Bs>
-    using all = std::is_same<integer_sequence<bool, true, Bs...>,
-                             integer_sequence<bool, Bs..., true>>;
-
-#ifdef MPARK_TYPE_PACK_ELEMENT
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = __type_pack_element<I, Ts...>;
-#else
-    template <std::size_t I, typename... Ts>
-    struct type_pack_element_impl {
-      private:
-      template <typename>
-      struct set;
-
-      template <std::size_t... Is>
-      struct set<index_sequence<Is...>> : indexed_type<Is, Ts>... {};
-
-      template <typename T>
-      inline static std::enable_if<true, T> impl(indexed_type<I, T>);
-
-      inline static std::enable_if<false> impl(...);
-
-      public:
-      using type = decltype(impl(set<index_sequence_for<Ts...>>{}));
-    };
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element = typename type_pack_element_impl<I, Ts...>::type;
-
-    template <std::size_t I, typename... Ts>
-    using type_pack_element_t = typename type_pack_element<I, Ts...>::type;
-#endif
-
-#ifdef MPARK_TRIVIALITY_TYPE_TRAITS
-    using std::is_trivially_copy_constructible;
-    using std::is_trivially_move_constructible;
-    using std::is_trivially_copy_assignable;
-    using std::is_trivially_move_assignable;
-#else
-    template <typename T>
-    struct is_trivially_copy_constructible
-        : bool_constant<
-              std::is_copy_constructible<T>::value && __has_trivial_copy(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_constructible : bool_constant<__is_trivial(T)> {};
-
-    template <typename T>
-    struct is_trivially_copy_assignable
-        : bool_constant<
-              std::is_copy_assignable<T>::value && __has_trivial_assign(T)> {};
-
-    template <typename T>
-    struct is_trivially_move_assignable : bool_constant<__is_trivial(T)> {};
-#endif
-
-    template <typename T, bool>
-    struct dependent_type : T {};
-
-    template <typename Is, std::size_t J>
-    struct push_back;
-
-    template <typename Is, std::size_t J>
-    using push_back_t = typename push_back<Is, J>::type;
-
-    template <std::size_t... Is, std::size_t J>
-    struct push_back<index_sequence<Is...>, J> {
-      using type = index_sequence<Is..., J>;
-    };
-
-  }  // namespace lib
-}  // namespace mpark
-
-#undef MPARK_RETURN
-
-#endif  // MPARK_LIB_HPP
-
-
-namespace mpark {
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-
-#define AUTO auto
-#define AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto &&
-#define AUTO_REFREF_RETURN(...) { return __VA_ARGS__; }
-
-#define DECLTYPE_AUTO decltype(auto)
-#define DECLTYPE_AUTO_RETURN(...) { return __VA_ARGS__; }
-
-#else
-
-#define AUTO auto
-#define AUTO_RETURN(...) \
-  -> lib::decay_t<decltype(__VA_ARGS__)> { return __VA_ARGS__; }
-
-#define AUTO_REFREF auto
-#define AUTO_REFREF_RETURN(...)                                           \
-  -> decltype((__VA_ARGS__)) {                                            \
-    static_assert(std::is_reference<decltype((__VA_ARGS__))>::value, ""); \
-    return __VA_ARGS__;                                                   \
-  }
-
-#define DECLTYPE_AUTO auto
-#define DECLTYPE_AUTO_RETURN(...) \
-  -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
-
-#endif
-
-  class bad_variant_access : public std::exception {
-    public:
-    virtual const char *what() const noexcept override { return "bad_variant_access"; }
-  };
-
-  [[noreturn]] inline void throw_bad_variant_access() {
-#ifdef MPARK_EXCEPTIONS
-    throw bad_variant_access{};
-#else
-    std::terminate();
-    MPARK_BUILTIN_UNREACHABLE;
-#endif
-  }
-
-  template <typename... Ts>
-  class variant;
-
-  template <typename T>
-  struct variant_size;
-
-#ifdef MPARK_VARIABLE_TEMPLATES
-  template <typename T>
-  constexpr std::size_t variant_size_v = variant_size<T>::value;
-#endif
-
-  template <typename T>
-  struct variant_size<const T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<volatile T> : variant_size<T> {};
-
-  template <typename T>
-  struct variant_size<const volatile T> : variant_size<T> {};
-
-  template <typename... Ts>
-  struct variant_size<variant<Ts...>> : lib::size_constant<sizeof...(Ts)> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative;
-
-  template <std::size_t I, typename T>
-  using variant_alternative_t = typename variant_alternative<I, T>::type;
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const T>
-      : std::add_const<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, volatile T>
-      : std::add_volatile<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename T>
-  struct variant_alternative<I, const volatile T>
-      : std::add_cv<variant_alternative_t<I, T>> {};
-
-  template <std::size_t I, typename... Ts>
-  struct variant_alternative<I, variant<Ts...>> {
-    static_assert(I < sizeof...(Ts),
-                  "index out of bounds in `std::variant_alternative<>`");
-    using type = lib::type_pack_element_t<I, Ts...>;
-  };
-
-  constexpr std::size_t variant_npos = static_cast<std::size_t>(-1);
-
-  namespace detail {
-
-    constexpr std::size_t not_found = static_cast<std::size_t>(-1);
-    constexpr std::size_t ambiguous = static_cast<std::size_t>(-2);
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      constexpr lib::array<bool, sizeof...(Ts)> matches = {
-          {std::is_same<T, Ts>::value...}
-      };
-      std::size_t result = not_found;
-      for (std::size_t i = 0; i < sizeof...(Ts); ++i) {
-        if (matches[i]) {
-          if (result != not_found) {
-            return ambiguous;
-          }
-          result = i;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t) {
-      return result;
-    }
-
-    template <typename... Bs>
-    inline constexpr std::size_t find_index_impl(std::size_t result,
-                                                 std::size_t idx,
-                                                 bool b,
-                                                 Bs... bs) {
-      return b ? (result != not_found ? ambiguous
-                                      : find_index_impl(idx, idx + 1, bs...))
-               : find_index_impl(result, idx + 1, bs...);
-    }
-
-    template <typename T, typename... Ts>
-    inline constexpr std::size_t find_index() {
-      return find_index_impl(not_found, 0, std::is_same<T, Ts>::value...);
-    }
-#endif
-
-    template <std::size_t I>
-    using find_index_sfinae_impl =
-        lib::enable_if_t<I != not_found && I != ambiguous,
-                         lib::size_constant<I>>;
-
-    template <typename T, typename... Ts>
-    using find_index_sfinae = find_index_sfinae_impl<find_index<T, Ts...>()>;
-
-    template <std::size_t I>
-    struct find_index_checked_impl : lib::size_constant<I> {
-      static_assert(I != not_found, "the specified type is not found.");
-      static_assert(I != ambiguous, "the specified type is ambiguous.");
-    };
-
-    template <typename T, typename... Ts>
-    using find_index_checked = find_index_checked_impl<find_index<T, Ts...>()>;
-
-    struct valueless_t {};
-
-    enum class Trait { TriviallyAvailable, Available, Unavailable };
-
-    template <typename T,
-              template <typename> class IsTriviallyAvailable,
-              template <typename> class IsAvailable>
-    inline constexpr Trait trait() {
-      return IsTriviallyAvailable<T>::value
-                 ? Trait::TriviallyAvailable
-                 : IsAvailable<T>::value ? Trait::Available
-                                         : Trait::Unavailable;
-    }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... traits_) {
-      Trait result = Trait::TriviallyAvailable;
-      lib::array<Trait, sizeof...(Traits)> traits = {{traits_...}};
-      for (std::size_t i = 0; i < sizeof...(Traits); ++i) {
-        Trait t = traits[i];
-        if (static_cast<int>(t) > static_cast<int>(result)) {
-          result = t;
-        }
-      }
-      return result;
-    }
-#else
-    inline constexpr Trait common_trait_impl(Trait result) { return result; }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait_impl(Trait result,
-                                             Trait t,
-                                             Traits... ts) {
-      return static_cast<int>(t) > static_cast<int>(result)
-                 ? common_trait_impl(t, ts...)
-                 : common_trait_impl(result, ts...);
-    }
-
-    template <typename... Traits>
-    inline constexpr Trait common_trait(Traits... ts) {
-      return common_trait_impl(Trait::TriviallyAvailable, ts...);
-    }
-#endif
-
-    template <typename... Ts>
-    struct traits {
-      static constexpr Trait copy_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_copy_constructible,
-                             std::is_copy_constructible>()...);
-
-      static constexpr Trait move_constructible_trait =
-          common_trait(trait<Ts,
-                             lib::is_trivially_move_constructible,
-                             std::is_move_constructible>()...);
-
-      static constexpr Trait copy_assignable_trait =
-          common_trait(copy_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_copy_assignable,
-                             std::is_copy_assignable>()...);
-
-      static constexpr Trait move_assignable_trait =
-          common_trait(move_constructible_trait,
-                       trait<Ts,
-                             lib::is_trivially_move_assignable,
-                             std::is_move_assignable>()...);
-
-      static constexpr Trait destructible_trait =
-          common_trait(trait<Ts,
-                             std::is_trivially_destructible,
-                             std::is_destructible>()...);
-    };
-
-    namespace access {
-
-      struct recursive_union {
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename V>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<0>) {
-          return lib::forward<V>(v).head_;
-        }
-
-        template <typename V, std::size_t I>
-        inline static constexpr auto &&get_alt(V &&v, in_place_index_t<I>) {
-          return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{});
-        }
-#else
-        template <std::size_t I, bool Dummy = true>
-        struct get_alt_impl {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(get_alt_impl<I - 1>{}(lib::forward<V>(v).tail_))
-        };
-
-        template <bool Dummy>
-        struct get_alt_impl<0, Dummy> {
-          template <typename V>
-          inline constexpr AUTO_REFREF operator()(V &&v) const
-            AUTO_REFREF_RETURN(lib::forward<V>(v).head_)
-        };
-
-        template <typename V, std::size_t I>
-        inline static constexpr AUTO_REFREF get_alt(V &&v, in_place_index_t<I>)
-          AUTO_REFREF_RETURN(get_alt_impl<I>{}(lib::forward<V>(v)))
-#endif
-      };
-
-      struct base {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-#ifdef _MSC_VER
-          AUTO_REFREF_RETURN(recursive_union::get_alt(
-              lib::forward<V>(v).data_, in_place_index_t<I>{}))
-#else
-          AUTO_REFREF_RETURN(recursive_union::get_alt(
-              data(lib::forward<V>(v)), in_place_index_t<I>{}))
-#endif
-      };
-
-      struct variant {
-        template <std::size_t I, typename V>
-        inline static constexpr AUTO_REFREF get_alt(V &&v)
-          AUTO_REFREF_RETURN(base::get_alt<I>(lib::forward<V>(v).impl_))
-      };
-
-    }  // namespace access
-
-    namespace visitation {
-
-#if defined(MPARK_CPP14_CONSTEXPR) && !defined(_MSC_VER)
-#define MPARK_VARIANT_SWITCH_VISIT
-#endif
-
-      struct base {
-        template <typename Visitor, typename... Vs>
-        using dispatch_result_t = decltype(
-            lib::invoke(std::declval<Visitor>(),
-                        access::base::get_alt<0>(std::declval<Vs>())...));
-
-        template <typename Expected>
-        struct expected {
-          template <typename Actual>
-          inline static constexpr bool but_got() {
-            return std::is_same<Expected, Actual>::value;
-          }
-        };
-
-        template <typename Expected, typename Actual>
-        struct visit_return_type_check {
-          static_assert(
-              expected<Expected>::template but_got<Actual>(),
-              "`visit` requires the visitor to have a single return type");
-
-          template <typename Visitor, typename... Alts>
-          inline static constexpr DECLTYPE_AUTO invoke(Visitor &&visitor,
-                                                       Alts &&... alts)
-            DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
-                                             lib::forward<Alts>(alts)...))
-        };
-
-#ifdef MPARK_VARIANT_SWITCH_VISIT
-        template <bool B, typename R, typename... ITs>
-        struct dispatcher;
-
-        template <typename R, typename... ITs>
-        struct dispatcher<false, R, ITs...> {
-          template <std::size_t B, typename F, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch(
-              F &&, typename ITs::type &&..., Vs &&...) {
-            MPARK_BUILTIN_UNREACHABLE;
-          }
-
-          template <std::size_t I, typename F, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch_case(F &&, Vs &&...) {
-            MPARK_BUILTIN_UNREACHABLE;
-          }
-
-          template <std::size_t B, typename F, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch_at(std::size_t,
-                                                             F &&,
-                                                             Vs &&...) {
-            MPARK_BUILTIN_UNREACHABLE;
-          }
-        };
-
-        template <typename R, typename... ITs>
-        struct dispatcher<true, R, ITs...> {
-          template <std::size_t B, typename F>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch(
-              F &&f, typename ITs::type &&... visited_vs) {
-            using Expected = R;
-            using Actual = decltype(lib::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<ITs::value>(
-                    lib::forward<typename ITs::type>(visited_vs))...));
-            return visit_return_type_check<Expected, Actual>::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<ITs::value>(
-                    lib::forward<typename ITs::type>(visited_vs))...);
-          }
-
-          template <std::size_t B, typename F, typename V, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch(
-              F &&f, typename ITs::type &&... visited_vs, V &&v, Vs &&... vs) {
-#define MPARK_DISPATCH(I)                                                   \
-  dispatcher<(I < lib::decay_t<V>::size()),                                 \
-             R,                                                             \
-             ITs...,                                                        \
-             lib::indexed_type<I, V>>::                                     \
-      template dispatch<0>(lib::forward<F>(f),                              \
-                           lib::forward<typename ITs::type>(visited_vs)..., \
-                           lib::forward<V>(v),                              \
-                           lib::forward<Vs>(vs)...)
-
-#define MPARK_DEFAULT(I)                                                      \
-  dispatcher<(I < lib::decay_t<V>::size()), R, ITs...>::template dispatch<I>( \
-      lib::forward<F>(f),                                                     \
-      lib::forward<typename ITs::type>(visited_vs)...,                        \
-      lib::forward<V>(v),                                                     \
-      lib::forward<Vs>(vs)...)
-
-            switch (v.index()) {
-              case B + 0: return MPARK_DISPATCH(B + 0);
-              case B + 1: return MPARK_DISPATCH(B + 1);
-              case B + 2: return MPARK_DISPATCH(B + 2);
-              case B + 3: return MPARK_DISPATCH(B + 3);
-              case B + 4: return MPARK_DISPATCH(B + 4);
-              case B + 5: return MPARK_DISPATCH(B + 5);
-              case B + 6: return MPARK_DISPATCH(B + 6);
-              case B + 7: return MPARK_DISPATCH(B + 7);
-              case B + 8: return MPARK_DISPATCH(B + 8);
-              case B + 9: return MPARK_DISPATCH(B + 9);
-              case B + 10: return MPARK_DISPATCH(B + 10);
-              case B + 11: return MPARK_DISPATCH(B + 11);
-              case B + 12: return MPARK_DISPATCH(B + 12);
-              case B + 13: return MPARK_DISPATCH(B + 13);
-              case B + 14: return MPARK_DISPATCH(B + 14);
-              case B + 15: return MPARK_DISPATCH(B + 15);
-              case B + 16: return MPARK_DISPATCH(B + 16);
-              case B + 17: return MPARK_DISPATCH(B + 17);
-              case B + 18: return MPARK_DISPATCH(B + 18);
-              case B + 19: return MPARK_DISPATCH(B + 19);
-              case B + 20: return MPARK_DISPATCH(B + 20);
-              case B + 21: return MPARK_DISPATCH(B + 21);
-              case B + 22: return MPARK_DISPATCH(B + 22);
-              case B + 23: return MPARK_DISPATCH(B + 23);
-              case B + 24: return MPARK_DISPATCH(B + 24);
-              case B + 25: return MPARK_DISPATCH(B + 25);
-              case B + 26: return MPARK_DISPATCH(B + 26);
-              case B + 27: return MPARK_DISPATCH(B + 27);
-              case B + 28: return MPARK_DISPATCH(B + 28);
-              case B + 29: return MPARK_DISPATCH(B + 29);
-              case B + 30: return MPARK_DISPATCH(B + 30);
-              case B + 31: return MPARK_DISPATCH(B + 31);
-              default: return MPARK_DEFAULT(B + 32);
-            }
-
-#undef MPARK_DEFAULT
-#undef MPARK_DISPATCH
-          }
-
-          template <std::size_t I, typename F, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch_case(F &&f,
-                                                               Vs &&... vs) {
-            using Expected = R;
-            using Actual = decltype(
-                lib::invoke(lib::forward<F>(f),
-                            access::base::get_alt<I>(lib::forward<Vs>(vs))...));
-            return visit_return_type_check<Expected, Actual>::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<I>(lib::forward<Vs>(vs))...);
-          }
-
-          template <std::size_t B, typename F, typename V, typename... Vs>
-          MPARK_ALWAYS_INLINE static constexpr R dispatch_at(std::size_t index,
-                                                             F &&f,
-                                                             V &&v,
-                                                             Vs &&... vs) {
-            static_assert(lib::all<(lib::decay_t<V>::size() ==
-                                    lib::decay_t<Vs>::size())...>::value,
-                          "all of the variants must be the same size.");
-#define MPARK_DISPATCH_AT(I)                                               \
-  dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_case<I>( \
-      lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
-
-#define MPARK_DEFAULT(I)                                                 \
-  dispatcher<(I < lib::decay_t<V>::size()), R>::template dispatch_at<I>( \
-      index, lib::forward<F>(f), lib::forward<V>(v), lib::forward<Vs>(vs)...)
-
-            switch (index) {
-              case B + 0: return MPARK_DISPATCH_AT(B + 0);
-              case B + 1: return MPARK_DISPATCH_AT(B + 1);
-              case B + 2: return MPARK_DISPATCH_AT(B + 2);
-              case B + 3: return MPARK_DISPATCH_AT(B + 3);
-              case B + 4: return MPARK_DISPATCH_AT(B + 4);
-              case B + 5: return MPARK_DISPATCH_AT(B + 5);
-              case B + 6: return MPARK_DISPATCH_AT(B + 6);
-              case B + 7: return MPARK_DISPATCH_AT(B + 7);
-              case B + 8: return MPARK_DISPATCH_AT(B + 8);
-              case B + 9: return MPARK_DISPATCH_AT(B + 9);
-              case B + 10: return MPARK_DISPATCH_AT(B + 10);
-              case B + 11: return MPARK_DISPATCH_AT(B + 11);
-              case B + 12: return MPARK_DISPATCH_AT(B + 12);
-              case B + 13: return MPARK_DISPATCH_AT(B + 13);
-              case B + 14: return MPARK_DISPATCH_AT(B + 14);
-              case B + 15: return MPARK_DISPATCH_AT(B + 15);
-              case B + 16: return MPARK_DISPATCH_AT(B + 16);
-              case B + 17: return MPARK_DISPATCH_AT(B + 17);
-              case B + 18: return MPARK_DISPATCH_AT(B + 18);
-              case B + 19: return MPARK_DISPATCH_AT(B + 19);
-              case B + 20: return MPARK_DISPATCH_AT(B + 20);
-              case B + 21: return MPARK_DISPATCH_AT(B + 21);
-              case B + 22: return MPARK_DISPATCH_AT(B + 22);
-              case B + 23: return MPARK_DISPATCH_AT(B + 23);
-              case B + 24: return MPARK_DISPATCH_AT(B + 24);
-              case B + 25: return MPARK_DISPATCH_AT(B + 25);
-              case B + 26: return MPARK_DISPATCH_AT(B + 26);
-              case B + 27: return MPARK_DISPATCH_AT(B + 27);
-              case B + 28: return MPARK_DISPATCH_AT(B + 28);
-              case B + 29: return MPARK_DISPATCH_AT(B + 29);
-              case B + 30: return MPARK_DISPATCH_AT(B + 30);
-              case B + 31: return MPARK_DISPATCH_AT(B + 31);
-              default: return MPARK_DEFAULT(B + 32);
-            }
-
-#undef MPARK_DEFAULT
-#undef MPARK_DISPATCH_AT
-          }
-        };
-#else
-        template <typename T>
-        inline static constexpr const T &at(const T &elem) noexcept {
-          return elem;
-        }
-
-        template <typename T, std::size_t N, typename... Is>
-        inline static constexpr const lib::remove_all_extents_t<T> &at(
-            const lib::array<T, N> &elems, std::size_t i, Is... is) noexcept {
-          return at(elems[i], is...);
-        }
-
-        template <typename F, typename... Fs>
-        inline static constexpr lib::array<lib::decay_t<F>, sizeof...(Fs) + 1>
-        make_farray(F &&f, Fs &&... fs) {
-          return {{lib::forward<F>(f), lib::forward<Fs>(fs)...}};
-        }
-
-        template <typename F, typename... Vs>
-        struct make_fmatrix_impl {
-
-          template <std::size_t... Is>
-          inline static constexpr dispatch_result_t<F, Vs...> dispatch(
-              F &&f, Vs &&... vs) {
-            using Expected = dispatch_result_t<F, Vs...>;
-            using Actual = decltype(lib::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<Is>(lib::forward<Vs>(vs))...));
-            return visit_return_type_check<Expected, Actual>::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<Is>(lib::forward<Vs>(vs))...);
-          }
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-          template <std::size_t... Is>
-          inline static constexpr auto impl(lib::index_sequence<Is...>) {
-            return &dispatch<Is...>;
-          }
-
-          template <typename Is, std::size_t... Js, typename... Ls>
-          inline static constexpr auto impl(Is,
-                                            lib::index_sequence<Js...>,
-                                            Ls... ls) {
-            return make_farray(impl(lib::push_back_t<Is, Js>{}, ls...)...);
-          }
-#else
-          template <typename...>
-          struct impl;
-
-          template <std::size_t... Is>
-          struct impl<lib::index_sequence<Is...>> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(&dispatch<Is...>)
-          };
-
-          template <typename Is, std::size_t... Js, typename... Ls>
-          struct impl<Is, lib::index_sequence<Js...>, Ls...> {
-            inline constexpr AUTO operator()() const
-              AUTO_RETURN(
-                  make_farray(impl<lib::push_back_t<Is, Js>, Ls...>{}()...))
-          };
-#endif
-        };
-
-#ifdef MPARK_RETURN_TYPE_DEDUCTION
-        template <typename F, typename... Vs>
-        inline static constexpr auto make_fmatrix() {
-          return make_fmatrix_impl<F, Vs...>::impl(
-              lib::index_sequence<>{},
-              lib::make_index_sequence<lib::decay_t<Vs>::size()>{}...);
-        }
-#else
-        template <typename F, typename... Vs>
-        inline static constexpr AUTO make_fmatrix()
-          AUTO_RETURN(
-              typename make_fmatrix_impl<F, Vs...>::template impl<
-                  lib::index_sequence<>,
-                  lib::make_index_sequence<lib::decay_t<Vs>::size()>...>{}())
-#endif
-
-        template <typename F, typename... Vs>
-        struct make_fdiagonal_impl {
-          template <std::size_t I>
-          inline static constexpr dispatch_result_t<F, Vs...> dispatch(
-              F &&f, Vs &&... vs) {
-            using Expected = dispatch_result_t<F, Vs...>;
-            using Actual = decltype(
-                lib::invoke(lib::forward<F>(f),
-                            access::base::get_alt<I>(lib::forward<Vs>(vs))...));
-            return visit_return_type_check<Expected, Actual>::invoke(
-                lib::forward<F>(f),
-                access::base::get_alt<I>(lib::forward<Vs>(vs))...);
-          }
-
-          template <std::size_t... Is>
-          inline static constexpr AUTO impl(lib::index_sequence<Is...>)
-            AUTO_RETURN(make_farray(&dispatch<Is>...))
-        };
-
-        template <typename F, typename V, typename... Vs>
-        inline static constexpr auto make_fdiagonal()
-            -> decltype(make_fdiagonal_impl<F, V, Vs...>::impl(
-                lib::make_index_sequence<lib::decay_t<V>::size()>{})) {
-          static_assert(lib::all<(lib::decay_t<V>::size() ==
-                                  lib::decay_t<Vs>::size())...>::value,
-                        "all of the variants must be the same size.");
-          return make_fdiagonal_impl<F, V, Vs...>::impl(
-              lib::make_index_sequence<lib::decay_t<V>::size()>{});
-        }
-#endif
-      };
-
-#if !defined(MPARK_VARIANT_SWITCH_VISIT) && \
-    (!defined(_MSC_VER) || _MSC_VER >= 1910)
-      template <typename F, typename... Vs>
-      using fmatrix_t = decltype(base::make_fmatrix<F, Vs...>());
-
-      template <typename F, typename... Vs>
-      struct fmatrix {
-        static constexpr fmatrix_t<F, Vs...> value =
-            base::make_fmatrix<F, Vs...>();
-      };
-
-      template <typename F, typename... Vs>
-      constexpr fmatrix_t<F, Vs...> fmatrix<F, Vs...>::value;
-
-      template <typename F, typename... Vs>
-      using fdiagonal_t = decltype(base::make_fdiagonal<F, Vs...>());
-
-      template <typename F, typename... Vs>
-      struct fdiagonal {
-        static constexpr fdiagonal_t<F, Vs...> value =
-            base::make_fdiagonal<F, Vs...>();
-      };
-
-      template <typename F, typename... Vs>
-      constexpr fdiagonal_t<F, Vs...> fdiagonal<F, Vs...>::value;
-#endif
-
-      struct alt {
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-#ifdef MPARK_VARIANT_SWITCH_VISIT
-          DECLTYPE_AUTO_RETURN(
-              base::dispatcher<
-                  true,
-                  base::dispatch_result_t<Visitor,
-                                          decltype(as_base(
-                                              lib::forward<Vs>(vs)))...>>::
-                  template dispatch<0>(lib::forward<Visitor>(visitor),
-                                       as_base(lib::forward<Vs>(vs))...))
-#elif !defined(_MSC_VER) || _MSC_VER >= 1910
-          DECLTYPE_AUTO_RETURN(base::at(
-              fmatrix<Visitor &&,
-                      decltype(as_base(lib::forward<Vs>(vs)))...>::value,
-              vs.index()...)(lib::forward<Visitor>(visitor),
-                             as_base(lib::forward<Vs>(vs))...))
-#else
-          DECLTYPE_AUTO_RETURN(base::at(
-              base::make_fmatrix<Visitor &&,
-                      decltype(as_base(lib::forward<Vs>(vs)))...>(),
-              vs.index()...)(lib::forward<Visitor>(visitor),
-                             as_base(lib::forward<Vs>(vs))...))
-#endif
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-#ifdef MPARK_VARIANT_SWITCH_VISIT
-          DECLTYPE_AUTO_RETURN(
-              base::dispatcher<
-                  true,
-                  base::dispatch_result_t<Visitor,
-                                          decltype(as_base(
-                                              lib::forward<Vs>(vs)))...>>::
-                  template dispatch_at<0>(index,
-                                          lib::forward<Visitor>(visitor),
-                                          as_base(lib::forward<Vs>(vs))...))
-#elif !defined(_MSC_VER) || _MSC_VER >= 1910
-          DECLTYPE_AUTO_RETURN(base::at(
-              fdiagonal<Visitor &&,
-                        decltype(as_base(lib::forward<Vs>(vs)))...>::value,
-              index)(lib::forward<Visitor>(visitor),
-                     as_base(lib::forward<Vs>(vs))...))
-#else
-          DECLTYPE_AUTO_RETURN(base::at(
-              base::make_fdiagonal<Visitor &&,
-                        decltype(as_base(lib::forward<Vs>(vs)))...>(),
-              index)(lib::forward<Visitor>(visitor),
-                     as_base(lib::forward<Vs>(vs))...))
-#endif
-      };
-
-      struct variant {
-        private:
-        template <typename Visitor>
-        struct visitor {
-          template <typename... Values>
-          inline static constexpr bool does_not_handle() {
-            return lib::is_invocable<Visitor, Values...>::value;
-          }
-        };
-
-        template <typename Visitor, typename... Values>
-        struct visit_exhaustiveness_check {
-          static_assert(visitor<Visitor>::template does_not_handle<Values...>(),
-                        "`visit` requires the visitor to be exhaustive.");
-
-          inline static constexpr DECLTYPE_AUTO invoke(Visitor &&visitor,
-                                                       Values &&... values)
-            DECLTYPE_AUTO_RETURN(lib::invoke(lib::forward<Visitor>(visitor),
-                                             lib::forward<Values>(values)...))
-        };
-
-        template <typename Visitor>
-        struct value_visitor {
-          Visitor &&visitor_;
-
-          template <typename... Alts>
-          inline constexpr DECLTYPE_AUTO operator()(Alts &&... alts) const
-            DECLTYPE_AUTO_RETURN(
-                visit_exhaustiveness_check<
-                    Visitor,
-                    decltype((lib::forward<Alts>(alts).value))...>::
-                    invoke(lib::forward<Visitor>(visitor_),
-                           lib::forward<Alts>(alts).value...))
-        };
-
-        template <typename Visitor>
-        inline static constexpr AUTO make_value_visitor(Visitor &&visitor)
-          AUTO_RETURN(value_visitor<Visitor>{lib::forward<Visitor>(visitor)})
-
-        public:
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt(Visitor &&visitor,
-                                                        Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(alt::visit_alt(lib::forward<Visitor>(visitor),
-                                              lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index,
-                                                           Visitor &&visitor,
-                                                           Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              alt::visit_alt_at(index,
-                                lib::forward<Visitor>(visitor),
-                                lib::forward<Vs>(vs).impl_...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value(Visitor &&visitor,
-                                                          Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt(make_value_visitor(lib::forward<Visitor>(visitor)),
-                        lib::forward<Vs>(vs)...))
-
-        template <typename Visitor, typename... Vs>
-        inline static constexpr DECLTYPE_AUTO visit_value_at(std::size_t index,
-                                                             Visitor &&visitor,
-                                                             Vs &&... vs)
-          DECLTYPE_AUTO_RETURN(
-              visit_alt_at(index,
-                           make_value_visitor(lib::forward<Visitor>(visitor)),
-                           lib::forward<Vs>(vs)...))
-      };
-
-    }  // namespace visitation
-
-    template <std::size_t Index, typename T>
-    struct alt {
-      using value_type = T;
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-      template <typename... Args>
-      inline explicit constexpr alt(in_place_t, Args &&... args)
-          : value(lib::forward<Args>(args)...) {}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-      T value;
-    };
-
-    template <Trait DestructibleTrait, std::size_t Index, typename... Ts>
-    union recursive_union;
-
-    template <Trait DestructibleTrait, std::size_t Index>
-    union recursive_union<DestructibleTrait, Index> {};
-
-#define MPARK_VARIANT_RECURSIVE_UNION(destructible_trait, destructor)      \
-  template <std::size_t Index, typename T, typename... Ts>                 \
-  union recursive_union<destructible_trait, Index, T, Ts...> {             \
-    public:                                                                \
-    inline explicit constexpr recursive_union(valueless_t) noexcept        \
-        : dummy_{} {}                                                      \
-                                                                           \
-    template <typename... Args>                                            \
-    inline explicit constexpr recursive_union(in_place_index_t<0>,         \
-                                              Args &&... args)             \
-        : head_(in_place_t{}, lib::forward<Args>(args)...) {}              \
-                                                                           \
-    template <std::size_t I, typename... Args>                             \
-    inline explicit constexpr recursive_union(in_place_index_t<I>,         \
-                                              Args &&... args)             \
-        : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...) {} \
-                                                                           \
-    recursive_union(const recursive_union &) = default;                    \
-    recursive_union(recursive_union &&) = default;                         \
-                                                                           \
-    destructor                                                             \
-                                                                           \
-    recursive_union &operator=(const recursive_union &) = default;         \
-    recursive_union &operator=(recursive_union &&) = default;              \
-                                                                           \
-    private:                                                               \
-    char dummy_;                                                           \
-    alt<Index, T> head_;                                                   \
-    recursive_union<destructible_trait, Index + 1, Ts...> tail_;           \
-                                                                           \
-    friend struct access::recursive_union;                                 \
-  }
-
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::TriviallyAvailable,
-                                  ~recursive_union() = default;);
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Available,
-                                  ~recursive_union() {});
-    MPARK_VARIANT_RECURSIVE_UNION(Trait::Unavailable,
-                                  ~recursive_union() = delete;);
-
-#undef MPARK_VARIANT_RECURSIVE_UNION
-
-    using index_t = unsigned int;
-
-    template <Trait DestructibleTrait, typename... Ts>
-    class base {
-      public:
-      inline explicit constexpr base(valueless_t tag) noexcept
-          : data_(tag), index_(static_cast<index_t>(-1)) {}
-
-      template <std::size_t I, typename... Args>
-      inline explicit constexpr base(in_place_index_t<I>, Args &&... args)
-          : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...),
-            index_(I) {}
-
-      inline constexpr bool valueless_by_exception() const noexcept {
-        return index_ == static_cast<index_t>(-1);
-      }
-
-      inline constexpr std::size_t index() const noexcept {
-        return valueless_by_exception() ? variant_npos : index_;
-      }
-
-      protected:
-      using data_t = recursive_union<DestructibleTrait, 0, Ts...>;
-
-      friend inline constexpr base &as_base(base &b) { return b; }
-      friend inline constexpr const base &as_base(const base &b) { return b; }
-      friend inline constexpr base &&as_base(base &&b) { return lib::move(b); }
-      friend inline constexpr const base &&as_base(const base &&b) { return lib::move(b); }
-
-      friend inline constexpr data_t &data(base &b) { return b.data_; }
-      friend inline constexpr const data_t &data(const base &b) { return b.data_; }
-      friend inline constexpr data_t &&data(base &&b) { return lib::move(b).data_; }
-      friend inline constexpr const data_t &&data(const base &&b) { return lib::move(b).data_; }
-
-      inline static constexpr std::size_t size() { return sizeof...(Ts); }
-
-      data_t data_;
-      index_t index_;
-
-      friend struct access::base;
-      friend struct visitation::base;
-    };
-
-    struct dtor {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4100)
-#endif
-      template <typename Alt>
-      inline void operator()(Alt &alt) const noexcept { alt.~Alt(); }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-    };
-
-#if !defined(_MSC_VER) || _MSC_VER >= 1910
-#define MPARK_INHERITING_CTOR(type, base) using base::base;
-#else
-#define MPARK_INHERITING_CTOR(type, base)         \
-  template <typename... Args>                     \
-  inline explicit constexpr type(Args &&... args) \
-      : base(lib::forward<Args>(args)...) {}
-#endif
-
-    template <typename Traits, Trait = Traits::destructible_trait>
-    class destructor;
-
-#define MPARK_VARIANT_DESTRUCTOR(destructible_trait, definition, destroy) \
-  template <typename... Ts>                                               \
-  class destructor<traits<Ts...>, destructible_trait>                     \
-      : public base<destructible_trait, Ts...> {                          \
-    using super = base<destructible_trait, Ts...>;                        \
-                                                                          \
-    public:                                                               \
-    MPARK_INHERITING_CTOR(destructor, super)                              \
-    using super::operator=;                                               \
-                                                                          \
-    destructor(const destructor &) = default;                             \
-    destructor(destructor &&) = default;                                  \
-    definition                                                            \
-    destructor &operator=(const destructor &) = default;                  \
-    destructor &operator=(destructor &&) = default;                       \
-                                                                          \
-    protected:                                                            \
-    destroy                                                               \
-  }
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::TriviallyAvailable,
-        ~destructor() = default;,
-        inline void destroy() noexcept {
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Available,
-        ~destructor() { destroy(); },
-        inline void destroy() noexcept {
-          if (!this->valueless_by_exception()) {
-            visitation::alt::visit_alt(dtor{}, *this);
-          }
-          this->index_ = static_cast<index_t>(-1);
-        });
-
-    MPARK_VARIANT_DESTRUCTOR(
-        Trait::Unavailable,
-        ~destructor() = delete;,
-        inline void destroy() noexcept = delete;);
-
-#undef MPARK_VARIANT_DESTRUCTOR
-
-    template <typename Traits>
-    class constructor : public destructor<Traits> {
-      using super = destructor<Traits>;
-
-      public:
-      MPARK_INHERITING_CTOR(constructor, super)
-      using super::operator=;
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct ctor {
-        template <typename LhsAlt, typename RhsAlt>
-        inline void operator()(LhsAlt &lhs_alt, RhsAlt &&rhs_alt) const {
-          constructor::construct_alt(lhs_alt,
-                                     lib::forward<RhsAlt>(rhs_alt).value);
-        }
-      };
-#endif
-
-      template <std::size_t I, typename T, typename... Args>
-      inline static T &construct_alt(alt<I, T> &a, Args &&... args) {
-        auto *result = ::new (static_cast<void *>(lib::addressof(a)))
-            alt<I, T>(in_place_t{}, lib::forward<Args>(args)...);
-        return result->value;
-      }
-
-      template <typename Rhs>
-      inline static void generic_construct(constructor &lhs, Rhs &&rhs) {
-        lhs.destroy();
-        if (!rhs.valueless_by_exception()) {
-          visitation::alt::visit_alt_at(
-              rhs.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [](auto &lhs_alt, auto &&rhs_alt) {
-                constructor::construct_alt(
-                    lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value);
-              }
-#else
-              ctor{}
-#endif
-              ,
-              lhs,
-              lib::forward<Rhs>(rhs));
-          lhs.index_ = rhs.index_;
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_constructible_trait>
-    class move_constructor;
-
-#define MPARK_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class move_constructor<traits<Ts...>, move_constructible_trait>            \
-      : public constructor<traits<Ts...>> {                                  \
-    using super = constructor<traits<Ts...>>;                                \
-                                                                             \
-    public:                                                                  \
-    MPARK_INHERITING_CTOR(move_constructor, super)                           \
-    using super::operator=;                                                  \
-                                                                             \
-    move_constructor(const move_constructor &) = default;                    \
-    definition                                                               \
-    ~move_constructor() = default;                                           \
-    move_constructor &operator=(const move_constructor &) = default;         \
-    move_constructor &operator=(move_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        move_constructor(move_constructor &&that) = default;);
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Available,
-        move_constructor(move_constructor &&that) noexcept(
-            lib::all<std::is_nothrow_move_constructible<Ts>::value...>::value)
-            : move_constructor(valueless_t{}) {
-          this->generic_construct(*this, lib::move(that));
-        });
-
-    MPARK_VARIANT_MOVE_CONSTRUCTOR(
-        Trait::Unavailable,
-        move_constructor(move_constructor &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_CONSTRUCTOR
-
-    template <typename Traits, Trait = Traits::copy_constructible_trait>
-    class copy_constructor;
-
-#define MPARK_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, definition) \
-  template <typename... Ts>                                                  \
-  class copy_constructor<traits<Ts...>, copy_constructible_trait>            \
-      : public move_constructor<traits<Ts...>> {                             \
-    using super = move_constructor<traits<Ts...>>;                           \
-                                                                             \
-    public:                                                                  \
-    MPARK_INHERITING_CTOR(copy_constructor, super)                           \
-    using super::operator=;                                                  \
-                                                                             \
-    definition                                                               \
-    copy_constructor(copy_constructor &&) = default;                         \
-    ~copy_constructor() = default;                                           \
-    copy_constructor &operator=(const copy_constructor &) = default;         \
-    copy_constructor &operator=(copy_constructor &&) = default;              \
-  }
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::TriviallyAvailable,
-        copy_constructor(const copy_constructor &that) = default;);
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Available,
-        copy_constructor(const copy_constructor &that)
-            : copy_constructor(valueless_t{}) {
-          this->generic_construct(*this, that);
-        });
-
-    MPARK_VARIANT_COPY_CONSTRUCTOR(
-        Trait::Unavailable,
-        copy_constructor(const copy_constructor &) = delete;);
-
-#undef MPARK_VARIANT_COPY_CONSTRUCTOR
-
-    template <typename Traits>
-    class assignment : public copy_constructor<Traits> {
-      using super = copy_constructor<Traits>;
-
-      public:
-      MPARK_INHERITING_CTOR(assignment, super)
-      using super::operator=;
-
-      template <std::size_t I, typename... Args>
-      inline /* auto & */ auto emplace(Args &&... args)
-          -> decltype(this->construct_alt(access::base::get_alt<I>(*this),
-                                          lib::forward<Args>(args)...)) {
-        this->destroy();
-        auto &result = this->construct_alt(access::base::get_alt<I>(*this),
-                                           lib::forward<Args>(args)...);
-        this->index_ = I;
-        return result;
-      }
-
-      protected:
-#ifndef MPARK_GENERIC_LAMBDAS
-      template <typename That>
-      struct assigner {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &&that_alt) const {
-          self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value);
-        }
-        assignment *self;
-      };
-#endif
-
-      template <std::size_t I, typename T, typename Arg>
-      inline void assign_alt(alt<I, T> &a, Arg &&arg) {
-        if (this->index() == I) {
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4244)
-#endif
-          a.value = lib::forward<Arg>(arg);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-        } else {
-          struct {
-            void operator()(std::true_type) const {
-              this_->emplace<I>(lib::forward<Arg>(arg_));
-            }
-            void operator()(std::false_type) const {
-              this_->emplace<I>(T(lib::forward<Arg>(arg_)));
-            }
-            assignment *this_;
-            Arg &&arg_;
-          } impl{this, lib::forward<Arg>(arg)};
-          impl(lib::bool_constant<
-                   std::is_nothrow_constructible<T, Arg>::value ||
-                   !std::is_nothrow_move_constructible<T>::value>{});
-        }
-      }
-
-      template <typename That>
-      inline void generic_assign(That &&that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (that.valueless_by_exception()) {
-          this->destroy();
-        } else {
-          visitation::alt::visit_alt_at(
-              that.index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-              [this](auto &this_alt, auto &&that_alt) {
-                this->assign_alt(
-                    this_alt, lib::forward<decltype(that_alt)>(that_alt).value);
-              }
-#else
-              assigner<That>{this}
-#endif
-              ,
-              *this,
-              lib::forward<That>(that));
-        }
-      }
-    };
-
-    template <typename Traits, Trait = Traits::move_assignable_trait>
-    class move_assignment;
-
-#define MPARK_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class move_assignment<traits<Ts...>, move_assignable_trait>            \
-      : public assignment<traits<Ts...>> {                               \
-    using super = assignment<traits<Ts...>>;                             \
-                                                                         \
-    public:                                                              \
-    MPARK_INHERITING_CTOR(move_assignment, super)                        \
-    using super::operator=;                                              \
-                                                                         \
-    move_assignment(const move_assignment &) = default;                  \
-    move_assignment(move_assignment &&) = default;                       \
-    ~move_assignment() = default;                                        \
-    move_assignment &operator=(const move_assignment &) = default;       \
-    definition                                                           \
-  }
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        move_assignment &operator=(move_assignment &&that) = default;);
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Available,
-        move_assignment &
-        operator=(move_assignment &&that) noexcept(
-            lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                      std::is_nothrow_move_assignable<Ts>::value)...>::value) {
-          this->generic_assign(lib::move(that));
-          return *this;
-        });
-
-    MPARK_VARIANT_MOVE_ASSIGNMENT(
-        Trait::Unavailable,
-        move_assignment &operator=(move_assignment &&) = delete;);
-
-#undef MPARK_VARIANT_MOVE_ASSIGNMENT
-
-    template <typename Traits, Trait = Traits::copy_assignable_trait>
-    class copy_assignment;
-
-#define MPARK_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, definition) \
-  template <typename... Ts>                                              \
-  class copy_assignment<traits<Ts...>, copy_assignable_trait>            \
-      : public move_assignment<traits<Ts...>> {                          \
-    using super = move_assignment<traits<Ts...>>;                        \
-                                                                         \
-    public:                                                              \
-    MPARK_INHERITING_CTOR(copy_assignment, super)                        \
-    using super::operator=;                                              \
-                                                                         \
-    copy_assignment(const copy_assignment &) = default;                  \
-    copy_assignment(copy_assignment &&) = default;                       \
-    ~copy_assignment() = default;                                        \
-    definition                                                           \
-    copy_assignment &operator=(copy_assignment &&) = default;            \
-  }
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::TriviallyAvailable,
-        copy_assignment &operator=(const copy_assignment &that) = default;);
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Available,
-        copy_assignment &operator=(const copy_assignment &that) {
-          this->generic_assign(that);
-          return *this;
-        });
-
-    MPARK_VARIANT_COPY_ASSIGNMENT(
-        Trait::Unavailable,
-        copy_assignment &operator=(const copy_assignment &) = delete;);
-
-#undef MPARK_VARIANT_COPY_ASSIGNMENT
-
-    template <typename... Ts>
-    class impl : public copy_assignment<traits<Ts...>> {
-      using super = copy_assignment<traits<Ts...>>;
-
-      public:
-      MPARK_INHERITING_CTOR(impl, super)
-      using super::operator=;
-
-      template <std::size_t I, typename Arg>
-      inline void assign(Arg &&arg) {
-        this->assign_alt(access::base::get_alt<I>(*this),
-                         lib::forward<Arg>(arg));
-      }
-
-      inline void swap(impl &that) {
-        if (this->valueless_by_exception() && that.valueless_by_exception()) {
-          // do nothing.
-        } else if (this->index() == that.index()) {
-          visitation::alt::visit_alt_at(this->index(),
-#ifdef MPARK_GENERIC_LAMBDAS
-                                        [](auto &this_alt, auto &that_alt) {
-                                          using std::swap;
-                                          swap(this_alt.value,
-                                               that_alt.value);
-                                        }
-#else
-                                        swapper{}
-#endif
-                                        ,
-                                        *this,
-                                        that);
-        } else {
-          impl *lhs = this;
-          impl *rhs = lib::addressof(that);
-          if (lhs->move_nothrow() && !rhs->move_nothrow()) {
-            std::swap(lhs, rhs);
-          }
-          impl tmp(lib::move(*rhs));
-#ifdef MPARK_EXCEPTIONS
-          // EXTENSION: When the move construction of `lhs` into `rhs` throws
-          // and `tmp` is nothrow move constructible then we move `tmp` back
-          // into `rhs` and provide the strong exception safety guarantee.
-          try {
-            this->generic_construct(*rhs, lib::move(*lhs));
-          } catch (...) {
-            if (tmp.move_nothrow()) {
-              this->generic_construct(*rhs, lib::move(tmp));
-            }
-            throw;
-          }
-#else
-          this->generic_construct(*rhs, lib::move(*lhs));
-#endif
-          this->generic_construct(*lhs, lib::move(tmp));
-        }
-      }
-
-      private:
-#ifndef MPARK_GENERIC_LAMBDAS
-      struct swapper {
-        template <typename ThisAlt, typename ThatAlt>
-        inline void operator()(ThisAlt &this_alt, ThatAlt &that_alt) const {
-          using std::swap;
-          swap(this_alt.value, that_alt.value);
-        }
-      };
-#endif
-
-      inline constexpr bool move_nothrow() const {
-        return this->valueless_by_exception() ||
-               lib::array<bool, sizeof...(Ts)>{
-                   {std::is_nothrow_move_constructible<Ts>::value...}
-               }[this->index()];
-      }
-    };
-
-#undef MPARK_INHERITING_CTOR
-
-    template <std::size_t I, typename T>
-    struct overload_leaf {
-      using F = lib::size_constant<I> (*)(T);
-      operator F() const { return nullptr; }
-    };
-
-    template <typename... Ts>
-    struct overload_impl {
-      private:
-      template <typename>
-      struct impl;
-
-      template <std::size_t... Is>
-      struct impl<lib::index_sequence<Is...>> : overload_leaf<Is, Ts>... {};
-
-      public:
-      using type = impl<lib::index_sequence_for<Ts...>>;
-    };
-
-    template <typename... Ts>
-    using overload = typename overload_impl<Ts...>::type;
-
-    template <typename T, typename... Ts>
-    using best_match = lib::invoke_result_t<overload<Ts...>, T &&>;
-
-    template <typename T>
-    struct is_in_place_index : std::false_type {};
-
-    template <std::size_t I>
-    struct is_in_place_index<in_place_index_t<I>> : std::true_type {};
-
-    template <typename T>
-    struct is_in_place_type : std::false_type {};
-
-    template <typename T>
-    struct is_in_place_type<in_place_type_t<T>> : std::true_type {};
-
-  }  // detail
-
-  template <typename... Ts>
-  class variant {
-    static_assert(0 < sizeof...(Ts),
-                  "variant must consist of at least one alternative.");
-
-    static_assert(lib::all<!std::is_array<Ts>::value...>::value,
-                  "variant can not have an array type as an alternative.");
-
-    static_assert(lib::all<!std::is_reference<Ts>::value...>::value,
-                  "variant can not have a reference type as an alternative.");
-
-    static_assert(lib::all<!std::is_void<Ts>::value...>::value,
-                  "variant can not have a void type as an alternative.");
-
-    public:
-    template <
-        typename Front = lib::type_pack_element_t<0, Ts...>,
-        lib::enable_if_t<std::is_default_constructible<Front>::value, int> = 0>
-    inline constexpr variant() noexcept(
-        std::is_nothrow_default_constructible<Front>::value)
-        : impl_(in_place_index_t<0>{}) {}
-
-    variant(const variant &) = default;
-    variant(variant &&) = default;
-
-    template <
-        typename Arg,
-        typename Decayed = lib::decay_t<Arg>,
-        lib::enable_if_t<!std::is_same<Decayed, variant>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_index<Decayed>::value, int> = 0,
-        lib::enable_if_t<!detail::is_in_place_type<Decayed>::value, int> = 0,
-        std::size_t I = detail::best_match<Arg, Ts...>::value,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Arg>::value, int> = 0>
-    inline constexpr variant(Arg &&arg) noexcept(
-        std::is_nothrow_constructible<T, Arg>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) {}
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_index_t<I>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        Args &&... args) noexcept(std::is_nothrow_constructible<T,
-                                                                Args...>::value)
-        : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) {}
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline explicit constexpr variant(
-        in_place_type_t<T>,
-        std::initializer_list<Up> il,
-        Args &&... args) noexcept(std::
-                                      is_nothrow_constructible<
-                                          T,
-                                          std::initializer_list<Up> &,
-                                          Args...>::value)
-        : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) {}
-
-    ~variant() = default;
-
-    variant &operator=(const variant &) = default;
-    variant &operator=(variant &&) = default;
-
-    template <typename Arg,
-              lib::enable_if_t<!std::is_same<lib::decay_t<Arg>, variant>::value,
-                               int> = 0,
-              std::size_t I = detail::best_match<Arg, Ts...>::value,
-              typename T = lib::type_pack_element_t<I, Ts...>,
-              lib::enable_if_t<(std::is_assignable<T &, Arg>::value &&
-                                std::is_constructible<T, Arg>::value),
-                               int> = 0>
-    inline variant &operator=(Arg &&arg) noexcept(
-        (std::is_nothrow_assignable<T &, Arg>::value &&
-         std::is_nothrow_constructible<T, Arg>::value)) {
-      impl_.template assign<I>(lib::forward<Arg>(arg));
-      return *this;
-    }
-
-    template <
-        std::size_t I,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        std::size_t I,
-        typename Up,
-        typename... Args,
-        typename T = lib::type_pack_element_t<I, Ts...>,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T, Args...>::value, int> = 0>
-    inline T &emplace(Args &&... args) {
-      return impl_.template emplace<I>(lib::forward<Args>(args)...);
-    }
-
-    template <
-        typename T,
-        typename Up,
-        typename... Args,
-        std::size_t I = detail::find_index_sfinae<T, Ts...>::value,
-        lib::enable_if_t<std::is_constructible<T,
-                                               std::initializer_list<Up> &,
-                                               Args...>::value,
-                         int> = 0>
-    inline T &emplace(std::initializer_list<Up> il, Args &&... args) {
-      return impl_.template emplace<I>(il, lib::forward<Args>(args)...);
-    }
-
-    inline constexpr bool valueless_by_exception() const noexcept {
-      return impl_.valueless_by_exception();
-    }
-
-    inline constexpr std::size_t index() const noexcept {
-      return impl_.index();
-    }
-
-    template <bool Dummy = true,
-              lib::enable_if_t<
-                  lib::all<Dummy,
-                           (lib::dependent_type<std::is_move_constructible<Ts>,
-                                                Dummy>::value &&
-                            lib::dependent_type<lib::is_swappable<Ts>,
-                                                Dummy>::value)...>::value,
-                  int> = 0>
-    inline void swap(variant &that) noexcept(
-        lib::all<(std::is_nothrow_move_constructible<Ts>::value &&
-                  lib::is_nothrow_swappable<Ts>::value)...>::value) {
-      impl_.swap(that.impl_);
-    }
-
-    private:
-    detail::impl<Ts...> impl_;
-
-    friend struct detail::access::variant;
-    friend struct detail::visitation::variant;
-  };
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return v.index() == I;
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr bool holds_alternative(const variant<Ts...> &v) noexcept {
-    return holds_alternative<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-    template <std::size_t I, typename V>
-    struct generic_get_impl {
-      constexpr generic_get_impl(int) noexcept {}
-
-      constexpr AUTO_REFREF operator()(V &&v) const
-        AUTO_REFREF_RETURN(
-            access::variant::get_alt<I>(lib::forward<V>(v)).value)
-    };
-
-    template <std::size_t I, typename V>
-    inline constexpr AUTO_REFREF generic_get(V &&v)
-      AUTO_REFREF_RETURN(generic_get_impl<I, V>(
-          holds_alternative<I>(v) ? 0 : (throw_bad_variant_access(), 0))(
-          lib::forward<V>(v)))
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &get(
-      variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr variant_alternative_t<I, variant<Ts...>> &&get(
-      variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &get(
-      const variant<Ts...> &v) {
-    return detail::generic_get<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr const variant_alternative_t<I, variant<Ts...>> &&get(
-      const variant<Ts...> &&v) {
-    return detail::generic_get<I>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &get(variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr T &&get(variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &get(const variant<Ts...> &v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr const T &&get(const variant<Ts...> &&v) {
-    return get<detail::find_index_checked<T, Ts...>::value>(lib::move(v));
-  }
-
-  namespace detail {
-
-    template <std::size_t I, typename V>
-    inline constexpr /* auto * */ AUTO generic_get_if(V *v) noexcept
-      AUTO_RETURN(v && holds_alternative<I>(*v)
-                      ? lib::addressof(access::variant::get_alt<I>(*v).value)
-                      : nullptr)
-
-  }  // namespace detail
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<variant_alternative_t<I, variant<Ts...>>>
-  get_if(variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <std::size_t I, typename... Ts>
-  inline constexpr lib::add_pointer_t<
-      const variant_alternative_t<I, variant<Ts...>>>
-  get_if(const variant<Ts...> *v) noexcept {
-    return detail::generic_get_if<I>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<T>
-  get_if(variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  template <typename T, typename... Ts>
-  inline constexpr lib::add_pointer_t<const T>
-  get_if(const variant<Ts...> *v) noexcept {
-    return get_if<detail::find_index_checked<T, Ts...>::value>(v);
-  }
-
-  namespace detail {
-    template <typename RelOp>
-    struct convert_to_bool {
-      template <typename Lhs, typename Rhs>
-      inline constexpr bool operator()(Lhs &&lhs, Rhs &&rhs) const {
-        static_assert(std::is_convertible<lib::invoke_result_t<RelOp, Lhs, Rhs>,
-                                          bool>::value,
-                      "relational operators must return a type"
-                      " implicitly convertible to bool");
-        return lib::invoke(
-            RelOp{}, lib::forward<Lhs>(lhs), lib::forward<Rhs>(rhs));
-      }
-    };
-  }  // namespace detail
-
-  template <typename... Ts>
-  inline constexpr bool operator==(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using equal_to = detail::convert_to_bool<lib::equal_to>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    return variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs);
-#else
-    return lhs.index() == rhs.index() &&
-           (lhs.valueless_by_exception() ||
-            variant::visit_value_at(lhs.index(), equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator!=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using not_equal_to = detail::convert_to_bool<lib::not_equal_to>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.index() != rhs.index()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    return variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs);
-#else
-    return lhs.index() != rhs.index() ||
-           (!lhs.valueless_by_exception() &&
-            variant::visit_value_at(lhs.index(), not_equal_to{}, lhs, rhs));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using less = detail::convert_to_bool<lib::less>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.valueless_by_exception()) return true;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less{}, lhs, rhs);
-#else
-    return !rhs.valueless_by_exception() &&
-           (lhs.valueless_by_exception() || lhs.index() < rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), less{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>(const variant<Ts...> &lhs,
-                                  const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using greater = detail::convert_to_bool<lib::greater>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return false;
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater{}, lhs, rhs);
-#else
-    return !lhs.valueless_by_exception() &&
-           (rhs.valueless_by_exception() || lhs.index() > rhs.index() ||
-            (lhs.index() == rhs.index() &&
-             variant::visit_value_at(lhs.index(), greater{}, lhs, rhs)));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator<=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using less_equal = detail::convert_to_bool<lib::less_equal>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (lhs.valueless_by_exception()) return true;
-    if (rhs.valueless_by_exception()) return false;
-    if (lhs.index() < rhs.index()) return true;
-    if (lhs.index() > rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs);
-#else
-    return lhs.valueless_by_exception() ||
-           (!rhs.valueless_by_exception() &&
-            (lhs.index() < rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(lhs.index(), less_equal{}, lhs, rhs))));
-#endif
-  }
-
-  template <typename... Ts>
-  inline constexpr bool operator>=(const variant<Ts...> &lhs,
-                                   const variant<Ts...> &rhs) {
-    using detail::visitation::variant;
-    using greater_equal = detail::convert_to_bool<lib::greater_equal>;
-#ifdef MPARK_CPP14_CONSTEXPR
-    if (rhs.valueless_by_exception()) return true;
-    if (lhs.valueless_by_exception()) return false;
-    if (lhs.index() > rhs.index()) return true;
-    if (lhs.index() < rhs.index()) return false;
-    return variant::visit_value_at(lhs.index(), greater_equal{}, lhs, rhs);
-#else
-    return rhs.valueless_by_exception() ||
-           (!lhs.valueless_by_exception() &&
-            (lhs.index() > rhs.index() ||
-             (lhs.index() == rhs.index() &&
-              variant::visit_value_at(
-                  lhs.index(), greater_equal{}, lhs, rhs))));
-#endif
-  }
-
-  struct monostate {};
-
-  inline constexpr bool operator<(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator>(monostate, monostate) noexcept {
-    return false;
-  }
-
-  inline constexpr bool operator<=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator>=(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator==(monostate, monostate) noexcept {
-    return true;
-  }
-
-  inline constexpr bool operator!=(monostate, monostate) noexcept {
-    return false;
-  }
-
-#ifdef MPARK_CPP14_CONSTEXPR
-  namespace detail {
-
-    inline constexpr bool all(std::initializer_list<bool> bs) {
-      for (bool b : bs) {
-        if (!b) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
-    return (detail::all({!vs.valueless_by_exception()...})
-                ? (void)0
-                : throw_bad_variant_access()),
-           detail::visitation::variant::visit_value(
-               lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
-  }
-#else
-  namespace detail {
-
-    template <std::size_t N>
-    inline constexpr bool all_impl(const lib::array<bool, N> &bs,
-                                   std::size_t idx) {
-      return idx >= N || (bs[idx] && all_impl(bs, idx + 1));
-    }
-
-    template <std::size_t N>
-    inline constexpr bool all(const lib::array<bool, N> &bs) {
-      return all_impl(bs, 0);
-    }
-
-  }  // namespace detail
-
-  template <typename Visitor, typename... Vs>
-  inline constexpr DECLTYPE_AUTO visit(Visitor &&visitor, Vs &&... vs)
-    DECLTYPE_AUTO_RETURN(
-        (detail::all(
-             lib::array<bool, sizeof...(Vs)>{{!vs.valueless_by_exception()...}})
-             ? (void)0
-             : throw_bad_variant_access()),
-        detail::visitation::variant::visit_value(lib::forward<Visitor>(visitor),
-                                                 lib::forward<Vs>(vs)...))
-#endif
-
-  template <typename... Ts>
-  inline auto swap(variant<Ts...> &lhs,
-                   variant<Ts...> &rhs) noexcept(noexcept(lhs.swap(rhs)))
-      -> decltype(lhs.swap(rhs)) {
-    lhs.swap(rhs);
-  }
-
-  namespace detail {
-
-    template <typename T, typename...>
-    using enabled_type = T;
-
-    namespace hash {
-
-      template <typename H, typename K>
-      constexpr bool meets_requirements() noexcept {
-        return std::is_copy_constructible<H>::value &&
-               std::is_move_constructible<H>::value &&
-               lib::is_invocable_r<std::size_t, H, const K &>::value;
-      }
-
-      template <typename K>
-      constexpr bool is_enabled() noexcept {
-        using H = std::hash<K>;
-        return meets_requirements<H, K>() &&
-               std::is_default_constructible<H>::value &&
-               std::is_copy_assignable<H>::value &&
-               std::is_move_assignable<H>::value;
-      }
-
-    }  // namespace hash
-
-  }  // namespace detail
-
-#undef AUTO
-#undef AUTO_RETURN
-
-#undef AUTO_REFREF
-#undef AUTO_REFREF_RETURN
-
-#undef DECLTYPE_AUTO
-#undef DECLTYPE_AUTO_RETURN
-
-}  // namespace mpark
-
-namespace std {
-
-  template <typename... Ts>
-  struct hash<mpark::detail::enabled_type<
-      mpark::variant<Ts...>,
-      mpark::lib::enable_if_t<mpark::lib::all<mpark::detail::hash::is_enabled<
-          mpark::lib::remove_const_t<Ts>>()...>::value>>> {
-    using argument_type = mpark::variant<Ts...>;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &v) const {
-      using mpark::detail::visitation::variant;
-      std::size_t result =
-          v.valueless_by_exception()
-              ? 299792458  // Random value chosen by the universe upon creation
-              : variant::visit_alt(
-#ifdef MPARK_GENERIC_LAMBDAS
-                    [](const auto &alt) {
-                      using alt_type = mpark::lib::decay_t<decltype(alt)>;
-                      using value_type = mpark::lib::remove_const_t<
-                          typename alt_type::value_type>;
-                      return hash<value_type>{}(alt.value);
-                    }
-#else
-                    hasher{}
-#endif
-                    ,
-                    v);
-      return hash_combine(result, hash<std::size_t>{}(v.index()));
-    }
-
-    private:
-#ifndef MPARK_GENERIC_LAMBDAS
-    struct hasher {
-      template <typename Alt>
-      inline std::size_t operator()(const Alt &alt) const {
-        using alt_type = mpark::lib::decay_t<Alt>;
-        using value_type =
-            mpark::lib::remove_const_t<typename alt_type::value_type>;
-        return hash<value_type>{}(alt.value);
-      }
-    };
-#endif
-
-    static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) {
-      return lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
-    }
-  };
-
-  template <>
-  struct hash<mpark::monostate> {
-    using argument_type = mpark::monostate;
-    using result_type = std::size_t;
-
-    inline result_type operator()(const argument_type &) const noexcept {
-      return 66740831;  // return a fundamentally attractive random value.
-    }
-  };
-
-}  // namespace std
-
-#endif  // MPARK_VARIANT_HPP

+ 0 - 23
src/external/tiny/LICENSE.md

@@ -1,23 +0,0 @@
-Boost Software License - Version 0.1 - 23 March 2019
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.

+ 0 - 159
src/external/tiny/optional.h

@@ -1,159 +0,0 @@
-// Tiny Optional
-//
-// Copyright Alexander Radkov, 2019
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
-//
-
-#pragma once
-
-namespace tiny
-{
-    struct nullopt_t
-    {
-        struct _Tag {};
-        constexpr explicit nullopt_t(_Tag) {}
-    };
-    inline constexpr nullopt_t none    { nullopt_t::_Tag{} }; // matches boost::none
-    inline constexpr nullopt_t nullopt { nullopt_t::_Tag{} }; // matches std::nullopt
-
-    template<class _Ty>
-    class optional
-    {
-    private:
-        bool      _assigned;
-        _Ty       _value;
-
-        void reset()          { _assigned = false; }
-        void assert_value() { if (!has_value())   throw std::runtime_error{ "Bad optional access!" }; }
-
-    public:
-        constexpr optional() noexcept
-            : _assigned(false)
-        { }
-
-        constexpr optional(nullopt_t) noexcept
-            : _assigned(false)
-        { }
-
-        constexpr optional(_Ty value) noexcept
-            : _assigned(true)
-            , _value(value)
-        { }
-
-        constexpr explicit operator bool() const noexcept { return _assigned; }
-        constexpr bool has_value()         const noexcept { return _assigned; }
-        constexpr const _Ty * operator->() const          { return std:: addressof(_value); }
-        constexpr       _Ty * operator->()                { return std:: addressof(_value); }
-        constexpr const _Ty& operator*()   const &        { return _value; }
-        constexpr       _Ty& operator*()         &        { return _value; }
-        constexpr       _Ty&& operator*()        &&       { return std:: move(_value); }
-        constexpr const _Ty&& operator*()  const &&       { return std:: move(_value); }
-        constexpr const _Ty&  value()      const &        { assert_value();  return _value; }
-        constexpr       _Ty&  value()            &        { assert_value();  return _value; }
-        constexpr       _Ty&& value()            &&       { assert_value();  return std:: move(_value); }
-        constexpr const _Ty&& value()      const &&       { assert_value();  return std:: move(_value); }
-
-        optional & operator=(const nullopt_t& _Right)
-        {
-            reset();
-            return (*this);
-        }
-
-        template<class _Ty2 = _Ty>
-        optional & operator=(_Ty2&& _Right)
-        {
-            _value = std:: forward<_Ty2>(_Right);
-            _assigned = true;
-            return (*this);
-        }
-
-        template<class _Ty2>
-        optional & operator=(const optional<_Ty2>& _Right)
-        {
-            if (_Right)
-            {
-                _value = *_Right;
-                _assigned = true;
-            }
-            else
-            {
-                reset();
-            }
-
-            return (*this);
-        }
-    };
-
-    template<class _Ty>
-    constexpr bool operator==(const optional<_Ty>& _Left, nullopt_t) noexcept
-    {
-        return (!_Left.has_value());
-    }
-    template<class _Ty>
-    constexpr bool operator==(nullopt_t, const optional<_Ty>& _Right) noexcept
-    {
-        return (!_Right.has_value());
-    }
-
-    template<class _Ty>
-    constexpr bool operator!=(const optional<_Ty>& _Left, nullopt_t) noexcept
-    {
-        return (_Left.has_value());
-    }
-
-    template<class _Ty>
-    constexpr bool operator!=(nullopt_t, const optional<_Ty>& _Right) noexcept
-    {
-        return (_Right.has_value());
-    }
-
-    template<class _Ty>
-    constexpr bool operator<(const optional<_Ty>&, nullopt_t) noexcept
-    {
-        return (false);
-    }
-
-    template<class _Ty>
-    constexpr bool operator<(nullopt_t, const optional<_Ty>& _Right) noexcept
-    {
-        return (_Right.has_value());
-    }
-
-    template<class _Ty>
-    constexpr bool operator<=(const optional<_Ty>& _Left, nullopt_t) noexcept
-    {
-        return (!_Left.has_value());
-    }
-
-    template<class _Ty>
-    constexpr bool operator<=(nullopt_t, const optional<_Ty>&) noexcept
-    {
-        return (true);
-    }
-
-    template<class _Ty>
-    constexpr bool operator>(const optional<_Ty>& _Left, nullopt_t) noexcept
-    {
-        return (_Left.has_value());
-    }
-
-    template<class _Ty>
-    constexpr bool operator>(nullopt_t, const optional<_Ty>&) noexcept
-    {
-        return (false);
-    }
-
-    template<class _Ty>
-    constexpr bool operator>=(const optional<_Ty>&, nullopt_t) noexcept
-    {
-        return (true);
-    }
-
-    template<class _Ty>
-    constexpr bool operator>=(nullopt_t, const optional<_Ty>& _Right) noexcept
-    {
-        return (!_Right.has_value());
-    }
-}