2071 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			2071 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///
 | 
						|
// optional - An implementation of std::optional with extensions
 | 
						|
// Written in 2017 by Sy Brand (tartanllama@gmail.com, @TartanLlama)
 | 
						|
//
 | 
						|
// Documentation available at https://tl.tartanllama.xyz/
 | 
						|
//
 | 
						|
// To the extent possible under law, the author(s) have dedicated all
 | 
						|
// copyright and related and neighboring rights to this software to the
 | 
						|
// public domain worldwide. This software is distributed without any warranty.
 | 
						|
//
 | 
						|
// You should have received a copy of the CC0 Public Domain Dedication
 | 
						|
// along with this software. If not, see
 | 
						|
// <http://creativecommons.org/publicdomain/zero/1.0/>.
 | 
						|
///
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_HPP
 | 
						|
#define TL_OPTIONAL_HPP
 | 
						|
 | 
						|
#define TL_OPTIONAL_VERSION_MAJOR 1
 | 
						|
#define TL_OPTIONAL_VERSION_MINOR 0
 | 
						|
#define TL_OPTIONAL_VERSION_PATCH 0
 | 
						|
 | 
						|
#include <exception>
 | 
						|
#include <functional>
 | 
						|
#include <new>
 | 
						|
#include <type_traits>
 | 
						|
#include <utility>
 | 
						|
 | 
						|
#if (defined(_MSC_VER) && _MSC_VER == 1900)
 | 
						|
#define TL_OPTIONAL_MSVC2015
 | 
						|
#endif
 | 
						|
 | 
						|
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 &&              \
 | 
						|
     !defined(__clang__))
 | 
						|
#define TL_OPTIONAL_GCC49
 | 
						|
#endif
 | 
						|
 | 
						|
#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 &&              \
 | 
						|
     !defined(__clang__))
 | 
						|
#define TL_OPTIONAL_GCC54
 | 
						|
#endif
 | 
						|
 | 
						|
#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 &&              \
 | 
						|
     !defined(__clang__))
 | 
						|
#define TL_OPTIONAL_GCC55
 | 
						|
#endif
 | 
						|
 | 
						|
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 &&              \
 | 
						|
     !defined(__clang__))
 | 
						|
// GCC < 5 doesn't support overloading on const&& for member functions
 | 
						|
#define TL_OPTIONAL_NO_CONSTRR
 | 
						|
 | 
						|
// GCC < 5 doesn't support some standard C++11 type traits
 | 
						|
#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)                                     \
 | 
						|
  std::has_trivial_copy_constructor<T>::value
 | 
						|
#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign<T>::value
 | 
						|
 | 
						|
// This one will be different for GCC 5.7 if it's ever supported
 | 
						|
#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
 | 
						|
 | 
						|
// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks std::vector
 | 
						|
// for non-copyable types
 | 
						|
#elif (defined(__GNUC__) && __GNUC__ < 8 &&                                                \
 | 
						|
     !defined(__clang__))
 | 
						|
#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
 | 
						|
#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
 | 
						|
namespace tl {
 | 
						|
	namespace detail {
 | 
						|
		template<class T>
 | 
						|
		struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T> {};
 | 
						|
#ifdef _GLIBCXX_VECTOR
 | 
						|
		template<class T, class A>
 | 
						|
		struct is_trivially_copy_constructible<std::vector<T, A>>
 | 
						|
			: std::is_trivially_copy_constructible<T> {};
 | 
						|
#endif      
 | 
						|
	}
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)                                     \
 | 
						|
    tl::detail::is_trivially_copy_constructible<T>::value
 | 
						|
#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T)                                        \
 | 
						|
  std::is_trivially_copy_assignable<T>::value
 | 
						|
#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
 | 
						|
#else
 | 
						|
#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)                                     \
 | 
						|
  std::is_trivially_copy_constructible<T>::value
 | 
						|
#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T)                                        \
 | 
						|
  std::is_trivially_copy_assignable<T>::value
 | 
						|
#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
 | 
						|
#endif
 | 
						|
 | 
						|
#if __cplusplus > 201103L
 | 
						|
#define TL_OPTIONAL_CXX14
 | 
						|
#endif
 | 
						|
 | 
						|
// constexpr implies const in C++11, not C++14
 | 
						|
#if (__cplusplus == 201103L || defined(TL_OPTIONAL_MSVC2015) ||                \
 | 
						|
     defined(TL_OPTIONAL_GCC49))
 | 
						|
#define TL_OPTIONAL_11_CONSTEXPR
 | 
						|
#else
 | 
						|
#define TL_OPTIONAL_11_CONSTEXPR constexpr
 | 
						|
#endif
 | 
						|
 | 
						|
namespace tl {
 | 
						|
#ifndef TL_MONOSTATE_INPLACE_MUTEX
 | 
						|
#define TL_MONOSTATE_INPLACE_MUTEX
 | 
						|
	/// Used to represent an optional with no data; essentially a bool
 | 
						|
	class monostate {};
 | 
						|
 | 
						|
	///  A tag type to tell optional to construct its value in-place
 | 
						|
	struct in_place_t {
 | 
						|
		explicit in_place_t() = default;
 | 
						|
	};
 | 
						|
	/// A tag to tell optional to construct its value in-place
 | 
						|
	static constexpr in_place_t in_place{};
 | 
						|
#endif
 | 
						|
 | 
						|
	template <class T> class optional;
 | 
						|
 | 
						|
	namespace detail {
 | 
						|
#ifndef TL_TRAITS_MUTEX
 | 
						|
#define TL_TRAITS_MUTEX
 | 
						|
		// C++14-style aliases for brevity
 | 
						|
		template <class T> using remove_const_t = typename std::remove_const<T>::type;
 | 
						|
		template <class T>
 | 
						|
		using remove_reference_t = typename std::remove_reference<T>::type;
 | 
						|
		template <class T> using decay_t = typename std::decay<T>::type;
 | 
						|
		template <bool E, class T = void>
 | 
						|
		using enable_if_t = typename std::enable_if<E, T>::type;
 | 
						|
		template <bool B, class T, class F>
 | 
						|
		using conditional_t = typename std::conditional<B, T, F>::type;
 | 
						|
 | 
						|
		// std::conjunction from C++17
 | 
						|
		template <class...> struct conjunction : std::true_type {};
 | 
						|
		template <class B> struct conjunction<B> : B {};
 | 
						|
		template <class B, class... Bs>
 | 
						|
		struct conjunction<B, Bs...>
 | 
						|
			: std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
 | 
						|
 | 
						|
#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
 | 
						|
#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
 | 
						|
#endif
 | 
						|
 | 
						|
		// In C++11 mode, there's an issue in libc++'s std::mem_fn
 | 
						|
		// which results in a hard-error when using it in a noexcept expression
 | 
						|
		// in some cases. This is a check to workaround the common failing case.
 | 
						|
#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
 | 
						|
		template <class T> struct is_pointer_to_non_const_member_func : std::false_type {};
 | 
						|
		template <class T, class Ret, class... Args>
 | 
						|
		struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...)> : std::true_type {};
 | 
						|
		template <class T, class Ret, class... Args>
 | 
						|
		struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...)&> : std::true_type {};
 | 
						|
		template <class T, class Ret, class... Args>
 | 
						|
		struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...)&&> : std::true_type {};
 | 
						|
		template <class T, class Ret, class... Args>
 | 
						|
		struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) volatile> : std::true_type {};
 | 
						|
		template <class T, class Ret, class... Args>
 | 
						|
		struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) volatile&> : std::true_type {};
 | 
						|
		template <class T, class Ret, class... Args>
 | 
						|
		struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) volatile&&> : std::true_type {};
 | 
						|
 | 
						|
		template <class T> struct is_const_or_const_ref : std::false_type {};
 | 
						|
		template <class T> struct is_const_or_const_ref<T const&> : std::true_type {};
 | 
						|
		template <class T> struct is_const_or_const_ref<T const> : std::true_type {};
 | 
						|
#endif
 | 
						|
 | 
						|
		// std::invoke from C++17
 | 
						|
		// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
 | 
						|
		template <typename Fn, typename... Args,
 | 
						|
#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
 | 
						|
			typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value
 | 
						|
				&& is_const_or_const_ref<Args...>::value)>,
 | 
						|
#endif
 | 
						|
			typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
 | 
						|
			int = 0>
 | 
						|
			constexpr auto invoke(Fn&& f, Args &&... args) noexcept(
 | 
						|
				noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
 | 
						|
			-> decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
 | 
						|
			return std::mem_fn(f)(std::forward<Args>(args)...);
 | 
						|
		}
 | 
						|
 | 
						|
		template <typename Fn, typename... Args,
 | 
						|
			typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
 | 
						|
			constexpr auto invoke(Fn&& f, Args &&... args) noexcept(
 | 
						|
				noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
 | 
						|
			-> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
 | 
						|
			return std::forward<Fn>(f)(std::forward<Args>(args)...);
 | 
						|
		}
 | 
						|
 | 
						|
		// std::invoke_result from C++17
 | 
						|
		template <class F, class, class... Us> struct invoke_result_impl;
 | 
						|
 | 
						|
		template <class F, class... Us>
 | 
						|
		struct invoke_result_impl<
 | 
						|
			F, decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...), void()),
 | 
						|
			Us...> {
 | 
						|
			using type = decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
 | 
						|
		};
 | 
						|
 | 
						|
		template <class F, class... Us>
 | 
						|
		using invoke_result = invoke_result_impl<F, void, Us...>;
 | 
						|
 | 
						|
		template <class F, class... Us>
 | 
						|
		using invoke_result_t = typename invoke_result<F, Us...>::type;
 | 
						|
 | 
						|
#if defined(_MSC_VER) && _MSC_VER <= 1900
 | 
						|
		// TODO make a version which works with MSVC 2015
 | 
						|
		template <class T, class U = T> struct is_swappable : std::true_type {};
 | 
						|
 | 
						|
		template <class T, class U = T> struct is_nothrow_swappable : std::true_type {};
 | 
						|
#else
 | 
						|
		// https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept
 | 
						|
		namespace swap_adl_tests {
 | 
						|
			// if swap ADL finds this then it would call std::swap otherwise (same
 | 
						|
			// signature)
 | 
						|
			struct tag {};
 | 
						|
 | 
						|
			template <class T> tag swap(T&, T&);
 | 
						|
			template <class T, std::size_t N> tag swap(T(&a)[N], T(&b)[N]);
 | 
						|
 | 
						|
			// helper functions to test if an unqualified swap is possible, and if it
 | 
						|
			// becomes std::swap
 | 
						|
			template <class, class> std::false_type can_swap(...) noexcept(false);
 | 
						|
			template <class T, class U,
 | 
						|
				class = decltype(swap(std::declval<T&>(), std::declval<U&>()))>
 | 
						|
				std::true_type can_swap(int) noexcept(noexcept(swap(std::declval<T&>(),
 | 
						|
					std::declval<U&>())));
 | 
						|
 | 
						|
			template <class, class> std::false_type uses_std(...);
 | 
						|
			template <class T, class U>
 | 
						|
			std::is_same<decltype(swap(std::declval<T&>(), std::declval<U&>())), tag>
 | 
						|
				uses_std(int);
 | 
						|
 | 
						|
			template <class T>
 | 
						|
			struct is_std_swap_noexcept
 | 
						|
				: std::integral_constant<bool,
 | 
						|
				std::is_nothrow_move_constructible<T>::value&&
 | 
						|
				std::is_nothrow_move_assignable<T>::value> {};
 | 
						|
 | 
						|
			template <class T, std::size_t N>
 | 
						|
			struct is_std_swap_noexcept<T[N]> : is_std_swap_noexcept<T> {};
 | 
						|
 | 
						|
			template <class T, class U>
 | 
						|
			struct is_adl_swap_noexcept
 | 
						|
				: std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
 | 
						|
		} // namespace swap_adl_tests
 | 
						|
 | 
						|
		template <class T, class U = T>
 | 
						|
		struct is_swappable
 | 
						|
			: std::integral_constant<
 | 
						|
			bool,
 | 
						|
			decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
 | 
						|
			(!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
 | 
						|
				(std::is_move_assignable<T>::value &&
 | 
						|
					std::is_move_constructible<T>::value))> {};
 | 
						|
 | 
						|
		template <class T, std::size_t N>
 | 
						|
		struct is_swappable<T[N], T[N]>
 | 
						|
			: std::integral_constant<
 | 
						|
			bool,
 | 
						|
			decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
 | 
						|
			(!decltype(
 | 
						|
				detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value ||
 | 
						|
				is_swappable<T, T>::value)> {};
 | 
						|
 | 
						|
		template <class T, class U = T>
 | 
						|
		struct is_nothrow_swappable
 | 
						|
			: std::integral_constant<
 | 
						|
			bool,
 | 
						|
			is_swappable<T, U>::value &&
 | 
						|
			((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value
 | 
						|
				&& detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
 | 
						|
				(!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
 | 
						|
					detail::swap_adl_tests::is_adl_swap_noexcept<T,
 | 
						|
					U>::value))> {
 | 
						|
		};
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
		// std::void_t from C++17
 | 
						|
		template <class...> struct voider { using type = void; };
 | 
						|
		template <class... Ts> using void_t = typename voider<Ts...>::type;
 | 
						|
 | 
						|
		// Trait for checking if a type is a tl::optional
 | 
						|
		template <class T> struct is_optional_impl : std::false_type {};
 | 
						|
		template <class T> struct is_optional_impl<optional<T>> : std::true_type {};
 | 
						|
		template <class T> using is_optional = is_optional_impl<decay_t<T>>;
 | 
						|
 | 
						|
		// Change void to tl::monostate
 | 
						|
		template <class U>
 | 
						|
		using fixup_void = conditional_t<std::is_void<U>::value, monostate, U>;
 | 
						|
 | 
						|
		template <class F, class U, class = invoke_result_t<F, U>>
 | 
						|
		using get_map_return = optional<fixup_void<invoke_result_t<F, U>>>;
 | 
						|
 | 
						|
		// Check if invoking F for some Us returns void
 | 
						|
		template <class F, class = void, class... U> struct returns_void_impl;
 | 
						|
		template <class F, class... U>
 | 
						|
		struct returns_void_impl<F, void_t<invoke_result_t<F, U...>>, U...>
 | 
						|
			: std::is_void<invoke_result_t<F, U...>> {};
 | 
						|
		template <class F, class... U>
 | 
						|
		using returns_void = returns_void_impl<F, void, U...>;
 | 
						|
 | 
						|
		template <class T, class... U>
 | 
						|
		using enable_if_ret_void = enable_if_t<returns_void<T&&, U...>::value>;
 | 
						|
 | 
						|
		template <class T, class... U>
 | 
						|
		using disable_if_ret_void = enable_if_t<!returns_void<T&&, U...>::value>;
 | 
						|
 | 
						|
		template <class T, class U>
 | 
						|
		using enable_forward_value =
 | 
						|
			detail::enable_if_t<std::is_constructible<T, U&&>::value &&
 | 
						|
			!std::is_same<detail::decay_t<U>, in_place_t>::value &&
 | 
						|
			!std::is_same<optional<T>, detail::decay_t<U>>::value>;
 | 
						|
 | 
						|
		template <class T, class U, class Other>
 | 
						|
		using enable_from_other = detail::enable_if_t<
 | 
						|
			std::is_constructible<T, Other>::value &&
 | 
						|
			!std::is_constructible<T, optional<U>&>::value &&
 | 
						|
			!std::is_constructible<T, optional<U>&&>::value &&
 | 
						|
			!std::is_constructible<T, const optional<U>&>::value &&
 | 
						|
			!std::is_constructible<T, const optional<U>&&>::value &&
 | 
						|
			!std::is_convertible<optional<U>&, T>::value &&
 | 
						|
			!std::is_convertible<optional<U>&&, T>::value &&
 | 
						|
			!std::is_convertible<const optional<U>&, T>::value &&
 | 
						|
			!std::is_convertible<const optional<U>&&, T>::value>;
 | 
						|
 | 
						|
		template <class T, class U>
 | 
						|
		using enable_assign_forward = detail::enable_if_t<
 | 
						|
			!std::is_same<optional<T>, detail::decay_t<U>>::value &&
 | 
						|
			!detail::conjunction<std::is_scalar<T>,
 | 
						|
			std::is_same<T, detail::decay_t<U>>>::value&&
 | 
						|
			std::is_constructible<T, U>::value&& std::is_assignable<T&, U>::value>;
 | 
						|
 | 
						|
		template <class T, class U, class Other>
 | 
						|
		using enable_assign_from_other = detail::enable_if_t<
 | 
						|
			std::is_constructible<T, Other>::value&&
 | 
						|
			std::is_assignable<T&, Other>::value &&
 | 
						|
			!std::is_constructible<T, optional<U>&>::value &&
 | 
						|
			!std::is_constructible<T, optional<U>&&>::value &&
 | 
						|
			!std::is_constructible<T, const optional<U>&>::value &&
 | 
						|
			!std::is_constructible<T, const optional<U>&&>::value &&
 | 
						|
			!std::is_convertible<optional<U>&, T>::value &&
 | 
						|
			!std::is_convertible<optional<U>&&, T>::value &&
 | 
						|
			!std::is_convertible<const optional<U>&, T>::value &&
 | 
						|
			!std::is_convertible<const optional<U>&&, T>::value &&
 | 
						|
			!std::is_assignable<T&, optional<U>&>::value &&
 | 
						|
			!std::is_assignable<T&, optional<U>&&>::value &&
 | 
						|
			!std::is_assignable<T&, const optional<U>&>::value &&
 | 
						|
			!std::is_assignable<T&, const optional<U>&&>::value>;
 | 
						|
 | 
						|
		// The storage base manages the actual storage, and correctly propagates
 | 
						|
		// trivial destruction from T. This case is for when T is not trivially
 | 
						|
		// destructible.
 | 
						|
		template <class T, bool = ::std::is_trivially_destructible<T>::value>
 | 
						|
		struct optional_storage_base {
 | 
						|
			TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
 | 
						|
				: m_dummy(), m_has_value(false) {}
 | 
						|
 | 
						|
			template <class... U>
 | 
						|
			TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u)
 | 
						|
				: m_value(std::forward<U>(u)...), m_has_value(true) {}
 | 
						|
 | 
						|
			~optional_storage_base() {
 | 
						|
				if(m_has_value) {
 | 
						|
					m_value.~T();
 | 
						|
					m_has_value = false;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			struct dummy {};
 | 
						|
			union {
 | 
						|
				dummy m_dummy;
 | 
						|
				T m_value;
 | 
						|
			};
 | 
						|
 | 
						|
			bool m_has_value;
 | 
						|
		};
 | 
						|
 | 
						|
		// This case is for when T is trivially destructible.
 | 
						|
		template <class T> struct optional_storage_base<T, true> {
 | 
						|
			TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept
 | 
						|
				: m_dummy(), m_has_value(false) {}
 | 
						|
 | 
						|
			template <class... U>
 | 
						|
			TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U &&... u)
 | 
						|
				: m_value(std::forward<U>(u)...), m_has_value(true) {}
 | 
						|
 | 
						|
			// No destructor, so this class is trivially destructible
 | 
						|
 | 
						|
			struct dummy {};
 | 
						|
			union {
 | 
						|
				dummy m_dummy;
 | 
						|
				T m_value;
 | 
						|
			};
 | 
						|
 | 
						|
			bool m_has_value = false;
 | 
						|
		};
 | 
						|
 | 
						|
		// This base class provides some handy member functions which can be used in
 | 
						|
		// further derived classes
 | 
						|
		template <class T> struct optional_operations_base : optional_storage_base<T> {
 | 
						|
			using optional_storage_base<T>::optional_storage_base;
 | 
						|
 | 
						|
			void hard_reset() noexcept {
 | 
						|
				get().~T();
 | 
						|
				this->m_has_value = false;
 | 
						|
			}
 | 
						|
 | 
						|
			template <class... Args> void construct(Args &&... args) noexcept {
 | 
						|
				new (std::addressof(this->m_value)) T(std::forward<Args>(args)...);
 | 
						|
				this->m_has_value = true;
 | 
						|
			}
 | 
						|
 | 
						|
			template <class Opt> void assign(Opt&& rhs) {
 | 
						|
				if(this->has_value()) {
 | 
						|
					if(rhs.has_value()) {
 | 
						|
						this->m_value = std::forward<Opt>(rhs).get();
 | 
						|
					}
 | 
						|
					else {
 | 
						|
						this->m_value.~T();
 | 
						|
						this->m_has_value = false;
 | 
						|
					}
 | 
						|
				}
 | 
						|
 | 
						|
				else if(rhs.has_value()) {
 | 
						|
					construct(std::forward<Opt>(rhs).get());
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			bool has_value() const { return this->m_has_value; }
 | 
						|
 | 
						|
			TL_OPTIONAL_11_CONSTEXPR T& get()& { return this->m_value; }
 | 
						|
			TL_OPTIONAL_11_CONSTEXPR const T& get() const& { return this->m_value; }
 | 
						|
			TL_OPTIONAL_11_CONSTEXPR T&& get()&& { return std::move(this->m_value); }
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
			constexpr const T&& get() const&& { return std::move(this->m_value); }
 | 
						|
#endif
 | 
						|
		};
 | 
						|
 | 
						|
		// This class manages conditionally having a trivial copy constructor
 | 
						|
		// This specialization is for when T is trivially copy constructible
 | 
						|
		template <class T, bool = TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>
 | 
						|
		struct optional_copy_base : optional_operations_base<T> {
 | 
						|
			using optional_operations_base<T>::optional_operations_base;
 | 
						|
		};
 | 
						|
 | 
						|
		// This specialization is for when T is not trivially copy constructible
 | 
						|
		template <class T>
 | 
						|
		struct optional_copy_base<T, false> : optional_operations_base<T> {
 | 
						|
			using optional_operations_base<T>::optional_operations_base;
 | 
						|
 | 
						|
			optional_copy_base() = default;
 | 
						|
			optional_copy_base(const optional_copy_base& rhs)
 | 
						|
				: optional_operations_base<T>() {
 | 
						|
				if(rhs.has_value()) {
 | 
						|
					this->construct(rhs.get());
 | 
						|
				}
 | 
						|
				else {
 | 
						|
					this->m_has_value = false;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			optional_copy_base(optional_copy_base&& rhs) = default;
 | 
						|
			optional_copy_base& operator=(const optional_copy_base& rhs) = default;
 | 
						|
			optional_copy_base& operator=(optional_copy_base&& rhs) = default;
 | 
						|
		};
 | 
						|
 | 
						|
		// This class manages conditionally having a trivial move constructor
 | 
						|
		// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
 | 
						|
		// doesn't implement an analogue to std::is_trivially_move_constructible. We
 | 
						|
		// have to make do with a non-trivial move constructor even if T is trivially
 | 
						|
		// move constructible
 | 
						|
#ifndef TL_OPTIONAL_GCC49
 | 
						|
		template <class T, bool = std::is_trivially_move_constructible<T>::value>
 | 
						|
		struct optional_move_base : optional_copy_base<T> {
 | 
						|
			using optional_copy_base<T>::optional_copy_base;
 | 
						|
		};
 | 
						|
#else
 | 
						|
		template <class T, bool = false> struct optional_move_base;
 | 
						|
#endif
 | 
						|
		template <class T> struct optional_move_base<T, false> : optional_copy_base<T> {
 | 
						|
			using optional_copy_base<T>::optional_copy_base;
 | 
						|
 | 
						|
			optional_move_base() = default;
 | 
						|
			optional_move_base(const optional_move_base& rhs) = default;
 | 
						|
 | 
						|
			optional_move_base(optional_move_base&& rhs) noexcept(
 | 
						|
				std::is_nothrow_move_constructible<T>::value) {
 | 
						|
				if(rhs.has_value()) {
 | 
						|
					this->construct(std::move(rhs.get()));
 | 
						|
				}
 | 
						|
				else {
 | 
						|
					this->m_has_value = false;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			optional_move_base& operator=(const optional_move_base& rhs) = default;
 | 
						|
			optional_move_base& operator=(optional_move_base&& rhs) = default;
 | 
						|
		};
 | 
						|
 | 
						|
		// This class manages conditionally having a trivial copy assignment operator
 | 
						|
		template <class T, bool = TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) &&
 | 
						|
			TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) &&
 | 
						|
			TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T)>
 | 
						|
			struct optional_copy_assign_base : optional_move_base<T> {
 | 
						|
			using optional_move_base<T>::optional_move_base;
 | 
						|
		};
 | 
						|
 | 
						|
		template <class T>
 | 
						|
		struct optional_copy_assign_base<T, false> : optional_move_base<T> {
 | 
						|
			using optional_move_base<T>::optional_move_base;
 | 
						|
 | 
						|
			optional_copy_assign_base() = default;
 | 
						|
			optional_copy_assign_base(const optional_copy_assign_base& rhs) = default;
 | 
						|
 | 
						|
			optional_copy_assign_base(optional_copy_assign_base&& rhs) = default;
 | 
						|
			optional_copy_assign_base& operator=(const optional_copy_assign_base& rhs) {
 | 
						|
				this->assign(rhs);
 | 
						|
				return *this;
 | 
						|
			}
 | 
						|
			optional_copy_assign_base&
 | 
						|
				operator=(optional_copy_assign_base&& rhs) = default;
 | 
						|
		};
 | 
						|
 | 
						|
		// This class manages conditionally having a trivial move assignment operator
 | 
						|
		// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
 | 
						|
		// doesn't implement an analogue to std::is_trivially_move_assignable. We have
 | 
						|
		// to make do with a non-trivial move assignment operator even if T is trivially
 | 
						|
		// move assignable
 | 
						|
#ifndef TL_OPTIONAL_GCC49
 | 
						|
		template <class T, bool = std::is_trivially_destructible<T>::value
 | 
						|
			&& std::is_trivially_move_constructible<T>::value
 | 
						|
			&& std::is_trivially_move_assignable<T>::value>
 | 
						|
			struct optional_move_assign_base : optional_copy_assign_base<T> {
 | 
						|
			using optional_copy_assign_base<T>::optional_copy_assign_base;
 | 
						|
		};
 | 
						|
#else
 | 
						|
		template <class T, bool = false> struct optional_move_assign_base;
 | 
						|
#endif
 | 
						|
 | 
						|
		template <class T>
 | 
						|
		struct optional_move_assign_base<T, false> : optional_copy_assign_base<T> {
 | 
						|
			using optional_copy_assign_base<T>::optional_copy_assign_base;
 | 
						|
 | 
						|
			optional_move_assign_base() = default;
 | 
						|
			optional_move_assign_base(const optional_move_assign_base& rhs) = default;
 | 
						|
 | 
						|
			optional_move_assign_base(optional_move_assign_base&& rhs) = default;
 | 
						|
 | 
						|
			optional_move_assign_base&
 | 
						|
				operator=(const optional_move_assign_base& rhs) = default;
 | 
						|
 | 
						|
			optional_move_assign_base&
 | 
						|
				operator=(optional_move_assign_base&& rhs) noexcept(
 | 
						|
					std::is_nothrow_move_constructible<T>::value
 | 
						|
					&& std::is_nothrow_move_assignable<T>::value) {
 | 
						|
				this->assign(std::move(rhs));
 | 
						|
				return *this;
 | 
						|
			}
 | 
						|
		};
 | 
						|
 | 
						|
		// optional_delete_ctor_base will conditionally delete copy and move
 | 
						|
		// constructors depending on whether T is copy/move constructible
 | 
						|
		template <class T, bool EnableCopy = std::is_copy_constructible<T>::value,
 | 
						|
			bool EnableMove = std::is_move_constructible<T>::value>
 | 
						|
			struct optional_delete_ctor_base {
 | 
						|
			optional_delete_ctor_base() = default;
 | 
						|
			optional_delete_ctor_base(const optional_delete_ctor_base&) = default;
 | 
						|
			optional_delete_ctor_base(optional_delete_ctor_base&&) noexcept = default;
 | 
						|
			optional_delete_ctor_base&
 | 
						|
				operator=(const optional_delete_ctor_base&) = default;
 | 
						|
			optional_delete_ctor_base&
 | 
						|
				operator=(optional_delete_ctor_base&&) noexcept = default;
 | 
						|
		};
 | 
						|
 | 
						|
		template <class T> struct optional_delete_ctor_base<T, true, false> {
 | 
						|
			optional_delete_ctor_base() = default;
 | 
						|
			optional_delete_ctor_base(const optional_delete_ctor_base&) = default;
 | 
						|
			optional_delete_ctor_base(optional_delete_ctor_base&&) noexcept = delete;
 | 
						|
			optional_delete_ctor_base&
 | 
						|
				operator=(const optional_delete_ctor_base&) = default;
 | 
						|
			optional_delete_ctor_base&
 | 
						|
				operator=(optional_delete_ctor_base&&) noexcept = default;
 | 
						|
		};
 | 
						|
 | 
						|
		template <class T> struct optional_delete_ctor_base<T, false, true> {
 | 
						|
			optional_delete_ctor_base() = default;
 | 
						|
			optional_delete_ctor_base(const optional_delete_ctor_base&) = delete;
 | 
						|
			optional_delete_ctor_base(optional_delete_ctor_base&&) noexcept = default;
 | 
						|
			optional_delete_ctor_base&
 | 
						|
				operator=(const optional_delete_ctor_base&) = default;
 | 
						|
			optional_delete_ctor_base&
 | 
						|
				operator=(optional_delete_ctor_base&&) noexcept = default;
 | 
						|
		};
 | 
						|
 | 
						|
		template <class T> struct optional_delete_ctor_base<T, false, false> {
 | 
						|
			optional_delete_ctor_base() = default;
 | 
						|
			optional_delete_ctor_base(const optional_delete_ctor_base&) = delete;
 | 
						|
			optional_delete_ctor_base(optional_delete_ctor_base&&) noexcept = delete;
 | 
						|
			optional_delete_ctor_base&
 | 
						|
				operator=(const optional_delete_ctor_base&) = default;
 | 
						|
			optional_delete_ctor_base&
 | 
						|
				operator=(optional_delete_ctor_base&&) noexcept = default;
 | 
						|
		};
 | 
						|
 | 
						|
		// optional_delete_assign_base will conditionally delete copy and move
 | 
						|
		// constructors depending on whether T is copy/move constructible + assignable
 | 
						|
		template <class T,
 | 
						|
			bool EnableCopy = (std::is_copy_constructible<T>::value&&
 | 
						|
				std::is_copy_assignable<T>::value),
 | 
						|
			bool EnableMove = (std::is_move_constructible<T>::value&&
 | 
						|
				std::is_move_assignable<T>::value)>
 | 
						|
			struct optional_delete_assign_base {
 | 
						|
			optional_delete_assign_base() = default;
 | 
						|
			optional_delete_assign_base(const optional_delete_assign_base&) = default;
 | 
						|
			optional_delete_assign_base(optional_delete_assign_base&&) noexcept =
 | 
						|
				default;
 | 
						|
			optional_delete_assign_base&
 | 
						|
				operator=(const optional_delete_assign_base&) = default;
 | 
						|
			optional_delete_assign_base&
 | 
						|
				operator=(optional_delete_assign_base&&) noexcept = default;
 | 
						|
		};
 | 
						|
 | 
						|
		template <class T> struct optional_delete_assign_base<T, true, false> {
 | 
						|
			optional_delete_assign_base() = default;
 | 
						|
			optional_delete_assign_base(const optional_delete_assign_base&) = default;
 | 
						|
			optional_delete_assign_base(optional_delete_assign_base&&) noexcept =
 | 
						|
				default;
 | 
						|
			optional_delete_assign_base&
 | 
						|
				operator=(const optional_delete_assign_base&) = default;
 | 
						|
			optional_delete_assign_base&
 | 
						|
				operator=(optional_delete_assign_base&&) noexcept = delete;
 | 
						|
		};
 | 
						|
 | 
						|
		template <class T> struct optional_delete_assign_base<T, false, true> {
 | 
						|
			optional_delete_assign_base() = default;
 | 
						|
			optional_delete_assign_base(const optional_delete_assign_base&) = default;
 | 
						|
			optional_delete_assign_base(optional_delete_assign_base&&) noexcept =
 | 
						|
				default;
 | 
						|
			optional_delete_assign_base&
 | 
						|
				operator=(const optional_delete_assign_base&) = delete;
 | 
						|
			optional_delete_assign_base&
 | 
						|
				operator=(optional_delete_assign_base&&) noexcept = default;
 | 
						|
		};
 | 
						|
 | 
						|
		template <class T> struct optional_delete_assign_base<T, false, false> {
 | 
						|
			optional_delete_assign_base() = default;
 | 
						|
			optional_delete_assign_base(const optional_delete_assign_base&) = default;
 | 
						|
			optional_delete_assign_base(optional_delete_assign_base&&) noexcept =
 | 
						|
				default;
 | 
						|
			optional_delete_assign_base&
 | 
						|
				operator=(const optional_delete_assign_base&) = delete;
 | 
						|
			optional_delete_assign_base&
 | 
						|
				operator=(optional_delete_assign_base&&) noexcept = delete;
 | 
						|
		};
 | 
						|
 | 
						|
	} // namespace detail
 | 
						|
 | 
						|
	/// A tag type to represent an empty optional
 | 
						|
	struct nullopt_t {
 | 
						|
		struct do_not_use {};
 | 
						|
		constexpr explicit nullopt_t(do_not_use, do_not_use) noexcept {}
 | 
						|
	};
 | 
						|
	/// Represents an empty optional
 | 
						|
	static constexpr nullopt_t nullopt{ nullopt_t::do_not_use{},
 | 
						|
									   nullopt_t::do_not_use{} };
 | 
						|
 | 
						|
	class bad_optional_access : public std::exception {
 | 
						|
	public:
 | 
						|
		bad_optional_access() = default;
 | 
						|
		const char* what() const noexcept { return "Optional has no value"; }
 | 
						|
	};
 | 
						|
 | 
						|
	/// An optional object is an object that contains the storage for another
 | 
						|
	/// object and manages the lifetime of this contained object, if any. The
 | 
						|
	/// contained object may be initialized after the optional object has been
 | 
						|
	/// initialized, and may be destroyed before the optional object has been
 | 
						|
	/// destroyed. The initialization state of the contained object is tracked by
 | 
						|
	/// the optional object.
 | 
						|
	template <class T>
 | 
						|
	class optional : private detail::optional_move_assign_base<T>,
 | 
						|
		private detail::optional_delete_ctor_base<T>,
 | 
						|
		private detail::optional_delete_assign_base<T> {
 | 
						|
		using base = detail::optional_move_assign_base<T>;
 | 
						|
 | 
						|
		static_assert(!std::is_same<T, in_place_t>::value,
 | 
						|
			"instantiation of optional with in_place_t is ill-formed");
 | 
						|
		static_assert(!std::is_same<detail::decay_t<T>, nullopt_t>::value,
 | 
						|
			"instantiation of optional with nullopt_t is ill-formed");
 | 
						|
 | 
						|
	public:
 | 
						|
		// The different versions for C++14 and 11 are needed because deduced return
 | 
						|
		// types are not SFINAE-safe. This provides better support for things like
 | 
						|
		// generic lambdas. C.f.
 | 
						|
		// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0826r0.html
 | 
						|
#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) &&               \
 | 
						|
    !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
 | 
						|
  /// Carries out some operation which returns an optional on the stored
 | 
						|
  /// object if there is one.
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f)& {
 | 
						|
			using result = detail::invoke_result_t<F, T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f)&& {
 | 
						|
			using result = detail::invoke_result_t<F, T&&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto and_then(F&& f) const& {
 | 
						|
			using result = detail::invoke_result_t<F, const T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F> constexpr auto and_then(F&& f) const&& {
 | 
						|
			using result = detail::invoke_result_t<F, const T&&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
#endif
 | 
						|
#else
 | 
						|
  /// Carries out some operation which returns an optional on the stored
 | 
						|
  /// object if there is one.
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&> and_then(F&& f)& {
 | 
						|
			using result = detail::invoke_result_t<F, T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&&> and_then(F&& f)&& {
 | 
						|
			using result = detail::invoke_result_t<F, T&&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		constexpr detail::invoke_result_t<F, const T&> and_then(F&& f) const& {
 | 
						|
			using result = detail::invoke_result_t<F, const T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F>
 | 
						|
		constexpr detail::invoke_result_t<F, const T&&> and_then(F&& f) const&& {
 | 
						|
			using result = detail::invoke_result_t<F, const T&&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) &&               \
 | 
						|
    !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
 | 
						|
		/// Carries out some operation on the stored object if there is one.
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto map(F&& f)& {
 | 
						|
			return optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto map(F&& f)&& {
 | 
						|
			return optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto map(F&& f) const& {
 | 
						|
			return optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto map(F&& f) const&& {
 | 
						|
			return optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
#else
 | 
						|
		/// Carries out some operation on the stored object if there is one.
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			map(F&& f)& {
 | 
						|
			return optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional&&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			map(F&& f)&& {
 | 
						|
			return optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		constexpr decltype(optional_map_impl(std::declval<const optional&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			map(F&& f) const& {
 | 
						|
			return optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F>
 | 
						|
		constexpr decltype(optional_map_impl(std::declval<const optional&&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			map(F&& f) const&& {
 | 
						|
			return optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) &&               \
 | 
						|
    !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
 | 
						|
		/// Carries out some operation on the stored object if there is one.
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto transform(F&& f)& {
 | 
						|
			return optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto transform(F&& f)&& {
 | 
						|
			return optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto transform(F&& f) const& {
 | 
						|
			return optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto transform(F&& f) const&& {
 | 
						|
			return optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
#else
 | 
						|
		/// Carries out some operation on the stored object if there is one.
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			transform(F&& f)& {
 | 
						|
			return optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval<optional&&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			transform(F&& f)&& {
 | 
						|
			return optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		constexpr decltype(optional_map_impl(std::declval<const optional&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			transform(F&& f) const& {
 | 
						|
			return optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F>
 | 
						|
		constexpr decltype(optional_map_impl(std::declval<const optional&&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			transform(F&& f) const&& {
 | 
						|
			return optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Calls `f` if the optional is empty
 | 
						|
		template <class F, detail::enable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f)& {
 | 
						|
			if(has_value())
 | 
						|
				return *this;
 | 
						|
 | 
						|
			std::forward<F>(f)();
 | 
						|
			return nullopt;
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::disable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f)& {
 | 
						|
			return has_value() ? *this : std::forward<F>(f)();
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::enable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> or_else(F&& f)&& {
 | 
						|
			if(has_value())
 | 
						|
				return std::move(*this);
 | 
						|
 | 
						|
			std::forward<F>(f)();
 | 
						|
			return nullopt;
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::disable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f)&& {
 | 
						|
			return has_value() ? std::move(*this) : std::forward<F>(f)();
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::enable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> or_else(F&& f) const& {
 | 
						|
			if(has_value())
 | 
						|
				return *this;
 | 
						|
 | 
						|
			std::forward<F>(f)();
 | 
						|
			return nullopt;
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::disable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) const& {
 | 
						|
			return has_value() ? *this : std::forward<F>(f)();
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F, detail::enable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> or_else(F&& f) const&& {
 | 
						|
			if(has_value())
 | 
						|
				return std::move(*this);
 | 
						|
 | 
						|
			std::forward<F>(f)();
 | 
						|
			return nullopt;
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::disable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> or_else(F&& f) const&& {
 | 
						|
			return has_value() ? std::move(*this) : std::forward<F>(f)();
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Maps the stored value with `f` if there is one, otherwise returns `u`.
 | 
						|
		template <class F, class U> U map_or(F&& f, U&& u)& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: std::forward<U>(u);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, class U> U map_or(F&& f, U&& u)&& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: std::forward<U>(u);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, class U> U map_or(F&& f, U&& u) const& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: std::forward<U>(u);
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F, class U> U map_or(F&& f, U&& u) const&& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: std::forward<U>(u);
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Maps the stored value with `f` if there is one, otherwise calls
 | 
						|
		/// `u` and returns the result.
 | 
						|
		template <class F, class U>
 | 
						|
		detail::invoke_result_t<U> map_or_else(F&& f, U&& u)& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: std::forward<U>(u)();
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, class U>
 | 
						|
		detail::invoke_result_t<U> map_or_else(F&& f, U&& u)&& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: std::forward<U>(u)();
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, class U>
 | 
						|
		detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: std::forward<U>(u)();
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F, class U>
 | 
						|
		detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const&& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: std::forward<U>(u)();
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Returns `u` if `*this` has a value, otherwise an empty optional.
 | 
						|
		template <class U>
 | 
						|
		constexpr optional<typename std::decay<U>::type> conjunction(U&& u) const {
 | 
						|
			using result = optional<detail::decay_t<U>>;
 | 
						|
			return has_value() ? result{ u } : result{ nullopt };
 | 
						|
		}
 | 
						|
 | 
						|
		/// Returns `rhs` if `*this` is empty, otherwise the current value.
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs)& {
 | 
						|
			return has_value() ? *this : rhs;
 | 
						|
		}
 | 
						|
 | 
						|
		constexpr optional disjunction(const optional& rhs) const& {
 | 
						|
			return has_value() ? *this : rhs;
 | 
						|
		}
 | 
						|
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs)&& {
 | 
						|
			return has_value() ? std::move(*this) : rhs;
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		constexpr optional disjunction(const optional& rhs) const&& {
 | 
						|
			return has_value() ? std::move(*this) : rhs;
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs)& {
 | 
						|
			return has_value() ? *this : std::move(rhs);
 | 
						|
		}
 | 
						|
 | 
						|
		constexpr optional disjunction(optional&& rhs) const& {
 | 
						|
			return has_value() ? *this : std::move(rhs);
 | 
						|
		}
 | 
						|
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs)&& {
 | 
						|
			return has_value() ? std::move(*this) : std::move(rhs);
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		constexpr optional disjunction(optional&& rhs) const&& {
 | 
						|
			return has_value() ? std::move(*this) : std::move(rhs);
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Takes the value out of the optional, leaving it empty
 | 
						|
		optional take() {
 | 
						|
			optional ret = std::move(*this);
 | 
						|
			reset();
 | 
						|
			return ret;
 | 
						|
		}
 | 
						|
 | 
						|
		using value_type = T;
 | 
						|
 | 
						|
		/// Constructs an optional that does not contain a value.
 | 
						|
		constexpr optional() noexcept = default;
 | 
						|
 | 
						|
		constexpr optional(nullopt_t) noexcept {}
 | 
						|
 | 
						|
		/// Copy constructor
 | 
						|
		///
 | 
						|
		/// If `rhs` contains a value, the stored value is direct-initialized with
 | 
						|
		/// it. Otherwise, the constructed optional is empty.
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional(const optional& rhs) = default;
 | 
						|
 | 
						|
		/// Move constructor
 | 
						|
		///
 | 
						|
		/// If `rhs` contains a value, the stored value is direct-initialized with
 | 
						|
		/// it. Otherwise, the constructed optional is empty.
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional(optional&& rhs) = default;
 | 
						|
 | 
						|
		/// Constructs the stored value in-place using the given arguments.
 | 
						|
		template <class... Args>
 | 
						|
		constexpr explicit optional(
 | 
						|
			detail::enable_if_t<std::is_constructible<T, Args...>::value, in_place_t>,
 | 
						|
			Args &&... args)
 | 
						|
			: base(in_place, std::forward<Args>(args)...) {}
 | 
						|
 | 
						|
		template <class U, class... Args>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR explicit optional(
 | 
						|
			detail::enable_if_t<std::is_constructible<T, std::initializer_list<U>&,
 | 
						|
			Args &&...>::value,
 | 
						|
			in_place_t>,
 | 
						|
			std::initializer_list<U> il, Args &&... args) {
 | 
						|
			this->construct(il, std::forward<Args>(args)...);
 | 
						|
		}
 | 
						|
 | 
						|
		/// Constructs the stored value with `u`.
 | 
						|
		template <
 | 
						|
			class U = T,
 | 
						|
			detail::enable_if_t<std::is_convertible<U&&, T>::value>* = nullptr,
 | 
						|
			detail::enable_forward_value<T, U>* = nullptr>
 | 
						|
			constexpr optional(U&& u) : base(in_place, std::forward<U>(u)) {}
 | 
						|
 | 
						|
		template <
 | 
						|
			class U = T,
 | 
						|
			detail::enable_if_t<!std::is_convertible<U&&, T>::value>* = nullptr,
 | 
						|
			detail::enable_forward_value<T, U>* = nullptr>
 | 
						|
			constexpr explicit optional(U&& u) : base(in_place, std::forward<U>(u)) {}
 | 
						|
 | 
						|
		/// Converting copy constructor.
 | 
						|
		template <
 | 
						|
			class U, detail::enable_from_other<T, U, const U&>* = nullptr,
 | 
						|
			detail::enable_if_t<std::is_convertible<const U&, T>::value>* = nullptr>
 | 
						|
			optional(const optional<U>& rhs) {
 | 
						|
			if(rhs.has_value()) {
 | 
						|
				this->construct(*rhs);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		template <class U, detail::enable_from_other<T, U, const U&>* = nullptr,
 | 
						|
			detail::enable_if_t<!std::is_convertible<const U&, T>::value>* =
 | 
						|
			nullptr>
 | 
						|
			explicit optional(const optional<U>& rhs) {
 | 
						|
			if(rhs.has_value()) {
 | 
						|
				this->construct(*rhs);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		/// Converting move constructor.
 | 
						|
		template <
 | 
						|
			class U, detail::enable_from_other<T, U, U&&>* = nullptr,
 | 
						|
			detail::enable_if_t<std::is_convertible<U&&, T>::value>* = nullptr>
 | 
						|
			optional(optional<U>&& rhs) {
 | 
						|
			if(rhs.has_value()) {
 | 
						|
				this->construct(std::move(*rhs));
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		template <
 | 
						|
			class U, detail::enable_from_other<T, U, U&&>* = nullptr,
 | 
						|
			detail::enable_if_t<!std::is_convertible<U&&, T>::value>* = nullptr>
 | 
						|
			explicit optional(optional<U>&& rhs) {
 | 
						|
			if(rhs.has_value()) {
 | 
						|
				this->construct(std::move(*rhs));
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		/// Destroys the stored value if there is one.
 | 
						|
		~optional() = default;
 | 
						|
 | 
						|
		/// Assignment to empty.
 | 
						|
		///
 | 
						|
		/// Destroys the current value if there is one.
 | 
						|
		optional& operator=(nullopt_t) noexcept {
 | 
						|
			if(has_value()) {
 | 
						|
				this->m_value.~T();
 | 
						|
				this->m_has_value = false;
 | 
						|
			}
 | 
						|
 | 
						|
			return *this;
 | 
						|
		}
 | 
						|
 | 
						|
		/// Copy assignment.
 | 
						|
		///
 | 
						|
		/// Copies the value from `rhs` if there is one. Otherwise resets the stored
 | 
						|
		/// value in `*this`.
 | 
						|
		optional& operator=(const optional& rhs) = default;
 | 
						|
 | 
						|
		/// Move assignment.
 | 
						|
		///
 | 
						|
		/// Moves the value from `rhs` if there is one. Otherwise resets the stored
 | 
						|
		/// value in `*this`.
 | 
						|
		optional& operator=(optional&& rhs) = default;
 | 
						|
 | 
						|
		/// Assigns the stored value from `u`, destroying the old value if there was
 | 
						|
		/// one.
 | 
						|
		template <class U = T, detail::enable_assign_forward<T, U>* = nullptr>
 | 
						|
		optional& operator=(U&& u) {
 | 
						|
			if(has_value()) {
 | 
						|
				this->m_value = std::forward<U>(u);
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				this->construct(std::forward<U>(u));
 | 
						|
			}
 | 
						|
 | 
						|
			return *this;
 | 
						|
		}
 | 
						|
 | 
						|
		/// Converting copy assignment operator.
 | 
						|
		///
 | 
						|
		/// Copies the value from `rhs` if there is one. Otherwise resets the stored
 | 
						|
		/// value in `*this`.
 | 
						|
		template <class U,
 | 
						|
			detail::enable_assign_from_other<T, U, const U&>* = nullptr>
 | 
						|
			optional& operator=(const optional<U>& rhs) {
 | 
						|
			if(has_value()) {
 | 
						|
				if(rhs.has_value()) {
 | 
						|
					this->m_value = *rhs;
 | 
						|
				}
 | 
						|
				else {
 | 
						|
					this->hard_reset();
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			if(rhs.has_value()) {
 | 
						|
				this->construct(*rhs);
 | 
						|
			}
 | 
						|
 | 
						|
			return *this;
 | 
						|
		}
 | 
						|
 | 
						|
		// TODO check exception guarantee
 | 
						|
		/// Converting move assignment operator.
 | 
						|
		///
 | 
						|
		/// Moves the value from `rhs` if there is one. Otherwise resets the stored
 | 
						|
		/// value in `*this`.
 | 
						|
		template <class U, detail::enable_assign_from_other<T, U, U>* = nullptr>
 | 
						|
		optional& operator=(optional<U>&& rhs) {
 | 
						|
			if(has_value()) {
 | 
						|
				if(rhs.has_value()) {
 | 
						|
					this->m_value = std::move(*rhs);
 | 
						|
				}
 | 
						|
				else {
 | 
						|
					this->hard_reset();
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			if(rhs.has_value()) {
 | 
						|
				this->construct(std::move(*rhs));
 | 
						|
			}
 | 
						|
 | 
						|
			return *this;
 | 
						|
		}
 | 
						|
 | 
						|
		/// Constructs the value in-place, destroying the current one if there is
 | 
						|
		/// one.
 | 
						|
		template <class... Args> T& emplace(Args &&... args) {
 | 
						|
			static_assert(std::is_constructible<T, Args &&...>::value,
 | 
						|
				"T must be constructible with Args");
 | 
						|
 | 
						|
			*this = nullopt;
 | 
						|
			this->construct(std::forward<Args>(args)...);
 | 
						|
			return value();
 | 
						|
		}
 | 
						|
 | 
						|
		template <class U, class... Args>
 | 
						|
		detail::enable_if_t<
 | 
						|
			std::is_constructible<T, std::initializer_list<U>&, Args &&...>::value,
 | 
						|
			T&>
 | 
						|
			emplace(std::initializer_list<U> il, Args &&... args) {
 | 
						|
			*this = nullopt;
 | 
						|
			this->construct(il, std::forward<Args>(args)...);
 | 
						|
			return value();
 | 
						|
		}
 | 
						|
 | 
						|
		/// Swaps this optional with the other.
 | 
						|
		///
 | 
						|
		/// If neither optionals have a value, nothing happens.
 | 
						|
		/// If both have a value, the values are swapped.
 | 
						|
		/// If one has a value, it is moved to the other and the movee is left
 | 
						|
		/// valueless.
 | 
						|
		void
 | 
						|
			swap(optional& rhs) noexcept(std::is_nothrow_move_constructible<T>::value
 | 
						|
				&& detail::is_nothrow_swappable<T>::value) {
 | 
						|
			using std::swap;
 | 
						|
			if(has_value()) {
 | 
						|
				if(rhs.has_value()) {
 | 
						|
					swap(**this, *rhs);
 | 
						|
				}
 | 
						|
				else {
 | 
						|
					new (std::addressof(rhs.m_value)) T(std::move(this->m_value));
 | 
						|
					this->m_value.T::~T();
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else if(rhs.has_value()) {
 | 
						|
				new (std::addressof(this->m_value)) T(std::move(rhs.m_value));
 | 
						|
				rhs.m_value.T::~T();
 | 
						|
			}
 | 
						|
			swap(this->m_has_value, rhs.m_has_value);
 | 
						|
		}
 | 
						|
 | 
						|
		/// Returns a pointer to the stored value
 | 
						|
		constexpr const T* operator->() const {
 | 
						|
			return std::addressof(this->m_value);
 | 
						|
		}
 | 
						|
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR T* operator->() {
 | 
						|
			return std::addressof(this->m_value);
 | 
						|
		}
 | 
						|
 | 
						|
		/// Returns the stored value
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR T& operator*()& { return this->m_value; }
 | 
						|
 | 
						|
		constexpr const T& operator*() const& { return this->m_value; }
 | 
						|
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR T&& operator*()&& {
 | 
						|
			return std::move(this->m_value);
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		constexpr const T&& operator*() const&& { return std::move(this->m_value); }
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Returns whether or not the optional has a value
 | 
						|
		constexpr bool has_value() const noexcept { return this->m_has_value; }
 | 
						|
 | 
						|
		constexpr explicit operator bool() const noexcept {
 | 
						|
			return this->m_has_value;
 | 
						|
		}
 | 
						|
 | 
						|
		/// Returns the contained value if there is one, otherwise throws bad_optional_access
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR T& value()& {
 | 
						|
			if(has_value())
 | 
						|
				return this->m_value;
 | 
						|
			throw bad_optional_access();
 | 
						|
		}
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR const T& value() const& {
 | 
						|
			if(has_value())
 | 
						|
				return this->m_value;
 | 
						|
			throw bad_optional_access();
 | 
						|
		}
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR T&& value()&& {
 | 
						|
			if(has_value())
 | 
						|
				return std::move(this->m_value);
 | 
						|
			throw bad_optional_access();
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR const T&& value() const&& {
 | 
						|
			if(has_value())
 | 
						|
				return std::move(this->m_value);
 | 
						|
			throw bad_optional_access();
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Returns the stored value if there is one, otherwise returns `u`
 | 
						|
		template <class U> constexpr T value_or(U&& u) const& {
 | 
						|
			static_assert(std::is_copy_constructible<T>::value &&
 | 
						|
				std::is_convertible<U&&, T>::value,
 | 
						|
				"T must be copy constructible and convertible from U");
 | 
						|
			return has_value() ? **this : static_cast<T>(std::forward<U>(u));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class U> TL_OPTIONAL_11_CONSTEXPR T value_or(U&& u)&& {
 | 
						|
			static_assert(std::is_move_constructible<T>::value &&
 | 
						|
				std::is_convertible<U&&, T>::value,
 | 
						|
				"T must be move constructible and convertible from U");
 | 
						|
			return has_value() ? **this : static_cast<T>(std::forward<U>(u));
 | 
						|
		}
 | 
						|
 | 
						|
		/// Destroys the stored value if one exists, making the optional empty
 | 
						|
		void reset() noexcept {
 | 
						|
			if(has_value()) {
 | 
						|
				this->m_value.~T();
 | 
						|
				this->m_has_value = false;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}; // namespace tl
 | 
						|
 | 
						|
	/// Compares two optional objects
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator==(const optional<T>& lhs,
 | 
						|
		const optional<U>& rhs) {
 | 
						|
		return lhs.has_value() == rhs.has_value() &&
 | 
						|
			(!lhs.has_value() || *lhs == *rhs);
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator!=(const optional<T>& lhs,
 | 
						|
		const optional<U>& rhs) {
 | 
						|
		return lhs.has_value() != rhs.has_value() ||
 | 
						|
			(lhs.has_value() && *lhs != *rhs);
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator<(const optional<T>& lhs,
 | 
						|
		const optional<U>& rhs) {
 | 
						|
		return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs);
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator>(const optional<T>& lhs,
 | 
						|
		const optional<U>& rhs) {
 | 
						|
		return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs);
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator<=(const optional<T>& lhs,
 | 
						|
		const optional<U>& rhs) {
 | 
						|
		return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs);
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator>=(const optional<T>& lhs,
 | 
						|
		const optional<U>& rhs) {
 | 
						|
		return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs);
 | 
						|
	}
 | 
						|
 | 
						|
	/// Compares an optional to a `nullopt`
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator==(const optional<T>& lhs, nullopt_t) noexcept {
 | 
						|
		return !lhs.has_value();
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator==(nullopt_t, const optional<T>& rhs) noexcept {
 | 
						|
		return !rhs.has_value();
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator!=(const optional<T>& lhs, nullopt_t) noexcept {
 | 
						|
		return lhs.has_value();
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator!=(nullopt_t, const optional<T>& rhs) noexcept {
 | 
						|
		return rhs.has_value();
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator<(const optional<T>&, nullopt_t) noexcept {
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator<(nullopt_t, const optional<T>& rhs) noexcept {
 | 
						|
		return rhs.has_value();
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator<=(const optional<T>& lhs, nullopt_t) noexcept {
 | 
						|
		return !lhs.has_value();
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept {
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator>(const optional<T>& lhs, nullopt_t) noexcept {
 | 
						|
		return lhs.has_value();
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator>(nullopt_t, const optional<T>&) noexcept {
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept {
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
	template <class T>
 | 
						|
	inline constexpr bool operator>=(nullopt_t, const optional<T>& rhs) noexcept {
 | 
						|
		return !rhs.has_value();
 | 
						|
	}
 | 
						|
 | 
						|
	/// Compares the optional with a value.
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator==(const optional<T>& lhs, const U& rhs) {
 | 
						|
		return lhs.has_value() ? *lhs == rhs : false;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator==(const U& lhs, const optional<T>& rhs) {
 | 
						|
		return rhs.has_value() ? lhs == *rhs : false;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator!=(const optional<T>& lhs, const U& rhs) {
 | 
						|
		return lhs.has_value() ? *lhs != rhs : true;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator!=(const U& lhs, const optional<T>& rhs) {
 | 
						|
		return rhs.has_value() ? lhs != *rhs : true;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator<(const optional<T>& lhs, const U& rhs) {
 | 
						|
		return lhs.has_value() ? *lhs < rhs : true;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator<(const U& lhs, const optional<T>& rhs) {
 | 
						|
		return rhs.has_value() ? lhs < *rhs : false;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator<=(const optional<T>& lhs, const U& rhs) {
 | 
						|
		return lhs.has_value() ? *lhs <= rhs : true;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator<=(const U& lhs, const optional<T>& rhs) {
 | 
						|
		return rhs.has_value() ? lhs <= *rhs : false;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator>(const optional<T>& lhs, const U& rhs) {
 | 
						|
		return lhs.has_value() ? *lhs > rhs : false;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator>(const U& lhs, const optional<T>& rhs) {
 | 
						|
		return rhs.has_value() ? lhs > *rhs : true;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator>=(const optional<T>& lhs, const U& rhs) {
 | 
						|
		return lhs.has_value() ? *lhs >= rhs : false;
 | 
						|
	}
 | 
						|
	template <class T, class U>
 | 
						|
	inline constexpr bool operator>=(const U& lhs, const optional<T>& rhs) {
 | 
						|
		return rhs.has_value() ? lhs >= *rhs : true;
 | 
						|
	}
 | 
						|
 | 
						|
	template <class T,
 | 
						|
		detail::enable_if_t<std::is_move_constructible<T>::value>* = nullptr,
 | 
						|
		detail::enable_if_t<detail::is_swappable<T>::value>* = nullptr>
 | 
						|
		void swap(optional<T>& lhs,
 | 
						|
			optional<T>& rhs) noexcept(noexcept(lhs.swap(rhs))) {
 | 
						|
		return lhs.swap(rhs);
 | 
						|
	}
 | 
						|
 | 
						|
	namespace detail {
 | 
						|
		struct i_am_secret {};
 | 
						|
	} // namespace detail
 | 
						|
 | 
						|
	template <class T = detail::i_am_secret, class U,
 | 
						|
		class Ret =
 | 
						|
		detail::conditional_t<std::is_same<T, detail::i_am_secret>::value,
 | 
						|
		detail::decay_t<U>, T>>
 | 
						|
		inline constexpr optional<Ret> make_optional(U&& v) {
 | 
						|
		return optional<Ret>(std::forward<U>(v));
 | 
						|
	}
 | 
						|
 | 
						|
	template <class T, class... Args>
 | 
						|
	inline constexpr optional<T> make_optional(Args &&... args) {
 | 
						|
		return optional<T>(in_place, std::forward<Args>(args)...);
 | 
						|
	}
 | 
						|
	template <class T, class U, class... Args>
 | 
						|
	inline constexpr optional<T> make_optional(std::initializer_list<U> il,
 | 
						|
		Args &&... args) {
 | 
						|
		return optional<T>(in_place, il, std::forward<Args>(args)...);
 | 
						|
	}
 | 
						|
 | 
						|
#if __cplusplus >= 201703L
 | 
						|
	template <class T> optional(T)->optional<T>;
 | 
						|
#endif
 | 
						|
 | 
						|
	/// \exclude
 | 
						|
	namespace detail {
 | 
						|
#ifdef TL_OPTIONAL_CXX14
 | 
						|
		template <class Opt, class F,
 | 
						|
			class Ret = decltype(detail::invoke(std::declval<F>(),
 | 
						|
				*std::declval<Opt>())),
 | 
						|
			detail::enable_if_t<!std::is_void<Ret>::value>* = nullptr>
 | 
						|
			constexpr auto optional_map_impl(Opt&& opt, F&& f) {
 | 
						|
			return opt.has_value()
 | 
						|
				? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt))
 | 
						|
				: optional<Ret>(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class Opt, class F,
 | 
						|
			class Ret = decltype(detail::invoke(std::declval<F>(),
 | 
						|
				*std::declval<Opt>())),
 | 
						|
			detail::enable_if_t<std::is_void<Ret>::value>* = nullptr>
 | 
						|
			auto optional_map_impl(Opt&& opt, F&& f) {
 | 
						|
			if(opt.has_value()) {
 | 
						|
				detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
 | 
						|
				return make_optional(monostate{});
 | 
						|
			}
 | 
						|
 | 
						|
			return optional<monostate>(nullopt);
 | 
						|
		}
 | 
						|
#else
 | 
						|
		template <class Opt, class F,
 | 
						|
			class Ret = decltype(detail::invoke(std::declval<F>(),
 | 
						|
				*std::declval<Opt>())),
 | 
						|
			detail::enable_if_t<!std::is_void<Ret>::value>* = nullptr>
 | 
						|
 | 
						|
			constexpr auto optional_map_impl(Opt&& opt, F&& f) -> optional<Ret> {
 | 
						|
			return opt.has_value()
 | 
						|
				? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt))
 | 
						|
				: optional<Ret>(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class Opt, class F,
 | 
						|
			class Ret = decltype(detail::invoke(std::declval<F>(),
 | 
						|
				*std::declval<Opt>())),
 | 
						|
			detail::enable_if_t<std::is_void<Ret>::value>* = nullptr>
 | 
						|
 | 
						|
			auto optional_map_impl(Opt&& opt, F&& f) -> optional<monostate> {
 | 
						|
			if(opt.has_value()) {
 | 
						|
				detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt));
 | 
						|
				return monostate{};
 | 
						|
			}
 | 
						|
 | 
						|
			return nullopt;
 | 
						|
		}
 | 
						|
#endif
 | 
						|
	} // namespace detail
 | 
						|
 | 
						|
	/// Specialization for when `T` is a reference. `optional<T&>` acts similarly
 | 
						|
	/// to a `T*`, but provides more operations and shows intent more clearly.
 | 
						|
	template <class T> class optional<T&> {
 | 
						|
	public:
 | 
						|
		// The different versions for C++14 and 11 are needed because deduced return
 | 
						|
		// types are not SFINAE-safe. This provides better support for things like
 | 
						|
		// generic lambdas. C.f.
 | 
						|
		// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0826r0.html
 | 
						|
#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) &&               \
 | 
						|
    !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
 | 
						|
 | 
						|
  /// Carries out some operation which returns an optional on the stored
 | 
						|
  /// object if there is one.
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f)& {
 | 
						|
			using result = detail::invoke_result_t<F, T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f)&& {
 | 
						|
			using result = detail::invoke_result_t<F, T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto and_then(F&& f) const& {
 | 
						|
			using result = detail::invoke_result_t<F, const T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F> constexpr auto and_then(F&& f) const&& {
 | 
						|
			using result = detail::invoke_result_t<F, const T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
#endif
 | 
						|
#else
 | 
						|
  /// Carries out some operation which returns an optional on the stored
 | 
						|
  /// object if there is one.
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&> and_then(F&& f)& {
 | 
						|
			using result = detail::invoke_result_t<F, T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t<F, T&> and_then(F&& f)&& {
 | 
						|
			using result = detail::invoke_result_t<F, T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		constexpr detail::invoke_result_t<F, const T&> and_then(F&& f) const& {
 | 
						|
			using result = detail::invoke_result_t<F, const T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F>
 | 
						|
		constexpr detail::invoke_result_t<F, const T&> and_then(F&& f) const&& {
 | 
						|
			using result = detail::invoke_result_t<F, const T&>;
 | 
						|
			static_assert(detail::is_optional<result>::value,
 | 
						|
				"F must return an optional");
 | 
						|
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: result(nullopt);
 | 
						|
		}
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) &&               \
 | 
						|
    !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
 | 
						|
		/// Carries out some operation on the stored object if there is one.
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto map(F&& f)& {
 | 
						|
			return detail::optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto map(F&& f)&& {
 | 
						|
			return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto map(F&& f) const& {
 | 
						|
			return detail::optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto map(F&& f) const&& {
 | 
						|
			return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
#else
 | 
						|
		/// Carries out some operation on the stored object if there is one.
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			map(F&& f)& {
 | 
						|
			return detail::optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional&&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			map(F&& f)&& {
 | 
						|
			return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		constexpr decltype(detail::optional_map_impl(std::declval<const optional&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			map(F&& f) const& {
 | 
						|
			return detail::optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F>
 | 
						|
		constexpr decltype(detail::optional_map_impl(std::declval<const optional&&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			map(F&& f) const&& {
 | 
						|
			return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) &&               \
 | 
						|
    !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55)
 | 
						|
		/// Carries out some operation on the stored object if there is one.
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto transform(F&& f)& {
 | 
						|
			return detail::optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> TL_OPTIONAL_11_CONSTEXPR auto transform(F&& f)&& {
 | 
						|
			return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto transform(F&& f) const& {
 | 
						|
			return detail::optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F> constexpr auto transform(F&& f) const&& {
 | 
						|
			return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
#else
 | 
						|
		/// Carries out some operation on the stored object if there is one.
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			transform(F&& f)& {
 | 
						|
			return detail::optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		/// \group map
 | 
						|
		/// \synopsis template <class F> auto transform(F &&f) &&;
 | 
						|
		template <class F>
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl(std::declval<optional&&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			transform(F&& f)&& {
 | 
						|
			return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F>
 | 
						|
		constexpr decltype(detail::optional_map_impl(std::declval<const optional&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			transform(F&& f) const& {
 | 
						|
			return detail::optional_map_impl(*this, std::forward<F>(f));
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F>
 | 
						|
		constexpr decltype(detail::optional_map_impl(std::declval<const optional&&>(),
 | 
						|
			std::declval<F&&>()))
 | 
						|
			transform(F&& f) const&& {
 | 
						|
			return detail::optional_map_impl(std::move(*this), std::forward<F>(f));
 | 
						|
		}
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Calls `f` if the optional is empty
 | 
						|
		template <class F, detail::enable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f)& {
 | 
						|
			if(has_value())
 | 
						|
				return *this;
 | 
						|
 | 
						|
			std::forward<F>(f)();
 | 
						|
			return nullopt;
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::disable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f)& {
 | 
						|
			return has_value() ? *this : std::forward<F>(f)();
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::enable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> or_else(F&& f)&& {
 | 
						|
			if(has_value())
 | 
						|
				return std::move(*this);
 | 
						|
 | 
						|
			std::forward<F>(f)();
 | 
						|
			return nullopt;
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::disable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f)&& {
 | 
						|
			return has_value() ? std::move(*this) : std::forward<F>(f)();
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::enable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> or_else(F&& f) const& {
 | 
						|
			if(has_value())
 | 
						|
				return *this;
 | 
						|
 | 
						|
			std::forward<F>(f)();
 | 
						|
			return nullopt;
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::disable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) const& {
 | 
						|
			return has_value() ? *this : std::forward<F>(f)();
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F, detail::enable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> or_else(F&& f) const&& {
 | 
						|
			if(has_value())
 | 
						|
				return std::move(*this);
 | 
						|
 | 
						|
			std::forward<F>(f)();
 | 
						|
			return nullopt;
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, detail::disable_if_ret_void<F>* = nullptr>
 | 
						|
		optional<T> or_else(F&& f) const&& {
 | 
						|
			return has_value() ? std::move(*this) : std::forward<F>(f)();
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Maps the stored value with `f` if there is one, otherwise returns `u`
 | 
						|
		template <class F, class U> U map_or(F&& f, U&& u)& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: std::forward<U>(u);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, class U> U map_or(F&& f, U&& u)&& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: std::forward<U>(u);
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, class U> U map_or(F&& f, U&& u) const& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: std::forward<U>(u);
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F, class U> U map_or(F&& f, U&& u) const&& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: std::forward<U>(u);
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Maps the stored value with `f` if there is one, otherwise calls
 | 
						|
		/// `u` and returns the result.
 | 
						|
		template <class F, class U>
 | 
						|
		detail::invoke_result_t<U> map_or_else(F&& f, U&& u)& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: std::forward<U>(u)();
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, class U>
 | 
						|
		detail::invoke_result_t<U> map_or_else(F&& f, U&& u)&& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: std::forward<U>(u)();
 | 
						|
		}
 | 
						|
 | 
						|
		template <class F, class U>
 | 
						|
		detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), **this)
 | 
						|
				: std::forward<U>(u)();
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		template <class F, class U>
 | 
						|
		detail::invoke_result_t<U> map_or_else(F&& f, U&& u) const&& {
 | 
						|
			return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
 | 
						|
				: std::forward<U>(u)();
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Returns `u` if `*this` has a value, otherwise an empty optional.
 | 
						|
		template <class U>
 | 
						|
		constexpr optional<typename std::decay<U>::type> conjunction(U&& u) const {
 | 
						|
			using result = optional<detail::decay_t<U>>;
 | 
						|
			return has_value() ? result{ u } : result{ nullopt };
 | 
						|
		}
 | 
						|
 | 
						|
		/// Returns `rhs` if `*this` is empty, otherwise the current value.
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs)& {
 | 
						|
			return has_value() ? *this : rhs;
 | 
						|
		}
 | 
						|
 | 
						|
		constexpr optional disjunction(const optional& rhs) const& {
 | 
						|
			return has_value() ? *this : rhs;
 | 
						|
		}
 | 
						|
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs)&& {
 | 
						|
			return has_value() ? std::move(*this) : rhs;
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		constexpr optional disjunction(const optional& rhs) const&& {
 | 
						|
			return has_value() ? std::move(*this) : rhs;
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs)& {
 | 
						|
			return has_value() ? *this : std::move(rhs);
 | 
						|
		}
 | 
						|
 | 
						|
		constexpr optional disjunction(optional&& rhs) const& {
 | 
						|
			return has_value() ? *this : std::move(rhs);
 | 
						|
		}
 | 
						|
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs)&& {
 | 
						|
			return has_value() ? std::move(*this) : std::move(rhs);
 | 
						|
		}
 | 
						|
 | 
						|
#ifndef TL_OPTIONAL_NO_CONSTRR
 | 
						|
		constexpr optional disjunction(optional&& rhs) const&& {
 | 
						|
			return has_value() ? std::move(*this) : std::move(rhs);
 | 
						|
		}
 | 
						|
#endif
 | 
						|
 | 
						|
		/// Takes the value out of the optional, leaving it empty
 | 
						|
		optional take() {
 | 
						|
			optional ret = std::move(*this);
 | 
						|
			reset();
 | 
						|
			return ret;
 | 
						|
		}
 | 
						|
 | 
						|
		using value_type = T&;
 | 
						|
 | 
						|
		/// Constructs an optional that does not contain a value.
 | 
						|
		constexpr optional() noexcept : m_value(nullptr) {}
 | 
						|
 | 
						|
		constexpr optional(nullopt_t) noexcept : m_value(nullptr) {}
 | 
						|
 | 
						|
		/// Copy constructor
 | 
						|
		///
 | 
						|
		/// If `rhs` contains a value, the stored value is direct-initialized with
 | 
						|
		/// it. Otherwise, the constructed optional is empty.
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional(const optional& rhs) noexcept = default;
 | 
						|
 | 
						|
		/// Move constructor
 | 
						|
		///
 | 
						|
		/// If `rhs` contains a value, the stored value is direct-initialized with
 | 
						|
		/// it. Otherwise, the constructed optional is empty.
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR optional(optional&& rhs) = default;
 | 
						|
 | 
						|
		/// Constructs the stored value with `u`.
 | 
						|
		template <class U = T,
 | 
						|
			detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>
 | 
						|
			* = nullptr>
 | 
						|
			constexpr optional(U&& u)  noexcept : m_value(std::addressof(u)) {
 | 
						|
			static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
 | 
						|
		}
 | 
						|
 | 
						|
		template <class U>
 | 
						|
		constexpr explicit optional(const optional<U>& rhs) noexcept : optional(*rhs) {}
 | 
						|
 | 
						|
		/// No-op
 | 
						|
		~optional() = default;
 | 
						|
 | 
						|
		/// Assignment to empty.
 | 
						|
		///
 | 
						|
		/// Destroys the current value if there is one.
 | 
						|
		optional& operator=(nullopt_t) noexcept {
 | 
						|
			m_value = nullptr;
 | 
						|
			return *this;
 | 
						|
		}
 | 
						|
 | 
						|
		/// Copy assignment.
 | 
						|
		///
 | 
						|
		/// Rebinds this optional to the referee of `rhs` if there is one. Otherwise
 | 
						|
		/// resets the stored value in `*this`.
 | 
						|
		optional& operator=(const optional& rhs) = default;
 | 
						|
 | 
						|
		/// Rebinds this optional to `u`.
 | 
						|
		template <class U = T,
 | 
						|
			detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>
 | 
						|
			* = nullptr>
 | 
						|
			optional& operator=(U&& u) {
 | 
						|
			static_assert(std::is_lvalue_reference<U>::value, "U must be an lvalue");
 | 
						|
			m_value = std::addressof(u);
 | 
						|
			return *this;
 | 
						|
		}
 | 
						|
 | 
						|
		/// Converting copy assignment operator.
 | 
						|
		///
 | 
						|
		/// Rebinds this optional to the referee of `rhs` if there is one. Otherwise
 | 
						|
		/// resets the stored value in `*this`.
 | 
						|
		template <class U> optional& operator=(const optional<U>& rhs) noexcept {
 | 
						|
			m_value = std::addressof(rhs.value());
 | 
						|
			return *this;
 | 
						|
		}
 | 
						|
 | 
						|
		/// Rebinds this optional to `u`.
 | 
						|
		template <class U = T,
 | 
						|
			detail::enable_if_t<!detail::is_optional<detail::decay_t<U>>::value>
 | 
						|
			* = nullptr>
 | 
						|
			optional& emplace(U&& u) noexcept {
 | 
						|
			return *this = std::forward<U>(u);
 | 
						|
		}
 | 
						|
 | 
						|
		void swap(optional& rhs) noexcept { std::swap(m_value, rhs.m_value); }
 | 
						|
 | 
						|
		/// Returns a pointer to the stored value
 | 
						|
		constexpr const T* operator->() const noexcept { return m_value; }
 | 
						|
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR T* operator->() noexcept { return m_value; }
 | 
						|
 | 
						|
		/// Returns the stored value
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR T& operator*() noexcept { return *m_value; }
 | 
						|
 | 
						|
		constexpr const T& operator*() const noexcept { return *m_value; }
 | 
						|
 | 
						|
		constexpr bool has_value() const noexcept { return m_value != nullptr; }
 | 
						|
 | 
						|
		constexpr explicit operator bool() const noexcept {
 | 
						|
			return m_value != nullptr;
 | 
						|
		}
 | 
						|
 | 
						|
		/// Returns the contained value if there is one, otherwise throws bad_optional_access
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR T& value() {
 | 
						|
			if(has_value())
 | 
						|
				return *m_value;
 | 
						|
			throw bad_optional_access();
 | 
						|
		}
 | 
						|
		TL_OPTIONAL_11_CONSTEXPR const T& value() const {
 | 
						|
			if(has_value())
 | 
						|
				return *m_value;
 | 
						|
			throw bad_optional_access();
 | 
						|
		}
 | 
						|
 | 
						|
		/// Returns the stored value if there is one, otherwise returns `u`
 | 
						|
		template <class U> constexpr T value_or(U&& u) const& noexcept {
 | 
						|
			static_assert(std::is_copy_constructible<T>::value &&
 | 
						|
				std::is_convertible<U&&, T>::value,
 | 
						|
				"T must be copy constructible and convertible from U");
 | 
						|
			return has_value() ? **this : static_cast<T>(std::forward<U>(u));
 | 
						|
		}
 | 
						|
 | 
						|
		/// \group value_or
 | 
						|
		template <class U> TL_OPTIONAL_11_CONSTEXPR T value_or(U&& u) && noexcept {
 | 
						|
			static_assert(std::is_move_constructible<T>::value &&
 | 
						|
				std::is_convertible<U&&, T>::value,
 | 
						|
				"T must be move constructible and convertible from U");
 | 
						|
			return has_value() ? **this : static_cast<T>(std::forward<U>(u));
 | 
						|
		}
 | 
						|
 | 
						|
		/// Destroys the stored value if one exists, making the optional empty
 | 
						|
		void reset() noexcept { m_value = nullptr; }
 | 
						|
 | 
						|
	private:
 | 
						|
		T* m_value;
 | 
						|
	}; // namespace tl
 | 
						|
 | 
						|
 | 
						|
 | 
						|
} // namespace tl
 | 
						|
 | 
						|
namespace std {
 | 
						|
	// TODO SFINAE
 | 
						|
	template <class T> struct hash<tl::optional<T>> {
 | 
						|
		::std::size_t operator()(const tl::optional<T>& o) const {
 | 
						|
			if(!o.has_value())
 | 
						|
				return 0;
 | 
						|
 | 
						|
			return std::hash<tl::detail::remove_const_t<T>>()(*o);
 | 
						|
		}
 | 
						|
	};
 | 
						|
} // namespace std
 | 
						|
 | 
						|
#endif
 |