#ifndef ARDUINO_ARCH_ESP32
// <optional> -*- C++ -*-

// Copyright (C) 2013-2024 Free Software Foundation, Inc.
// Copyright The GNU Toolchain Authors.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/optional
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_OPTIONAL
#define _GLIBCXX_OPTIONAL 1

#pragma GCC system_header

#define __glibcxx_want_freestanding_optional
#define __glibcxx_want_optional
#define __glibcxx_want_constrained_equality
#include <bits/version.h>

#ifdef __cpp_lib_optional // C++ >= 17

#include <exception>
#include <new>
#include <initializer_list>
#include <bits/enable_special_members.h>
#include <bits/exception_defines.h>
#include <bits/functional_hash.h>
#include <bits/stl_construct.h> // _Construct
#include <bits/utility.h>		// in_place_t
#if __cplusplus > 201703L
#include <compare>
#include <bits/invoke.h> // std::__invoke
#endif
#if __cplusplus > 202002L
#include <concepts>
#endif
#if __cpp_static_assert < 201411L
#define _STATICASSERT17(expr) static_assert(expr, #expr)
#else
#define _STATICASSERT17(expr) static_assert(expr)
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
	_GLIBCXX_BEGIN_NAMESPACE_VERSION

	/**
	 *  @addtogroup utilities
	 *  @{
	 */

	template <typename _Tp>
	class optional;

	/// Tag type to disengage optional objects.
	struct nullopt_t
	{
		// Do not user-declare default constructor at all for
		// optional_value = {} syntax to work.
		// nullopt_t() = delete;

		// Used for constructing nullopt.
		enum class _Construct
		{
			_Token
		};

		// Must be constexpr for nullopt_t to be literal.
		explicit constexpr nullopt_t(_Construct) noexcept {}
	};

	/// Tag to disengage optional objects.
	constexpr nullopt_t nullopt{nullopt_t::_Construct::_Token};

	template <typename _Fn>
	struct _Optional_func
	{
		_Fn &_M_f;
	};

	/**
	 *  @brief Exception class thrown when a disengaged optional object is
	 *  dereferenced.
	 *  @ingroup exceptions
	 */
	class bad_optional_access : public exception
	{
	public:
		bad_optional_access() = default;
		virtual ~bad_optional_access() = default;

		const char *what() const noexcept override
		{
			return "bad optional access";
		}
	};

	// XXX Does not belong here.
	[[__noreturn__]] inline void
	__throw_bad_optional_access()
	{
		_GLIBCXX_THROW_OR_ABORT(bad_optional_access());
	}

	// This class template manages construction/destruction of
	// the contained value for a std::optional.
	template <typename _Tp>
	struct _Optional_payload_base
	{
		using _Stored_type = remove_const_t<_Tp>;

		_Optional_payload_base() = default;
		~_Optional_payload_base() = default;

		template <typename... _Args>
		_GLIBCXX14_CONSTEXPR
		_Optional_payload_base(in_place_t __tag, _Args &&...__args)
			: _M_payload(__tag, std::forward<_Args>(__args)...),
			  _M_engaged(true)
		{
		}

		template <typename _Up, typename... _Args>
		_GLIBCXX14_CONSTEXPR
		_Optional_payload_base(std::initializer_list<_Up> __il,
							   _Args &&...__args)
			: _M_payload(__il, std::forward<_Args>(__args)...),
			  _M_engaged(true)
		{
		}

		// Constructor used by _Optional_base copy constructor when the
		// contained value is not trivially copy constructible.
		_GLIBCXX14_CONSTEXPR
		_Optional_payload_base(bool /* __engaged */,
							   const _Optional_payload_base &__other)
		{
			if (__other._M_engaged)
				this->_M_construct(__other._M_get());
		}

		// Constructor used by _Optional_base move constructor when the
		// contained value is not trivially move constructible.
		_GLIBCXX14_CONSTEXPR
		_Optional_payload_base(bool /* __engaged */,
							   _Optional_payload_base &&__other)
		{
			if (__other._M_engaged)
				this->_M_construct(std::move(__other._M_get()));
		}

		// Copy constructor is only used to when the contained value is
		// trivially copy constructible.
		_Optional_payload_base(const _Optional_payload_base &) = default;

		// Move constructor is only used to when the contained value is
		// trivially copy constructible.
		_Optional_payload_base(_Optional_payload_base &&) = default;

		_Optional_payload_base &
		operator=(const _Optional_payload_base &) = default;

		_Optional_payload_base &
		operator=(_Optional_payload_base &&) = default;

		// used to perform non-trivial copy assignment.
		_GLIBCXX14_CONSTEXPR
		void _M_copy_assign(const _Optional_payload_base &__other)
		{
			if (this->_M_engaged && __other._M_engaged)
				this->_M_get() = __other._M_get();
			else
			{
				if (__other._M_engaged)
					this->_M_construct(__other._M_get());
				else
					this->_M_reset();
			}
		}

		// used to perform non-trivial move assignment.
		constexpr void
		_M_move_assign(_Optional_payload_base &&__other) noexcept(_STRUCT14VALUEV(__and_, is_nothrow_move_constructible<_Tp>,
																				  is_nothrow_move_assignable<_Tp>))
		{
			if (this->_M_engaged && __other._M_engaged)
				this->_M_get() = std::move(__other._M_get());
			else
			{
				if (__other._M_engaged)
					this->_M_construct(std::move(__other._M_get()));
				else
					this->_M_reset();
			}
		}

		struct _Empty_byte
		{
		};

		template <typename _Up, bool = _CSL_Struct14Value_V(is_trivially_destructible, _Up)>
		union _Storage
		{
			constexpr _Storage() noexcept : _M_empty() {}

			template <typename... _Args>
			constexpr _Storage(in_place_t, _Args &&...__args)
				: _M_value(std::forward<_Args>(__args)...)
			{
			}

			template <typename _Vp, typename... _Args>
			constexpr _Storage(std::initializer_list<_Vp> __il, _Args &&...__args)
				: _M_value(__il, std::forward<_Args>(__args)...)
			{
			}

#if __cplusplus >= 202002L
			template <typename _Fn, typename _Arg>
			constexpr _Storage(_Optional_func<_Fn> __f, _Arg &&__arg)
				: _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
										 std::forward<_Arg>(__arg)))
			{
			}
#endif

#if __cpp_concepts >= 202002L // Conditionally trivial special member functions
			~_Storage() = default;

			// User-provided destructor is needed when _Up has non-trivial dtor.
			_GLIBCXX20_CONSTEXPR
			~_Storage()
				requires(!_CSL_Struct14Value_V(is_trivially_destructible, _Up))
			{
			}

			_Storage(const _Storage &) = default;
			_Storage(_Storage &&) = default;
			_Storage &operator=(const _Storage &) = default;
			_Storage &operator=(_Storage &&) = default;
#endif

			_Empty_byte _M_empty;
			_Up _M_value;
		};

#if __cpp_concepts < 202002L
		template <typename _Up>
		union _Storage<_Up, false>
		{
			constexpr _Storage() noexcept : _M_empty() {}

			template <typename... _Args>
			constexpr _Storage(in_place_t, _Args &&...__args)
				: _M_value(std::forward<_Args>(__args)...)
			{
			}

			template <typename _Vp, typename... _Args>
			constexpr _Storage(std::initializer_list<_Vp> __il, _Args &&...__args)
				: _M_value(__il, std::forward<_Args>(__args)...)
			{
			}

#if __cplusplus >= 202002L
			template <typename _Fn, typename _Arg>
			constexpr _Storage(_Optional_func<_Fn> __f, _Arg &&__arg)
				: _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),
										 std::forward<_Arg>(__arg)))
			{
			}
#endif

			// User-provided destructor is needed when _Up has non-trivial dtor.
			_GLIBCXX20_CONSTEXPR ~_Storage() {}

			_Storage(const _Storage &) = default;
			_Storage(_Storage &&) = default;
			_Storage &operator=(const _Storage &) = default;
			_Storage &operator=(_Storage &&) = default;

			_Empty_byte _M_empty;
			_Up _M_value;
		};
#endif

		_Storage<_Stored_type> _M_payload;

		bool _M_engaged = false;

		template <typename... _Args>
		_GLIBCXX14_CONSTEXPR void
		_M_construct(_Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Stored_type, _Args...))
		{
			std::_Construct(std::__addressof(this->_M_payload._M_value),
							std::forward<_Args>(__args)...);
			this->_M_engaged = true;
		}

		_GLIBCXX14_CONSTEXPR void
		_M_destroy() noexcept
		{
			_M_engaged = false;
			_M_payload._M_value.~_Stored_type();
		}

#if __cplusplus >= 202002L
		template <typename _Fn, typename _Up>
		constexpr void
		_M_apply(_Optional_func<_Fn> __f, _Up &&__x)
		{
			std::construct_at(std::__addressof(this->_M_payload),
							  __f, std::forward<_Up>(__x));
			_M_engaged = true;
		}
#endif

		// The _M_get() operations have _M_engaged as a precondition.
		// They exist to access the contained value with the appropriate
		// const-qualification, because _M_payload has had the const removed.

		_GLIBCXX14_CONSTEXPR
		_Tp &_M_get() noexcept
		{
			return this->_M_payload._M_value;
		}

		_GLIBCXX14_CONSTEXPR
		const _Tp &_M_get() const noexcept
		{
			return this->_M_payload._M_value;
		}

		// _M_reset is a 'safe' operation with no precondition.
		_GLIBCXX14_CONSTEXPR
		void _M_reset() noexcept
		{
			if (this->_M_engaged)
				_M_destroy();
			else // This seems redundant but improves codegen, see PR 112480.
				this->_M_engaged = false;
		}
	};

	// Class template that manages the payload for optionals.
	template <typename _Tp,
			  bool /*_HasTrivialDestructor*/ =
				  _CSL_Struct14Value_V(is_trivially_destructible, _Tp),
			  bool /*_HasTrivialCopy */ =
				  _CSL_Struct14Value_V(is_trivially_copy_assignable, _Tp) && _CSL_Struct14Value_V(is_trivially_copy_constructible, _Tp),
			  bool /*_HasTrivialMove */ =
				  _CSL_Struct14Value_V(is_trivially_move_assignable, _Tp) && _CSL_Struct14Value_V(is_trivially_move_constructible, _Tp)>
	struct _Optional_payload;

	// Payload for potentially-constexpr optionals (trivial copy/move/destroy).
	template <typename _Tp>
	struct _Optional_payload<_Tp, true, true, true>
		: _Optional_payload_base<_Tp>
	{
		using _Optional_payload_base<_Tp>::_Optional_payload_base;

		_Optional_payload() = default;
	};

	// Payload for optionals with non-trivial copy construction/assignment.
	template <typename _Tp>
	struct _Optional_payload<_Tp, true, false, true>
		: _Optional_payload_base<_Tp>
	{
		using _Optional_payload_base<_Tp>::_Optional_payload_base;

		_Optional_payload() = default;
		~_Optional_payload() = default;
		_Optional_payload(const _Optional_payload &) = default;
		_Optional_payload(_Optional_payload &&) = default;
		_Optional_payload &operator=(_Optional_payload &&) = default;

		// Non-trivial copy assignment.
		constexpr _Optional_payload &
		operator=(const _Optional_payload &__other)
		{
			this->_M_copy_assign(__other);
			return *this;
		}
	};

	// Payload for optionals with non-trivial move construction/assignment.
	template <typename _Tp>
	struct _Optional_payload<_Tp, true, true, false>
		: _Optional_payload_base<_Tp>
	{
		using _Optional_payload_base<_Tp>::_Optional_payload_base;

		_Optional_payload() = default;
		~_Optional_payload() = default;
		_Optional_payload(const _Optional_payload &) = default;
		_Optional_payload(_Optional_payload &&) = default;
		_Optional_payload &operator=(const _Optional_payload &) = default;

		// Non-trivial move assignment.
		constexpr _Optional_payload &
		operator=(_Optional_payload &&__other) noexcept(_STRUCT14VALUEV(__and_, is_nothrow_move_constructible<_Tp>,
																		is_nothrow_move_assignable<_Tp>))
		{
			this->_M_move_assign(std::move(__other));
			return *this;
		}
	};

	// Payload for optionals with non-trivial copy and move assignment.
	template <typename _Tp>
	struct _Optional_payload<_Tp, true, false, false>
		: _Optional_payload_base<_Tp>
	{
		using _Optional_payload_base<_Tp>::_Optional_payload_base;

		_Optional_payload() = default;
		~_Optional_payload() = default;
		_Optional_payload(const _Optional_payload &) = default;
		_Optional_payload(_Optional_payload &&) = default;

		// Non-trivial copy assignment.
		constexpr _Optional_payload &
		operator=(const _Optional_payload &__other)
		{
			this->_M_copy_assign(__other);
			return *this;
		}

		// Non-trivial move assignment.
		constexpr _Optional_payload &
		operator=(_Optional_payload &&__other) noexcept(_STRUCT14VALUEV(__and_, is_nothrow_move_constructible<_Tp>,
																		is_nothrow_move_assignable<_Tp>))
		{
			this->_M_move_assign(std::move(__other));
			return *this;
		}
	};

	// Payload for optionals with non-trivial destructors.
	template <typename _Tp, bool _Copy, bool _Move>
	struct _Optional_payload<_Tp, false, _Copy, _Move>
		: _Optional_payload<_Tp, true, false, false>
	{
		// Base class implements all the constructors and assignment operators:
		using _Optional_payload<_Tp, true, false, false>::_Optional_payload;
		_Optional_payload() = default;
		_Optional_payload(const _Optional_payload &) = default;
		_Optional_payload(_Optional_payload &&) = default;
		_Optional_payload &operator=(const _Optional_payload &) = default;
		_Optional_payload &operator=(_Optional_payload &&) = default;

		// Destructor needs to destroy the contained value:
		_GLIBCXX20_CONSTEXPR ~_Optional_payload() { this->_M_reset(); }
	};

	/**
	 * @brief Class template that provides copy/move constructors of optional.
	 *
	 * Such a separate base class template is necessary in order to
	 * conditionally make copy/move constructors trivial.
	 *
	 * When the contained value is trivially copy/move constructible,
	 * the copy/move constructors of _Optional_base will invoke the
	 * trivial copy/move constructor of _Optional_payload. Otherwise,
	 * they will invoke _Optional_payload(bool, const _Optional_payload&)
	 * or _Optional_payload(bool, _Optional_payload&&) to initialize
	 * the contained value, if copying/moving an engaged optional.
	 *
	 * Whether the other special members are trivial is determined by the
	 * _Optional_payload<_Tp> specialization used for the _M_payload member.
	 *
	 * @see optional, _Enable_special_members
	 */
	template <typename _Tp,
			  bool = _CSL_Struct14Value_V(is_trivially_copy_constructible, _Tp),
			  bool = _CSL_Struct14Value_V(is_trivially_move_constructible, _Tp)>
	struct _Optional_base
	{
		// Constructors for disengaged optionals.
		constexpr _Optional_base() = default;

		// Constructors for engaged optionals.
		template <typename... _Args,
				  enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp, _Args...), bool> = false>
		constexpr explicit _Optional_base(in_place_t, _Args &&...__args)
			: _M_payload(in_place, std::forward<_Args>(__args)...)
		{
		}

		template <typename _Up, typename... _Args,
				  enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp,
												   initializer_list<_Up> &,
												   _Args...),
							  bool> = false>
		constexpr explicit _Optional_base(in_place_t,
										  initializer_list<_Up> __il,
										  _Args &&...__args)
			: _M_payload(in_place, __il, std::forward<_Args>(__args)...)
		{
		}

		// Copy and move constructors.
		constexpr _Optional_base(const _Optional_base &__other) noexcept(_CSL_Struct14Value_V(is_nothrow_copy_constructible, _Tp))
			: _M_payload(__other._M_payload._M_engaged, __other._M_payload)
		{
		}

		constexpr _Optional_base(_Optional_base &&__other) noexcept(_CSL_Struct14Value_V(is_nothrow_move_constructible, _Tp))
			: _M_payload(__other._M_payload._M_engaged,
						 std::move(__other._M_payload))
		{
		}

#if __cpp_concepts >= 202002L // Conditionally trivial special member functions
		// Define these in the primary template if possible, so that we don't
		// need to use partial specializations of this class template.
		constexpr _Optional_base(const _Optional_base &)
			requires _CSL_Struct14Value_V
		(is_trivially_copy_constructible, _Tp) = default;

		constexpr _Optional_base(_Optional_base &&)
			requires _CSL_Struct14Value_V
		(is_trivially_move_constructible, _Tp) = default;
#endif

		// Assignment operators.
		_Optional_base &operator=(const _Optional_base &) = default;
		_Optional_base &operator=(_Optional_base &&) = default;

		_Optional_payload<_Tp> _M_payload;

	protected:
		// For the primary template, we define these functions here.
		using _Stored_type = remove_const_t<_Tp>;

		// The _M_construct operation has !_M_engaged as a precondition
		// while _M_destruct has _M_engaged as a precondition.
		template <typename... _Args>
		_GLIBCXX14_CONSTEXPR void
		_M_construct(_Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Stored_type, _Args...))
		{
			_M_payload._M_construct(std::forward<_Args>(__args)...);
		}

		constexpr void
		_M_destruct() noexcept
		{
			_M_payload._M_destroy();
		}

		// _M_reset is a 'safe' operation with no precondition.
		constexpr void
		_M_reset() noexcept
		{
			_M_payload._M_reset();
		}

		constexpr bool _M_is_engaged() const noexcept
		{
			return _M_payload._M_engaged;
		}

		// The _M_get operations have _M_engaged as a precondition.
		_GLIBCXX14_CONSTEXPR
		_Tp &_M_get() noexcept
		{
			return _M_payload._M_get();
		}

		_GLIBCXX14_CONSTEXPR
		const _Tp &_M_get() const noexcept
		{
			return _M_payload._M_get();
		}
	};

#if __cpp_concepts < 202002L
	// If P0848R3 "Conditionally Trivial Special Member Functions" is not
	// supported (as determined from the __cpp_concepts macro value), the
	// _Optional_base primary template only has non-trivial copy and move
	// constructors. Use partial specializations of _Optional_base<T, C, M>
	// that have a trivial copy and/or move constructor.

	// Common base class for _Optional_base<T> to avoid repeating these
	// member functions in each partial specialization.
	// Only used if P0848R3 "Conditionally Trivial Special Member Functions"
	// is not supported, as indicated by the __cpp_concepts value.
	template <typename _Tp, typename _Dp>
	class _Optional_base_impl
	{
	protected:
		using _Stored_type = remove_const_t<_Tp>;

		// The _M_construct operation has !_M_engaged as a precondition
		// while _M_destruct has _M_engaged as a precondition.
		template <typename... _Args>
		constexpr void
		_M_construct(_Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Stored_type, _Args...))
		{
			static_cast<_Dp *>(this)->_M_payload._M_construct(
				std::forward<_Args>(__args)...);
		}

		constexpr void
		_M_destruct() noexcept
		{
			static_cast<_Dp *>(this)->_M_payload._M_destroy();
		}

		// _M_reset is a 'safe' operation with no precondition.
		constexpr void
		_M_reset() noexcept
		{
			static_cast<_Dp *>(this)->_M_payload._M_reset();
		}

		constexpr bool _M_is_engaged() const noexcept
		{
			return static_cast<const _Dp *>(this)->_M_payload._M_engaged;
		}

		// The _M_get operations have _M_engaged as a precondition.
		_GLIBCXX14_CONSTEXPR
		_Tp &_M_get() noexcept
		{
			return static_cast<_Dp *>(this)->_M_payload._M_get();
		}

		_GLIBCXX14_CONSTEXPR
		const _Tp &_M_get() const noexcept
		{
			return static_cast<const _Dp *>(this)->_M_payload._M_get();
		}
	};

	template <typename _Tp>
	struct _Optional_base<_Tp, false, true> // trivial move ctor
		: _Optional_base_impl<_Tp, _Optional_base<_Tp>>
	{
		// Constructors for disengaged optionals.
		constexpr _Optional_base() = default;

		// Constructors for engaged optionals.
		template <typename... _Args,
				  enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp, _Args...), bool> = false>
		constexpr explicit _Optional_base(in_place_t, _Args &&...__args)
			: _M_payload(in_place, std::forward<_Args>(__args)...)
		{
		}

		template <typename _Up, typename... _Args,
				  enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp,
												   initializer_list<_Up> &,
												   _Args...),
							  bool> = false>
		constexpr explicit _Optional_base(in_place_t,
										  initializer_list<_Up> __il,
										  _Args... __args)
			: _M_payload(in_place, __il, std::forward<_Args>(__args)...)
		{
		}

		// Copy and move constructors.
		constexpr _Optional_base(const _Optional_base &__other)
			: _M_payload(__other._M_payload._M_engaged, __other._M_payload)
		{
		}

		constexpr _Optional_base(_Optional_base &&__other) = default;

		// Assignment operators.
		_Optional_base &operator=(const _Optional_base &) = default;
		_Optional_base &operator=(_Optional_base &&) = default;

		_Optional_payload<_Tp> _M_payload;
	};

	template <typename _Tp>
	struct _Optional_base<_Tp, true, false> // trivial copy ctor
		: _Optional_base_impl<_Tp, _Optional_base<_Tp>>
	{
		// Constructors for disengaged optionals.
		constexpr _Optional_base() = default;

		// Constructors for engaged optionals.
		template <typename... _Args,
				  enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp, _Args...), bool> = false>
		constexpr explicit _Optional_base(in_place_t, _Args &&...__args)
			: _M_payload(in_place, std::forward<_Args>(__args)...)
		{
		}

		template <typename _Up, typename... _Args,
				  enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp,
												   initializer_list<_Up> &,
												   _Args...),
							  bool> = false>
		constexpr explicit _Optional_base(in_place_t,
										  initializer_list<_Up> __il,
										  _Args &&...__args)
			: _M_payload(in_place, __il, std::forward<_Args>(__args)...)
		{
		}

		// Copy and move constructors.
		constexpr _Optional_base(const _Optional_base &__other) = default;

		constexpr _Optional_base(_Optional_base &&__other) noexcept(_CSL_Struct14Value_V(is_nothrow_move_constructible, _Tp))
			: _M_payload(__other._M_payload._M_engaged,
						 std::move(__other._M_payload))
		{
		}

		// Assignment operators.
		_Optional_base &operator=(const _Optional_base &) = default;
		_Optional_base &operator=(_Optional_base &&) = default;

		_Optional_payload<_Tp> _M_payload;
	};

	template <typename _Tp>
	struct _Optional_base<_Tp, true, true> // trivial copy and move ctors
		: _Optional_base_impl<_Tp, _Optional_base<_Tp>>
	{
		// Constructors for disengaged optionals.
		constexpr _Optional_base() = default;

		// Constructors for engaged optionals.
		template <typename... _Args,
				  enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp, _Args...), bool> = false>
		constexpr explicit _Optional_base(in_place_t, _Args &&...__args)
			: _M_payload(in_place, std::forward<_Args>(__args)...)
		{
		}

		template <typename _Up, typename... _Args,
				  enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp,
												   initializer_list<_Up> &,
												   _Args...),
							  bool> = false>
		constexpr explicit _Optional_base(in_place_t,
										  initializer_list<_Up> __il,
										  _Args &&...__args)
			: _M_payload(in_place, __il, std::forward<_Args>(__args)...)
		{
		}

		// Copy and move constructors.
		constexpr _Optional_base(const _Optional_base &__other) = default;
		constexpr _Optional_base(_Optional_base &&__other) = default;

		// Assignment operators.
		_Optional_base &operator=(const _Optional_base &) = default;
		_Optional_base &operator=(_Optional_base &&) = default;

		_Optional_payload<_Tp> _M_payload;
	};
#endif // __cpp_concepts

	template <typename _Tp>
	class optional;

	template <typename _Tp>
	struct __is_optional : false_type
	{
	};
	template <typename _Tp>
	struct __is_optional<optional<_Tp>> : true_type
	{
	};
	template <typename _Tp>
	inline constexpr bool __is_optional_v _CSL_Function17Variable(__is_optional<_Tp>::value);

		template <typename _Tp, typename _Wp>
		using __converts_from_any_cvref = __or_<
			is_constructible<_Tp, _Wp &>, is_convertible<_Wp &, _Tp>,
			is_constructible<_Tp, _Wp>, is_convertible<_Wp, _Tp>,
			is_constructible<_Tp, const _Wp &>, is_convertible<const _Wp &, _Tp>,
			is_constructible<_Tp, const _Wp>, is_convertible<const _Wp, _Tp>>;

	template <typename _Tp, typename _Up>
	using __converts_from_optional = __converts_from_any_cvref<_Tp, optional<_Up>>;

	template <typename _Tp, typename _Up>
	using __assigns_from_optional =
		__or_<is_assignable<_Tp &, const optional<_Up> &>,
			  is_assignable<_Tp &, optional<_Up> &>,
			  is_assignable<_Tp &, const optional<_Up> &&>,
			  is_assignable<_Tp &, optional<_Up> &&>>;

#if __cpp_concepts && __cpp_conditional_explicit && __glibcxx_remove_cvref
#define _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL 1
#endif

	/**
	 * @brief Class template for optional values.
	 */
	template <typename _Tp>
	class optional
		: private _Optional_base<_Tp>,
		  private _Enable_copy_move<
			  // Copy constructor.
			  _CSL_Struct14Value_V(is_copy_constructible, _Tp),
			  // Copy assignment.
			  _STRUCT14VALUEV(__and_, is_copy_constructible<_Tp>, is_copy_assignable<_Tp>),
			  // Move constructor.
			  _CSL_Struct14Value_V(is_move_constructible, _Tp),
			  // Move assignment.
			  _STRUCT14VALUEV(__and_, is_move_constructible<_Tp>, is_move_assignable<_Tp>),
			  // Unique tag type.
			  optional<_Tp>>
	{
		_STATICASSERT17(!_CSL_Struct14Value_V(is_same, remove_cv_t<_Tp>, nullopt_t));
		_STATICASSERT17(!_CSL_Struct14Value_V(is_same, remove_cv_t<_Tp>, in_place_t));
		_STATICASSERT17(_CSL_Struct14Value_V(is_object, _Tp) && !_CSL_Struct14Value_V(is_array, _Tp));

	private:
		using _Base = _Optional_base<_Tp>;

		// SFINAE helpers

		// _GLIBCXX_RESOLVE_LIB_DEFECTS
		// 3836. std::expected<bool, E1> conversion constructor
		// expected(const expected<U, G>&) should take precedence over
		// expected(U&&) with operator bool
#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
		template <typename _From, typename = remove_cv_t<_Tp>>
		static constexpr bool __not_constructing_bool_from_optional = true;

		// If T is cv bool, remove_cvref_t<U> is not a specialization of optional
		// i.e. do not initialize a bool from optional<U>::operator bool().
		template <typename _From>
		static constexpr bool
			__not_constructing_bool_from_optional<_From, bool> = !_CSL_Struct14Value_V(__is_optional, remove_cvref_t<_From>);

		// If T is not cv bool, converts-from-any-cvref<T, optional<U>> is false.
		// The constructor that converts from optional<U> is disabled if the
		// contained value can be initialized from optional<U>, so that the
		// optional(U&&) constructor can be used instead.
		template <typename _From, typename = remove_cv_t<_Tp>>
		static constexpr bool __construct_from_contained_value = !__converts_from_optional<_Tp, _From>::value;

		// However, optional<U> can always be converted to bool, so don't apply
		// this constraint when T is cv bool.
		template <typename _From>
		static constexpr bool __construct_from_contained_value<_From, bool> = true;
#else
		template <typename _From, typename = remove_cv_t<_Tp>>
		struct __not_constructing_bool_from_optional
			: true_type
		{
		};

		template <typename _From>
		struct __not_constructing_bool_from_optional<_From, bool>
			: bool_constant<!_CSL_Struct14Value_V(__is_optional, __remove_cvref_t<_From>)>
		{
		};

		template <typename _From, typename = remove_cv_t<_Tp>>
		struct __construct_from_contained_value
			: __not_<__converts_from_optional<_Tp, _From>>
		{
		};

		template <typename _From>
		struct __construct_from_contained_value<_From, bool>
			: true_type
		{
		};

		template <typename _Up>
		using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
		template <typename _Up>
		using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
		template <typename _Up>
		using __is_bool = is_same<remove_cv_t<_Up>, bool>;
		template <typename... _Cond>
		using _Requires = enable_if_t<_STRUCT14VALUEV(__and_, _Cond...), bool>;
#endif

	public:
		using value_type = _Tp;

		constexpr optional() noexcept {}

		constexpr optional(nullopt_t) noexcept {}

		// Converting constructors for engaged optionals.
#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
		template <typename _Up = remove_cv_t<_Tp>>
			requires(!_CSL_Struct14Value_V(is_same, optional, remove_cvref_t < _Up) >) && (!_CSL_Struct14Value_V(is_same, in_place_t, remove_cvref_t < _Up) >) && _CSL_Struct14Value_V
		(is_constructible, _Tp, _Up) && __not_constructing_bool_from_optional<_Up> constexpr explicit(!_CSL_Struct14Value_V(is_convertible, _Up, _Tp)) optional(_Up &&__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Up)) : _Base(std::in_place, std::forward<_Up>(__t))
		{
		}

		template <typename _Up>
			requires(!_CSL_Struct14Value_V(is_same, optional, remove_cvref_t < _Up) >) && _CSL_Struct14Value_V
		(is_constructible, _Tp, const _Up &) && __construct_from_contained_value<_Up> constexpr explicit(!_CSL_Struct14Value_V(is_convertible, const _Up &, _Tp)) optional(const optional<_Up> &__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, const _Up &))
		{
			if (__t)
				emplace(__t._M_get());
		}

		template <typename _Up>
			requires(!_CSL_Struct14Value_V(is_same, optional, remove_cvref_t < _Up) >) && _CSL_Struct14Value_V
		(is_constructible, _Tp, _Up) && __construct_from_contained_value<_Up> constexpr explicit(!_CSL_Struct14Value_V(is_convertible, _Up, _Tp)) optional(optional<_Up> &&__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Up))
		{
			if (__t)
				emplace(std::move(__t._M_get()));
		}

		template <typename... _Args>
			requires _CSL_Struct14Value_V
		(is_constructible, _Tp, _Args...) explicit constexpr optional(in_place_t, _Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Args...))
			: _Base(std::in_place, std::forward<_Args>(__args)...)
		{
		}

		template <typename _Up, typename... _Args>
			requires _CSL_Struct14Value_V
		(is_constructible, _Tp, initializer_list < _Up) &, _Args... >
															   explicit constexpr optional(in_place_t, initializer_list<_Up> __il, _Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, initializer_list < _Up) &,
																																							   _Args... >)
			: _Base(std::in_place, __il, std::forward<_Args>(__args)...)
		{
		}
#else
		template <typename _Up = remove_cv_t<_Tp>,
				  _Requires<__not_self<_Up>, __not_tag<_Up>,
							is_constructible<_Tp, _Up>,
							is_convertible<_Up, _Tp>,
							__not_constructing_bool_from_optional<_Up>> = true>
		constexpr optional(_Up &&__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Up))
			: _Base(std::in_place, std::forward<_Up>(__t)) {}

		template <typename _Up = remove_cv_t<_Tp>,
				  _Requires<__not_self<_Up>, __not_tag<_Up>,
							is_constructible<_Tp, _Up>,
							__not_<is_convertible<_Up, _Tp>>,
							__not_constructing_bool_from_optional<_Up>> = false>
		explicit constexpr optional(_Up &&__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Up))
			: _Base(std::in_place, std::forward<_Up>(__t)) {}

		template <typename _Up,
				  _Requires<__not_<is_same<_Tp, _Up>>,
							is_constructible<_Tp, const _Up &>,
							is_convertible<const _Up &, _Tp>,
							__construct_from_contained_value<_Up>> = true>
		_GLIBCXX14_CONSTEXPR
		optional(const optional<_Up> &__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, const _Up &))
		{
			if (__t)
				emplace(__t._M_get());
		}

		template <typename _Up,
				  _Requires<__not_<is_same<_Tp, _Up>>,
							is_constructible<_Tp, const _Up &>,
							__not_<is_convertible<const _Up &, _Tp>>,
							__construct_from_contained_value<_Up>> = false>
		explicit _GLIBCXX14_CONSTEXPR optional(const optional<_Up> &__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, const _Up &))
		{
			if (__t)
				emplace(__t._M_get());
		}

		template <typename _Up,
				  _Requires<__not_<is_same<_Tp, _Up>>,
							is_constructible<_Tp, _Up>,
							is_convertible<_Up, _Tp>,
							__construct_from_contained_value<_Up>> = true>
		_GLIBCXX14_CONSTEXPR
		optional(optional<_Up> &&__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Up))
		{
			if (__t)
				emplace(std::move(__t._M_get()));
		}

		template <typename _Up,
				  _Requires<__not_<is_same<_Tp, _Up>>,
							is_constructible<_Tp, _Up>,
							__not_<is_convertible<_Up, _Tp>>,
							__construct_from_contained_value<_Up>> = false>
		explicit _GLIBCXX14_CONSTEXPR optional(optional<_Up> &&__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Up))
		{
			if (__t)
				emplace(std::move(__t._M_get()));
		}

		template <typename... _Args,
				  _Requires<is_constructible<_Tp, _Args...>> = false>
		explicit constexpr optional(in_place_t, _Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Args...))
			: _Base(std::in_place, std::forward<_Args>(__args)...) {}

		template <typename _Up, typename... _Args,
				  _Requires<is_constructible<_Tp,
											 initializer_list<_Up> &,
											 _Args...>> = false>
		explicit constexpr optional(in_place_t, initializer_list<_Up> __il, _Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, initializer_list<_Up> &,
																															 _Args...))
			: _Base(std::in_place, __il, std::forward<_Args>(__args)...) {}
#endif

		// Assignment operators.
		_GLIBCXX20_CONSTEXPR optional &
		operator=(nullopt_t) noexcept
		{
			this->_M_reset();
			return *this;
		}

		template <typename _Up = remove_cv_t<_Tp>>
#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
			requires(!_CSL_Struct14Value_V(is_same, optional, remove_cvref_t < _Up) >) && (!(_CSL_Struct14Value_V(is_scalar, _Tp) && _CSL_Struct14Value_V(is_same, _Tp, decay_t < _Up) >)) && _CSL_Struct14Value_V
		(is_constructible, _Tp, _Up) && _CSL_Struct14Value_V(is_assignable, _Tp &, _Up) constexpr optional &
#else
		enable_if_t<_STRUCT14VALUEV(__and_, __not_self<_Up>,
									__not_<__and_<is_scalar<_Tp>,
												  is_same<_Tp, decay_t<_Up>>>>,
									is_constructible<_Tp, _Up>,
									is_assignable<_Tp &, _Up>),
					optional &>
#endif
										operator=(_Up &&__u) noexcept(_STRUCT14VALUEV(__and_, is_nothrow_constructible<_Tp, _Up>, is_nothrow_assignable<_Tp &, _Up>))
		{
			if (this->_M_is_engaged())
				this->_M_get() = std::forward<_Up>(__u);
			else
				this->_M_construct(std::forward<_Up>(__u));

			return *this;
		}

		template <typename _Up>
#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
			requires(!_CSL_Struct14Value_V(is_same, optional, remove_cvref_t < _Up) >) && _CSL_Struct14Value_V
		(is_constructible, _Tp, const _Up &) && _CSL_Struct14Value_V(is_assignable, _Tp &, const _Up &) && (!__converts_from_optional<_Tp, _Up>::value) && (!__assigns_from_optional<_Tp, _Up>::value) constexpr optional &
#else
		enable_if_t<_STRUCT14VALUEV(__and_, __not_<is_same<_Tp, _Up>>,
									is_constructible<_Tp, const _Up &>,
									is_assignable<_Tp &, const _Up &>,
									__not_<__converts_from_optional<_Tp, _Up>>,
									__not_<__assigns_from_optional<_Tp, _Up>>),
					optional &>
#endif
																																						   operator=(const optional<_Up> &__u) noexcept(_STRUCT14VALUEV(__and_, is_nothrow_constructible<_Tp, const _Up &>, is_nothrow_assignable<_Tp &, const _Up &>))
		{
			if (__u)
			{
				if (this->_M_is_engaged())
					this->_M_get() = __u._M_get();
				else
					this->_M_construct(__u._M_get());
			}
			else
			{
				this->_M_reset();
			}
			return *this;
		}

		template <typename _Up>
#ifdef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL
			requires(!_CSL_Struct14Value_V(is_same, optional, remove_cvref_t < _Up) >) && _CSL_Struct14Value_V
		(is_constructible, _Tp, _Up) && _CSL_Struct14Value_V(is_assignable, _Tp &, _Up) && (!__converts_from_optional<_Tp, _Up>::value) && (!__assigns_from_optional<_Tp, _Up>::value) constexpr optional &
#else
		enable_if_t<_STRUCT14VALUEV(__and_, __not_<is_same<_Tp, _Up>>,
									is_constructible<_Tp, _Up>,
									is_assignable<_Tp &, _Up>,
									__not_<__converts_from_optional<_Tp, _Up>>,
									__not_<__assigns_from_optional<_Tp, _Up>>),
					optional &>
#endif
																																		   operator=(optional<_Up> &&__u) noexcept(_STRUCT14VALUEV(__and_, is_nothrow_constructible<_Tp, _Up>, is_nothrow_assignable<_Tp &, _Up>))
		{
			if (__u)
			{
				if (this->_M_is_engaged())
					this->_M_get() = std::move(__u._M_get());
				else
					this->_M_construct(std::move(__u._M_get()));
			}
			else
			{
				this->_M_reset();
			}

			return *this;
		}

		template <typename... _Args>
		_GLIBCXX20_CONSTEXPR
			enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp, _Args...), _Tp &>
			emplace(_Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Args...))
		{
			this->_M_reset();
			this->_M_construct(std::forward<_Args>(__args)...);
			return this->_M_get();
		}

		template <typename _Up, typename... _Args>
		_GLIBCXX20_CONSTEXPR
			enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp, initializer_list<_Up> &, _Args...),
						_Tp &>
			emplace(initializer_list<_Up> __il, _Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, initializer_list<_Up> &,
																								 _Args...))
		{
			this->_M_reset();
			this->_M_construct(__il, std::forward<_Args>(__args)...);
			return this->_M_get();
		}

		// Destructor is implicit, implemented in _Optional_base.

		// Swap.
		_GLIBCXX20_CONSTEXPR void
		swap(optional &__other) noexcept(_CSL_Struct14Value_V(is_nothrow_move_constructible, _Tp) && _CSL_Struct14Value_V(is_nothrow_swappable, _Tp))
		{
			using std::swap;

			if (this->_M_is_engaged() && __other._M_is_engaged())
				swap(this->_M_get(), __other._M_get());
			else if (this->_M_is_engaged())
			{
				__other._M_construct(std::move(this->_M_get()));
				this->_M_destruct();
			}
			else if (__other._M_is_engaged())
			{
				this->_M_construct(std::move(__other._M_get()));
				__other._M_destruct();
			}
		}

		// Observers.
		_GLIBCXX14_CONSTEXPR
		const _Tp *
		operator->() const noexcept
		{
			__glibcxx_assert(this->_M_is_engaged());
			return std::__addressof(this->_M_get());
		}

		_GLIBCXX14_CONSTEXPR
		_Tp *
		operator->() noexcept
		{
			__glibcxx_assert(this->_M_is_engaged());
			return std::__addressof(this->_M_get());
		}

		_GLIBCXX14_CONSTEXPR
		const _Tp &
		operator*() const & noexcept
		{
			__glibcxx_assert(this->_M_is_engaged());
			return this->_M_get();
		}

		_GLIBCXX14_CONSTEXPR
		_Tp &
		operator*() & noexcept
		{
			__glibcxx_assert(this->_M_is_engaged());
			return this->_M_get();
		}

		_GLIBCXX14_CONSTEXPR
		_Tp &&
		operator*() && noexcept
		{
			__glibcxx_assert(this->_M_is_engaged());
			return std::move(this->_M_get());
		}

		_GLIBCXX14_CONSTEXPR
		const _Tp &&
		operator*() const && noexcept
		{
			__glibcxx_assert(this->_M_is_engaged());
			return std::move(this->_M_get());
		}

		constexpr explicit operator bool() const noexcept
		{
			return this->_M_is_engaged();
		}

		constexpr bool has_value() const noexcept
		{
			return this->_M_is_engaged();
		}

		_GLIBCXX14_CONSTEXPR
		const _Tp &value() const &
		{
			if (this->_M_is_engaged())
				return this->_M_get();
			__throw_bad_optional_access();
		}

		_GLIBCXX14_CONSTEXPR
		_Tp &value() &
		{
			if (this->_M_is_engaged())
				return this->_M_get();
			__throw_bad_optional_access();
		}

		_GLIBCXX14_CONSTEXPR
		_Tp &&value() &&
		{
			if (this->_M_is_engaged())
				return std::move(this->_M_get());
			__throw_bad_optional_access();
		}

		_GLIBCXX14_CONSTEXPR
		const _Tp &&value() const &&
		{
			if (this->_M_is_engaged())
				return std::move(this->_M_get());
			__throw_bad_optional_access();
		}

		template <typename _Up = remove_cv_t<_Tp>>
		constexpr _Tp
		value_or(_Up &&__u) const &
		{
			_STATICASSERT17(_CSL_Struct14Value_V(is_copy_constructible, _Tp));
			_STATICASSERT17(_CSL_Struct14Value_V(is_convertible, _Up &&, _Tp));

			if (this->_M_is_engaged())
				return this->_M_get();
			else
				return static_cast<_Tp>(std::forward<_Up>(__u));
		}

		template <typename _Up = remove_cv_t<_Tp>>
		constexpr _Tp
		value_or(_Up &&__u) &&
		{
			_STATICASSERT17(_CSL_Struct14Value_V(is_move_constructible, _Tp));
			_STATICASSERT17(_CSL_Struct14Value_V(is_convertible, _Up &&, _Tp));

			if (this->_M_is_engaged())
				return std::move(this->_M_get());
			else
				return static_cast<_Tp>(std::forward<_Up>(__u));
		}

#if __cpp_lib_optional >= 202110L // C++23
		// [optional.monadic]

		template <typename _Fn>
		constexpr auto
		and_then(_Fn &&__f) &
		{
			using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp &>>;
			static_assert(_CSL_Struct14Value_V(__is_optional, remove_cvref_t<_Up>),
						  "the function passed to std::optional<T>::and_then "
						  "must return a std::optional");
			if (has_value())
				return std::__invoke(std::forward<_Fn>(__f), _M_get());
			else
				return _Up();
		}

		template <typename _Fn>
		constexpr auto
		and_then(_Fn &&__f) const &
		{
			using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp &>>;
			static_assert(_CSL_Struct14Value_V(__is_optional, _Up),
						  "the function passed to std::optional<T>::and_then "
						  "must return a std::optional");
			if (has_value())
				return std::__invoke(std::forward<_Fn>(__f), _M_get());
			else
				return _Up();
		}

		template <typename _Fn>
		constexpr auto
		and_then(_Fn &&__f) &&
		{
			using _Up = remove_cvref_t<invoke_result_t<_Fn, _Tp>>;
			static_assert(_CSL_Struct14Value_V(__is_optional, remove_cvref_t<_Up>),
						  "the function passed to std::optional<T>::and_then "
						  "must return a std::optional");
			if (has_value())
				return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
			else
				return _Up();
		}

		template <typename _Fn>
		constexpr auto
		and_then(_Fn &&__f) const &&
		{
			using _Up = remove_cvref_t<invoke_result_t<_Fn, const _Tp>>;
			static_assert(_CSL_Struct14Value_V(__is_optional, remove_cvref_t<_Up>),
						  "the function passed to std::optional<T>::and_then "
						  "must return a std::optional");
			if (has_value())
				return std::__invoke(std::forward<_Fn>(__f), std::move(_M_get()));
			else
				return _Up();
		}

		template <typename _Fn>
		constexpr auto
		transform(_Fn &&__f) &
		{
			using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp &>>;
			if (has_value())
				return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
			else
				return optional<_Up>();
		}

		template <typename _Fn>
		constexpr auto
		transform(_Fn &&__f) const &
		{
			using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp &>>;
			if (has_value())
				return optional<_Up>(_Optional_func<_Fn>{__f}, _M_get());
			else
				return optional<_Up>();
		}

		template <typename _Fn>
		constexpr auto
		transform(_Fn &&__f) &&
		{
			using _Up = remove_cv_t<invoke_result_t<_Fn, _Tp>>;
			if (has_value())
				return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
			else
				return optional<_Up>();
		}

		template <typename _Fn>
		constexpr auto
		transform(_Fn &&__f) const &&
		{
			using _Up = remove_cv_t<invoke_result_t<_Fn, const _Tp>>;
			if (has_value())
				return optional<_Up>(_Optional_func<_Fn>{__f}, std::move(_M_get()));
			else
				return optional<_Up>();
		}

		template <typename _Fn>
			requires invocable<_Fn> && copy_constructible<_Tp>
		constexpr optional
		or_else(_Fn &&__f) const &
		{
			using _Up = invoke_result_t<_Fn>;
			static_assert(_CSL_Struct14Value_V(is_same, remove_cvref_t < _Up), optional >,
						  "the function passed to std::optional<T>::or_else "
						  "must return a std::optional<T>");

			if (has_value())
				return *this;
			else
				return std::forward<_Fn>(__f)();
		}

		template <typename _Fn>
			requires invocable<_Fn> && move_constructible<_Tp>
		constexpr optional
		or_else(_Fn &&__f) &&
		{
			using _Up = invoke_result_t<_Fn>;
			static_assert(_CSL_Struct14Value_V(is_same, remove_cvref_t < _Up), optional >,
						  "the function passed to std::optional<T>::or_else "
						  "must return a std::optional<T>");

			if (has_value())
				return std::move(*this);
			else
				return std::forward<_Fn>(__f)();
		}
#endif

		_GLIBCXX20_CONSTEXPR void reset() noexcept { this->_M_reset(); }

	private:
		using _Base::_M_get;

		template <typename _Up>
		friend class optional;

#if __cpp_lib_optional >= 202110L // C++23
		template <typename _Fn, typename _Value>
		explicit constexpr optional(_Optional_func<_Fn> __f, _Value &&__v)
		{
			this->_M_payload._M_apply(__f, std::forward<_Value>(__v));
		}
#endif
	};

	template <typename _Tp>
	using __optional_relop_t =
		enable_if_t<_CSL_Struct14Value_V(is_convertible, _Tp, bool), bool>;

	template <typename _Tp, typename _Up>
	using __optional_eq_t = __optional_relop_t<
		decltype(std::declval<const _Tp &>() == std::declval<const _Up &>())>;

	template <typename _Tp, typename _Up>
	using __optional_ne_t = __optional_relop_t<
		decltype(std::declval<const _Tp &>() != std::declval<const _Up &>())>;

	template <typename _Tp, typename _Up>
	using __optional_lt_t = __optional_relop_t<
		decltype(std::declval<const _Tp &>() < std::declval<const _Up &>())>;

	template <typename _Tp, typename _Up>
	using __optional_gt_t = __optional_relop_t<
		decltype(std::declval<const _Tp &>() > std::declval<const _Up &>())>;

	template <typename _Tp, typename _Up>
	using __optional_le_t = __optional_relop_t<
		decltype(std::declval<const _Tp &>() <= std::declval<const _Up &>())>;

	template <typename _Tp, typename _Up>
	using __optional_ge_t = __optional_relop_t<
		decltype(std::declval<const _Tp &>() >= std::declval<const _Up &>())>;

	// Comparisons between optional values.
	template <typename _Tp, typename _Up>
	constexpr auto
	operator==(const optional<_Tp> &__lhs, const optional<_Up> &__rhs)
		-> __optional_eq_t<_Tp, _Up>
	{
		return static_cast<bool>(__lhs) == static_cast<bool>(__rhs) && (!__lhs || *__lhs == *__rhs);
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator!=(const optional<_Tp> &__lhs, const optional<_Up> &__rhs)
		-> __optional_ne_t<_Tp, _Up>
	{
		return static_cast<bool>(__lhs) != static_cast<bool>(__rhs) || (static_cast<bool>(__lhs) && *__lhs != *__rhs);
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator<(const optional<_Tp> &__lhs, const optional<_Up> &__rhs)
		-> __optional_lt_t<_Tp, _Up>
	{
		return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator>(const optional<_Tp> &__lhs, const optional<_Up> &__rhs)
		-> __optional_gt_t<_Tp, _Up>
	{
		return static_cast<bool>(__lhs) && (!__rhs || *__lhs > *__rhs);
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator<=(const optional<_Tp> &__lhs, const optional<_Up> &__rhs)
		-> __optional_le_t<_Tp, _Up>
	{
		return !__lhs || (static_cast<bool>(__rhs) && *__lhs <= *__rhs);
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator>=(const optional<_Tp> &__lhs, const optional<_Up> &__rhs)
		-> __optional_ge_t<_Tp, _Up>
	{
		return !__rhs || (static_cast<bool>(__lhs) && *__lhs >= *__rhs);
	}

#ifdef __cpp_lib_three_way_comparison
	template <typename _Tp, three_way_comparable_with<_Tp> _Up>
	[[nodiscard]]
	constexpr compare_three_way_result_t<_Tp, _Up>
	operator<=>(const optional<_Tp> &__x, const optional<_Up> &__y)
	{
		return __x && __y ? *__x <=> *__y : bool(__x) <=> bool(__y);
	}
#endif

	// Comparisons with nullopt.
	template <typename _Tp>
	[[nodiscard]]
	constexpr bool
	operator==(const optional<_Tp> &__lhs, nullopt_t) noexcept
	{
		return !__lhs;
	}

#ifdef __cpp_lib_three_way_comparison
	template <typename _Tp>
	[[nodiscard]]
	constexpr strong_ordering
	operator<=>(const optional<_Tp> &__x, nullopt_t) noexcept
	{
		return bool(__x) <=> false;
	}
#else
	template <typename _Tp>
	constexpr bool
	operator==(nullopt_t, const optional<_Tp> &__rhs) noexcept
	{
		return !__rhs;
	}

	template <typename _Tp>
	constexpr bool
	operator!=(const optional<_Tp> &__lhs, nullopt_t) noexcept
	{
		return static_cast<bool>(__lhs);
	}

	template <typename _Tp>
	constexpr bool
	operator!=(nullopt_t, const optional<_Tp> &__rhs) noexcept
	{
		return static_cast<bool>(__rhs);
	}

	template <typename _Tp>
	constexpr bool
	operator<(const optional<_Tp> & /* __lhs */, nullopt_t) noexcept
	{
		return false;
	}

	template <typename _Tp>
	constexpr bool
	operator<(nullopt_t, const optional<_Tp> &__rhs) noexcept
	{
		return static_cast<bool>(__rhs);
	}

	template <typename _Tp>
	constexpr bool
	operator>(const optional<_Tp> &__lhs, nullopt_t) noexcept
	{
		return static_cast<bool>(__lhs);
	}

	template <typename _Tp>
	constexpr bool
	operator>(nullopt_t, const optional<_Tp> & /* __rhs */) noexcept
	{
		return false;
	}

	template <typename _Tp>
	constexpr bool
	operator<=(const optional<_Tp> &__lhs, nullopt_t) noexcept
	{
		return !__lhs;
	}

	template <typename _Tp>
	constexpr bool
	operator<=(nullopt_t, const optional<_Tp> & /* __rhs */) noexcept
	{
		return true;
	}

	template <typename _Tp>
	constexpr bool
	operator>=(const optional<_Tp> & /* __lhs */, nullopt_t) noexcept
	{
		return true;
	}

	template <typename _Tp>
	constexpr bool
	operator>=(nullopt_t, const optional<_Tp> &__rhs) noexcept
	{
		return !__rhs;
	}
#endif // three-way-comparison

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4072. std::optional comparisons: constrain harder
#if __cpp_lib_concepts
#define _REQUIRES_NOT_OPTIONAL(T) requires(!_CSL_Struct14Value_V(__is_optional, T))
#else
#define _REQUIRES_NOT_OPTIONAL(T)
#endif

	// Comparisons with value type.
	template <typename _Tp, typename _Up>
	constexpr auto
	operator== [[nodiscard]] (const optional<_Tp> &__lhs, const _Up &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_eq_t<_Tp, _Up>>
	{
		return __lhs && *__lhs == __rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator== [[nodiscard]] (const _Tp &__lhs, const optional<_Up> &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_eq_t<_Tp, _Up>>
	{
		return __rhs && __lhs == *__rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator!= [[nodiscard]] (const optional<_Tp> &__lhs, const _Up &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_ne_t<_Tp, _Up>>
	{
		return !__lhs || *__lhs != __rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator!= [[nodiscard]] (const _Tp &__lhs, const optional<_Up> &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_ne_t<_Tp, _Up>>
	{
		return !__rhs || __lhs != *__rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator<[[nodiscard]] (const optional<_Tp> &__lhs, const _Up &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_lt_t<_Tp, _Up>>
	{
		return !__lhs || *__lhs < __rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator<[[nodiscard]] (const _Tp &__lhs, const optional<_Up> &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_lt_t<_Tp, _Up>>
	{
		return __rhs && __lhs < *__rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator> [[nodiscard]] (const optional<_Tp> &__lhs, const _Up &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_gt_t<_Tp, _Up>>
	{
		return __lhs && *__lhs > __rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator> [[nodiscard]] (const _Tp &__lhs, const optional<_Up> &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_gt_t<_Tp, _Up>>
	{
		return !__rhs || __lhs > *__rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator<= [[nodiscard]] (const optional<_Tp> &__lhs, const _Up &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_le_t<_Tp, _Up>>
	{
		return !__lhs || *__lhs <= __rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator<= [[nodiscard]] (const _Tp &__lhs, const optional<_Up> &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_le_t<_Tp, _Up>>
	{
		return __rhs && __lhs <= *__rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator>= [[nodiscard]] (const optional<_Tp> &__lhs, const _Up &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_ge_t<_Tp, _Up>>
	{
		return __lhs && *__lhs >= __rhs;
	}

	template <typename _Tp, typename _Up>
	constexpr auto
	operator>= [[nodiscard]] (const _Tp &__lhs, const optional<_Up> &__rhs)
	-> enable_if_t<!__is_optional_v<_Up> _CSL_Parentheses11, __optional_ge_t<_Tp, _Up>>
	{
		return !__rhs || __lhs >= *__rhs;
	}

#ifdef __cpp_lib_three_way_comparison
	template <typename _Tp, typename _Up>
		requires(!_CSL_Struct14Value_V(__is_optional, _Up)) && three_way_comparable_with<_Up, _Tp>
	constexpr compare_three_way_result_t<_Tp, _Up>
	operator<=> [[nodiscard]] (const optional<_Tp> &__x, const _Up & __v)
	{
		return bool(__x) ? *__x <=> __v : strong_ordering::less;
	}
#endif

	// Swap and creation functions.

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 2748. swappable traits for optionals
	template <typename _Tp>
	_GLIBCXX20_CONSTEXPR inline enable_if_t<_CSL_Struct14Value_V(is_move_constructible, _Tp) && _CSL_Struct14Value_V(is_swappable, _Tp)>
	swap(optional<_Tp> &__lhs, optional<_Tp> &__rhs) noexcept(noexcept(__lhs.swap(__rhs)))
	{
		__lhs.swap(__rhs);
	}

	template <typename _Tp>
	enable_if_t<!(_CSL_Struct14Value_V(is_move_constructible, _Tp) && _CSL_Struct14Value_V(is_swappable, _Tp))>
	swap(optional<_Tp> &, optional<_Tp> &) = delete;

	template <typename _Tp>
	constexpr enable_if_t<_CSL_Struct14Value_V(is_constructible, decay_t<_Tp>, _Tp),
						  optional<decay_t<_Tp>>>
	make_optional(_Tp &&__t) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, optional<decay_t<_Tp>>, _Tp))
	{
		return optional<decay_t<_Tp>>{std::forward<_Tp>(__t)};
	}

	template <typename _Tp, typename... _Args>
	constexpr enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp, _Args...),
						  optional<_Tp>>
	make_optional(_Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, _Args...))
	{
		return optional<_Tp>{in_place, std::forward<_Args>(__args)...};
	}

	template <typename _Tp, typename _Up, typename... _Args>
	constexpr enable_if_t<_CSL_Struct14Value_V(is_constructible, _Tp, initializer_list<_Up> &, _Args...),
						  optional<_Tp>>
	make_optional(initializer_list<_Up> __il, _Args &&...__args) noexcept(_CSL_Struct14Value_V(is_nothrow_constructible, _Tp, initializer_list<_Up> &, _Args...))
	{
		return optional<_Tp>{in_place, __il, std::forward<_Args>(__args)...};
	}

	// Hash.

	template <typename _Tp, typename _Up = remove_const_t<_Tp>,
			  bool = __poison_hash<_Up>::__enable_hash_call>
	struct __optional_hash_call_base
	{
		size_t
		operator()(const optional<_Tp> &__t) const
			noexcept(noexcept(hash<_Up>{}(*__t)))
		{
			// We pick an arbitrary hash for disengaged optionals which hopefully
			// usual values of _Tp won't typically hash to.
			constexpr size_t __magic_disengaged_hash = static_cast<size_t>(-3333);
			return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash;
		}
	};

	template <typename _Tp, typename _Up>
	struct __optional_hash_call_base<_Tp, _Up, false>
	{
	};

	template <typename _Tp>
	struct hash<optional<_Tp>>
		: private __poison_hash<remove_const_t<_Tp>>,
		  public __optional_hash_call_base<_Tp>
	{
		using result_type [[__deprecated__]] = size_t;
		using argument_type [[__deprecated__]] = optional<_Tp>;
	};

	template <typename _Tp>
	struct __is_fast_hash<hash<optional<_Tp>>> : __is_fast_hash<hash<_Tp>>
	{
	};

	/// @}

#if __cpp_deduction_guides >= 201606
	template <typename _Tp>
	optional(_Tp) -> optional<_Tp>;
#endif

#undef _GLIBCXX_USE_CONSTRAINTS_FOR_OPTIONAL

	_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // __cpp_lib_optional

#endif // _GLIBCXX_OPTIONAL
#else
#include_next <optional>
#endif