// variant header
#ifndef _VARIANT_
#define _VARIANT_

#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 <stdexcept>
#include <tuple>
#include <type_traits>

 #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_variant 201606L
 #endif /* defined(__ghs) && _HAS_CPP17 */

_STD_BEGIN
template<class... _Types>
#if defined(__ghs)
	class variant
	{
	// Provide a more helpful error message for the following requirement:
	//     "A program that instantiates the definition of variant with no
	//     template arguments is ill-formed."
	static_assert(sizeof...(_Types) > 0,
		"variant requires at least one template argument");
	};
#else
	class variant;
#endif


	// CLASS bad_variant_access
class bad_variant_access
	: public logic_error
	{	// signals access attempt for an empty variant object
public:
	typedef logic_error _Mybase;

#if defined(__ghs)
	bad_variant_access() _THROW0() :
	    _Mybase("access to empty variant object")
	{
	}
#endif

	explicit bad_variant_access(const string& _Message)
		: _Mybase(_Message.c_str())
		{	// construct from message string
		}

	explicit bad_variant_access(
#if defined(__ghs)		
		const char *_Message)
#else
		const char *_Message = "access to empty variant object")	
#endif	
#if defined(__ghs)
			_THROW0()
#endif /* defined(__ghs) */
		: _Mybase(_Message)
		{	// construct from message string
		}
	};

_INLINE_VAR _CONST_DATA size_t variant_npos = size_t(-1);

	// TEMPLATE CLASS _Variant_void
struct _Variant_void
	{	// mapped void for variant member
	};

template<class _Ty>
	struct _Is_variant_void
		: _Cat_base<is_same<remove_cv_t<_Ty>, _Variant_void>::value>
	{	// test for mapped void type
	};

	// TEMPLATE STRUCT _Xtype
template<class _Type>
	struct _Xtype
	{	// map type as needed
	typedef _Type type;
	};

template<>
	struct _Xtype<void>
	{	// void => _Variant_void
	typedef _Variant_void type;
	};

template<class _Type>
	struct _Xtype<_Type&>
	{	// T& => reference_wrapper
	typedef reference_wrapper<_Type> type;
	};

template<class _Type>
	struct _Xtype<reference_wrapper<_Type> >
	{	// reference_wrapper => reference_wrapper
	typedef reference_wrapper<_Type> type;
	};

template<class _Type>
	using _Xtype_t =
		typename _Xtype<_Type>::type;

	// STRUCT _Max_type_size
template<class... _Rest>
	struct _Max_type_size
	{	// get basic type size
	static const size_t size = 0;
	static const size_t alignment = 0;
	};

template<class _Type1,
	class... _Rest>
	struct _Max_type_size<_Type1, _Rest...>
	{	// get max type size
	typedef _Xtype_t<_Type1> type;
	static const size_t _My_size = sizeof (type);
	static const size_t _Tail_size = _Max_type_size<_Rest...>::size;
	static const size_t size =
		_My_size < _Tail_size ? _Tail_size : _My_size;

	static const size_t _My_align = alignment_of<type>::value;
	static const size_t _Tail_align = _Max_type_size<_Rest...>::alignment;
	static const size_t alignment =
		_My_align < _Tail_align ? _Tail_align : _My_align;
	};

	// TEMPLATE CLASS variant_alternative
template<size_t _Nth,
	class... _Types>
	struct _Nth_type_counter;

template<size_t _Nth,
	class _Type1,
	class... _Types>
	struct _Nth_type_counter<_Nth, _Type1, _Types...>
	{	// define Nth type
#if defined(__ghs)
	// Provide a more helpful error message if the index is too large.
	static_assert(sizeof...(_Types) > 0,
		"variant_alternative: index out of range");
#endif
	typedef typename _Nth_type_counter<_Nth - 1, _Types...>::type type;
	};

template<class _Type1,
	class... _Types>
	struct _Nth_type_counter<0, _Type1, _Types...>
	{	// define last type
	typedef _Type1 type;
	};

template<size_t _Index,
	class _Type>
	struct variant_alternative;

template<size_t _Index,
	class... _Types>
	struct variant_alternative<_Index, variant<_Types...> >
	{	// gets type of arbitrary alternative
	typedef typename _Nth_type_counter<_Index, _Types...>::type type;
	};

#if defined(__ghs)
template<size_t _Index,
	class _Type>
	struct variant_alternative<_Index, const _Type>
	{
	typedef add_const_t<typename variant_alternative<_Index, _Type>::type>
		type;
	};

template<size_t _Index,
	class _Type>
	struct variant_alternative<_Index, volatile _Type>
	{
	typedef add_volatile_t<typename variant_alternative<_Index, _Type>::type>
		type;
	};

template<size_t _Index,
	class _Type>
	struct variant_alternative<_Index, const volatile _Type>
	{
	typedef add_cv_t<typename variant_alternative<_Index, _Type>::type>
		type;
	};
#endif /* defined(__ghs) */

template<size_t _Index,
	class... _Types>
	using variant_alternative_t =
		typename variant_alternative<_Index, _Types...>::type;	

	// TEMPLATE CLASS variant_size
template<class _Ty>
	struct variant_size;	// undefined

template<class... _Types>
	struct variant_size<variant<_Types...> >
		: integral_constant<size_t, sizeof...(_Types)>
	{	// determines number of elements in a variant
	};

template<class _Ty>
	struct variant_size<const _Ty>
		: public variant_size<_Ty>
	{	// removes const
	};
	
template<class _Ty>
	struct variant_size<volatile _Ty>
		: public variant_size<_Ty>
	{	// removes volatile
	};
	
template<class _Ty>
	struct variant_size<const volatile _Ty>
		: public variant_size<_Ty>
	{	// removes const and volatile
	};

	// FORWARD REFERENCES
template<size_t _Idx,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	variant_alternative_t<_Idx, variant<_Types...> >&
		get(variant<_Types...>& _Obj);
template<size_t _Idx,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	variant_alternative_t<_Idx, variant<_Types...> >&&
		get(variant<_Types...>&& _Obj);
template<size_t _Idx,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	variant_alternative_t<_Idx, variant<_Types...> >const &
		get(const variant<_Types...>& _Obj);
template<size_t _Idx,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	variant_alternative_t<_Idx, variant<_Types...> >const &&
		get(const variant<_Types...>&& _Obj);
template<class _Ty,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	_Ty& get(variant<_Types...>& _Obj);
template<class _Ty,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	const _Ty& get(const variant<_Types...>& _Obj);
template<class _Ty,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	_Ty&& get(variant<_Types...>&& _Obj);
template<class _Ty,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	const _Ty&& get(const variant<_Types...>&& _Obj);

	// STRUCT _Count_fn1 AND USAGES
template<size_t _Index,
	template<class> class _Is_fn,
	class...>
	struct _Count_fn1;

template<size_t _Index,
	template<class> class _Is_fn,
	class _Ty0>
	struct _Count_fn1<_Index, _Is_fn, _Ty0>
	{	// count a successful call to _Is_fn<_Ty0>
	static const size_t count = _Is_fn<_Ty0>::value == true;
	static const size_t index = count != 0 ? _Index : 0;
	};

template<size_t _Index,
	template<class> class _Is_fn,
	class _Ty0,
	class _Type1,
	class... _Rest>
	struct _Count_fn1<_Index, _Is_fn, _Ty0, _Type1, _Rest...>
	{	// count successful calls to _Is_fn<_Types...>
	static const size_t count = _Count_fn1<_Index, _Is_fn, _Ty0>::count
		+ _Count_fn1<_Index + 1, _Is_fn, _Type1, _Rest...>::count;
	static const size_t index = _Count_fn1<_Index, _Is_fn, _Ty0>::index
		+ _Count_fn1<_Index + 1, _Is_fn, _Type1, _Rest...>::index;
	};

template<template<class> class _Is_fn,
	class... _Types>
	struct _Has_one
	{	// determine whether just one type succeeds for _Is_fn
	static const bool value =
		_Count_fn1<0, _Is_fn, _Types...>::count == 1;
	static const size_t index = !value ? variant_npos :
		_Count_fn1<0, _Is_fn, _Types...>::index;
	};

template<template<class> class _Is_fn,
	class... _Types>
	struct _Has_all
	{	// determine whether all types succeed for _Is_fn
	static const bool value =
		_Count_fn1<0, _Is_fn, _Types...>::count == sizeof... (_Types);
	};

template<class... _Types>
	using _All_ca =
		_Has_all<is_copy_assignable, _Types...>;
template<class... _Types>
	using _All_cc =
		_Has_all<is_copy_constructible, _Types...>;
template<class... _Types>
	using _All_ma =
		_Has_all<is_move_assignable, _Types...>;
template<class... _Types>
	using _All_mc =
		_Has_all<is_move_constructible, _Types...>;
template<class... _Types>
	using _All_nma =
		_Has_all<is_nothrow_move_assignable, _Types...>;
template<class... _Types>
	using _All_nmc =
		_Has_all<is_nothrow_move_constructible, _Types...>;
template<class... _Types>
	using _All_ns =
		_Has_all<is_nothrow_swappable, _Types...>;
template<class... _Types>
	using _All_s =
		_Has_all<is_swappable, _Types...>;
#if defined(__ghs)
template<class... _Types>
	using _All_td =
		_Has_all<is_trivially_destructible, _Types...>;
#endif

	// STRUCT _Count_fn2 AND USAGES
template<size_t _Index,
	template<class, class...> class _Is_fn,
	class _Ty,
	class _Type0,
	class...>
	struct _Count_fn2
#if defined(__ghs)
	{	// count a successful call to _Is_fn<_Type0, _Ty>
	/*
	Use the correct parameter order for type_traits, which requires that
	_Type0 (that is, "T_j", a.k.a. one of the alternatives of the variant)
	is first.  Most of the helpers that use this class (e.g. _One_ta,
	_One_tc, _One_tna, _One_tnc) rely on this parameter order.  The only
	exception is _One_ts (for std::is_same), which can accept either
	order.	
	*/
	static const size_t count = _Is_fn<_Type0, _Ty>::value == true;
#else
	{	// count a successful call to _Is_fn<_Ty, _Type0>
	static const size_t count = _Is_fn<_Ty, _Type0>::value == true;
#endif
	static const size_t index = count != 0 ? _Index : 0;
	};

template<size_t _Index,
	template<class, class...> class _Is_fn,
	class _Ty,
	class _Type0,
	class _Type1,
	class... _Rest>
	struct _Count_fn2<_Index, _Is_fn, _Ty, _Type0, _Type1, _Rest...>
	{	// count successful calls to _Is_fn<_Ty, _Type0>...
	static const size_t count =
		_Count_fn2<_Index, _Is_fn, _Ty, _Type0>::count
			+ _Count_fn2<_Index + 1, _Is_fn, _Ty, _Type1, _Rest...>::count;
	static const size_t index =
		_Count_fn2<_Index, _Is_fn, _Ty, _Type0>::index
			+ _Count_fn2<_Index + 1, _Is_fn, _Ty, _Type1, _Rest...>::index;
	};

template<template<class, class...> class _Is_fn,
	class _Ty,
	class... _Types>
	struct _One_t
	{	// determine whether just one type succeeds for _Is_fn
	static const bool value =
		_Count_fn2<0, _Is_fn, _Ty, _Types...>::count == 1;
	static const size_t index = !value ? variant_npos :
		_Count_fn2<0, _Is_fn, _Ty, _Types...>::index;
	};

template<class _Ty,
	class... _Types>
	using _One_ta = _One_t<is_assignable, _Ty&, _Types&...>;
template<class _Ty,
	class... _Types>
	using _One_tc = _One_t<is_constructible, _Ty, _Types...>;
template<class _Ty,
	class... _Types>
	using _One_tna = _One_t<is_nothrow_assignable, _Ty&, _Types&...>;
template<class _Ty,
	class... _Types>
	using _One_tnc = _One_t<is_nothrow_constructible, _Ty, _Types...>;
template<class _Ty,
	class... _Types>
	using _One_ts = _One_t<is_same, _Ty, _Types...>;

	// TEMPLATE STRUCT _Vfunc
#if !defined(__ghs)
template<class _Ty0,
	bool _Is_arith>
	struct _Safe_compare
	{	// compares arithmetic types
	int _Doit(_Ty0 *_Left, _Ty0 *_Right)
		{	// (don't) perform unsafe compare
		return (2);
		}
	};

template<class _Ty0>
	struct _Safe_compare<_Ty0, true>
	{	// compares arithmetic types
	int _Doit(_Ty0 *_Left, _Ty0 *_Right)
		{	// perform safe compare
		return (*_Left < *_Right ? -1
			: *_Left == *_Right ? 0
			: 1);
		}
	};
#endif /* !defined(__ghs) */

template<class _Ret,
	class _Visitor,
	class... _Targs,
	size_t... _Idx> inline
	_Ret _Do_invoke(_Visitor&& _Fn,
		tuple<_Targs...>&& _Args,
		index_sequence<_Idx...>)
	{	// do the actual visit call
	return (_STD invoke(_STD forward<_Visitor>(_Fn),
		_STD get<_Idx>(_STD forward<tuple<_Targs...> >(_Args))...));
	}

template<class...>
	struct _Vfunc;

template<class _First,
	class... _Rest>
	struct _Vfunc<_First, _Rest...>
	{	// performs various operations by runtime index
	typedef _Xtype_t<_First> _Ty0;

#if defined(__ghs)
	// Note: Per C++17 [variant.relops], each of std::variant's relational
	// operators requires that the corresponding relational operator exist and
	// return a "type that is convertible to bool" for each alternative. We
	// take this to mean that the type must be implicitly convertible, which
	// matches both the std::is_convertible type trait and other
	// implementations. To enforce these constraints (without adding other
	// constraints not required by the standard), each of these functions must:
	//   - Use only the corresponding relational operator on the underlying
	//     alternative type (for example, _Compare_LT(x, y) can't check if
	//     (y > x)).
	//   - Return the result of the alternative's relational operator without a
	//     cast or anything else that would permit using an explicit
	//     operator bool(). If the alternative's relational operator returns
	//     something with an explicit operator bool(), that must result in a
	//     compile error.
	template<size_t _VIndex, class _Vtype> inline static
		_CONST_FUN bool _Compare_EQ(size_t _Index, _Vtype *_Left, _Vtype *_Right)
		{	// Check if equal
		if (_Index == 0)
			return _Get(in_place_index_t<_VIndex>{}, _Left->_Storage._Myval) ==
			       _Get(in_place_index_t<_VIndex>{}, _Right->_Storage._Myval);
		else
			return (_Vfunc<_Rest...>()._Compare_EQ<_VIndex+1>(_Index - 1, _Left, _Right));
		}

	template<size_t _VIndex, class _Vtype> inline static
		_CONST_FUN bool _Compare_NE(size_t _Index, _Vtype *_Left, _Vtype *_Right)
		{	// Check if not equal
		if (_Index == 0)
			return _Get(in_place_index_t<_VIndex>{}, _Left->_Storage._Myval) !=
			       _Get(in_place_index_t<_VIndex>{}, _Right->_Storage._Myval);
		else
			return (_Vfunc<_Rest...>()._Compare_NE<_VIndex+1>(_Index - 1, _Left, _Right));
		}

	template<size_t _VIndex, class _Vtype> inline static
		_CONST_FUN bool _Compare_LT(size_t _Index, _Vtype *_Left, _Vtype *_Right)
		{	// Check if less than
		if (_Index == 0)
			return _Get(in_place_index_t<_VIndex>{}, _Left->_Storage._Myval) <
			       _Get(in_place_index_t<_VIndex>{}, _Right->_Storage._Myval);
		else
			return (_Vfunc<_Rest...>()._Compare_LT<_VIndex+1>(_Index - 1, _Left, _Right));
		}

	template<size_t _VIndex, class _Vtype> inline static
		_CONST_FUN bool _Compare_GT(size_t _Index, _Vtype *_Left, _Vtype *_Right)
		{	// Check if greater than
		if (_Index == 0)
			return _Get(in_place_index_t<_VIndex>{}, _Left->_Storage._Myval) >
			       _Get(in_place_index_t<_VIndex>{}, _Right->_Storage._Myval);
		else
			return (_Vfunc<_Rest...>()._Compare_GT<_VIndex+1>(_Index - 1, _Left, _Right));
		}

	template<size_t _VIndex, class _Vtype> inline static
		_CONST_FUN bool _Compare_LE(size_t _Index, _Vtype *_Left, _Vtype *_Right)
		{	// Check if less than or equal
		if (_Index == 0)
			return _Get(in_place_index_t<_VIndex>{}, _Left->_Storage._Myval) <=
			       _Get(in_place_index_t<_VIndex>{}, _Right->_Storage._Myval);
		else
			return (_Vfunc<_Rest...>()._Compare_LE<_VIndex+1>(_Index - 1, _Left, _Right));
		}

	template<size_t _VIndex, class _Vtype> inline static
		_CONST_FUN bool _Compare_GE(size_t _Index, _Vtype *_Left, _Vtype *_Right)
		{	// Check if greater than or equal
		if (_Index == 0)
			return _Get(in_place_index_t<_VIndex>{}, _Left->_Storage._Myval) >=
			       _Get(in_place_index_t<_VIndex>{}, _Right->_Storage._Myval);
		else
			return (_Vfunc<_Rest...>()._Compare_GE<_VIndex+1>(_Index - 1, _Left, _Right));
		}

#else
	template<class _Vtype> inline static
		int _Compare(size_t _Index, _Vtype *_Left, _Vtype *_Right)
		{	// perform compare
		if (_Index == 0)
			return (_Safe_compare<_Ty0, is_arithmetic<_Ty0>::value>()._Doit(
				(_Ty0 *)_Left, (_Ty0 *)_Right));
		else
			return (_Vfunc<_Rest...>()._Compare(_Index - 1, _Left, _Right));
		}
#endif

	template<class _Vtype> inline static
		void _Copy(size_t _Index, _Vtype *_Left, const _Vtype *_Right)
		{	// perform copy construction
		if (_Index == 0)
			new((void *)_Left)
				_Ty0(*(_Ty0 *)_Right);
		else
			_Vfunc<_Rest...>()._Copy(_Index - 1, _Left, _Right);
		}

	template<class _Vtype,
		class _Alloc> inline static
		void _Copy_al(size_t _Index, _Vtype *_Left, _Alloc _Al,
			const _Vtype *_Right)
		{	// perform uses allocator copy construction
		if (_Index == 0)
			new((void *)_Left)
				_Ty0(_STD allocator_arg, _Al, *(_Ty0 *)_Right);
		else
			_Vfunc<_Rest...>()._Copy_al(_Index - 1, _Left, _Al, _Right);
		}

#if defined(__ghs)
	template<size_t _VIndex, class _Vtype> inline static
		void _Copy_assign(size_t _Index, _Vtype *_Left, const _Vtype *_Right)
		{	// perform copy assignment
		if (_Index == 0)
		        {
			if (_Left->_Storage._Idx == _Right->_Storage._Idx)
				{
				_Left->_Storage._Val_by_excep = false;
				_STD get<_VIndex>(*_Left) = _STD get<_Ty0>(*_Right);
				}
			else if (is_nothrow_copy_constructible_v<_Ty0> || !is_nothrow_move_constructible_v<_Ty0>)
			        {
				_Left->~variant();
				new((void *)_Left) _Ty0(*(_Ty0 *)_Right);
			        }
			else
				_Left->operator=(_Vtype(*_Right));
		        }
		else
			_Vfunc<_Rest...>()._Copy_assign<_VIndex+1>(_Index - 1, _Left, _Right);
		}
#endif /* defined(__ghs) */

	template<class _Vtype> inline static
		void _Delete(size_t _Index, _Vtype *_This)
		{	// perform placement delete
		if (_Index == 0)
			_Destroy((_Ty0 *)_This);
		else
			_Vfunc<_Rest...>()._Delete(_Index - 1, _This);
		}

	template<class _Vtype> inline static
		size_t _Hash(size_t _Index, _Vtype *_This)
		{	// perform hash
		if (_Index == 0)
#if defined(__ghs)
			return (std::hash<_STD remove_const_t<_First> >()(*(_Ty0 *)_This));
#else
			return (std::hash<_First>()(*(_Ty0 *)_This));
#endif
		else
			return (_Vfunc<_Rest...>()._Hash(_Index - 1, _This));
		}

	template<class _Vtype> inline static
		void _Move(size_t _Index, _Vtype *_Left, const _Vtype *_Right)
		{	// perform move construction
		if (_Index == 0)
			new((void *)_Left)
				_Ty0(_STD move(*(_Ty0 *)_Right));
		else
			_Vfunc<_Rest...>()._Move(_Index - 1, _Left, _Right);
		}

	template<class _Vtype,
		class _Alloc> inline static
		void _Move_al(size_t _Index, _Vtype *_Left, _Alloc _Al,
			const _Vtype *_Right)
		{	// perform uses allocator move construction
		if (_Index == 0)
			new((void *)_Left)
				_Ty0(_STD allocator_arg, _Al, _STD move(*(_Ty0 *)_Right));
		else
			_Vfunc<_Rest...>()._Move_al(_Index - 1, _Left, _Al, _Right);
		}

#if defined(__ghs)
	template<size_t _VIndex, class _Vtype> inline static
		void _Move_assign(size_t _Index, _Vtype *_Left, const _Vtype *_Right)
		{	// perform move assignment
#if _HAS_EXCEPTIONS
		try
			{
#endif /* _HAS_EXCEPTIONS */
			if (_Index == 0)
				{
				if (_Left->_Storage._Idx == _Right->_Storage._Idx)
					{
					_Left->_Storage._Val_by_excep = false;
					static_cast<_Ty0&>(*static_cast<remove_reference_t<_Ty0&>*>((void *)_Left)) =
					    static_cast<_Ty0&&>(*static_cast<remove_reference_t<_Ty0&&>*>((void *)_Right));
					}
				else
					{
					_Left->~variant();
					new((void *)_Left)_Ty0(static_cast<_Ty0&&>(*static_cast<remove_reference_t<_Ty0&&>*>((void *)_Right)));
					}
				}
			else
			        _Vfunc<_Rest...>()._Move_assign<_VIndex+1>(_Index - 1, _Left, _Right);
#if _HAS_EXCEPTIONS
			}
		catch (...)
			{
			if (_Left->_Storage._Idx != _Right->_Storage._Idx)
			        _Left->_Storage._Val_by_excep = true;
			throw;
			}
#endif /* _HAS_EXCEPTIONS */
		}
	};
#else /* !defined(GHS) */
	
	template<class _Ret,
		class _Visitor,
		class _V0first,
		class... _V0rest,
		class... _Vtypes,
		class... _Ttypes>
		_Ret _Visit(size_t _Index,
			_Visitor&& _Fn,
			tuple<_Ttypes...>&& _Vals,
			variant<_V0first, _V0rest...>&& _V0,
			_Vtypes&&... _Vrest)
		{	// one or more variants, get their active values
		if (_Index == size_t(-1))
			return (_Vfunc<_V0first, _V0rest...>().
				template _Visit<_Ret>(_V0.index(),
				_STD forward<_Visitor>(_Fn),
				_STD forward<tuple<_Ttypes...> >(_Vals),
				_STD forward<variant<_V0first, _V0rest...> >(_V0),
				_STD forward<_Vtypes>(_Vrest)...));
		else if (0 < _Index)
			return (_Vfunc<_V0rest...>().
				template _Visit<_Ret>(_Index - 1,
				_STD forward<_Visitor>(_Fn),
				_STD forward<tuple<_Ttypes...> >(_Vals),
				_STD forward<variant<_V0first, _V0rest...> >(_V0),
				_STD forward<_Vtypes>(_Vrest)...));
		else
			{	// get active type from _V0
			typedef tuple<_Ttypes..., _V0first> _Newtypes;
			_Newtypes _Newvals(_STD tuple_cat(
				_STD forward<tuple<_Ttypes...> >(_Vals),
				_STD forward<tuple<_V0first> >(tuple<_V0first>(
					_STD forward<_V0first>(_STD get<_V0first>(
					_STD forward<variant<_V0first, _V0rest...> >(_V0)))))));
			return (_Visit<_Ret>(size_t(-1),
				_STD forward<_Visitor>(_Fn),
				_STD forward<_Newtypes>(_Newvals),
				_STD forward<_Vtypes>(_Vrest)...));
			}
		}
	
	template<class _Ret,
		class _Visitor,
		class... _Ttypes>
		_Ret _Visit(size_t _Index,
			_Visitor _Fn, tuple<_Ttypes...> _Vals)
		{	// no more values, call the function
		return (_Do_invoke<_Ret>(_STD forward<_Visitor>(_Fn),
			_STD forward<tuple<_Ttypes...> >(_Vals),
			index_sequence_for<_Ttypes...>()));
		}
	};
#endif /* !defined(GHS) */

template<>
	struct _Vfunc<>
	{	// backstop, called only if _Index too big
#if defined(__ghs)
	template<size_t _VIndex, class _Vtype> inline static
		bool _Compare_EQ(size_t, _Vtype *, _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::compare failed");
		}

	template<size_t _VIndex, class _Vtype> inline static
		bool _Compare_NE(size_t, _Vtype *, _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::compare failed");
		}

	template<size_t _VIndex, class _Vtype> inline static
		bool _Compare_LT(size_t, _Vtype *, _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::compare failed");
		}

	template<size_t _VIndex, class _Vtype> inline static
		bool _Compare_GT(size_t, _Vtype *, _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::compare failed");
		}

	template<size_t _VIndex, class _Vtype> inline static
		bool _Compare_LE(size_t, _Vtype *, _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::compare failed");
		}

	template<size_t _VIndex, class _Vtype> inline static
		bool _Compare_GE(size_t, _Vtype *, _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::compare failed");
		}

#else
	template<class _Vtype> inline static
		int _Compare(size_t, _Vtype *, _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::compare failed");
		}
#endif

	template<class _Vtype> inline static
		void _Copy(size_t, _Vtype *, const _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::copy failed");
		}

	template<class _Vtype,
		class _Alloc> inline static
		void _Copy_al(size_t, _Vtype *, _Alloc, const _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::copy(allocator) failed");
		}

#if defined(__ghs)
	template<size_t _VIndex, class _Vtype> inline static
		void _Copy_assign(size_t, _Vtype *, const _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::copy_assign failed");
		}
#endif

	template<class _Vtype> inline static
		void _Delete(size_t, _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::delete failed");
		}

	template<class _Vtype> inline static
		size_t _Hash(size_t, _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::hash failed");
		}

	template<class _Vtype> inline static
		void _Move(size_t, _Vtype *, const _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::move failed");
		}

	template<class _Vtype,
		class _Alloc> inline static
		void _Move_al(size_t, _Vtype *, _Alloc, const _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::move(allocator) failed");
		}

#if defined(__ghs)
	template<size_t _VIndex, class _Vtype> inline static
		void _Move_assign(size_t, _Vtype *, const _Vtype *)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::move_assign failed");
		}

	template<class _Ret, size_t N,
#else /* !defined(GHS) */
	template<class _Ret,
#endif /* !defined(GHS) */
		class... _Types>
		_Ret _Visit(_Types... _Vals)
		{	// just throw
		_THROW_N(bad_variant_access, "variant::visit failed");
		}
	};

 #if _HAS_VARIABLE_TEMPLATES
template<class _Ty>
	_INLINE_VAR _CONST_DATA size_t variant_size_v = variant_size<_Ty>::value;
 #endif /* _HAS_VARIABLE_TEMPLATES */

template<class... _Types,
	class = enable_if_t<_All_mc<_Types...>::value
		&& _All_s<_Types...>::value,
		void> >
	void swap(variant<_Types...>& _Left,
		variant<_Types...>&_Right)
			_NOEXCEPT_OP(_All_s<_Types...>::value)
	{	// swap _Left and _Right
	_Left.swap(_Right);
	}

 #if defined(__ghs)
// LWG 2766
template<class... _Types,
	class _Dummy = void,
	class = enable_if_t<!_All_s<_Types...>::value,
		void> >
	void swap(variant<_Types...>&,
		variant<_Types...>&) = delete;

// overload checking for converting ctor
template<class _Ty, size_t _Index, class ..._Rest>
struct _Img_Funcs {
	static void _F();
};

template<class _Ty, size_t _Index, class _Ti, class ..._Rest>
struct _Img_Funcs <_Ty, _Index, _Ti, _Rest...> : _Img_Funcs<_Ty, _Index + 1, _Rest...> {
	using _Img_Funcs<_Ty, _Index + 1, _Rest...>::_F;
	/* Use a dummy second parameter with a unique type so that none of the
	   _F overloads shadow each other.  This is needed to properly detect
	   ambiguity when there are multiple alternatives with the same type.
	   Otherwise, identical type overloads would shadow each other (rather
	   than coexisting in the overload set) and we'd miss the ambiguity. */	
#if _HAS_CPP20
	// Implement P0608R3
	template<class _ArrayTy =  _Ti[1]>
		static auto _F(_Ti, _Img_Funcs* = nullptr)
			-> decltype(_ArrayTy{forward<_Ty>(declval<_Ty&&>())},
				integral_constant<size_t, _Index>{});

#else
	static integral_constant<size_t, _Index> _F(_Ti, _Img_Funcs* = nullptr);
#endif
};

#if _HAS_CPP20
// Implement P0608R3
template<class _Ty, size_t _Index, class ..._Rest>
struct _Img_Funcs <_Ty, _Index, bool, _Rest...> : _Img_Funcs<_Ty, _Index + 1, _Rest...> {
	using _Img_Funcs<_Ty, _Index + 1, _Rest...>::_F;
	template<class _Ty1 = _Ty,
	        class = enable_if_t<
		        is_same<bool, remove_cv_t<remove_reference_t<_Ty1>>>::value >>
		static integral_constant<size_t, _Index> _F(bool);
};
#endif

template<bool _Has_overload, class _Ty, size_t _Index, class _Type0, class ..._Rest>
struct _Get_overload_index {
	static constexpr size_t value = 0;
};

template<class _Ty, size_t _Index, class _Type0, class ..._Rest>
struct _Get_overload_index <true, _Ty, _Index, _Type0, _Rest...> {
	static constexpr size_t value =
	        decltype(_Img_Funcs<_Ty, _Index, _Type0, _Rest...>::_F(declval<_Ty>()))::value;
};

template<class _Ty, class _Type0, class ..._Rest>
struct _Check_overload {

	template <class _T, size_t _Idx, class _T0, class... _Rst>
	static constexpr auto _Check(int)
		-> decltype(_Img_Funcs<_T, _Idx, _T0, _Rst...>::_F(declval<_T>()), true_type());

	template <class _T, size_t _Idx, class _T0, class... _Rst>
	static constexpr auto _Check(_Wrap_int)
		-> false_type;

	static constexpr bool value = decltype(_Check<_Ty, 0, _Type0, _Rest...>(0))::value;
	static constexpr size_t index = _Get_overload_index<value, _Ty, 0, _Type0, _Rest...>::value;
};

template<typename _Type, bool = std::is_literal_type_v<_Type>>
struct _UnionWrapper;

template<typename _Type>
struct _UnionWrapper<_Type, true>
{
	template<typename... _Args>
	_CONST_FUN 
	_UnionWrapper(_Args&&... __args)
	: _Storage(std::forward<_Args>(__args)...)
	{ }
	
	_CONST_FUN const _Type& _Get() const & noexcept
	{ return _Storage; }
	
	_CONST_FUN _Type& _Get() & noexcept
	{ return _Storage; }
	
	_CONST_FUN const _Type&& _Get() const && noexcept
	{ return std::move(_Storage); }
	
	_CONST_FUN _Type&& _Get() && noexcept
	{ return std::move(_Storage); }
	
	_Type _Storage;
};

#pragma ghs nowarning 1586
template<typename _Type>
struct _UnionWrapper<_Type, false>
{
	template<typename... _Args>
	_CONST_FUN
	_UnionWrapper(_Args&&... __args) __attribute__((noinline))
	{
	  ::new ((void*)std::addressof(_Storage))
	    _Type(std::forward<_Args>(__args)...);
	}
	
	const _Type& _Get() const & noexcept __attribute__((noinline))
	{ return *(_Type *)_STD addressof(_Storage); }
	
	_Type& _Get() & noexcept __attribute__((noinline))
	{ return *(_Type *)_STD addressof(_Storage); }
	
	const _Type&& _Get() const && noexcept __attribute__((noinline))
	{ return std::move(*(_Type *)_STD addressof(_Storage)); }
	
	_Type&& _Get() && noexcept __attribute__((noinline))
	{ return std::move(*(_Type *)_STD addressof(_Storage)); }

private:
	typename aligned_storage<sizeof(_Type), alignof(_Type)>::type _Storage;
};
#pragma ghs endnowarning 1586

template<class... _Types>
union _VariantUnion { };

template<class _Type0,
       class... _Rest>
union _VariantUnion<_Type0, _Rest...>
{
	_CONST_FUN _VariantUnion() : _Others() { }
	
	template<class... _Args>
	_CONST_FUN _VariantUnion(in_place_index_t<0>, _Args&&... __args)
	: _First(std::forward<_Args>(__args)...) { }
	
	template<size_t _Np, class... _Args>
	_CONST_FUN _VariantUnion(in_place_index_t<_Np>, _Args&&... __args)
	: _Others(in_place_index<_Np-1>, std::forward<_Args>(__args)...) { }
	
	_UnionWrapper<_Type0>   _First;
	_VariantUnion<_Rest...> _Others;
};

template<typename _Union>
_CONST_FUN decltype(auto)
_Get(in_place_index_t<0>, _Union&& __u) noexcept
{
	return std::forward<_Union>(__u)._First._Get();
}

template<size_t _Np, typename _Union>
_CONST_FUN decltype(auto)
_Get(in_place_index_t<_Np>, _Union&& __u) noexcept
{
	return _Get(in_place_index<_Np-1>, std::forward<_Union>(__u)._Others);
}

template<bool _TrivialDestructor,
	class _Type0,
	class... _Rest>
	class _VariantStorage
	{	// variant with one or more elements
public:
	typedef _Xtype_t<_Type0> _Ty0;
	
	_CONST_FUNX _VariantStorage(void)
		: _Idx(0), _Val_by_excep(false), _Myval()
		{
		}

	template<size_t _Index, typename... _Args>
	_CONST_FUNX _VariantStorage(in_place_index_t<_Index>, bool _Except, _Args&&... _Vals)
		: _Idx(_Index), _Val_by_excep(_Except), _Myval(in_place_index<_Index>, _STD forward<_Args>(_Vals)...)
		{
		}

	~_VariantStorage() _NOEXCEPT
		{	// destroy the object
		if (!_Val_by_excep)
			_Vfunc<_Ty0, _Rest...>()._Delete(_Idx, this);
		(volatile bool&)_Val_by_excep = true;	// [sic] GCC compiler bug
		}

	_VariantUnion<_Type0, _Rest...> _Myval;
	bool _Val_by_excep;
	size_t _Idx;
	};

template<class _Type0,
	class... _Rest>
	class _VariantStorage<true, _Type0, _Rest...>
	{	// variant with one or more elements
public:
	typedef _Xtype_t<_Type0> _Ty0;

	_CONST_FUNX _VariantStorage(void)
		: _Idx(0), _Val_by_excep(false), _Myval()
		{
		}

	template<size_t _Index, typename... _Args>
	_CONST_FUNX _VariantStorage(in_place_index_t<_Index>, bool _Except, _Args&&... _Vals)
		: _Idx(_Index), _Val_by_excep(_Except), _Myval(in_place_index<_Index>, _STD forward<_Args>(_Vals)...)
		{
		}

	_VariantUnion<_Type0, _Rest...> _Myval;
	bool _Val_by_excep;
	size_t _Idx;
	};

#endif /* defined(__ghs) */

	// TEMPLATE CLASS variant
template<class _Type0,
	class... _Rest>
	class variant<_Type0, _Rest...>
	{	// variant with one or more elements
#if defined(__ghs)
	// "All types in Types... shall be (possibly cv-qualified) object types
	// that are not arrays."
	// The is_object check is needed because we don't otherwise give an error
	// for simply instantiating variant on a reference type, if it's not the
	// first alternative. The is_array check is just to give a more helpful
	// error message to the user in that case. Note that is_object and is_array
	// already allow cv-qualifiers, so we don't need to strip them before
	// checking.
	static_assert((is_object_v<_Type0> && ... && is_object_v<_Rest>),
		"variant template parameters must be object types");
	static_assert((!is_array_v<_Type0> && ... && !is_array_v<_Rest>),
		"variant template parameters may not be array types");
	
	struct _NonExistentInvalid1 {};
	struct _NonExistentInvalid2 {};
#endif
public:
	typedef _Xtype_t<_Type0> _Ty0;
	typedef variant<_Type0, _Rest...> _Mytype;

	template<class _T0 = _Ty0,
		class = enable_if_t<
			is_default_constructible<_T0>::value,
			void> >
		_CONST_FUNX variant()
			_NOEXCEPT_OP(is_nothrow_default_constructible<_Ty0>::value)
#if defined(__ghs)
		: _Storage(in_place_index_t<0>{}, false)
		{	// default construct
		}
#else
		: _Idx(0),
			_Val_by_excep(false)
		{	// default construct
		new((void *)this)
			_Ty0();
		}
#endif /* defined(__ghs) */

#if defined(__ghs)
	variant(typename _STD conditional<!_All_cc<_Type0, _Rest...>::value, const variant&, _NonExistentInvalid1>::type _Right) = delete;
	
	variant(typename _STD conditional<_All_cc<_Type0, _Rest...>::value, const variant&, _NonExistentInvalid1>::type _Right)
		: _Storage()
		{	// copy construct
		_Storage._Idx = _Right._Storage._Idx;
		_Storage._Val_by_excep = _Right._Storage._Val_by_excep;
		if (!_Storage._Val_by_excep)
			_Vfunc<_Ty0, _Rest...>()._Copy(index(), this, &_Right);
		}
#else	
	variant(const variant& _Right)
		: _Idx(_Right._Idx),
			_Val_by_excep(_Right._Val_by_excep)
		{	// copy construct
		if (!_Val_by_excep)
			_Vfunc<_Ty0, _Rest...>()._Copy(index(), this, &_Right);
		}
#endif /* defined(__ghs) */

#if defined(__ghs)
	variant(typename _STD conditional<_All_mc<_Type0, _Rest...>::value, variant &&, _NonExistentInvalid2>::type _Right)
		_NOEXCEPT_OP((_All_nmc<_Ty0, _Rest...>::value))
		: _Storage()
		{	// move construct
		_Storage._Idx = _Right._Storage._Idx;
		_Storage._Val_by_excep = _Right._Storage._Val_by_excep;
		if (!_Storage._Val_by_excep)
			_Vfunc<_Ty0, _Rest...>()._Move(index(), this, &_Right);
		}
#else	
	variant(variant&& _Right)
		_NOEXCEPT_OP((_All_nmc<_Ty0, _Rest...>::value))
		: _Idx(_Right._Idx),
			_Val_by_excep(_Right._Val_by_excep)
		{	// move construct
		if (!_Val_by_excep)
			_Vfunc<_Ty0, _Rest...>()._Move(index(), this, &_Right);
		}
#endif

#if !defined(__ghs)
	template<class _Ty,
		class _T0 = _Ty0,
		class = enable_if_t<
			!is_same<decay_t<_Ty>, variant>::value
				&& _One_tc<_Ty, _T0, _Rest...>::value,
			void> >
		_CONST_FUNX variant(_Ty& _Val)
			_NOEXCEPT_OP((_One_tnc<_Ty, _T0, _Rest...>::value))
			: _Idx(_One_tc<_Ty, _T0, _Rest...>::index),
				_Val_by_excep(false)
		{	// construct from forwarded _Val
		const size_t _Ridx = _One_tc<_Ty, _T0, _Rest...>::index;
		typedef _Xtype_t<variant_alternative_t<_Ridx, _Mytype> > _Tyx;
		new((void *)this)
			_Tyx(_Val);
		}
#endif
	template<class _Ty,
#if defined(__ghs)
		class  _T0 = _Ty0,
		bool   _Found_alternative = _Check_overload<_Ty, _Type0, _Rest...>::value,
		size_t _Alternative_idx = _Check_overload<_Ty, _Type0, _Rest...>::index,
		class = enable_if_t<
			!is_same<decay_t<_Ty>, variant>::value
				&& !_Is_in_place_type_t<decay_t<_Ty>>::value
				&& !_Is_in_place_index_t<decay_t<_Ty>>::value
				&& _Found_alternative
				&& is_constructible<variant_alternative_t<
					_Alternative_idx, _Mytype>,
					_Ty>::value,
			void> >
#else
		class _T0 = _Ty0,
		class = enable_if_t<
			!is_same<decay_t<_Ty>, variant>::value
				&& _One_tc<_Ty, _T0, _Rest...>::value,
			void> >
#endif
		_CONST_FUNX variant(_Ty&& _Val)
#if defined(__ghs)
			_NOEXCEPT_OP((is_nothrow_constructible<variant_alternative_t<_Alternative_idx, _Mytype>, _Ty>::value))
			: _Storage(in_place_index_t<_Alternative_idx>{}, false, _STD forward<_Ty>(_Val))
		{	// construct from forwarded _Val
		}
#else
			_NOEXCEPT_OP((_One_tnc<_Ty, _T0, _Rest...>::value))
			: _Idx(_One_tc<_Ty, _T0, _Rest...>::index),
				_Val_by_excep(false)
		{	// construct from forwarded _Val
		const size_t _Ridx = _One_tc<_Ty, _T0, _Rest...>::index;
		typedef _Xtype_t<variant_alternative_t<_Ridx, _Mytype> > _Tyx;
		new((void *)this)
			_Tyx(_STD forward<_Ty>(_Val));
		}
#endif

	// IN-PLACE CONSTRUCTORS
	template<class _Ty,
		class... _Args,
		class _T0 = _Ty0,
		class = enable_if_t<
			_One_ts<_Ty, _T0, _Rest...>::value
				&& is_constructible<_Ty, _Args...>::value,
			void> >
		_CONST_FUNX explicit variant(_STD in_place_type_t<_Ty>,
			_Args&&... _Vals)
#if defined(__ghs)
			: _Storage(in_place_index_t<_One_ts<_Ty, _T0, _Rest...>::index>{}, false, _STD forward<_Args>(_Vals)...)
		{	// construct with _Args...
		}
#else
			: _Idx(_One_ts<_Ty, _T0, _Rest...>::index),
				_Val_by_excep(false)
		{	// construct with _Args...
		const size_t _Ridx = _One_ts<_Ty, _T0, _Rest...>::index;
		typedef _Xtype_t<variant_alternative_t<_Ridx, _Mytype> > _Tyx;
		new((void *)this)
			_Tyx(_STD forward<_Args>(_Vals)...);
		}
#endif

	template<class _Ty,
		class _Other,
		class... _Args,
		class _T0 = _Ty0,
		class = enable_if_t<
			_One_ts<_Ty, _T0, _Rest...>::value
				&& is_constructible<_Ty, _XSTD initializer_list<_Other>&,
					_Args...>::value,
			void> >
		_CONST_FUNX explicit variant(_STD in_place_type_t<_Ty>,
			_XSTD initializer_list<_Other> _Ilist, _Args&&... _Vals)
#if defined(__ghs)
			: _Storage(in_place_index_t<_One_ts<_Ty, _T0, _Rest...>::index>{}, false,
				_STD forward<_XSTD initializer_list<_Other> >(_Ilist),
				_STD forward<_Args>(_Vals)...)
		{	// construct with _Ilist, _Args...
		}
#else
			: _Idx(_One_ts<_Ty, _T0, _Rest...>::index),
				_Val_by_excep(false)
		{	// construct with _Ilist, _Args...
		const size_t _Ridx = _One_ts<_Ty, _T0, _Rest...>::index;
		typedef _Xtype_t<variant_alternative_t<_Ridx, _Mytype> > _Tyx;
		new((void *)this)
			_Tyx(_STD forward<_XSTD initializer_list<_Other> >(_Ilist),
				_STD forward<_Args>(_Vals)...);
		}
#endif

#if defined(__ghs)
	template <bool, const size_t _Index, class... _Args>
	struct _Is_indexible_and_constructible
	{
	    static const bool value = false;
	};
	
	template <const size_t _Index, class... _Args>
	struct _Is_indexible_and_constructible<true, _Index, _Args...>
	{
	    static const bool value =
		is_constructible<variant_alternative_t<_Index, _Mytype>,
							    _Args...>::value;
	};
#endif

	template<const size_t _Index,
		class... _Args,
		class = enable_if_t<
#if defined(__ghs)
			_Is_indexible_and_constructible<_Index < 1 + sizeof...(_Rest),
				_Index, _Args...>::value,
#else
			_Index < 1 + sizeof...(_Rest)
				&& is_constructible<variant_alternative_t<_Index, _Mytype>,
					_Args...>::value,
#endif
			void> >
		_CONST_FUNX explicit variant(_STD in_place_index_t<_Index>,
			_Args&&... _Vals)
#if defined(__ghs)
			: _Storage(in_place_index_t<_Index>{}, false, _STD forward<_Args>(_Vals)...)
		{	// construct with _Vals...
		}
#else
			: _Idx(_Index),
				_Val_by_excep(false)
		{	// construct with _Vals...
		typedef _Xtype_t<variant_alternative_t<_Index, _Mytype> > _Tyx;
		new((void *)this)
			_Tyx(_STD forward<_Args>(_Vals)...);
		}
#endif

	template<size_t _Index,
		class _Other,
		class... _Args,
		class = enable_if_t<
#if defined(__ghs)
			_Is_indexible_and_constructible<_Index < 1 + sizeof...(_Rest),
				_Index, _XSTD initializer_list<_Other>&, _Args...>::value,
#else
			_Index < 1 + sizeof...(_Rest)
				&& is_constructible<variant_alternative_t<_Index, _Mytype>,
					_XSTD initializer_list<_Other>&, _Args...>::value,
#endif
			void> >
		_CONST_FUNX explicit variant(_STD in_place_index_t<_Index>,
			_XSTD initializer_list<_Other> _Ilist, _Args&&..._Vals)
#if defined(__ghs)
			: _Storage(in_place_index_t<_Index>{}, false,
				_STD forward<_XSTD initializer_list<_Other> >(_Ilist),
				_STD forward<_Args>(_Vals)...)
		{	// construct with _Ilist, _Vals...
		}
#else
			: _Idx(_Index),
				_Val_by_excep(false)
		{	// construct with _Ilist, _Vals...
		typedef _Xtype_t<variant_alternative_t<_Index, _Mytype> > _Tyx;
		new((void *)this)
			_Tyx(_STD forward<_XSTD initializer_list<_Other> >(_Ilist),
				_STD forward<_Args>(_Vals)...);
		}
#endif


	// USES ALLOCATOR CONSTRUCTORS
#if !defined(__ghs)		
	template<class _Alloc,
		class _T0 = _Ty0,
		class = enable_if_t<
			uses_allocator<_T0, _Alloc>::value
				&& is_constructible<_T0, allocator_arg_t, _Alloc>::value,
			void> >
		variant(allocator_arg_t, const _Alloc& _Al)
			_NOEXCEPT_OP((is_nothrow_constructible<
				allocator_arg_t, _Alloc>::value))
#if defined(__ghs)
			: _Storage(0, false)
#else
			: _Idx(0), _Val_by_excep(false)
#endif

		{	// default construct with leading allocator
		new((void *)this)
			_T0(allocator_arg_t(), _Al);
		}

	template<class _Alloc,
		class _T0 = _Ty0,
		class = enable_if_t<
			uses_allocator<_T0, _Alloc>::value
				&& _All_cc<_T0, _Rest...>::value
				&& is_constructible<_T0,
					allocator_arg_t, _Alloc, const _T0&>::value,
			void> >
		variant(allocator_arg_t, const _Alloc& _Al,
			const variant& _Right)
#if defined(__ghs)
			: _Storage(_Right._Storage._Idx, _Right._Storage._Val_by_excep)
		{	// copy construct with leading allocator
		if (!_Storage._Val_by_excep)
#else
			: _Idx(_Right._Idx),
				_Val_by_excep(_Right._Val_by_excep)
		{	// copy construct with leading allocator
		if (!_Val_by_excep)
#endif
			_Vfunc<_Ty0, _Rest...>()._Copy_al(index(), this, _Al, &_Right);
		}

	template<class _Alloc,
		class _T0 = _Ty0,
		class = enable_if_t<
			uses_allocator<_T0, _Alloc>::value
				&& _All_mc<_T0, _Rest...>::value
				&& is_constructible<_T0,
					allocator_arg_t, _Alloc, _T0&&>::value,
			void> >
		variant(allocator_arg_t, const _Alloc& _Al,
			variant&& _Right)
#if defined(__ghs)
			: _Storage(_Right._Storage._Idx, _Right._Storage._Val_by_excep)
		{	// move construct with leading allocator
		if (!_Storage._Val_by_excep)
#else
			: _Idx(_Right._Idx),
				_Val_by_excep(_Right._Val_by_excep)
		{	// move construct with leading allocator
		if (!_Val_by_excep)
#endif
			_Vfunc<_Ty0, _Rest...>()._Move_al(index(), this, _Al, &_Right);
		}

	template<class _Alloc,
		class _T0 = _Ty0,
		class _Ty,
		class = enable_if_t<
			uses_allocator<_T0, _Alloc>::value
				&& !is_same<decay_t<_Ty>, variant>::value
				&& _One_tc<_Ty, _T0, _Rest...>::value
				&& is_constructible<_Ty,
					allocator_arg_t, _Alloc, _Ty>::value,
			void> >
		_CONST_FUNX variant(allocator_arg_t, const _Alloc& _Al, _Ty&& _Val)
			_NOEXCEPT_OP((_One_tnc<_Ty, _T0, _Rest...>::value))
#if defined(__ghs)
			: _Storage(_One_tc<_Ty, _T0, _Rest...>::index, false)
#else
			: _Idx(_One_tc<_Ty, _T0, _Rest...>::index),
				_Val_by_excep(false)
#endif
		{	// construct from forwarded val, leading allocator
		const size_t _Ridx = _One_tc<_Ty, _T0, _Rest...>::index;
		typedef _Xtype_t<variant_alternative_t<_Ridx, _Mytype> > _Tyx;
		new((void *)this)
			_Tyx(allocator_arg_t(), _Al, _STD forward<_Ty&&>(_Val));
		}

	template<class _Alloc,
		class _Ty,
		class _T0 = _Ty0,
		class... _Args,
		class = enable_if_t<
			uses_allocator<_T0, _Alloc>::value
				&& _One_ts<_Ty, _T0, _Rest...>::value
				&& is_constructible<_Ty, _Args...>::value,
			void> >
		_CONST_FUNX variant(allocator_arg_t, const _Alloc& _Al,
			_STD in_place_type_t<_Ty>,
				_Args&&... _Vals)
#if defined(__ghs)
			: _Storage(_One_ts<_Ty, _T0, _Rest...>::index, false)
#else
			: _Idx(_One_ts<_Ty, _T0, _Rest...>::index),
				_Val_by_excep(false)
#endif
		{	// construct from _Args..., leading allocator
		const size_t _Ridx = _One_ts<_Ty, _T0, _Rest...>::index;
		typedef variant_alternative_t<_Ridx, _Mytype> _Tyx;
		new((void *)this)
			_Tyx(allocator_arg_t(), _Al, _STD forward<_Args&&>(_Vals)...);
		}

	template<class _Alloc,
		class _Ty,
		class _Other,
		class _T0 = _Ty0,
		class... _Args,
		class = enable_if_t<
			uses_allocator<_T0, _Alloc>::value
				&& _One_ts<_Ty, _T0, _Rest...>::value
				&& is_constructible<_Ty, allocator_arg_t, const _Alloc&,
					_XSTD initializer_list<_Other>, _Args...>::value,
			void> >
		_CONST_FUNX variant(allocator_arg_t, const _Alloc& _Al,
			_STD in_place_type_t<_Ty>,
				_XSTD initializer_list<_Other> _Ilist, _Args&&... _Vals)
#if defined(__ghs)
			: _Storage(_One_ts<_Ty, _T0, _Rest...>::index, false)
#else
			: _Idx(_One_ts<_Ty, _T0, _Rest...>::index),
				_Val_by_excep(false)
#endif
		{	// construct from _Ilist, _Args..., leading allocator
		const size_t _Ridx = _One_ts<_Ty, _T0, _Rest...>::index;
		typedef variant_alternative_t<_Ridx, _Mytype> _Tyx;
		new((void *)this)
			_Tyx(allocator_arg_t(), _Al,
				_STD forward<_XSTD initializer_list<_Other> >(_Ilist),
					_STD forward<_Args&&>(_Vals)...);
		}

	template<class _Alloc,
		size_t _Index,
		class... _Args,
		class _T0 = _Ty0,
		class = enable_if_t<
			uses_allocator<_T0, _Alloc>::value
#if defined(__ghs)
				&& _Is_indexible_and_constructible<_Index < 1 + sizeof...(_Rest),
				        _Index, allocator_arg_t, _Alloc, _Args...>::value,
#else
				&& _Index < 1 + sizeof...(_Rest)
				&& is_constructible<variant_alternative_t<_Index, _Mytype>,
					allocator_arg_t, _Alloc, _Args...>::value,
#endif
			void> >
		_CONST_FUNX variant(allocator_arg_t, const _Alloc& _Al,
			_STD in_place_index_t<_Index>,
				_Args&&... _Vals)
#if defined(__ghs)
			: _Storage(_Index, false)
#else
			: _Idx(_Index),
				_Val_by_excep(false)
#endif
		{	// construct from _Vals..., leading allocator, at _Index
		typedef variant_alternative_t<_Index, _Mytype> _Tyx;
		new((void *)this)
			_Tyx(allocator_arg_t(), _Al,
				_STD forward<_Args&&>(_Vals)...);
		}

	template<class _Alloc,
		size_t _Index,
		class _Other,
		class... _Args,
		class _T0 = _Ty0,
		class = enable_if_t<
			uses_allocator<_T0, _Alloc>::value
#if defined(__ghs)
				&& _Is_indexible_and_constructible<_Index < 1 + sizeof...(_Rest),
				        _Index, allocator_arg_t, _Alloc, _Args...>::value, void> >
#else
				&& _Index < 1 + sizeof...(_Rest)
				&& is_constructible<variant_alternative_t<_Index, _Mytype>,
					allocator_arg_t, _Alloc, _Args...>::value,
#endif
			void> >
		_CONST_FUNX variant(allocator_arg_t, const _Alloc& _Al,
			_STD in_place_index_t<_Index>,
				_XSTD initializer_list<_Other> _Ilist, _Args&&..._Vals)
#if defined(__ghs)
			: _Storage(_Index, false)
#else
			: _Idx(_Index),
				_Val_by_excep(false)
#endif
		{	// construct from _Ilist, _Vals..., leading allocator, at _Index
		typedef variant_alternative_t<_Index, _Mytype> _Tyx;
		new((void *)this)
			_Tyx(allocator_arg_t(), _Al,
				_STD forward<_XSTD initializer_list<_Other> >(_Ilist),
					_STD forward<_Args&&>(_Vals)...);
		}
#endif
		
#if !defined(__ghs)
	~variant() _NOEXCEPT
		{	// destroy the object
		if (!_Val_by_excep)
			_Vfunc<_Ty0, _Rest...>()._Delete(index(), this);
		(volatile bool&)_Val_by_excep = true;	// [sic] GCC compiler bug
		}
#endif

#if defined(__ghs)
	variant& operator=(typename _STD conditional<!_All_cc<_Ty0, _Rest...>::value || !_All_ca<_Ty0, _Rest...>::value, const variant &, _NonExistentInvalid1>::type _Right) = delete;
	
	variant& operator=(typename _STD conditional<_All_cc<_Ty0, _Rest...>::value && _All_ca<_Ty0, _Rest...>::value, const variant &, _NonExistentInvalid1>::type _Right)
#else	
	variant& operator=(const variant& _Right)
#endif	
		{	// copy assign _Right
		if (this == &_Right)
			;
		else if (_Right.valueless_by_exception())
#if defined(__ghs)
			{
			this->~variant();
			_Storage._Val_by_excep = true;
			}
#else
			this->~variant();
#endif
		else
			{	// copy existing value
#if defined(__ghs)
			_Vfunc<_Ty0, _Rest...>()._Copy_assign<0>(_Right.index(), this, &_Right);
			_Storage._Idx = _Right.index();
			_Storage._Val_by_excep = false;
#else
			_Val_by_excep = false;
			_Vfunc<_Ty0, _Rest...>()._Copy(index(), this, &_Right);
#endif
			}
		return (*this);
		}

#if defined(__ghs)
	variant& operator=(typename _STD conditional<_All_mc<_Ty0, _Rest...>::value && _All_ma<_Ty0, _Rest...>::value, variant &&, _NonExistentInvalid2>::type _Right)
#else	
	variant& operator=(variant&& _Right)
#endif	
		_NOEXCEPT_OP((_All_nmc<_Ty0, _Rest...>::value
			&& _All_nma<_Ty0, _Rest...>::value))
		{	// move assign _Right
		if (this == &_Right)
			;
		else if (_Right.valueless_by_exception())
#if defined(__ghs)
			{
			this->~variant();
			_Storage._Val_by_excep = true;
			}
#else
			this->~variant();
#endif
		else
			{	// move existing value
#if defined(__ghs)
			_Vfunc<_Ty0, _Rest...>()._Move_assign<0>(_Right._Storage._Idx, this, &_Right);
			_Storage._Idx = _Right._Storage._Idx;
			_Storage._Val_by_excep = false;
#else
			_Val_by_excep = false;
			_Vfunc<_Ty0, _Rest...>()._Move(index(), this, &_Right);
#endif
			}
		return (*this);
		}

	template<class _Ty,
#if defined(__ghs)
		class _T0 = _Ty0,
		bool   _Found_alternative = _Check_overload<_Ty, _Type0, _Rest...>::value,
		size_t _Alternative_idx = _Check_overload<_Ty, _Type0, _Rest...>::index,
		class = enable_if_t<
			!is_same<decay_t<_Ty>, variant>::value
				&& _Found_alternative
				&& is_constructible<variant_alternative_t<
					_Alternative_idx, _Mytype>,
					_Ty>::value
				&& is_assignable<variant_alternative_t<
					_Alternative_idx, _Mytype>&,
					_Ty>::value,
#else
		class _T0 = _Ty0,
		class = enable_if_t<
			!is_same<decay_t<_Ty>, variant>::value
				&& _One_ta<_Ty, _T0, _Rest...>::value
				&& _One_ta<_Ty, _T0, _Rest...>::index ==
					_One_tc<_Ty, _T0, _Rest...>::index,
#endif
			void> >
		variant& operator=(_Ty&& _Val)
#if defined(__ghs)
			_NOEXCEPT_OP((is_nothrow_assignable<variant_alternative_t<_Alternative_idx, _Mytype>, _Ty>::value &&
				      is_nothrow_constructible<variant_alternative_t<_Alternative_idx, _Mytype>, _Ty>::value))
#else
			_NOEXCEPT_OP((_One_tna<_Ty, _T0, _Rest...>::value
				&& _One_tnc<_Ty, _T0, _Rest...>::value))
#endif /* defined(__ghs) */
		{	// assign by forwarding _Val
#if defined(__ghs)
		const size_t _Ridx = _Alternative_idx;
#else
		const size_t _Ridx = _One_ta<_Ty, _Ty0, _Rest...>::index;
#endif
		if (!valueless_by_exception() && _Ridx == index())
			get<_Ridx>(*this) = _STD forward<_Ty>(_Val);
		else
#if defined(__ghs)
			{
			typedef _Xtype_t<variant_alternative_t<_Ridx, _Mytype> > _Tyx;
			if (is_nothrow_constructible_v<_Tyx, _Ty> || !is_nothrow_move_constructible_v<_Tyx>)
			    this->emplace<_Ridx>(forward<_Ty>(_Val));
			else
			    this->operator=(variant(forward<_Ty>(_Val)));
			}
#else
			{	// destroy old and move in new
			this->~variant();
			new((void *)this)
				_Ty(_STD forward<_Ty>(_Val));
			this->_Idx = _Ridx;
			_Val_by_excep = false;
			}
#endif
		return (*this);
		}

	void swap(variant& _Right)
		_NOEXCEPT_OP((_All_mc<_Ty0, _Rest...>::value
			&& _All_s<_Ty0, _Rest...>::value))
		{	// swap *this and _Right
		if (!valueless_by_exception() && !_Right.valueless_by_exception())
			{	// swap whole values
#if defined(__ghs)
			if (this->_Storage._Idx == _Right._Storage._Idx)
				{
				_STD swap(_STD get<0>(*this), _STD get<0>(_Right));
				}
			else
				{
				variant _Temp = *this;
				this->_Storage._Idx = _Right._Storage._Idx;
				*this = _Right;
				_Right._Storage._Idx = _Temp._Storage._Idx;
				_Right = _Temp;
				}
#else
			variant _Temp = *this;
			*this = _Right;
			_Right = _Temp;
#endif
			}
		else if (!valueless_by_exception())
			{	// left exists, move it
			_Right = *this;
			this->~variant();
			}
		else if (!_Right.valueless_by_exception())
			{	// right exists, move it
			*this = _Right;
			_Right.~variant();
			}
		}

	// TEMPLATE FUNCTION emplace
	template<class _Ty,
		class... _Args,
		class _T0 = _Ty0,
		class = enable_if_t<
			_One_ts<_Ty, _T0, _Rest...>::value
				&& is_constructible<_Ty, _Args...>::value,
#if defined(__ghs)
			_Ty&> >
		_Ty& emplace(_Args&&... _Vals)
#else
			void> >
		void emplace(_Args&&... _Vals)
#endif
		{	// emplace with _Args... at _Ty
		const size_t _Ridx = _One_ts<_Ty, _T0, _Rest...>::index;
		typedef _Xtype_t<variant_alternative_t<_Ridx, _Mytype> > _Tyx;
		this->~variant();
		new((void *)this)
			_Tyx(_STD forward<_Args>(_Vals)...);
#if defined(__ghs)
		_Storage._Idx = _Ridx;
		_Storage._Val_by_excep = false;
		return (_Ty&)std::get<_Ridx>(*this);
#else
		_Idx = _Ridx;
		_Val_by_excep = false;
#endif
		}

	template<class _Ty,
		class _Other,
		class... _Args,
		class _T0 = _Ty0,
		class = enable_if_t<
			_One_ts<_Ty, _T0, _Rest...>::value
				&& is_constructible<
					_Ty, _XSTD initializer_list<_Other>&, _Args...>::value,
#if defined(__ghs)
			_Ty&> >
		_Ty& emplace(_XSTD initializer_list<_Other> _Ilist, _Args&&... _Vals)
#else
			void> >
		void emplace(_XSTD initializer_list<_Other> _Ilist, _Args&&... _Vals)
#endif
		{	// emplace with _Ilist, _Args... at _Ty
		const size_t _Ridx = _One_ts<_Ty, _T0, _Rest...>::index;
		typedef _Xtype_t<variant_alternative_t<_Ridx, _Mytype> > _Tyx;
		this->~variant();
		new((void *)this)
			_Tyx(_Ilist, _STD forward<_Args>(_Vals)...);
#if defined(__ghs)
		_Storage._Idx = _Ridx;
		_Storage._Val_by_excep = false;
		return (_Ty&)std::get<_Ridx>(*this);
#else
		_Idx = _Ridx;
		_Val_by_excep = false;
#endif
		}

	template<size_t _Index,
		class... _Args,
		class = enable_if_t<
#if defined(__ghs)
			_Is_indexible_and_constructible<_Index < 1 + sizeof...(_Rest),
				_Index, _Args...>::value,
			variant_alternative_t<_Index, variant>&> >
		variant_alternative_t<_Index, variant>& emplace(_Args&&... _Vals)
#else
			_Index < 1 + sizeof...(_Rest)
				&& is_constructible<
					variant_alternative_t<_Index, _Mytype>,
						_Args...>::value,
			void> >
		void emplace(_Args&&... _Vals)
#endif
		{	// emplace with _Args... at _Index
		typedef _Xtype_t<variant_alternative_t<_Index, _Mytype> > _Tyx;
		this->~variant();
		new((void *)this)
			_Tyx(_STD forward<_Args>(_Vals)...);
#if defined(__ghs)
		_Storage._Idx = _Index;
		_Storage._Val_by_excep = false;
		return std::get<_Index>(*this);
#else
		_Idx = _Index;
		_Val_by_excep = false;
#endif
		}

	template<size_t _Index,
		class _Other,
		class... _Args,
		class = enable_if_t<
#if defined(__ghs)
			_Is_indexible_and_constructible<
				    _Index < 1 + sizeof...(_Rest), _Index,
				   _XSTD initializer_list<_Other>&, _Args...>::value,
			variant_alternative_t<_Index, variant>&> >
		variant_alternative_t<_Index, variant>& emplace(_XSTD initializer_list<_Other> _Ilist, _Args&&... _Vals)
#else
			_Index < 1 + sizeof...(_Rest)
				&& is_constructible<
					variant_alternative_t<_Index, _Mytype>,
						_XSTD initializer_list<_Other>&, _Args...>::value,
			void> >
		void emplace(_XSTD initializer_list<_Other> _Ilist, _Args&&... _Vals)
#endif
		{	// emplace with _Ilist, _Args... at _Index
		typedef _Xtype_t<variant_alternative_t<_Index, _Mytype> > _Tyx;
		this->~variant();
		new((void *)this)
			_Tyx(_Ilist, _STD forward<_Args&&>(_Vals)...);
#if defined(__ghs)
		_Storage._Idx = _Index;
		_Storage._Val_by_excep = false;
		return std::get<_Index>(*this);
#else
		_Idx = _Index;
		_Val_by_excep = false;
#endif
		}

#if defined(__ghs)
	_CONST_FUN size_t index() const _NOEXCEPT
		{	// get index of stored type, or npos
		return (valueless_by_exception() ? variant_npos
			: _Storage._Idx);
		}

	_CONST_FUN bool valueless_by_exception() const _NOEXCEPT
		{	// return valueless flag
		return (_Storage._Val_by_excep);
		}

	_VariantStorage<_All_td<_Type0, _Rest...>::value, _Type0, _Rest...> _Storage;
#else
	_CONST_FUN size_t index() const _NOEXCEPT
		{	// get index of stored type, or npos
		return (valueless_by_exception() ? variant_npos
			: _Idx);
		}

	_CONST_FUN bool valueless_by_exception() const _NOEXCEPT
		{	// return valueless flag
		return (_Val_by_excep);
		}

	typename aligned_storage<
		_Max_type_size<_Type0, _Rest...>::size,
		_Max_type_size<_Type0, _Rest...>::alignment>::type
			_Myval;	// MUST COME FIRST
	size_t _Idx;
	bool _Val_by_excep;
#endif
	};

	// VALUE ACCESS
template<class _First,
	class... _Rest>
	_First _Nth_type(size_t _Index)
	{	// get first type in list
	return (_First());
	}

template<class _Ty,
	class... _Types>
	_CONST_FUN bool holds_alternative(
		const variant<_Types...>& _Obj) _NOEXCEPT
	{	// test if _Obj holds alternative _Ty
	return (_One_ts<_Ty, _Types...>::index == _Obj.index());
	}

	// TEMPLATE STRUCT _Varty
template<class _Ty,
	bool _Is_ref>
	struct _Varty_helper
	{	// return plain
	typedef _Ty& type;
	};

template<class _Ty>
	struct _Varty_helper<_Ty, true>
	{	// return reference wrapper
	typedef reference_wrapper<remove_reference_t<_Ty> >& type;
	};

template<class _Ty>
	struct _Varty
	{	// return plain
	typedef typename _Varty_helper<_Ty, is_reference<_Ty>::value>::type type;
	};

template<class _Type>
	using _Varty_t =
		typename _Varty<_Type>::type;

	// TEMPLATE FUNCTION get
template<size_t _Idx,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	variant_alternative_t<_Idx, variant<_Types...> >&
		get(variant<_Types...>& _Obj)
	{	// get reference to element _Idx in variant<_Types...>
	typedef variant_alternative_t<_Idx, variant<_Types...> > _Ty;
	if (_Obj.valueless_by_exception()
		|| _Obj.index() != _Idx
		|| _Is_variant_void<_Ty>::value)
		_THROW_N(bad_variant_access, "get<N>(variant&) failed");
#if defined(__ghs)
	return _Get(in_place_index_t<_Idx>{}, _Obj._Storage._Myval);
#else
	return ((_Ty&)_Varty_t<_Ty>(_Obj));
#endif
	}

template<size_t _Idx,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	variant_alternative_t<_Idx, variant<_Types...> >&&
		get(variant<_Types...>&& _Obj)
	{	// get rvalue reference to element _Idx in variant<_Types...>
	typedef variant_alternative_t<_Idx, variant<_Types...> > _Ty;
	if (_Obj.valueless_by_exception()
		|| _Obj.index() != _Idx
		|| _Is_variant_void<_Ty>::value)
		_THROW_N(bad_variant_access, "get<N>(variant&&) failed");
#if defined(__ghs)
	return _STD move(_Get(in_place_index_t<_Idx>{}, _Obj._Storage._Myval));
#else
	return ((_Ty&&)_Varty_t<_Ty>(_Obj));
#endif
	}

template<size_t _Idx,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	variant_alternative_t<_Idx, variant<_Types...> >const &
		get(const variant<_Types...>& _Obj)
	{	// get const reference to element _Idx in variant<_Types...>
	typedef variant_alternative_t<_Idx, variant<_Types...> > _Ty;
	if (_Obj.valueless_by_exception()
		|| _Obj.index() != _Idx
		|| _Is_variant_void<_Ty>::value)
		_THROW_N(bad_variant_access, "get<N>(const variant&) failed");
#if defined(__ghs)
	return _Get(in_place_index_t<_Idx>{}, _Obj._Storage._Myval);
#else
	return ((const _Ty&)_Varty_t<_Ty>(_Obj));
#endif
	}

template<size_t _Idx,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	variant_alternative_t<_Idx, variant<_Types...> >const &&
		get(const variant<_Types...>&& _Obj)
	{	// get const rvalue reference to element _Idx in variant<_Types...>
	typedef variant_alternative_t<_Idx, variant<_Types...> > _Ty;
	if (_Obj.valueless_by_exception()
		|| _Obj.index() != _Idx
		|| _Is_variant_void<_Ty>::value)
		_THROW_N(bad_variant_access, "get<N>(const variant&&) failed");
#if defined(__ghs)
	return _STD move(_Get(in_place_index_t<_Idx>{}, _Obj._Storage._Myval));
#else
	return ((const _Ty&&)_Varty_t<_Ty>(_Obj));
#endif
	}

template<class _Ty,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	_Ty& get(variant<_Types...>& _Obj)
	{	// get reference to element _Ty in variant<_Types...>
	if (_Obj.valueless_by_exception()
#if defined(__ghs)
		|| _One_ts<_Ty, _Types...>::index != _Obj._Storage._Idx
#else
		|| _One_ts<_Ty, _Types...>::index != _Obj._Idx
#endif
		|| _Is_variant_void<_Ty>::value)
		_THROW_N(bad_variant_access, "get<T>(variant&) failed");
#if defined(__ghs)
	return _Get(in_place_index_t<_One_ts<_Ty, _Types...>::index>{}, _Obj._Storage._Myval);
#else
	return ((_Ty&)_Varty_t<_Ty>(_Obj));
#endif
	}

template<class _Ty,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	const _Ty& get(const variant<_Types...>& _Obj)
	{	// get const reference to element _Ty in variant<_Types...>
	if (_Obj.valueless_by_exception()
		|| _One_ts<_Ty, _Types...>::index == variant_npos
		|| _Is_variant_void<_Ty>::value)
		_THROW_N(bad_variant_access, "get<T>(const variant&) holds no value");
#if defined(__ghs)
	if (_Obj.index() != _One_ts<_Ty, _Types...>::index)
		_THROW_N(bad_variant_access, "get<T>(const variant&&) failed");
	return _Get(in_place_index_t<_One_ts<_Ty, _Types...>::index>{}, _Obj._Storage._Myval);
#else
	return ((const _Ty&)_Varty_t<_Ty>(_Obj));
#endif
	}

template<class _Ty,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	_Ty&& get(variant<_Types...>&& _Obj)
	{	// get rvalue reference to element _Ty in variant<_Types...>
	if (_Obj.valueless_by_exception()
		|| _One_ts<_Ty, _Types...>::index == variant_npos
		|| _Is_variant_void<_Ty>::value)
		_THROW_N(bad_variant_access, "get<T>(variant&&) holds no value");
#if defined(__ghs)
	if (_Obj.index() != _One_ts<_Ty, _Types...>::index)
		_THROW_N(bad_variant_access, "get<T>(const variant&&) failed");
	return _STD move(_Get(in_place_index_t<_One_ts<_Ty, _Types...>::index>{}, _Obj._Storage._Myval));
#else
	return ((_Ty&&)_Varty_t<_Ty>(_Obj));
#endif
	}

template<class _Ty,
	class... _Types>
#if defined(__ghs)
	_CONST_FUN
#endif
	const _Ty&& get(const variant<_Types...>&& _Obj)
	{	// get const rvalue reference to element _Ty in variant<_Types...>
	if (_Obj.valueless_by_exception()
		|| _One_ts<_Ty, _Types...>::index == variant_npos
		|| _Is_variant_void<_Ty>::value)
		_THROW_N(bad_variant_access,
			"get<T>(const variant&&) holds no value");
#if defined(__ghs)
	if (_Obj.index() != _One_ts<_Ty, _Types...>::index)
		_THROW_N(bad_variant_access, "get<T>(const variant&&) failed");
	return _STD move(_Get(in_place_index_t<_One_ts<_Ty, _Types...>::index>{}, _Obj._Storage._Myval));
#else
	return ((const _Ty&&)_Varty_t<_Ty>(_Obj));
#endif
	}

	// TEMPLATE FUNCTION get_if
template<size_t _Idx,
	class _Ty>
	int *get_if(_Ty *) _NOEXCEPT
	{	// backstop
	return (nullptr);
	}

template<size_t _Idx,
	class... _Types,
	class = enable_if_t<_Idx < sizeof...(_Types),
		void> >
	_CONST_FUNX add_pointer_t<
		variant_alternative_t<_Idx, variant<_Types...> > >
	get_if(variant<_Types...> *_Pobj) _NOEXCEPT
	{	// get pointer to _Idx element if there, else nullptr
	typedef variant_alternative_t<_Idx, variant<_Types...> > _Ty;
#if defined(__ghs)
	if (_Pobj == nullptr
		|| _Pobj->valueless_by_exception()
#else
	if (_Pobj->valueless_by_exception()
#endif
		|| _Pobj->index() != _Idx
		|| _Is_variant_void<_Ty>::value)
		return (nullptr);
	else
#if defined(__ghs)
		return &_Get(in_place_index_t<_Idx>{}, _Pobj->_Storage._Myval);
#else
		return (&(_Ty&)_Varty_t<_Ty>(*_Pobj));
#endif
	}

template<size_t _Idx,
	class... _Types,
	class = enable_if_t<_Idx < sizeof...(_Types),
		void> >
	_CONST_FUNX add_pointer_t<
		const variant_alternative_t<_Idx, variant<_Types...> > >
	get_if(const variant<_Types...> *_Pobj) _NOEXCEPT
	{	// get pointer to _Idx const element if there, else nullptr
	typedef variant_alternative_t<_Idx, variant<_Types...> > _Ty;
#if defined(__ghs)
	if (_Pobj == nullptr
		|| _Pobj->valueless_by_exception()
#else
	if (_Pobj->valueless_by_exception()
#endif
		|| _Pobj->index() != _Idx
		|| _Is_variant_void<_Ty>::value)
		return (nullptr);
	else
#if defined(__ghs)
		return &_Get(in_place_index_t<_Idx>{}, _Pobj->_Storage._Myval);
#else
		return (&(const _Ty&)_Varty_t<_Ty>(*_Pobj));
#endif
	}

template<class _Ty,
	class... _Types>
	_CONST_FUNX add_pointer_t<_Ty>
		get_if(variant<_Types...> *_Pobj) _NOEXCEPT
	{	// get pointer to _Ty element if there, else nullptr
#if defined(__ghs)
	if (_Pobj == nullptr
		|| _Pobj->valueless_by_exception()
#else
	if (_Pobj->valueless_by_exception()
#endif
		|| _Pobj->index() != _One_ts<_Ty, _Types...>::index
		|| _Is_variant_void<_Ty>::value)
		return (nullptr);
	else
#if defined(__ghs)
		return &_Get(in_place_index_t<_One_ts<_Ty, _Types...>::index>{}, _Pobj->_Storage._Myval);
#else
		return (&(_Ty&)_Varty_t<_Ty>(*_Pobj));
#endif
	}

template<class _Ty,
	class... _Types>
	_CONST_FUNX add_pointer_t<const _Ty>
		get_if(const variant<_Types...> *_Pobj) _NOEXCEPT
	{	// get pointer to const _Ty element if there, else nullptr
#if defined(__ghs)
	if (_Pobj == nullptr
		|| _Pobj->valueless_by_exception()
#else
	if (_Pobj->valueless_by_exception()
#endif
		|| _Pobj->index() != _One_ts<_Ty, _Types...>::index
		|| _Is_variant_void<_Ty>::value)
		return (nullptr);
	else
#if defined(__ghs)
		return &_Get(in_place_index_t<_One_ts<_Ty, _Types...>::index>{}, _Pobj->_Storage._Myval);
#else
		return (&(const _Ty&)_Varty_t<_Ty>(*_Pobj));
#endif
	}

	// RELATIONAL OPERATORS
template<class... _Types>
	_CONST_FUNX bool operator==(const variant<_Types...>& _Left,
		const variant<_Types...>& _Right)
	{	// test if _Left == _Right
	size_t _Lidx = _Left.index();
	size_t _Ridx = _Right.index();
	return (_Lidx != _Ridx ? false
		: _Left.valueless_by_exception() ? true
#if defined(__ghs)
		: _Vfunc<_Types...>()._Compare_EQ<0>(_Lidx, &_Left, &_Right)
#else
		: _Vfunc<_Types...>()._Compare(_Lidx, &_Left, &_Right) == 0
#endif
		);
	}

template<class... _Types>
	_CONST_FUNX bool operator!=(const variant<_Types...>& _Left,
		const variant<_Types...>& _Right)
	{	// test if _Left != _Right
	size_t _Lidx = _Left.index();
	size_t _Ridx = _Right.index();
	return (_Lidx != _Ridx ? true
		: _Left.valueless_by_exception() ? false
#if defined(__ghs)
		: _Vfunc<_Types...>()._Compare_NE<0>(_Lidx, &_Left, &_Right)
#else
		: _Vfunc<_Types...>()._Compare(_Lidx, &_Left, &_Right) != 0
#endif
		);
	}

template<class... _Types>
	_CONST_FUNX bool operator<(const variant<_Types...>& _Left,
		const variant<_Types...>& _Right)
	{	// test if _Left < _Right
	size_t _Lidx = _Left.index();
	size_t _Ridx = _Right.index();
	return (_Right.valueless_by_exception() ? false
		: _Left.valueless_by_exception() ? true
		: _Lidx < _Ridx ? true
		: _Lidx > _Ridx ? false
#if defined(__ghs)
		: _Vfunc<_Types...>()._Compare_LT<0>(_Lidx, &_Left, &_Right)
#else
		: _Vfunc<_Types...>()._Compare(_Lidx, &_Left, &_Right) < 0
#endif
		);
	}

template<class... _Types>
	_CONST_FUNX bool operator>=(const variant<_Types...>& _Left,
		const variant<_Types...>& _Right)
	{	// test if _Left >= _Right
	size_t _Lidx = _Left.index();
	size_t _Ridx = _Right.index();
	return (_Right.valueless_by_exception() ? true
		: _Left.valueless_by_exception() ? false
		: _Lidx > _Ridx ? true
		: _Lidx < _Ridx ? false
#if defined(__ghs)
		: _Vfunc<_Types...>()._Compare_GE<0>(_Lidx, &_Left, &_Right)
#else
		: _Vfunc<_Types...>()._Compare(_Lidx, &_Left, &_Right) >= 0
#endif
		);
	}

template<class... _Types>
	_CONST_FUNX bool operator>(const variant<_Types...>& _Left,
		const variant<_Types...>& _Right)
	{	// test if _Left > _Right
	size_t _Lidx = _Left.index();
	size_t _Ridx = _Right.index();
	return (_Left.valueless_by_exception() ? false
		: _Right.valueless_by_exception() ? true
		: _Lidx > _Ridx ? true
		: _Lidx < _Ridx ? false
#if defined(__ghs)
		: _Vfunc<_Types...>()._Compare_GT<0>(_Lidx, &_Left, &_Right)
#else
		: _Vfunc<_Types...>()._Compare(_Lidx, &_Left, &_Right) > 0
#endif
		);
	}

template<class... _Types>
	_CONST_FUNX bool operator<=(const variant<_Types...>& _Left,
		const variant<_Types...>& _Right)
	{	// test if _Left <= _Right
	size_t _Lidx = _Left.index();
	size_t _Ridx = _Right.index();
	return (_Left.valueless_by_exception() ? true
		: _Right.valueless_by_exception() ? false
#if defined(__ghs)
		: _Lidx < _Ridx ? true
#else
		: _Lidx <= _Ridx ? true
#endif
		: _Lidx > _Ridx ? false
#if defined(__ghs)
		: _Vfunc<_Types...>()._Compare_LE<0>(_Lidx, &_Left, &_Right)
#else
		: _Vfunc<_Types...>()._Compare(_Lidx, &_Left, &_Right) <= 0
#endif
		);
	}

	// VISITATION
template<class _Visitor,
	class... _Types>
	struct _Visitor_returns;

template<class _Visitor>
	struct _Visitor_returns<_Visitor>
	{	// get return type of no called elements
	typedef decltype(declval<_Visitor>()()) type;
	};
#if defined(__ghs)
template<class _Visitor,
	class _Type0>
	struct _Visitor_returns<_Visitor, _Type0&&>
	{	// get common return type of single called element of a variant
	typedef decltype(declval<_Visitor>()(declval<_Type0&&>())) type;
	};
#else
template<class _Visitor,
	class _Type0>
	struct _Visitor_returns<_Visitor, _Type0>
	{	// get common return type of single called element of a variant
	typedef decltype(declval<_Visitor>()(declval<_Type0>())) type;
	};
#endif

template<class _Visitor,
	class _Type0>
	struct _Visitor_returns<_Visitor, _Type0&>
	{	// get common return type of single called element of a variant
	typedef decltype(declval<_Visitor>()(declval<_Type0&>())) type;
	};

#if defined(__ghs)
template<class _Visitor,
	class _Type0>
	struct _Visitor_returns<_Visitor, const _Type0&&>
	{	// get common return type of single called element of a variant
	typedef decltype(declval<_Visitor>()(declval<const _Type0&&>())) type;
	};
#else
template<class _Visitor,
	class _Type0>
	struct _Visitor_returns<_Visitor, const _Type0>
	{	// get common return type of single called element of a variant
	typedef decltype(declval<_Visitor>()(declval<const _Type0>())) type;
	};
#endif

template<class _Visitor,
	class _Type0>
	struct _Visitor_returns<_Visitor, const _Type0&>
	{	// get common return type of single called element of a variant
	typedef decltype(declval<_Visitor>()(declval<const _Type0&>())) type;
	};

template<class _Visitor,
	class _Type0,
	class _Type1,
	class... _Rest>
	struct _Visitor_returns<_Visitor, _Type0, _Type1, _Rest...>
	{	// get common return type of two or more called elements of a variant
	typedef typename _Visitor_returns<_Visitor, _Type0>::type _Ty0;
	typedef typename _Visitor_returns<_Visitor, _Type1, _Rest...>::type _Ty1;
	typedef common_type_t<_Ty0, _Ty1> type;
	};

template<class _Visitor,
	class... _Vars>
	struct _All_visitor_returns;

#if defined(__ghs)
template<class _Visitor,
	class... _Types>
	struct _All_visitor_returns<_Visitor, variant<_Types...>&&>
	{	// get common return type of all called elements of a variant
	typedef typename _Visitor_returns<_Visitor, _Types&&...>::type type;
	};

template<class _Visitor,
	class... _Types>
	struct _All_visitor_returns<_Visitor, variant<_Types...>&>
	{	// get common return type of all called elements of a variant
	typedef typename _Visitor_returns<_Visitor, _Types&...>::type type;
	};

template<class _Visitor,
	class... _Types>
	struct _All_visitor_returns<_Visitor, const variant<_Types...>&&>
	{	// get common return type of all called elements of a variant
	typedef typename _Visitor_returns<_Visitor, const _Types&&...>::type type;
	};

template<class _Visitor,
	class... _Types>
	struct _All_visitor_returns<_Visitor, const variant<_Types...>&>
	{	// get common return type of all called elements of a variant
	typedef typename _Visitor_returns<_Visitor, const _Types&...>::type type;
	};

template<class _Visitor,
	class _VType1,
	class _VType2,
	class... _Rest>
	struct _All_visitor_returns<_Visitor, _VType1, _VType2, _Rest...>
	{	// get common return type of two or more called variants
	typedef typename _All_visitor_returns<_Visitor, _VType1 >::type _Ty0;
	typedef typename _All_visitor_returns<_Visitor, _VType2,
						        _Rest...>::type _Ty1;
	typedef common_type_t<_Ty0, _Ty1> type;
	};
#else
template<class _Visitor,
	class... _Types>
	struct _All_visitor_returns<_Visitor, variant<_Types...> >
	{	// get common return type of all called elements of a variant
	typedef typename _Visitor_returns<_Visitor, _Types...>::type type;
	};

template<class _Visitor,
	class... _Types>
	struct _All_visitor_returns<_Visitor, variant<_Types...>&>
	{	// get common return type of all called elements of a variant
	typedef typename _Visitor_returns<_Visitor, _Types&...>::type type;
	};

template<class _Visitor,
	class... _Types0,
	class... _Types1,
	class... _Rest>
	struct _All_visitor_returns<_Visitor,
		variant<_Types0...>, variant<_Types1...>, _Rest...>
	{	// get common return type of two or more called variants
	typedef typename _All_visitor_returns<_Visitor,
		variant<_Types0...> >::type _Ty0;
	typedef typename _All_visitor_returns<_Visitor,
		variant<_Types1>..., _Rest...>::type _Ty1;
	typedef common_type_t<_Ty0, _Ty1> type;
	};
#endif

#if defined(__ghs)
inline
#endif /* defined(__ghs) */
bool _All_variants_valid()
	{	// no variants, always true
	return (true);
	}

#if defined(__ghs)
template<class _Variant0>
	bool _All_variants_valid(_Variant0&& _Var0)
	{	// test if first holds value
	return (!_STD forward<_Variant0>(_Var0).valueless_by_exception());
	}

template<class _Variant0,
	class _Variant1,
	class... _Variants>
	bool _All_variants_valid(_Variant0&& _Var0, _Variant1&& _Var1,
		_Variants&&... _Vars)
	{	// test if all hold values
	return (_All_variants_valid(_STD forward<_Variant0>(_Var0))
		&& _All_variants_valid(_STD forward<_Variant1>(_Var1),
			_STD forward<_Variants>(_Vars)...));
	}

template <class _Visitor, class ..._Visitor2> _Visitor &_FirstOf(_Visitor & _Vfirst, const _Visitor2 & ... _Vrest)
{
    return _Vfirst;
}

template <class...>
	struct _Visitfunc
	{
	};

template<class _First>
	struct _Visitfunc<_First>
	{	// performs visit operation by runtime index
	template<size_t _VIndex, class _Visitor, class _Vtype> _CONST_FUNX inline static
	auto _VisitR(_Visitor&& _Fn, size_t _Index, _Vtype &&_Var)
	{
	    // _Index must be zero, because there is only one remaining type in
	    // the variant (ie. _First is the last type in the variant)
	    return _STD invoke(std::forward<_Visitor>(_Fn),
		    std::move(_Get(in_place_index_t<_VIndex>{},
			    _Var._Storage._Myval)));
	}

	template<size_t _VIndex, class _Visitor, class _Vtype> _CONST_FUNX inline static
	auto _VisitR(_Visitor&& _Fn, size_t _Index, _Vtype &_Var)
	{
	    // _Index must be zero, because there is only one remaining type in
	    // the variant (ie. _First is the last type in the variant)
	    return _STD invoke(std::forward<_Visitor>(_Fn),
		    _Get(in_place_index_t<_VIndex>{},
			    _Var._Storage._Myval));
	}
	};

template<class _First,
	class... _Rest>
	struct _Visitfunc<_First, _Rest...>
	{	// performs visit operation by runtime index
	template<size_t _VIndex, class _Visitor, class _Vtype> _CONST_FUNX inline static
	auto _VisitR(_Visitor&& _Fn, size_t _Index, _Vtype &&_Var)
	{
	    if (_Index == 0)
		return _STD invoke(std::forward<_Visitor>(_Fn),
			std::move(_Get(in_place_index_t<_VIndex>{},
				_Var._Storage._Myval)));
	    else
		return (_Visitfunc<_Rest...>::_VisitR<_VIndex+1>(
			std::forward<_Visitor>(_Fn), _Index - 1,
			std::move(_Var)));
	}

	template<size_t _VIndex, class _Visitor, class _Vtype> _CONST_FUNX inline static
	auto _VisitR(_Visitor&& _Fn, size_t _Index, _Vtype &_Var)
	{
	    if (_Index == 0)
		return _STD invoke(std::forward<_Visitor>(_Fn),
			_Get(in_place_index_t<_VIndex>{},
				_Var._Storage._Myval));
	    else
		return (_Visitfunc<_Rest...>::_VisitR<_VIndex+1>(
			std::forward<_Visitor>(_Fn), _Index - 1,
			_Var));
	}
	};

template<class _Visitor, class ..._VTypes> _CONST_FUNX inline static
auto _Visit(_Visitor&& _Fn, variant<_VTypes...> &_Var)
{
    return _Visitfunc<_VTypes...>::_VisitR<0>(std::forward<_Visitor>(_Fn),
	    _Var.index(), _Var);
}

template<class _Visitor, class ..._VTypes> _CONST_FUNX inline static
auto _Visit(_Visitor&& _Fn, variant<_VTypes...> &&_Var)
{
    return _Visitfunc<_VTypes...>::_VisitR<0>(std::forward<_Visitor>(_Fn),
	    _Var.index(), std::move(_Var));
}

template<class _Visitor, class ..._VTypes> _CONST_FUNX inline static
auto _Visit(_Visitor&& _Fn, const variant<_VTypes...> &_Var)
{
    return _Visitfunc<_VTypes...>::_VisitR<0>(std::forward<_Visitor>(_Fn),
	    _Var.index(), _Var);
}

template<class _Visitor, class ..._VTypes> _CONST_FUNX inline static
auto _Visit(_Visitor&& _Fn, const variant<_VTypes...> &&_Var)
{
    return _Visitfunc<_VTypes...>::_VisitR<0>(std::forward<_Visitor>(_Fn),
	    _Var.index(), std::move(_Var));
}

	// TEMPLATE FUNCTION visit
template<class _Visitor,
	class... _Vtypes>
	_CONST_FUNX auto
		visit(_Visitor&& _Fn, _Vtypes&&..._Vars)
			-> typename _All_visitor_returns<
				_Visitor,
				decltype(std::forward<_Vtypes>(_Vars))...>::type
	{	// call visitor for active values of variants
	static_assert(sizeof...(_Vars) <= 1,
		      "std::visit with more than one variant not supported");
	if (!_All_variants_valid(_STD forward<_Vtypes>(_Vars)...))
		_THROW_N(bad_variant_access,
			"visit(fn, variant...) has valueless variant");
	typedef typename _All_visitor_returns<
		_Visitor, decltype(std::forward<_Vtypes>(_Vars))...>::type _Ret;
	return _Visit(std::forward<_Visitor>(_Fn), std::forward<_Vtypes>(_Vars)...);
	}
#else /* defined(__ghs) */
template<class _Variant0>
	bool _All_variants_valid(_Variant0 _Var0)
	{	// test if first holds value
	return (!_Var0.valueless_by_exception());
	}

template<class _Variant0,
	class _Variant1,
	class... _Variants>
	bool _All_variants_valid(_Variant0 _Var0, _Variant1 _Var1,
		_Variants... _Vars)
	{	// test if all hold values
	return (_All_variants_valid(_Var0)
		&& _All_variants_valid(_Var1, _Vars...));
	}

	// TEMPLATE FUNCTION visit
template<class _Visitor,
	class... _Vtypes>
	_CONST_FUNX typename _All_visitor_returns<
		_Visitor, _Vtypes...>::type
		visit(_Visitor&& _Fn, _Vtypes... _Vars)
	{	// call visitor for active values of variants
	if (!_All_variants_valid(_Vars...))
		_THROW_N(bad_variant_access,
			"visit(fn, variant...) has valueless variant");
	typedef typename _All_visitor_returns<
		_Visitor, _Vtypes...>::type _Ret;
	return (_Vfunc<char>()._Visit<_Ret>(size_t(-1),
		_STD forward<_Visitor>(_Fn),
			tuple<>(),
			_FirstOf(_Vars...),
			_STD forward<_Vtypes>(_Vars)...));
	}
#endif /* defined(__ghs) */

#if defined(__ghs)
template<class _Visitor>
	auto visit(_Visitor&& _Fn)
	{	// call visitor for no variants
	return _STD forward<_Visitor>(_Fn)();
	}
#else
template<class _Visitor>
	void visit(_Visitor&& _Fn)
	{	// call visitor for no variants
	_STD forward<_Visitor>(_Fn)();
	}
#endif

	// STRUCT monostate
struct monostate
	{	// dummy class for variant<monostate, ...>
	};

_CONST_FUN bool operator==(monostate, monostate) _NOEXCEPT
	{	// test if monostate == monostate
	return (true);
	}

_CONST_FUN bool operator!=(monostate, monostate) _NOEXCEPT
	{	// test if monostate != monostate
	return (false);
	}

_CONST_FUN bool operator<(monostate, monostate) _NOEXCEPT
	{	// test if monostate < monostate
	return (false);
	}

_CONST_FUN bool operator<=(monostate, monostate) _NOEXCEPT
	{	// test if monostate >= monostate
	return (true);
	}

_CONST_FUN bool operator>(monostate, monostate) _NOEXCEPT
	{	// test if monostate > monostate
#if defined(__ghs)
	return (false);
#else
	return (true);
#endif
	}

_CONST_FUN bool operator>=(monostate, monostate) _NOEXCEPT
	{	// test if monostate >= monostate
	return (true);
	}
_STD_END

namespace std {
	// TEMPLATE STRUCT SPECIALIZATION hash
template<class... _Types>
	struct hash<_STD variant<_Types...> >
#if defined(__ghs)
	: public _Conditional_bitwise_hash<_STD variant<_Types...>, _Is_hashable_v<remove_const_t<_Types>...> >
#endif
	{	// hash functor for stored variant
#if defined(__ghs)
	template <bool _Bool_value = _Is_hashable_v<remove_const_t<_Types>...>, class = enable_if_t<_Bool_value> >
#endif
	size_t operator()(const _STD variant<_Types...>& _Value) const
#if defined(__ghs)
	    _NOEXCEPT
#endif
		{	// hash stored value to size_t
 		if (_Value.valueless_by_exception())
			return (hash<size_t>()(0));
		else
			return (_Vfunc<_Types...>()._Hash(_Value.index(), &_Value));
		}
	};

template<>
	struct hash<_STD monostate>
	{	// hash functor for lone monostate value
	size_t operator()(const _STD monostate& _Value) const
#if defined(__ghs)
	    _NOEXCEPT
#endif
		{	// hash _Value to size_t or throw
		return (hash<size_t>()(0));
		}
	};

template<class... _Types,
	class _Alloc>
	struct uses_allocator<_STD variant<_Types...>, _Alloc>
		: true_type
	{	// true_type
	};
} // 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 /* _VARIANT_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V8.03b/17:0063 */
