// optional standard header
#ifndef _OPTIONAL_
#define _OPTIONAL_

#if defined(__ghs)
 #include <yvals.h>
 #if !_HAS_CPP17
  #error This file requires ISO C++17 support in the compiler
 #endif /* _HAS_CPP17 */
#endif /* __ghs */

#include <functional>

 #if defined(__ghs)
  #pragma ghs start_cxx_lib_header
  #pragma ghs startdata
  #if defined(__ghs_max_pack_value)
   #pragma pack (push, __ghs_max_pack_value)
  #endif /* defined(__ghs_max_pack_value) */
 #endif /* defined(__ghs) */

 #if defined(__ghs) && _HAS_CPP17
  #define __cpp_lib_optional 201606L
 #endif /* defined(__ghs) && _HAS_CPP17 */

_STD_BEGIN
class bad_optional_access
	: public _XSTD exception
	{	// signals access attempt for an empty optional object
public:
	typedef _XSTD exception _Mybase;
	
#if defined(__ghs)
	bad_optional_access() : _Mybase("access to empty optional object")
	{
	}
#endif
	
	explicit bad_optional_access(const string& _Message)
		: _Mybase(_Message.c_str())
		{	// construct from message string
		}

	explicit bad_optional_access(
#if defined(__ghs)		
		const char *_Message)
#else
		const char *_Message = "access to empty optional object")		
#endif	
		: _Mybase(_Message)
		{	// construct from message string
		}
	};

struct nullopt_t
	{	// flags comparison with empty
#if defined(__ghs)
	// "Type nullopt_t shall not have a default constructor or an
	// initializer-list constructor, and shall not be an aggregate."
	explicit _CONST_FUN nullopt_t(int) {}
#endif
	};

_INLINE_VAR _CONST_DATA nullopt_t nullopt
	{	// empty class
#if defined(__ghs)
	0
#endif
	};

#if defined(__ghs) //start of chain of base classes

//forward declaration
template<class _Ty>
class optional;
	
namespace _Optional_helper
{
	class _NonExistentInvalid1
	{
	private:
		explicit _NonExistentInvalid1(int) = delete;
	};
	class _NonExistentInvalid2
	{
	private:
		explicit _NonExistentInvalid2(int) = delete;
	};

	template <class _Ty, class _Uty>
	class _Is_optional_converting_constructor_SFINAE_enabled
	{
	public:
		static _CONST_DATA bool value = !is_constructible_v<_Ty, optional<_Uty>&>
						&& !is_constructible_v<_Ty, optional<_Uty>&&>
						&& !is_constructible_v<_Ty, const optional<_Uty>&>
						&& !is_constructible_v<_Ty, const optional<_Uty>&&>
						&& !is_convertible_v<optional<_Uty>&, _Ty>
						&& !is_convertible_v<optional<_Uty>&&, _Ty>
						&& !is_convertible_v<const optional<_Uty>&, _Ty>
						&& !is_convertible_v<const optional<_Uty>&&, _Ty>;
	};
	template <class _Ty, class _Uty>
	_INLINE_VAR _CONST_DATA bool _Is_optional_converting_constructor_SFINAE_enabled_v = _Is_optional_converting_constructor_SFINAE_enabled<_Ty, _Uty>::value;
	
	template <class _Ty, class _Uty>
	class _Is_optional_converting_assignment_SFINAE_enabled
	{
	public:
		static _CONST_DATA bool value = _Is_optional_converting_constructor_SFINAE_enabled<_Ty, _Uty>::value
						&& !is_assignable_v<_Ty &, optional<_Uty> &>
						&& !is_assignable_v<_Ty &, optional<_Uty> &&>
						&& !is_assignable_v<_Ty &, const optional<_Uty> &>
						&& !is_assignable_v<_Ty &, const optional<_Uty> &&>;
	};

	template <class _Ty, class _Uty>
	_INLINE_VAR _CONST_DATA bool _Is_optional_converting_assignment_SFINAE_enabled_v = _Is_optional_converting_assignment_SFINAE_enabled<_Ty, _Uty>::value;
};

//non-trivial destructor
template<class _Ty,
	 bool _Trivially_destructible = is_trivially_destructible_v<_Ty>,
	 bool _Copy_constructible = is_copy_constructible_v<_Ty>,
	 bool _Copy_assignable    = is_copy_constructible_v<_Ty> && is_copy_assignable_v<_Ty>>
	struct _Optional_base 
	{
	bool _Exists;
	struct _EmptyStruct {};
	union
	{
		_EmptyStruct _Placeholder;
		_Ty _Myvalue;
	};

	_CONST_FUN _Optional_base() _NOEXCEPT
		: _Exists(false), _Placeholder()
		{	// construct empty
		}
	
	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct by moving _Args...
		}

	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_STD in_place_t, _Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct with list of arguments
		}

	/* We can't rely on the '= default' syntax to always result in an
	   approriately defined or deleted function for copy ctors or copy
	   assignment.  This is because _Ty could have a copy ctor or
	   copy assignment operator with a non-const parameter.  That matters
	   because the '= default' syntax requires that we match the qualifiers
	   that would have been implicitly used (which depend upon _Ty); if
	   the qualifiers don't match then it results in a compilation error.
	   It is difficult to detect whether _Ty's copy parameter was 'const' or
	   not, which is annoying.  Thankfully, when _Ty uses a non-const copy
	   parameter than it makes it non-copy-constructible (or
	   non-copy-assignable), which means that we need to delete the
	   functions anyway.  This works because the '= delete' syntax doesn't
	   require the qualifiers to match the implicit version. */
	_CONST_FUN _Optional_base(const _Optional_base& _Right) = delete;
	_CONST_FUN _Optional_base(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_base& operator=(const _Optional_base& _Right) = delete;
	_CONST_FUN _Optional_base& operator=(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	void _Destroy()
		{	// destroy the object
		if (!is_trivially_destructible_v<_Ty> && _Exists)
			(_STD addressof(_Myvalue))->~_Ty();
		_Exists = false;
		_Placeholder = _EmptyStruct();
		}
	
	~_Optional_base()
		{	// destroy the object
			_Destroy();       
		}
	};

//trivial destructor
template<class _Ty>
	class _Optional_base<_Ty, true, false, false> 
	{
protected:	    
	bool _Exists;
	struct _EmptyStruct {};
	union
	{
		_EmptyStruct _Placeholder;
		_Ty _Myvalue;
	};

	_CONST_FUN _Optional_base() _NOEXCEPT
		: _Exists(false), _Placeholder()
		{	// construct empty
		}
	
	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct by moving _Args...
		}

	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_STD in_place_t, _Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct with list of arguments
		}

	/* We can't rely on the '= default' syntax to always result in an
	   approriately defined or deleted function for copy ctors or copy
	   assignment.  This is because _Ty could have a copy ctor or
	   copy assignment operator with a non-const parameter.  That matters
	   because the '= default' syntax requires that we match the qualifiers
	   that would have been implicitly used (which depend upon _Ty); if
	   the qualifiers don't match then it results in a compilation error.
	   It is difficult to detect whether _Ty's copy parameter was 'const' or
	   not, which is annoying.  Thankfully, when _Ty uses a non-const copy
	   parameter than it makes it non-copy-constructible (or
	   non-copy-assignable), which means that we need to delete the
	   functions anyway.  This works because the '= delete' syntax doesn't
	   require the qualifiers to match the implicit version. */
	_CONST_FUN _Optional_base(const _Optional_base& _Right) = delete;
	_CONST_FUN _Optional_base(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_base& operator=(const _Optional_base& _Right) = delete;
	_CONST_FUN _Optional_base& operator=(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	void _Destroy()
		{	// destroy the trivial object
		_Exists = false;
		_Placeholder = _EmptyStruct();
		}
	
	~_Optional_base() = default;
	};

template<class _Ty>
	struct _Optional_base<_Ty, false, true, false>
	{
	bool _Exists;
	struct _EmptyStruct {};
	union
	{
		_EmptyStruct _Placeholder;
		_Ty _Myvalue;
	};

	_CONST_FUN _Optional_base() _NOEXCEPT
		: _Exists(false), _Placeholder()
		{	// construct empty
		}
	
	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct by moving _Args...
		}

	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_STD in_place_t, _Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct with list of arguments
		}

	_CONST_FUN _Optional_base(const _Optional_base& _Right) = default;
	_CONST_FUN _Optional_base(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_base& operator=(const _Optional_base& _Right) = delete;
	_CONST_FUN _Optional_base& operator=(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	void _Destroy()
		{	// destroy the object
		if (!is_trivially_destructible_v<_Ty> && _Exists)
			(_STD addressof(_Myvalue))->~_Ty();
		_Exists = false;
		_Placeholder = _EmptyStruct();
		}
	
	~_Optional_base()
		{	// destroy the object
			_Destroy();       
		}
	};

//trivial destructor
template<class _Ty>
	struct _Optional_base<_Ty, true, true, false>
	{
protected:	    
	bool _Exists;
	struct _EmptyStruct {};
	union
	{
		_EmptyStruct _Placeholder;
		_Ty _Myvalue;
	};

	_CONST_FUN _Optional_base() _NOEXCEPT
		: _Exists(false), _Placeholder()
		{	// construct empty
		}
	
	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct by moving _Args...
		}

	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_STD in_place_t, _Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct with list of arguments
		}

	_CONST_FUN _Optional_base(const _Optional_base& _Right) = default;
	_CONST_FUN _Optional_base(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_base& operator=(const _Optional_base& _Right) = delete;
	_CONST_FUN _Optional_base& operator=(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	void _Destroy()
		{	// destroy the trivial object
		_Exists = false;
		_Placeholder = _EmptyStruct();
		}
	
	~_Optional_base() = default;
	};


template<class _Ty>
	struct _Optional_base<_Ty, false, false, true>; // Impossible;

template<class _Ty>
	struct _Optional_base<_Ty, true, false, true>; // Impossible;

template<class _Ty>
	struct _Optional_base<_Ty, false, true, true>
	{
	bool _Exists;
	struct _EmptyStruct {};
	union
	{
		_EmptyStruct _Placeholder;
		_Ty _Myvalue;
	};

	_CONST_FUN _Optional_base() _NOEXCEPT
		: _Exists(false), _Placeholder()
		{	// construct empty
		}
	
	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct by moving _Args...
		}

	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_STD in_place_t, _Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct with list of arguments
		}

	_CONST_FUN _Optional_base(const _Optional_base& _Right) = default;
	_CONST_FUN _Optional_base(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_base& operator=(const _Optional_base& _Right) = default;
	_CONST_FUN _Optional_base& operator=(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	void _Destroy()
		{	// destroy the object
		if (!is_trivially_destructible_v<_Ty> && _Exists)
			(_STD addressof(_Myvalue))->~_Ty();
		_Exists = false;
		_Placeholder = _EmptyStruct();
		}
	
	~_Optional_base()
		{	// destroy the object
			_Destroy();       
		}
	};

template<class _Ty>
	struct _Optional_base<_Ty, true, true, true>
	{
protected:	    
	bool _Exists;
	struct _EmptyStruct {};
	union
	{
		_EmptyStruct _Placeholder;
		_Ty _Myvalue;
	};

	_CONST_FUN _Optional_base() _NOEXCEPT
		: _Exists(false), _Placeholder()
		{	// construct empty
		}
	
	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct by moving _Args...
		}

	template<class... _Types, class = enable_if_t<is_constructible_v<_Ty, _Types...>> >
	_CONST_FUN explicit _Optional_base(_STD in_place_t, _Types&&... _Args)
			: _Exists(true),
			_Myvalue(_STD forward<_Types>(_Args)...)
		{	// construct with list of arguments
		}

	_CONST_FUN _Optional_base(const _Optional_base& _Right) = default;
	_CONST_FUN _Optional_base(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_base& operator=(const _Optional_base& _Right) = default;
	_CONST_FUN _Optional_base& operator=(_Optional_base&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	void _Destroy()
		{	// destroy the trivial object
		_Exists = false;
		_Placeholder = _EmptyStruct();
		}
	
	~_Optional_base() = default;
	};

//non-trivial copy constructor
template<class _Ty, bool>
	class _Optional_trivially_copy_constructible : public _Optional_base<_Ty>
	{
private:
	 typedef _Optional_base<_Ty> _Mybase;
protected:
	_CONST_FUN _Optional_trivially_copy_constructible() _NOEXCEPT = default;
	
	_CONST_FUN _Optional_trivially_copy_constructible(conditional_t<!is_copy_constructible_v<_Ty>, const _Optional_trivially_copy_constructible&, _Optional_helper::_NonExistentInvalid1> _Right) = delete;
	
	_CONST_FUN _Optional_trivially_copy_constructible(conditional_t<is_copy_constructible_v<_Ty>, const _Optional_trivially_copy_constructible&, _Optional_helper::_NonExistentInvalid1> _Right)
		: _Mybase()
		{	// copy from non-empty _Right
		if (_Right._Exists)
			{	// copy nonempty object
			::new ((void *)_STD addressof(this->_Myvalue)) _Ty(_Right._Myvalue);
			this->_Exists = true;
			}
		}

	_CONST_FUN _Optional_trivially_copy_constructible(_Optional_trivially_copy_constructible&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_trivially_copy_constructible& operator=(const _Optional_trivially_copy_constructible& _Right) = default;
	_CONST_FUN _Optional_trivially_copy_constructible& operator=(_Optional_trivially_copy_constructible&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	using _Mybase::_Optional_base;
	};

//trivial copy constructor
template<class _Ty>
	class _Optional_trivially_copy_constructible<_Ty, true> : public _Optional_base<_Ty>
	{
protected:
	_CONST_FUN _Optional_trivially_copy_constructible() _NOEXCEPT = default;
	_CONST_FUN _Optional_trivially_copy_constructible(const _Optional_trivially_copy_constructible& _Right) = default;
	_CONST_FUN _Optional_trivially_copy_constructible(_Optional_trivially_copy_constructible&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_trivially_copy_constructible& operator=(const _Optional_trivially_copy_constructible& _Right) = default;
	_CONST_FUN _Optional_trivially_copy_constructible& operator=(_Optional_trivially_copy_constructible&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	using _Optional_base<_Ty>::_Optional_base;
	};

//non-trivial move constructor
template<class _Ty, bool>
	class _Optional_trivially_move_constructible : public _Optional_trivially_copy_constructible<_Ty, is_trivially_copy_constructible_v<_Ty> >
	{
private:	    
        typedef _Optional_trivially_copy_constructible<_Ty, is_trivially_copy_constructible_v<_Ty> > _Mybase;	    
protected:
	_CONST_FUN _Optional_trivially_move_constructible() _NOEXCEPT = default;
	_CONST_FUN _Optional_trivially_move_constructible(const _Optional_trivially_move_constructible& _Right) = default;

	_CONST_FUN _Optional_trivially_move_constructible(conditional_t<is_move_constructible_v<_Ty>, _Optional_trivially_move_constructible &&, _Optional_helper::_NonExistentInvalid2> _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>)
			: _Mybase()
		{	// move from non-empty _Right
		if (_Right._Exists)
			{	// move nonempty
			::new ((void *)_STD addressof(this->_Myvalue))
				_Ty(_STD forward<_Ty>(_Right._Myvalue));
			this->_Exists = true;
			}
		}
		
	_CONST_FUN _Optional_trivially_move_constructible& operator=(const _Optional_trivially_move_constructible& _Right) = default;
	_CONST_FUN _Optional_trivially_move_constructible& operator=(_Optional_trivially_move_constructible&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	using _Mybase::_Optional_trivially_copy_constructible;
	};

//trivial move constructor
template<class _Ty>
	class _Optional_trivially_move_constructible<_Ty, true> : public _Optional_trivially_copy_constructible<_Ty, is_trivially_copy_constructible_v<_Ty> >
	{
protected:
	_CONST_FUN _Optional_trivially_move_constructible() _NOEXCEPT = default;
	_CONST_FUN _Optional_trivially_move_constructible(const _Optional_trivially_move_constructible& _Right) = default;
	_CONST_FUN _Optional_trivially_move_constructible(_Optional_trivially_move_constructible&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_trivially_move_constructible& operator=(const _Optional_trivially_move_constructible& _Right) = default;
	_CONST_FUN _Optional_trivially_move_constructible& operator=(_Optional_trivially_move_constructible&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	using _Optional_trivially_copy_constructible<_Ty, is_trivially_copy_constructible_v<_Ty> >::_Optional_trivially_copy_constructible;
	};

//non-trivial copy assignment operator
template<class _Ty, bool>
	class _Optional_trivially_copy_assignable : public _Optional_trivially_move_constructible<_Ty, is_trivially_move_constructible_v<_Ty> >
	{
protected:
	_CONST_FUN _Optional_trivially_copy_assignable() _NOEXCEPT = default;
	_CONST_FUN _Optional_trivially_copy_assignable(const _Optional_trivially_copy_assignable& _Right) = default;
	_CONST_FUN _Optional_trivially_copy_assignable(_Optional_trivially_copy_assignable&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;

	_CONST_FUN _Optional_trivially_copy_assignable& operator=(conditional_t<!is_copy_constructible_v<_Ty> || !is_copy_assignable_v<_Ty>, const _Optional_trivially_copy_assignable &, _Optional_helper::_NonExistentInvalid1> _Right) = delete;
	
	_CONST_FUN _Optional_trivially_copy_assignable& operator=(conditional_t<is_copy_constructible_v<_Ty> && is_copy_assignable_v<_Ty>, const _Optional_trivially_copy_assignable &, _Optional_helper::_NonExistentInvalid1> _Right)
		{	// copy assign
		if (!this->_Exists && !_Right._Exists)
			;	// nothing to do
		else if (!this->_Exists)
			{	// copy construct from _Right
			::new ((void *)_STD addressof(this->_Myvalue)) _Ty(_Right._Myvalue);
			this->_Exists = true;
			}
		else if (!_Right._Exists)
			this->_Destroy();
		else
			this->_Myvalue = _Right._Myvalue;
		return (*this);
		}
	
	_CONST_FUN _Optional_trivially_copy_assignable& operator=(_Optional_trivially_copy_assignable&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	using _Optional_trivially_move_constructible<_Ty, is_trivially_move_constructible_v<_Ty> >::_Optional_trivially_move_constructible;
	};

//trivial copy assignment operator
template<class _Ty>
	class _Optional_trivially_copy_assignable<_Ty, true> : public _Optional_trivially_move_constructible<_Ty, is_trivially_move_constructible_v<_Ty> >
	{
protected:
	_CONST_FUN _Optional_trivially_copy_assignable() _NOEXCEPT = default;
	_CONST_FUN _Optional_trivially_copy_assignable(const _Optional_trivially_copy_assignable& _Right) = default;
	_CONST_FUN _Optional_trivially_copy_assignable(_Optional_trivially_copy_assignable&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_trivially_copy_assignable& operator=(const _Optional_trivially_copy_assignable& _Right) = default;
	_CONST_FUN _Optional_trivially_copy_assignable& operator=(_Optional_trivially_copy_assignable&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	using _Optional_trivially_move_constructible<_Ty, is_trivially_move_constructible_v<_Ty> >::_Optional_trivially_move_constructible;
	};


//non-trivial move assignment operator
template<class _Ty, bool>
	class _Optional_trivially_move_assignable : public _Optional_trivially_copy_assignable<_Ty, is_trivially_copy_constructible_v<_Ty> && is_trivially_copy_assignable_v<_Ty> && is_trivially_destructible_v<_Ty> >
	{
protected:
	_CONST_FUN _Optional_trivially_move_assignable() _NOEXCEPT = default;
	_CONST_FUN _Optional_trivially_move_assignable(const _Optional_trivially_move_assignable& _Right) = default;
	_CONST_FUN _Optional_trivially_move_assignable(_Optional_trivially_move_assignable&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_trivially_move_assignable& operator=(const _Optional_trivially_move_assignable& _Right) = default;

	_CONST_FUN _Optional_trivially_move_assignable& operator=(conditional_t<is_move_constructible_v<_Ty> && is_move_assignable_v<_Ty>, _Optional_trivially_move_assignable &&, _Optional_helper::_NonExistentInvalid2> _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>)
		{	// move assign
		if (!this->_Exists && !_Right._Exists)
			;	// nothing to do
		else if (!this->_Exists)
			{	// move construct from _Right
			::new ((void *)_STD addressof(this->_Myvalue)) _Ty(_STD move(_Right._Myvalue));
			this->_Exists = true;
			}
		else if (!_Right._Exists)
			this->_Destroy();
		else
			this->_Myvalue = _STD move(_Right._Myvalue);	// move assign
		return (*this);
		}
		
	using _Optional_trivially_copy_assignable<_Ty, is_trivially_copy_constructible_v<_Ty> && is_trivially_copy_assignable_v<_Ty> && is_trivially_destructible_v<_Ty> >::_Optional_trivially_copy_assignable;
	};

//trivial move assignment operator
template<class _Ty>
	class _Optional_trivially_move_assignable<_Ty, true> : public _Optional_trivially_copy_assignable<_Ty, is_trivially_copy_constructible_v<_Ty> && is_trivially_copy_assignable_v<_Ty> && is_trivially_destructible_v<_Ty> >
	{
protected:
	_CONST_FUN _Optional_trivially_move_assignable() _NOEXCEPT = default;
	_CONST_FUN _Optional_trivially_move_assignable(const _Optional_trivially_move_assignable& _Right) = default;
	_CONST_FUN _Optional_trivially_move_assignable(_Optional_trivially_move_assignable&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
	_CONST_FUN _Optional_trivially_move_assignable& operator=(const _Optional_trivially_move_assignable& _Right) = default;
	_CONST_FUN _Optional_trivially_move_assignable& operator=(_Optional_trivially_move_assignable&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;

	using _Optional_trivially_copy_assignable<_Ty, is_trivially_copy_constructible_v<_Ty> && is_trivially_copy_assignable_v<_Ty> && is_trivially_destructible_v<_Ty> >::_Optional_trivially_copy_assignable;
	};
#endif //end of chain of base classes

		// TEMPLATE CLASS optional
template<class _Ty>
#if defined(__ghs)
	class optional : public _Optional_trivially_move_assignable<_Ty, is_trivially_move_constructible_v<_Ty> && is_trivially_move_assignable_v<_Ty> && is_trivially_destructible_v<_Ty> >
#else	
	class optional
#endif
	{	// manages an optional object
#if defined(__ghs)
	// "A program that necessitates the instantiation of template optional for
	// a reference type, or for possibly cv-qualified types in_place_t or
	// nullopt_t is ill-formed."
	static_assert(!is_reference_v<_Ty>,
		"std::optional of reference type not allowed.");
	static_assert(!is_same_v<remove_cv_t<_Ty>, in_place_t>,
		"std::optional of (possibly cv-qualified) in_place_t not allowed.");
	static_assert(!is_same_v<remove_cv_t<_Ty>, nullopt_t>,
		"std::optional of (possibly cv-qualified) nullopt_t not allowed.");
#endif

#if defined(__ghs)
private:
	template <class _Uty> friend class optional;
	typedef _Optional_trivially_move_assignable<_Ty, is_trivially_move_constructible_v<_Ty> && is_trivially_move_assignable_v<_Ty> && is_trivially_destructible_v<_Ty> > _Mybase;
#endif

public:
	typedef _Ty value_type;

	_CONST_FUN optional() _NOEXCEPT
#if defined(__ghs)
		: _Mybase()
#else
		: _Exists(false)
#endif
		{	// construct empty
		}

	_CONST_FUN optional(nullopt_t) _NOEXCEPT
#if defined(__ghs)
		: _Mybase()
#else
		: _Exists(false)
#endif
		{	// construct empty
		}

#if defined(__ghs)
	_CONST_FUN optional(const optional& _Right) = default;
#else	
	_CONST_FUN optional(const optional& _Right)
		: _Exists(false)
		{	// copy from non-empty _Right
		if (_Right._Exists)
			{	// copy nonempty object
			::new ((void *)&_Myvalue) _Ty(_Right._Myvalue);
			_Exists = true;
			}
		}
#endif

#if defined(__ghs)
	_CONST_FUN optional(optional&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty>) = default;
#else	
	_CONST_FUN optional(optional&& _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value)
			: _Exists(false)
		{	// move from non-empty _Right
		if (_Right._Exists)
			{	// move nonempty
			::new ((void *)&_Myvalue)
				_Ty(_STD forward<_Ty>(_Right._Myvalue));
			_Exists = true;
			}
		}
#endif

	template<class... _Types,
		class = enable_if_t<
			is_constructible<_Ty, _Types...>::value,
			void> >
		_CONST_FUN explicit optional(_STD in_place_t, _Types&&... _Args)
#if defined(__ghs)
			: _Mybase(_STD in_place, _STD forward<_Types>(_Args)...)
#else		
			: _Exists(true),
				_Myvalue(_STD forward<_Types>(_Args)...)
#endif			
		{	// construct with list of arguments
		}

	template<class _Other,
		class... _Types,
		class = enable_if_t<
			is_constructible<_Ty,
				_XSTD initializer_list<_Other>, _Types...>::value,
					void> >
		_CONST_FUN explicit optional(_STD in_place_t,
			_XSTD initializer_list<_Other> _Ilist, _Types&&... _Args)
#if defined(__ghs)
			: _Mybase(_Ilist, _STD forward<_Types>(_Args)...)
#else		
			: _Exists(true),
				_Myvalue(_Ilist, _STD forward<_Types>(_Args)...)
#endif			
		{	// construct with initializer_list, list of arguments
		}

#if defined(__ghs)
//conditonally explicit constructors
	template<class _Uty = _Ty,
		typename _STD enable_if_t<
			is_constructible<_Ty, _Uty&&>::value
				&& !is_same<decay_t<_Uty>, in_place_t>::value
				&& !is_same<optional<_Ty>, decay_t<_Uty> >::value
				&& is_convertible<_Uty &&, _Ty>::value,
			int> = 0>
		_CONST_FUN optional(_Uty&& _Right)
			: _Mybase(_STD forward<_Uty>(_Right))
		{	// move non-empty _Right
		}

	template<class _Uty = _Ty,
		typename _STD enable_if_t<
			is_constructible<_Ty, _Uty&&>::value
				&& !is_same<decay_t<_Uty>, in_place_t>::value
				&& !is_same<optional<_Ty>, decay_t<_Uty> >::value
				&& !is_convertible<_Uty &&, _Ty>::value,
			int> = 0>
		_CONST_FUN explicit optional(_Uty&& _Right)
			: _Mybase(_STD forward<_Uty>(_Right))
		{	// move non-empty _Right
		}
#else
	template<class _Uty = _Ty,
		class = enable_if_t<
			is_constructible<_Ty, _Uty&&>::value
				&& !is_same<decay_t<_Uty>, in_place_t>::value
				&& !is_same<optional<_Ty>, decay_t<_Uty> >::value,
			void> >
		_CONST_FUN explicit optional(_Uty&& _Right)
			: _Exists(true),
				_Myvalue(_STD forward<_Uty>(_Right))
		{	// move non-empty _Right
		}
#endif		

#if defined(__ghs)
//conditonally explicit constructors		
	template<class _Uty,
		typename _STD enable_if_t<
			is_constructible_v<_Ty, const _Uty&>
			&& _Optional_helper::_Is_optional_converting_constructor_SFINAE_enabled_v<_Ty, _Uty>
			&& is_convertible_v<const _Uty &, _Ty>,
			int> = 0>
		optional(const optional<_Uty>& _Right)
			: _Mybase()
		{	// copy non-empty _Right
		if (_Right._Exists)
			{	// move nonempty
			::new ((void *)_STD addressof(this->_Myvalue)) _Ty(_Right._Myvalue);
			this->_Exists = true;		    
			}
		}

		
	template<class _Uty,
		typename _STD enable_if_t<
			is_constructible_v<_Ty, const _Uty&>
			&& _Optional_helper::_Is_optional_converting_constructor_SFINAE_enabled_v<_Ty, _Uty>
			&& !is_convertible_v<const _Uty &, _Ty>,
			int> = 0>
		explicit optional(const optional<_Uty>& _Right)
			: _Mybase()
		{	// copy non-empty _Right
		if (_Right._Exists)
			{	// move nonempty
			::new ((void *)_STD addressof(this->_Myvalue)) _Ty(_Right._Myvalue);
			this->_Exists = true;		    
			}
		}
#else
	template<class _Uty,
		class = enable_if_t<
			is_constructible<_Ty, const _Uty&>::value
				&& !is_constructible<_Ty, optional<_Uty>&>::value
				&& !is_constructible<_Ty, optional<_Uty>&&>::value
				&& !is_constructible<_Ty, const optional<_Uty>&>::value
				&& !is_constructible<_Ty, const optional<_Uty>&&>::value
				&& !is_convertible<optional<_Uty>&, _Ty>::value
				&& !is_convertible<optional<_Uty>&&, _Ty>::value
				&& !is_convertible<const optional<_Uty>&, _Ty>::value
				&& !is_convertible<const optional<_Uty>&&, _Ty>::value,
			void> >
		explicit optional(const optional<_Uty>& _Right)
			: _Exists(false)
		{	// copy non-empty _Right
		if (_Right._Exists)
			{	// move nonempty
			::new ((void *)&_Myvalue) _Ty(_Right._Myvalue);
			_Exists = true;
			}
		}
#endif
		
#if defined(__ghs)
//conditonally explicit constructors		
	template<class _Uty,
		typename _STD enable_if_t<
			is_constructible_v<_Ty, _Uty&&>
			&& _Optional_helper::_Is_optional_converting_constructor_SFINAE_enabled_v<_Ty, _Uty>
			&& is_convertible_v<_Uty &&, _Ty>,
			int> = 0>
		optional(optional<_Uty>&& _Right)
			: _Mybase()
		{	// copy non-empty _Right
		if (_Right._Exists)
			{	// move nonempty
			::new ((void *)_STD addressof(this->_Myvalue))
				_Ty(_STD forward<_Uty>(_Right._Myvalue));
			this->_Exists = true;
			}
		}

	template<class _Uty,
		typename _STD enable_if_t<
			is_constructible_v<_Ty, _Uty&&>
			&& _Optional_helper::_Is_optional_converting_constructor_SFINAE_enabled_v<_Ty, _Uty>
			&& !is_convertible_v<_Uty &&, _Ty>,
			int> = 0>
		explicit optional(optional<_Uty>&& _Right)
			: _Mybase()
		{	// copy non-empty _Right
		if (_Right._Exists)
			{	// move nonempty
			::new ((void *)_STD addressof(this->_Myvalue))
				_Ty(_STD forward<_Uty>(_Right._Myvalue));
			this->_Exists = true;
			}
		}
#else
	template<class _Uty,
		class = enable_if_t<
			is_constructible<_Ty, _Uty&&>::value
				&& !is_constructible<_Ty, optional<_Uty>&>::value
				&& !is_constructible<_Ty, optional<_Uty>&&>::value
				&& !is_constructible<_Ty, const optional<_Uty>&>::value
				&& !is_constructible<_Ty, const optional<_Uty>&&>::value
				&& !is_convertible<optional<_Uty>&, _Ty>::value
				&& !is_convertible<optional<_Uty>&&, _Ty>::value
				&& !is_convertible<const optional<_Uty>&, _Ty>::value
				&& !is_convertible<const optional<_Uty>&&, _Ty>::value,
			void> >
		explicit optional(optional<_Uty>&& _Right)
			: _Exists(false)
		{	// copy non-empty _Right
		if (_Right._Exists)
			{	// move nonempty
			::new ((void *)&_Myvalue)
				_Ty(_STD forward<_Uty>(_Right._Myvalue));
			_Exists = true;
			}
		}
#endif

#if !defined(__ghs)		
	void _Destroy()
		{	// destroy the object
		if (!is_trivially_destructible<_Ty>::value && _Exists)
			(&_Myvalue)->~_Ty();
		_Exists = false;
		}
#endif	

#if defined(__ghs)	
	~optional() = default;
#else	
	~optional() _NOEXCEPT_OP(is_trivially_destructible<_Ty>::value)
		{	// destroy trivial object
		_Destroy();       
		}
#endif

	optional& operator=(nullopt_t) _NOEXCEPT
		{	// destroy the object
#if defined(__ghs)
		this->_Destroy();
#else
		_Destroy();
#endif
		return (*this);
		}
	
#if defined(__ghs)
	_CONST_FUN optional& operator=(const optional& _Right) = default;
#else	
	optional& operator=(const optional& _Right)
		{	// copy assign
		if (!_Exists && !_Right._Exists)
			;	// nothing to do
		else if (!_Exists)
			{	// copy construct from _Right
			::new ((void *)&_Myvalue) _Ty(_Right._Myvalue);
			_Exists = true;
			}
		else if (!_Right._Exists)
			_Destroy();
		else
			_Myvalue = _Right._Myvalue;
		return (*this);
		}
#endif

#if defined(__ghs)
	_CONST_FUN optional& operator=(optional&& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>) = default;
#else	
	optional& operator=(optional&& _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value
			&& is_nothrow_move_assignable<_Ty>::value)
		{	// move assign
		if (!_Exists && !_Right._Exists)
			;	// nothing to do
		else if (!_Exists)
			{	// move construct from _Right
			::new ((void *)&_Myvalue) _Ty(_STD move(_Right._Myvalue));
			_Exists = true;
			}
		else if (!_Right._Exists)
			;	// leave as is
		else
			_Myvalue = _STD move(_Right._Myvalue);	// move assign
		return (*this);
		}
#endif

#if defined(__ghs)		
	template<class _Other = _Ty,
#else
	template<class _Other,
#endif	
		class = enable_if_t<
			!is_same<optional<_Ty>, decay_t<_Other> >::value
			&& is_constructible<_Ty, _Other>::value
#if defined(__ghs)
			&& is_assignable<_Ty&, _Other>::value &&
			(!is_scalar<_Ty>::value || !is_same<_Ty, decay_t<_Other> >::value),
#else
			&& is_assignable<_Ty&, _Other>::value,
#endif			
			void> >
		optional& operator=(_Other&& _Right)
		{	// move assign
#if defined(__ghs)		    
		if (this->_Exists)
			this->_Myvalue = _STD forward<_Other>(_Right);	// move assign
		else
			{	// move construct from _Right
			::new ((void *)_STD addressof(this->_Myvalue)) _Ty(_STD forward<_Other>(_Right));
			this->_Exists = true;
		    
#else
		if (_Exists)
			_Myvalue = _STD forward<_Other>(_Right);	// move assign
		else
			{	// move construct from _Right
			::new ((void *)&_Myvalue) _Ty(_STD forward<_Other>(_Right));
			_Exists = true;
#endif
			}
		return (*this);
		}
		
#if defined(__ghs)
	template<class _Uty,
		class = enable_if_t<
			is_constructible_v<_Ty, const _Uty &> &&
			is_assignable_v<_Ty &, const _Uty &> &&
			_Optional_helper::_Is_optional_converting_assignment_SFINAE_enabled_v<_Ty, _Uty>,
			void> >
		optional & operator=(const optional<_Uty> & _Right)
		{    	// copy assign
		if (!this->_Exists && !_Right._Exists)
			;	// nothing to do
		else if (!this->_Exists)
			{	// copy construct from _Right
			::new ((void *)_STD addressof(this->_Myvalue)) _Ty(_Right._Myvalue);
			this->_Exists = true;			
			}
		else if (!_Right._Exists)
			this->_Destroy();
		else
			this->_Myvalue = _Right._Myvalue;
		return (*this);
		}

	template<class _Uty,
		class = enable_if_t<
			is_constructible_v<_Ty, _Uty> &&
			is_assignable_v<_Ty &, _Uty> &&
			_Optional_helper::_Is_optional_converting_assignment_SFINAE_enabled_v<_Ty, _Uty>,
			void> >
		optional & operator=(optional<_Uty> && _Right)
		{    	// move assign
		if (!this->_Exists && !_Right._Exists)
			;	// nothing to do
		else if (!this->_Exists)
			{	// move construct from _Right
			::new ((void *)_STD addressof(this->_Myvalue)) _Ty(_STD move(_Right._Myvalue));
			this->_Exists = true;
			}
		else if (!_Right._Exists)
			//the standard says it should be destroyed in this case
			this->_Destroy();
		else
			this->_Myvalue = _STD move(_Right._Myvalue);	// move assign
		return (*this);
		}
#endif

	template<class... _Types>
		_Ty& emplace(_Types&&... _Args)
		{	// reconstruct in place from _Args...
#if defined(__ghs)
		this->_Destroy();
		::new ((void *)_STD addressof(this->_Myvalue))
			_Ty(_STD forward<_Types>(_Args)...);
		this->_Exists = true;	// leave object destroyed if initializer throws
		return (this->_Myvalue);
#else
		_Destroy();
		::new ((void *)&_Myvalue)
			_Ty(_STD forward<_Types>(_Args)...);
		_Exists = true;	// leave object destroyed if initializer throws
		return (_Myvalue);
#endif
		}

	template<class _Other,
		class... _Types,
		class = enable_if_t<
			is_constructible<_Ty, _XSTD initializer_list<_Other>&,
				_Types&&...>::value,
			void> >
		_Ty& emplace(_XSTD initializer_list<_Other> _Ilist, _Types&&..._Args)
		{	// reconstruct in place from _Ilist, _Args...
#if defined(__ghs)
		this->_Destroy();
		::new ((void *)_STD addressof(this->_Myvalue))
			_Ty(_Ilist, _STD forward<_Types>(_Args)...);
		this->_Exists = true;	// leave object destroyed if initializer throws
		return (this->_Myvalue);
#else
		_Destroy();		    
		::new ((void *)&_Myvalue)
			_Ty(_Ilist, _STD forward<_Types>(_Args)...);
		_Exists = true;	// leave object destroyed if initializer throws
		return (_Myvalue);
#endif
		}

	void swap(optional<_Ty>& _Right)
		_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value
			&& is_nothrow_swappable<_Ty>::value)
		{	// swap
#if defined(__ghs)
		if (!this->_Exists && !_Right._Exists)
			;	// nothing to do
		else if (!this->_Exists)
			{	// move construct from _Right, destroy _Right
			::new ((void *)_STD addressof(this->_Myvalue)) _Ty(_STD move(_Right._Myvalue));
			this->_Exists = true;			
#else
		if (!_Exists && !_Right._Exists)
			;	// nothing to do
		else if (!_Exists)
			{	// move construct from _Right, destroy _Right
			::new ((void *)&_Myvalue) _Ty(_STD move(_Right._Myvalue));
			_Exists = true;
#endif			
			_Right._Destroy();
			}
		else if (!_Right._Exists)
			{	// move construct from *this, destroy *this
#if defined(__ghs)		    
			::new ((void *)_STD addressof(_Right._Myvalue)) _Ty(_STD move(this->_Myvalue));
			_Right._Exists = true;
			this->_Destroy();
#else			
			::new ((void *)&_Right._Myvalue) _Ty(_STD move(_Myvalue));
			_Right._Exists = true;
			_Destroy();
#endif			
			}
		else
			{	// swap the values
#if defined(__ghs)
			using std::swap;    
			swap(*(*this), *_Right);   
#else		    
			_Ty _Temp = _STD move(_Myvalue);
			_Myvalue = _STD move(_Right._Myvalue);
			_Right._Myvalue = _STD move(_Temp);
#endif			
			}
		}

	_CONST_FUN const _Ty *operator->() const
		{	// get &value
#if defined(__ghs)	    
		return (_STD addressof(this->_Myvalue));
#else		
		return (&_Myvalue);
#endif		
		}

	_CONST_FUN _Ty *operator->()
		{	// get &value
#if defined(__ghs)	    
		return (_STD addressof(this->_Myvalue));
#else		
		return (&_Myvalue);
#endif		
		}

	_CONST_FUN const _Ty& operator*() const&
		{	// get value
#if defined(__ghs)	    
		return (this->_Myvalue);
#else		
		return (_Myvalue);
#endif		
		}

	_CONST_FUN _Ty& operator*() &
		{	// get value
#if defined(__ghs)	    
		return (this->_Myvalue);
#else		
		return (_Myvalue);
#endif		
		}

	_CONST_FUN _Ty&& operator*() &&
		{	// get moved value
#if defined(__ghs)	    
		return (_STD move(this->_Myvalue));
#else		
		return (_STD move(_Myvalue));
#endif		
		}

	_CONST_FUN const _Ty&& operator*() const &&
		{	// get moved value
#if defined(__ghs)	    
		return (_STD move(this->_Myvalue));
#else		
		return (_STD move(_Myvalue));
#endif		
		}

	_CONST_FUN explicit operator bool() const _NOEXCEPT
		{	// test if value exists
#if defined(__ghs)	    
		return (this->_Exists);
#else		
		return (_Exists);
#endif
		}

	_CONST_FUN bool has_value() const _NOEXCEPT
		{	// test if value exists
#if defined(__ghs)	    
		return (this->_Exists);
#else		
		return (_Exists);
#endif
		}

	_CONST_FUN _Ty& value() &
		{	// get value or throw
		if (!bool(*this))
			_THROW_N(bad_optional_access, "optional<T> is empty");
#if defined(__ghs)	    
		return (this->_Myvalue);
#else		
		return (_Myvalue);
#endif		
		}

	_CONST_FUN const _Ty& value() const &
		{	// get value or throw
		if (!bool(*this))
			_THROW_N(bad_optional_access, "optional<T> is empty");
#if defined(__ghs)	    
		return (this->_Myvalue);
#else		
		return (_Myvalue);
#endif		
		}

	_CONST_FUN _Ty&& value() &&
		{	// get value or throw
		if (!bool(*this))
			_THROW_N(bad_optional_access, "optional<T> is empty");
#if defined(__ghs)	    
		return (_STD move(this->_Myvalue));
#else		
		return (_STD move(_Myvalue));
#endif		
		}

	_CONST_FUN const _Ty&& value() const &&
		{	// get value or throw
		if (!bool(*this))
			_THROW_N(bad_optional_access, "optional<T> is empty");
#if defined(__ghs)	    
		return (_STD move(this->_Myvalue));
#else		
		return (_STD move(_Myvalue));
#endif		
		}

	template<class _Other>
		_CONST_FUN _Ty value_or(_Other&& _Altval) const&
		{	// get moved value or _Altval
		if (!bool(*this))
			return (static_cast<_Ty>(_STD forward<_Other>(_Altval)));
		else
			return (**this);
		}

	template<class _Other>
		_CONST_FUN _Ty value_or(_Other&& _Altval) &&
		{	// get value or _Altval
		if (!bool(*this))
			return (static_cast<_Ty>(_STD forward<_Other>(_Altval)));
		else
			return (_STD move(**this));
		}

	void reset() _NOEXCEPT
		{	// destroy any stored value
#if defined(__ghs)	    
		this->_Destroy();
#else		
		_Destroy();
#endif
		}

private:
#if !defined(__ghs)	
	bool _Exists;
	_Ty _Myvalue;
#endif
	};

#if defined(__ghs)
//deduction guide
template<class T> optional(T) -> optional<T>;
#endif

#if defined(__ghs)
bool _Optional_comparison_test_function(bool) noexcept;
#endif

template<class _Ty,
#if defined(__ghs)	
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() == *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif	
	_CONST_FUN bool operator==(const optional<_Ty>& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left == _Right
	return (bool(_Left) != bool(_Right) ? false
		: bool(_Left) == false ? true
		: *_Left == *_Right);
	}

template<class _Ty,
#if defined(__ghs)	
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() == declval<const _Uty&>() ))>
#else
	class _Uty>
#endif	
	_CONST_FUN bool operator==(const optional<_Ty>& _Left,
		const _Uty& _Right)
	{	// test if _Left == _Right
	return (bool(_Left) ? *_Left == _Right : false);
	}

template<class _Ty,
#if defined(__ghs)	
	class _Uty, class = decltype(_Optional_comparison_test_function(declval<const _Ty&>() == *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator==(const _Ty& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left == _Right
	return (bool(_Right) ? _Left == *_Right : false);
	}

template<class _Ty>
	_CONST_FUN bool operator==(const optional<_Ty>&
		_Left, nullopt_t _Right) _NOEXCEPT
	{	// test if _Left == _Right
	return (!_Left);
	}

template<class _Ty>
	_CONST_FUN bool operator==(nullopt_t _Left,
		const optional<_Ty>& _Right) _NOEXCEPT
	{	// test if _Left == _Right
	return (!_Right);
	}

template<class _Ty,
#if defined(__ghs)	
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() != *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator!=(const optional<_Ty>& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left != _Right
#if defined(__ghs)
	// Can't define this in terms of (_Left == _Right) because for user-defined
	// types, (_Left == _Right) may be ill-formed or it may not be the negation
	// of (_Left != _Right).
	return (bool(_Left) != bool(_Right) ? true
		: bool(_Left) == false ? false
		: *_Left != *_Right);
#else
	return (!(_Left == _Right));
#endif
	}

template<class _Ty,
#if defined(__ghs)	
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() != declval<const _Uty&>() ))>
#else
	class _Uty>
#endif	
	_CONST_FUN bool operator!=(const optional<_Ty>& _Left,
		const _Uty& _Right)
	{	// test if _Left != _Right
#if defined(__ghs)
	return (bool(_Left) ? *_Left != _Right : true);
#else
	return (!(_Left == _Right));
#endif
	}

template<class _Ty,
#if defined(__ghs)
	class _Uty, class = decltype(_Optional_comparison_test_function(declval<const _Ty&>() != *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator!=(const _Ty& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left != _Right
#if defined(__ghs)
	return (bool(_Right) ? _Left != *_Right : true);
#else
	return (!(_Left == _Right));
#endif
	}

template<class _Ty>
	_CONST_FUN bool operator!=(const optional<_Ty>& _Left,
		nullopt_t _Right) _NOEXCEPT
	{	// test if _Left != _Right
#if defined(__ghs)
	// Note: Comparisons against nullopt_t are all defined without reference to
	// the relational operators of the underlying types. As such, these
	// comparisons do form a total ordering, even if the underlying type's
	// relational operators are nonexistent or totally crazy. So for the
	// nullopt_t overloads, it is safe to define != as the negation of ==, and
	// similar things below.
#endif
	return (!(_Left == _Right));
	}

template<class _Ty>
	_CONST_FUN bool operator!=(nullopt_t _Left,
		const optional<_Ty>& _Right) _NOEXCEPT
	{	// test if _Left != _Right
	return (!(_Left == _Right));
	}

template<class _Ty,
#if defined(__ghs)	
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() < *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator<(const optional<_Ty>& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left < _Right
	return (!_Right ? false
		: !_Left ? true
		: *_Left < *_Right);
	}

template<class _Ty,
#if defined(__ghs)
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() < declval<const _Uty&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator<(const optional<_Ty>& _Left,
		const _Uty& _Right)
	{	// test if _Left < _Right
	return (bool(_Left) ? *_Left < _Right : true);
	}

template<class _Ty,
#if defined(__ghs)
	class _Uty, class = decltype(_Optional_comparison_test_function(declval<const _Ty&>() < *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator<(const _Ty& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left < _Right
	return (bool(_Right) ? _Left < *_Right : false);
	}

template<class _Ty>
	_CONST_FUN bool operator<(const optional<_Ty>& _Left,
		nullopt_t _Right) _NOEXCEPT
	{	// test if _Left < _Right
	return (false);
	}

template<class _Ty>
	_CONST_FUN bool operator<(nullopt_t _Left,
		const optional<_Ty>& _Right) _NOEXCEPT
	{	// test if _Left < _Right
	return (bool(_Right));
	}

template<class _Ty,
#if defined(__ghs)	
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() > *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator>(const optional<_Ty>& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left > _Right
#if defined(__ghs)
	// Can't define this in terms of (_Right < _Left) because for user-defined
	// types, (_Right < _Left) may be ill-formed or it may return a different
	// value than (_Left > _Right).
	return (!_Left ? false
		: !_Right ? true
		: *_Left > *_Right);
#else
	return (_Right < _Left);
#endif
	}

template<class _Ty,
#if defined(__ghs)
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() > declval<const _Uty&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator>(const optional<_Ty>& _Left,
		const _Uty& _Right)
	{	// test if _Left > _Right
#if defined(__ghs)
	return (bool(_Left) ? *_Left > _Right : false);
#else
	return (_Right < _Left);
#endif
	}

template<class _Ty,
#if defined(__ghs)
	class _Uty, class = decltype(_Optional_comparison_test_function(declval<const _Ty&>() > *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator>(const _Ty& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left > _Right
#if defined(__ghs)
	return (bool(_Right) ? _Left > *_Right : true);
#else
	return (_Right < _Left);
#endif
	}

template<class _Ty>
	_CONST_FUN bool operator>(const optional<_Ty>& _Left,
		nullopt_t _Right) _NOEXCEPT
	{	// test if _Left > _Right
	return (_Right < _Left);
	}

template<class _Ty>
	_CONST_FUN bool operator>(nullopt_t _Left,
		const optional<_Ty>& _Right) _NOEXCEPT
	{	// test if _Left > _Right
	return (_Right < _Left);
	}

template<class _Ty,
#if defined(__ghs)	
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() <= *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator<=(const optional<_Ty>& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left <= _Right
#if defined(__ghs)
	// Can't define this in terms of (_Right < _Left) because: (1) for
	// user-defined types, (_Right < _Left) may be ill-formed or it may not be
	// the negation of (_Left <= _Right); (2) for NaNs, the two are definitely
	// not negations of each other (both are false).
	return (!_Left ? true
		: !_Right ? false
		: *_Left <= *_Right);
#else
	return (!(_Right < _Left));
#endif
	}

template<class _Ty,
#if defined(__ghs)
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() <= declval<const _Uty&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator<=(const optional<_Ty>& _Left,
		const _Uty& _Right)
	{	// test if _Left <= _Right
#if defined(__ghs)
	return (bool(_Left) ? *_Left <= _Right : true);
#else
	return (!(_Right < _Left));
#endif
	}

template<class _Ty,
#if defined(__ghs)
	class _Uty, class = decltype(_Optional_comparison_test_function(declval<const _Ty&>() <= *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator<=(const _Ty& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left <= _Right
#if defined(__ghs)
	return (bool(_Right) ? _Left <= *_Right : false);
#else
	return (!(_Right < _Left));
#endif
	}

template<class _Ty>
	_CONST_FUN bool operator<=(const optional<_Ty>& _Left,
		nullopt_t _Right) _NOEXCEPT
	{	// test if _Left <= _Right
	return (!(_Right < _Left));
	}

template<class _Ty>
	_CONST_FUN bool operator<=(nullopt_t _Left,
		const optional<_Ty>& _Right) _NOEXCEPT
	{	// test if _Left <= _Right
	return (!(_Right < _Left));
	}

template<class _Ty,
#if defined(__ghs)	
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() >= *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator>=(const optional<_Ty>& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left >= _Right
#if defined(__ghs)
	// Can't define this in terms of (_Left < _Right) because: (1) for
	// user-defined types, (_Left < _Right) may be ill-formed or it may not be
	// the negation of (_Left >= _Right); (2) for NaNs, the two are definitely
	// not negations of each other (both are false).
	return (!_Right ? true
		: !_Left ? false
		: *_Left >= *_Right);
#else
	return (!(_Left < _Right));
#endif
	}

template<class _Ty,
#if defined(__ghs)
	class _Uty, class = decltype(_Optional_comparison_test_function(*declval<const optional<_Ty>&>() >= declval<const _Uty&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator>=(const optional<_Ty>& _Left,
		const _Uty& _Right)
	{	// test if _Left >= _Right
#if defined(__ghs)
	return (bool(_Left) ? *_Left >= _Right : false);
#else
	return (!(_Left < _Right));
#endif
	}

template<class _Ty,
#if defined(__ghs)
	class _Uty, class = decltype(_Optional_comparison_test_function(declval<const _Ty&>() >= *declval<const optional<_Uty>&>() ))>
#else
	class _Uty>
#endif
	_CONST_FUN bool operator>=(const _Ty& _Left,
		const optional<_Uty>& _Right)
	{	// test if _Left >= _Right
#if defined(__ghs)
	return (bool(_Right) ? _Left >= *_Right : true);
#else
	return (!(_Left < _Right));
#endif
	}

template<class _Ty>
	_CONST_FUN bool operator>=(const optional<_Ty>& _Left,
		nullopt_t _Right) _NOEXCEPT
	{	// test if _Left >= _Right
	return (!(_Left < _Right));
	}

template<class _Ty>
	_CONST_FUN bool operator>=(nullopt_t _Left,
		const optional<_Ty>& _Right) _NOEXCEPT
	{	// test if _Left >= _Right
	return (!(_Left < _Right));
	}

template<class _Ty,
	class = enable_if_t<
		is_move_constructible<_Ty>::value && is_swappable<_Ty>::value,
		void> >
	void swap(optional<_Ty>& _Left, optional<_Ty>& _Right)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right)))
	{	// swap _Left and _Right
	_Left.swap(_Right);
	}

 #if defined(__ghs)
// LWG 2766
template<class _Ty,
	class _Dummy = void,
	class = enable_if_t<
		!(is_move_constructible<_Ty>::value && is_swappable<_Ty>::value),
		void> >
	void swap(optional<_Ty>&, optional<_Ty>&) = delete;	
 #endif /* defined(__ghs) */

template<class _Ty>
	_CONST_FUN optional<decay_t<_Ty> > make_optional(_Ty&& _Value)
	{	// make optional<_Ty> from _Value
	return (optional<decay_t<_Ty> >(_STD forward<_Ty>(_Value)));
	}

template<class _Ty,
	class... _Types>
	_CONST_FUN optional<_Ty> make_optional(_Types&&... _Args)
	{	// make optional<_Ty> from _Args...
	return (optional<_Ty>(_STD in_place, _STD forward<_Types>(_Args)...));
	}

template<class _Ty,
	class _Other,
	class... _Types>
	_CONST_FUN optional<_Ty> make_optional(
		_XSTD initializer_list<_Other> _Ilist,_Types&&... _Args)
	{	// make optional with initializer_list, _Args...
	return (optional<_Ty>(_STD in_place,
#if defined(__ghs)		
		_Ilist, _STD forward<_Types>(_Args)...));
#else	
		_Ilist, _STD forward<_Ty>(_Args)...));
#endif	
	}
_STD_END

namespace std {
	// TEMPLATE STRUCT SPECIALIZATION hash
template<class _Ty>
#if defined(__ghs)
	struct hash<optional<_Ty> > : public _Conditional_bitwise_hash<_Ty, _Is_hashable_v<remove_const_t<_Ty>> >
	{	// hash functor for optional<_Ty>
        typedef remove_const_t<_Ty> _Internal_use_Ty;
	
	template <bool _Bool_value = _Is_hashable_v<_Internal_use_Ty>, class = enable_if_t<_Bool_value> >
	size_t operator()(const optional<_Ty>& _Value) const
		{	// hash _Value to size_t or throw
		if(_Value.has_value() == true)
		{
			return hash<_Internal_use_Ty>()(*_Value);
		}
		else
		{ //empty optional object
			return 1;
		}
		}
#else							     
	struct hash<optional<_Ty> >
	{	// hash functor for optional<_Ty>
	size_t operator()(const optional<_Ty>& _Value) const
		{	// hash _Value to size_t or throw
		return (hash<_Ty>()(_Value.value_or(_Ty())));
		}
#endif	
	};
} // namespace std

 #if defined(__ghs)
  #if defined(__ghs_max_pack_value)
   #pragma pack(pop)
  #endif /* defined(__ghs_max_pack_value) */
  #pragma ghs enddata
  #pragma ghs end_cxx_lib_header
 #endif /* defined(__ghs) */

#endif /* _OPTIONAL_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V8.03b/17:0063 */
