| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | // Copyright 2017 Dolphin Emulator Project | 
					
						
							|  |  |  | // Licensed under GPLv2+ | 
					
						
							|  |  |  | // Refer to the license.txt file included. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 10:47:54 -05:00
										 |  |  | #if __cplusplus >= 201703L && __has_include_next(<variant>) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #include_next <variant> | 
					
						
							|  |  |  | #else | 
					
						
							|  |  |  | // 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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |    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> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     constexpr explicit variant(in_place_type_t<T>, Args&&...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     template <class T, class U, class... Args> | 
					
						
							|  |  |  |     constexpr explicit variant( | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |         in_place_type_t<T>, initializer_list<U>, Args&&...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     template <size_t I, class... Args> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     constexpr explicit variant(in_place_index_t<I>, Args&&...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     template <size_t I, class U, class... Args> | 
					
						
							|  |  |  |     constexpr explicit variant( | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |         in_place_index_t<I>, initializer_list<U>, Args&&...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 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. | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_FULL_VER < 190024210) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #error "MPark.Variant requires C++11 support." | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef __has_builtin | 
					
						
							|  |  |  | #define __has_builtin(x) 0 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #ifndef __has_include | 
					
						
							|  |  |  | #define __has_include(x) 0 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #ifndef __has_feature | 
					
						
							|  |  |  | #define __has_feature(x) 0 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #if __has_builtin(__builtin_addressof) || (defined(__GNUC__) && __GNUC__ >= 7) || defined(_MSC_VER) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #define MPARK_BUILTIN_ADDRESSOF | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #if __has_builtin(__builtin_unreachable) | 
					
						
							|  |  |  | #define MPARK_BUILTIN_UNREACHABLE | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #if __has_builtin(__type_pack_element) | 
					
						
							|  |  |  | #define MPARK_TYPE_PACK_ELEMENT | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304 | 
					
						
							|  |  |  | #define MPARK_CPP14_CONSTEXPR | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) ||                                  \ | 
					
						
							|  |  |  |     (defined(_MSC_VER) && defined(_CPPUNWIND)) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #if !defined(__GLIBCXX__) || __has_include(<codecvt>)  // >= libstdc++-5 | 
					
						
							|  |  |  | #define MPARK_TRIVIALITY_TYPE_TRAITS | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #endif  // MPARK_CONFIG_HPP | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #include "in_place.h" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | // 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 <functional> | 
					
						
							|  |  |  | #include <memory> | 
					
						
							|  |  |  | #include <type_traits> | 
					
						
							|  |  |  | #include <utility> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define RETURN(...)                                                                                \ | 
					
						
							|  |  |  |   noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) { return __VA_ARGS__; } | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 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]; } | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   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> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | inline constexpr remove_reference_t<T>&& move(T&& t) noexcept | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return static_cast<remove_reference_t<T>&&>(t); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #ifdef MPARK_INTEGER_SEQUENCE | 
					
						
							|  |  |  | using std::index_sequence; | 
					
						
							|  |  |  | using std::index_sequence_for; | 
					
						
							|  |  |  | using std::integer_sequence; | 
					
						
							|  |  |  | using std::make_index_sequence; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #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...> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | struct voider : identity<void> | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename... Ts> | 
					
						
							|  |  |  | using void_t = typename voider<Ts...>::type; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace detail | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | namespace swappable | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | using std::swap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename T> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | struct is_swappable | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 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: | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   static constexpr bool value = decltype(test<T>(0))::value; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | using detail::swappable::is_nothrow_swappable; | 
					
						
							|  |  |  | using detail::swappable::is_swappable; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // <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> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | using all = std::is_same<integer_sequence<bool, true, Bs...>, integer_sequence<bool, Bs..., true>>; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #ifdef MPARK_TRIVIALITY_TYPE_TRAITS | 
					
						
							|  |  |  | using std::is_trivially_copy_assignable; | 
					
						
							|  |  |  | using std::is_trivially_copy_constructible; | 
					
						
							|  |  |  | using std::is_trivially_move_assignable; | 
					
						
							|  |  |  | using std::is_trivially_move_constructible; | 
					
						
							|  |  |  | #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>; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | }  // 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__; } | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #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__; } | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #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(); | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #ifdef MPARK_BUILTIN_UNREACHABLE | 
					
						
							|  |  |  |   __builtin_unreachable(); | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #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> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | struct variant_alternative<I, variant<Ts...>> | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   static_assert(I < sizeof...(Ts), "Index out of bounds in std::variant_alternative<>"); | 
					
						
							|  |  |  |   using type = lib::type_pack_element_t<I, Ts...>; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   return IsTriviallyAvailable<T>::value ? | 
					
						
							|  |  |  |              Trait::TriviallyAvailable : | 
					
						
							|  |  |  |              IsAvailable<T>::value ? Trait::Available : Trait::Unavailable; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #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( | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       trait<Ts, lib::is_trivially_copy_constructible, std::is_copy_constructible>()...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   static constexpr Trait move_constructible_trait = common_trait( | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       trait<Ts, lib::is_trivially_move_constructible, std::is_move_constructible>()...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   static constexpr Trait copy_assignable_trait = | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       common_trait(copy_constructible_trait, | 
					
						
							|  |  |  |                    trait<Ts, lib::is_trivially_copy_assignable, std::is_copy_assignable>()...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   static constexpr Trait move_assignable_trait = | 
					
						
							|  |  |  |       common_trait(move_constructible_trait, | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                    trait<Ts, lib::is_trivially_move_assignable, std::is_move_assignable>()...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   inline static constexpr auto&& get_alt(V&& v, in_place_index_t<0>) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     return lib::forward<V>(v).head_; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template <typename V, std::size_t I> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   inline static constexpr auto&& get_alt(V&& v, in_place_index_t<I>) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     return get_alt(lib::forward<V>(v).tail_, in_place_index_t<I - 1>{}); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | #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> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   inline static constexpr AUTO_REFREF get_alt(V&& v, in_place_index_t<I>) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |       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) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       AUTO_REFREF_RETURN(recursive_union::get_alt(data(lib::forward<V>(v)), in_place_index_t<I>{})) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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() | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     static_assert(lib::all<std::is_same<F, Fs>::value...>::value, | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |                   "`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()>{})) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     static_assert(lib::all<(lib::decay_t<V>::size() == lib::decay_t<Vs>::size())...>::value, | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |                   "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 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   template <typename F, typename... Vs, typename Is> | 
					
						
							|  |  |  |   inline static constexpr auto make_fmatrix_impl(Is is) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     return make_dispatch<F, Vs...>(is); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   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) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     return make_farray(make_fmatrix_impl<F, Vs...>(lib::push_back_t<Is, Js>{}, ls...)...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     template <typename Is> | 
					
						
							|  |  |  |     struct impl<Is> | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       inline constexpr AUTO operator()() const AUTO_RETURN(make_dispatch<F, Vs...>(Is{})) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     template <typename Is, std::size_t... Js, typename... Ls> | 
					
						
							|  |  |  |     struct impl<Is, lib::index_sequence<Js...>, Ls...> | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |       inline constexpr AUTO operator()() const | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |           AUTO_RETURN(make_farray(impl<lib::push_back_t<Is, Js>, Ls...>{}()...)) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template <typename F, typename... Vs> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   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()>...>{}()) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #endif | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | };  // namespace base | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 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 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   template <typename Visitor, typename... Vs> | 
					
						
							|  |  |  |   inline static constexpr DECLTYPE_AUTO visit_alt_at(std::size_t index, Visitor&& visitor, | 
					
						
							|  |  |  |                                                      Vs&&... vs) | 
					
						
							|  |  |  |       DECLTYPE_AUTO_RETURN( | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |           base::at(fdiagonal<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>::value, | 
					
						
							|  |  |  |                    index)(lib::forward<Visitor>(visitor), as_base(lib::forward<Vs>(vs))...)) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           template <typename Visitor, typename... Vs> | 
					
						
							|  |  |  |           inline static constexpr DECLTYPE_AUTO | 
					
						
							|  |  |  |       visit_alt(Visitor&& visitor, Vs&&... vs) DECLTYPE_AUTO_RETURN( | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |           base::at(fmatrix<Visitor&&, decltype(as_base(lib::forward<Vs>(vs)))...>::value, | 
					
						
							|  |  |  |                    vs.index()...)(lib::forward<Visitor>(visitor), as_base(lib::forward<Vs>(vs))...)) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |             DECLTYPE_AUTO_RETURN(alt::visit_alt_at(index, lib::forward<Visitor>(visitor), | 
					
						
							|  |  |  |                                                    lib::forward<Vs>(vs).impl_...)) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 template <typename Visitor, typename... Vs> | 
					
						
							|  |  |  |                 inline static constexpr DECLTYPE_AUTO visit_alt(Visitor&& visitor, Vs&&... vs) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                     DECLTYPE_AUTO_RETURN(alt::visit_alt(lib::forward<Visitor>(visitor), | 
					
						
							|  |  |  |                                                         lib::forward<Vs>(vs).impl_...)) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         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> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   inline explicit constexpr alt(in_place_t, Args&&... args) : value(lib::forward<Args>(args)...) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #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_{} {}                  \ | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                                                                                                    \ | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     template <typename... Args>                                                                    \ | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     inline explicit constexpr recursive_union(in_place_index_t<0>, Args&&... args)                 \ | 
					
						
							|  |  |  |         : head_(in_place_t{}, lib::forward<Args>(args)...)                                         \ | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     {                                                                                              \ | 
					
						
							|  |  |  |     }                                                                                              \ | 
					
						
							|  |  |  |                                                                                                    \ | 
					
						
							|  |  |  |     template <std::size_t I, typename... Args>                                                     \ | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     inline explicit constexpr recursive_union(in_place_index_t<I>, Args&&... args)                 \ | 
					
						
							|  |  |  |         : tail_(in_place_index_t<I - 1>{}, lib::forward<Args>(args)...)                            \ | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     {                                                                                              \ | 
					
						
							|  |  |  |     }                                                                                              \ | 
					
						
							|  |  |  |                                                                                                    \ | 
					
						
							|  |  |  |     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: | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   inline explicit constexpr base(valueless_t tag) noexcept | 
					
						
							|  |  |  |       : data_(tag), index_(static_cast<index_t>(-1)) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template <std::size_t I, typename... Args> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   inline explicit constexpr base(in_place_index_t<I>, Args&&... args) | 
					
						
							|  |  |  |       : data_(in_place_index_t<I>{}, lib::forward<Args>(args)...), index_(I) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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: | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   using data_t = recursive_union<DestructibleTrait, 0, Ts...>; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   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); } | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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_; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   inline static constexpr std::size_t size() { return sizeof...(Ts); } | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   data_t data_; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   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()) | 
					
						
							|  |  |  |                            { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                              visitation::alt::visit_alt(dtor{}, *this); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |                            } | 
					
						
							|  |  |  |                            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))) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |         alt<I, T>(in_place_t{}, lib::forward<Args>(args)...); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     return a.value; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template <typename Rhs> | 
					
						
							|  |  |  |   inline static void generic_construct(constructor& lhs, Rhs&& rhs) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     lhs.destroy(); | 
					
						
							|  |  |  |     if (!rhs.valueless_by_exception()) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       visitation::alt::visit_alt_at(rhs.index(), | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #ifdef MPARK_GENERIC_LAMBDAS | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                                     [](auto& lhs_alt, auto&& rhs_alt) { | 
					
						
							|  |  |  |                                       constructor::construct_alt( | 
					
						
							|  |  |  |                                           lhs_alt, lib::forward<decltype(rhs_alt)>(rhs_alt).value); | 
					
						
							|  |  |  |                                     } | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #else | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                                     ctor {} | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #endif | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                                     , | 
					
						
							|  |  |  |                                     lhs, lib::forward<Rhs>(rhs)); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |       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;); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 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)); }); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       self->assign_alt(this_alt, lib::forward<ThatAlt>(that_alt).value); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     assignment* self; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   template <std::size_t I, typename T, typename Arg> | 
					
						
							|  |  |  |   inline void assign_alt(alt<I, T>& a, Arg&& arg) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     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 | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |         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_))); } | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |         assignment* this_; | 
					
						
							|  |  |  |         Arg&& arg_; | 
					
						
							|  |  |  |       } impl{this, lib::forward<Arg>(arg)}; | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       impl(lib::bool_constant < std::is_nothrow_constructible<T, Arg>::value || | 
					
						
							|  |  |  |            !std::is_nothrow_move_constructible<T>::value > {}); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       visitation::alt::visit_alt_at( | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |           that.index(), | 
					
						
							|  |  |  | #ifdef MPARK_GENERIC_LAMBDAS | 
					
						
							|  |  |  |           [this](auto& this_alt, auto&& that_alt) { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |             this->assign_alt(this_alt, lib::forward<decltype(that_alt)>(that_alt).value); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |           } | 
					
						
							|  |  |  | #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;); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 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; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |     this->assign_alt(access::base::get_alt<I>(*this), lib::forward<Arg>(arg)); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   inline void swap(impl& that) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (this->valueless_by_exception() && that.valueless_by_exception()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       // do nothing. | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (this->index() == that.index()) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       visitation::alt::visit_alt_at(this->index(), | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #ifdef MPARK_GENERIC_LAMBDAS | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                                     [](auto& this_alt, auto& that_alt) { | 
					
						
							|  |  |  |                                       using std::swap; | 
					
						
							|  |  |  |                                       swap(this_alt.value, that_alt.value); | 
					
						
							|  |  |  |                                     } | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #else | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                                     swapper {} | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | #endif | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |                                     , | 
					
						
							|  |  |  |                                     *this, that); | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     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()]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | template <std::size_t I, typename T> | 
					
						
							|  |  |  | struct overload_leaf | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   using F = lib::size_constant<I> (*)(T); | 
					
						
							|  |  |  |   operator F() const { return nullptr; } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | template <typename... Ts> | 
					
						
							|  |  |  | struct overload_impl | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 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...>>; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | template <typename... Ts> | 
					
						
							|  |  |  | using overload = typename overload_impl<Ts...>::type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | template <typename T, typename... Ts> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | using best_match = lib::invoke_result_t<overload<Ts...>, T&&>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename T> | 
					
						
							|  |  |  | struct is_in_place_index : std::false_type | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | { | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | template <std::size_t I> | 
					
						
							|  |  |  | struct is_in_place_index<in_place_index_t<I>> : std::true_type | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 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 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace detail | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       : impl_(in_place_index_t<0>{}) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   variant(const variant&) = default; | 
					
						
							|  |  |  |   variant(variant&&) = default; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   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...>, | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |             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) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       : impl_(in_place_index_t<I>{}, lib::forward<Arg>(arg)) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   inline explicit constexpr variant(in_place_index_t<I>, Args&&... args) noexcept( | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |       std::is_nothrow_constructible<T, Args...>::value) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   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> | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   inline explicit constexpr variant( | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       in_place_index_t<I>, std::initializer_list<Up> il, | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |       Args&&... args) noexcept(std::is_nothrow_constructible<T, std::initializer_list<Up>&, | 
					
						
							|  |  |  |                                                              Args...>::value) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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> | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   inline explicit constexpr variant(in_place_type_t<T>, Args&&... args) noexcept( | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |       std::is_nothrow_constructible<T, Args...>::value) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       : impl_(in_place_index_t<I>{}, lib::forward<Args>(args)...) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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( | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       in_place_type_t<T>, std::initializer_list<Up> il, | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |       Args&&... args) noexcept(std::is_nothrow_constructible<T, std::initializer_list<Up>&, | 
					
						
							|  |  |  |                                                              Args...>::value) | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       : impl_(in_place_index_t<I>{}, il, lib::forward<Args>(args)...) | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ~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, | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |       std::size_t I = detail::best_match<Arg, Ts...>::value, | 
					
						
							|  |  |  |       typename T = lib::type_pack_element_t<I, Ts...>, | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |       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)...); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  |   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> | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   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(); } | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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> | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   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) {} | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  |   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 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | struct monostate | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | { | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | #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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace std | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | using mpark::bad_variant_access; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | using mpark::get; | 
					
						
							|  |  |  | using mpark::get_if; | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | using mpark::holds_alternative; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | using mpark::monostate; | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | using mpark::variant; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | using mpark::variant_alternative; | 
					
						
							|  |  |  | using mpark::variant_alternative_t; | 
					
						
							| 
									
										
										
										
											2018-05-11 11:02:48 -07:00
										 |  |  | using mpark::variant_size; | 
					
						
							|  |  |  | using mpark::visit; | 
					
						
							| 
									
										
										
										
											2017-05-26 23:14:52 +02:00
										 |  |  | }  // namespace std | 
					
						
							|  |  |  | #endif |