// type_traits standard header (core)
#pragma once
#ifndef _TYPE_TRAITS_
#define _TYPE_TRAITS_
#ifndef RC_INVOKED
#include <xstddef>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,_STL_WARNING_LEVEL)
 #pragma warning(disable: _STL_DISABLED_WARNINGS)
 _STL_DISABLE_CLANG_WARNINGS
 #pragma push_macro("new")
 #undef new

 #pragma warning(disable: 4180)	// qualifier applied to function type has no meaning; ignored

_STD_BEGIN
	// STRUCT TEMPLATE integer_sequence
template<class _Ty,
	_Ty... _Vals>
	struct integer_sequence
	{	// sequence of integer parameters
	static_assert(is_integral_v<_Ty>,
		"integer_sequence<T, I...> requires T to be an integral type.");

	using value_type = _Ty;

	_NODISCARD static constexpr size_t size() noexcept
		{	// get length of parameter list
		return (sizeof...(_Vals));
		}
	};

	// ALIAS TEMPLATE make_integer_sequence
template<class _Ty,
	_Ty _Size>
	using make_integer_sequence = __make_integer_seq<integer_sequence, _Ty, _Size>;

template<size_t... _Vals>
	using index_sequence = integer_sequence<size_t, _Vals...>;

template<size_t _Size>
	using make_index_sequence = make_integer_sequence<size_t, _Size>;

template<class... _Types>
	using index_sequence_for = make_index_sequence<sizeof...(_Types)>;

	// STRUCT TEMPLATE conjunction
template<bool _First_value,
	class _First,
	class... _Rest>
	struct _Conjunction
	{	// handle false trait or last trait
	using type = _First;
	};

template<class _True,
	class _Next,
	class... _Rest>
	struct _Conjunction<true, _True, _Next, _Rest...>
	{	// the first trait is true, try the next one
	using type = typename _Conjunction<_Next::value, _Next, _Rest...>::type;
	};

template<class... _Traits>
	struct conjunction
		: true_type
	{	// If _Traits is empty, true_type
	};

template<class _First,
	class... _Rest>
	struct conjunction<_First, _Rest...>
		: _Conjunction<_First::value, _First, _Rest...>::type
	{	// Otherwise, if any of _Traits are false, the first false trait
		// Otherwise, the last trait in _Traits
	};

template<class... _Traits>
	_INLINE_VAR constexpr bool conjunction_v = conjunction<_Traits...>::value;

	// STRUCT TEMPLATE disjunction
template<bool _First_value,
	class _First,
	class... _Rest>
	struct _Disjunction
	{	// handle true trait or last trait
	using type = _First;
	};

template<class _False,
	class _Next,
	class... _Rest>
	struct _Disjunction<false, _False, _Next, _Rest...>
	{	// first trait is false, try the next trait
	using type = typename _Disjunction<_Next::value, _Next, _Rest...>::type;
	};

template<class... _Traits>
	struct disjunction
		: false_type
	{	// If _Traits is empty, false_type
	};

template<class _First,
	class... _Rest>
	struct disjunction<_First, _Rest...>
		: _Disjunction<_First::value, _First, _Rest...>::type
	{	// Otherwise, if any of _Traits are true, the first true trait
		// Otherwise, the last trait in _Traits
	};

template<class... _Traits>
	_INLINE_VAR constexpr bool disjunction_v = disjunction<_Traits...>::value;

	// STRUCT TEMPLATE negation
template<class _Trait>
	struct negation
		: bool_constant<!static_cast<bool>(_Trait::value)>
	{	// The negated result of _Trait
	};

template<class _Trait>
	_INLINE_VAR constexpr bool negation_v = negation<_Trait>::value;

	// VARIABLE TEMPLATE _Is_any_of_v
template<class _Ty,
	class... _Types>
	_INLINE_VAR constexpr bool _Is_any_of_v = disjunction_v<is_same<_Ty, _Types>...>;

	// STRUCT TEMPLATE _Arg_types
template<class... _Types>
	struct _Arg_types
	{	// provide argument_type, etc. (sometimes)
	};

template<class _Ty1>
	struct _Arg_types<_Ty1>
	{	// provide argument_type, etc. (sometimes)
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 argument_type;
	};

template<class _Ty1,
	class _Ty2>
	struct _Arg_types<_Ty1, _Ty2>
	{	// provide argument_type, etc. (sometimes)
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 first_argument_type;
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty2 second_argument_type;
	};

	// STRUCT TEMPLATE is_function
template<class _Ty>
	struct _Is_function
	{	// determine whether _Ty is a function
	using _Bool_type = false_type;
	};

#define _IS_FUNCTION(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \
template<class _Ret, \
	class... _Types> \
	struct _Is_function<_Ret CALL_OPT (_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> \
		: _Arg_types<_Types...> \
	{	/* determine whether _Ty is a function */ \
	using _Bool_type = true_type; \
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \
	};

_NON_MEMBER_CALL_CV_REF_NOEXCEPT(_IS_FUNCTION)
#undef _IS_FUNCTION

#define _IS_FUNCTION_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \
template<class _Ret, \
	class... _Types> \
	struct _Is_function<_Ret (_Types..., ...) CV_REF_NOEXCEPT_OPT> \
	{	/* no calling conventions for ellipsis */ \
	using _Bool_type = true_type; \
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \
	};

_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_FUNCTION_ELLIPSIS)
#undef _IS_FUNCTION_ELLIPSIS

template<class _Ty>
	struct is_function
		: _Is_function<_Ty>::_Bool_type
	{	// determine whether _Ty is a function
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_function_v = is_function<_Ty>::value;


template<class _Ty>
	struct _Is_memfunptr
	{	// base class for member function pointer predicates
	using _Bool_type = false_type;
	};

#define _IS_MEMFUNPTR(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \
template<class _Ret, \
	class _Arg0, \
	class... _Types> \
	struct _Is_memfunptr<_Ret (CALL_OPT _Arg0::*)(_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> \
		: _Arg_types<CV_OPT _Arg0 *, _Types...> \
	{	/* base class for member function pointer predicates */ \
	using _Bool_type = true_type; \
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \
	using _Class_type = _Arg0; \
	using _Guide_type = enable_if<!is_same_v<int REF_OPT, int&&>, _Ret (_Types...)>; \
	};

_MEMBER_CALL_CV_REF_NOEXCEPT(_IS_MEMFUNPTR)
#undef _IS_MEMFUNPTR

#define _IS_MEMFUNPTR_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \
template<class _Ret, \
	class _Arg0, \
	class... _Types> \
	struct _Is_memfunptr<_Ret (_Arg0::*)(_Types..., ...) CV_REF_NOEXCEPT_OPT> \
	{	/* no calling conventions for ellipsis */ \
	using _Bool_type = true_type; \
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \
	using _Class_type = _Arg0; \
	using _Guide_type = enable_if<false>; \
	};

_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_MEMFUNPTR_ELLIPSIS)
#undef _IS_MEMFUNPTR_ELLIPSIS

	// STRUCT TEMPLATE is_void
template<class _Ty>
	struct is_void
		: false_type
	{	// determine whether _Ty is void
	};

#define _IS_VOID(CV_OPT) \
template<> \
	struct is_void<CV_OPT void> \
		: true_type \
	{	/* determine whether _Ty is void */ \
	};

_CLASS_DEFINE_CV(_IS_VOID)
#undef _IS_VOID

template<class _Ty>
	_INLINE_VAR constexpr bool is_void_v = is_void<_Ty>::value;

	// ALIAS TEMPLATE void_t
template<class... _Types>
	using void_t = void;

	// Type modifiers
	// STRUCT TEMPLATE add_const
template<class _Ty>
	struct add_const
	{	// add top level const qualifier
	using type = const _Ty;
	};

template<class _Ty>
	using add_const_t = const _Ty;

	// STRUCT TEMPLATE add_volatile
template<class _Ty>
	struct add_volatile
	{	// add top level volatile qualifier
	using type = volatile _Ty;
	};

template<class _Ty>
	using add_volatile_t = volatile _Ty;

	// STRUCT TEMPLATE add_cv
template<class _Ty>
	struct add_cv
	{	// add top level const and volatile qualifiers
	using type = const volatile _Ty;
	};

template<class _Ty>
	using add_cv_t = const volatile _Ty;

	// STRUCT TEMPLATE _Add_reference
template<class _Ty,
	class = void>
	struct _Add_reference
	{	// add reference
	using _Lvalue = _Ty;
	using _Rvalue = _Ty;
	};

template<class _Ty>
	struct _Add_reference<_Ty, void_t<_Ty&>>
	{	// add reference
	using _Lvalue = _Ty&;
	using _Rvalue = _Ty&&;
	};

	// STRUCT TEMPLATE add_lvalue_reference
template<class _Ty>
	struct add_lvalue_reference
	{	// add lvalue reference
	using type = typename _Add_reference<_Ty>::_Lvalue;
	};

template<class _Ty>
	using add_lvalue_reference_t = typename _Add_reference<_Ty>::_Lvalue;

	// STRUCT TEMPLATE add_rvalue_reference
template<class _Ty>
	struct add_rvalue_reference
	{	// add rvalue reference
	using type = typename _Add_reference<_Ty>::_Rvalue;
	};

template<class _Ty>
	using add_rvalue_reference_t = typename _Add_reference<_Ty>::_Rvalue;

	// FUNCTION TEMPLATE declval
template<class _Ty>
	add_rvalue_reference_t<_Ty> declval() noexcept;

	// STRUCT TEMPLATE remove_extent
template<class _Ty>
	struct remove_extent
	{	// remove array extent
	using type = _Ty;
	};

template<class _Ty, size_t _Ix>
	struct remove_extent<_Ty[_Ix]>
	{	// remove array extent
	using type = _Ty;
	};

template<class _Ty>
	struct remove_extent<_Ty[]>
	{	// remove array extent
	using type = _Ty;
	};

template<class _Ty>
	using remove_extent_t = typename remove_extent<_Ty>::type;

	// STRUCT TEMPLATE remove_all_extents
template<class _Ty>
	struct remove_all_extents
	{	// remove all array extents
	using type = _Ty;
	};

template<class _Ty, size_t _Ix>
	struct remove_all_extents<_Ty[_Ix]>
	{	// remove all array extents
	using type = typename remove_all_extents<_Ty>::type;
	};

template<class _Ty>
	struct remove_all_extents<_Ty[]>
	{	// remove all array extents
	using type = typename remove_all_extents<_Ty>::type;
	};

template<class _Ty>
	using remove_all_extents_t = typename remove_all_extents<_Ty>::type;

	// STRUCT TEMPLATE remove_pointer
template<class _Ty>
	struct remove_pointer
	{	// remove pointer
	using type = _Ty;
	};

#define _REMOVE_POINTER(CV_OPT) \
template<class _Ty> \
	struct remove_pointer<_Ty * CV_OPT> \
	{	/* remove pointer */ \
	using type = _Ty; \
	};

_CLASS_DEFINE_CV(_REMOVE_POINTER)
#undef _REMOVE_POINTER

template<class _Ty>
	using remove_pointer_t = typename remove_pointer<_Ty>::type;

	// STRUCT TEMPLATE add_pointer
template<class _Ty,
	class = void>
	struct _Add_pointer
	{	// add pointer
	using type = _Ty;
	};

template<class _Ty>
	struct _Add_pointer<_Ty, void_t<remove_reference_t<_Ty> *>>
	{	// add pointer
	using type = remove_reference_t<_Ty> *;
	};

template<class _Ty>
	struct add_pointer
	{	// add pointer
	using type = typename _Add_pointer<_Ty>::type;
	};

template<class _Ty>
	using add_pointer_t = typename _Add_pointer<_Ty>::type;

	// TYPE PREDICATES
	// STRUCT TEMPLATE is_array
template<class _Ty>
	struct is_array
		: false_type
	{	// determine whether _Ty is an array
	};

template<class _Ty, size_t _Nx>
	struct is_array<_Ty[_Nx]>
		: true_type
	{	// determine whether _Ty is an array
	};

template<class _Ty>
	struct is_array<_Ty[]>
		: true_type
	{	// determine whether _Ty is an array
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_array_v = is_array<_Ty>::value;

	// STRUCT TEMPLATE is_lvalue_reference
template<class _Ty>
	struct is_lvalue_reference
		: false_type
	{	// determine whether _Ty is an lvalue reference
	};

template<class _Ty>
	struct is_lvalue_reference<_Ty&>
		: true_type
	{	// determine whether _Ty is an lvalue reference
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Ty>::value;

	// STRUCT TEMPLATE is_rvalue_reference
template<class _Ty>
	struct is_rvalue_reference
		: false_type
	{	// determine whether _Ty is an rvalue reference
	};

template<class _Ty>
	struct is_rvalue_reference<_Ty&&>
		: true_type
	{	// determine whether _Ty is an rvalue reference
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Ty>::value;

	// STRUCT TEMPLATE is_reference
template<class _Ty>
	struct is_reference
		: false_type
	{	// determine whether _Ty is a reference
	};

template<class _Ty>
	struct is_reference<_Ty&>
		: true_type
	{	// determine whether _Ty is a reference
	};

template<class _Ty>
	struct is_reference<_Ty&&>
		: true_type
	{	// determine whether _Ty is a reference
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_reference_v = is_reference<_Ty>::value;

	// STRUCT TEMPLATE is_member_object_pointer
template<class _Ty,
	bool _Pmf = _Is_memfunptr<_Ty>::_Bool_type::value>
	struct _Is_member_object_pointer
		: false_type
	{	// determine whether _Ty is a pointer to member object
	};

template<class _Ty1,
	class _Ty2>
	struct _Is_member_object_pointer<_Ty1 _Ty2::*, false>
		: true_type
	{	// determine whether _Ty is a pointer to member object
	using _Class_type = _Ty2;
	};

template<class _Ty>
	struct is_member_object_pointer
		: _Is_member_object_pointer<remove_cv_t<_Ty>>::type
	{	// determine whether _Ty is a pointer to member object
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Ty>::value;

	// STRUCT TEMPLATE is_member_function_pointer
template<class _Ty>
	struct is_member_function_pointer
		: _Is_memfunptr<remove_cv_t<_Ty>>::_Bool_type
	{	// determine whether _Ty is a pointer to member function
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Ty>::value;

	// STRUCT TEMPLATE is_pointer
template<class _Ty>
	struct is_pointer
		: false_type
	{	// determine whether _Ty is a pointer
	};

template<class _Ty>
	struct is_pointer<_Ty *>
		: true_type
	{	// determine whether _Ty is a pointer
	};

template<class _Ty>
	struct is_pointer<_Ty * const>
		: true_type
	{	// determine whether _Ty is a pointer
	};

template<class _Ty>
	struct is_pointer<_Ty * volatile>
		: true_type
	{	// determine whether _Ty is a pointer
	};

template<class _Ty>
	struct is_pointer<_Ty * const volatile>
		: true_type
	{	// determine whether _Ty is a pointer
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_pointer_v = is_pointer<_Ty>::value;

	// STRUCT TEMPLATE is_null_pointer
template<class _Ty>
	struct is_null_pointer
		: bool_constant<is_same_v<remove_cv_t<_Ty>, nullptr_t>>
	{	// determine whether _Ty is nullptr_t
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_null_pointer_v = is_same_v<remove_cv_t<_Ty>, nullptr_t>;

	// STRUCT TEMPLATE is_union
template<class _Ty>
	struct is_union
		: bool_constant<__is_union(_Ty)>
	{	// determine whether _Ty is a union
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_union_v = __is_union(_Ty);

	// STRUCT TEMPLATE is_class
template<class _Ty>
	struct is_class
		: bool_constant<__is_class(_Ty)>
	{	// determine whether _Ty is a class
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_class_v = __is_class(_Ty);

	// STRUCT TEMPLATE is_fundamental
template<class _Ty>
	struct is_fundamental
		: bool_constant<is_arithmetic_v<_Ty>
		|| is_void_v<_Ty>
		|| is_null_pointer_v<_Ty>>
	{	// determine whether _Ty is a fundamental type
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_fundamental_v = is_fundamental<_Ty>::value;

	// STRUCT TEMPLATE is_object
template<class _Ty>
	struct is_object
		: bool_constant<!is_function_v<_Ty>
		&& !is_reference_v<_Ty>
		&& !is_void_v<_Ty>>
	{	// determine whether _Ty is an object type
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_object_v = is_object<_Ty>::value;

	// STRUCT TEMPLATE is_convertible
template<class _From,
	class _To>
	struct is_convertible
		: bool_constant<__is_convertible_to(_From, _To)>
	{	// determine whether _From is convertible to _To
	};

template<class _From,
	class _To>
	_INLINE_VAR constexpr bool is_convertible_v = __is_convertible_to(_From, _To);

	// STRUCT TEMPLATE is_enum
template<class _Ty>
	struct is_enum
		: bool_constant<__is_enum(_Ty)>
	{	// determine whether _Ty is an enumerated type
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_enum_v = __is_enum(_Ty);

	// STRUCT TEMPLATE is_compound
template<class _Ty>
	struct is_compound
		: bool_constant<!is_fundamental_v<_Ty>>
	{	// determine whether _Ty is a compound type
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_compound_v = is_compound<_Ty>::value;

	// STRUCT TEMPLATE is_member_pointer
template<class _Ty>
	struct is_member_pointer
		: bool_constant<is_member_object_pointer_v<_Ty>
		|| is_member_function_pointer_v<_Ty>>
	{	// determine whether _Ty is a pointer to member
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_member_pointer_v = is_member_pointer<_Ty>::value;

	// STRUCT TEMPLATE is_scalar
template<class _Ty>
	struct is_scalar
		: bool_constant<is_arithmetic_v<_Ty>
		|| is_enum_v<_Ty>
		|| is_pointer_v<_Ty>
		|| is_member_pointer_v<_Ty>
		|| is_null_pointer_v<_Ty>>
	{	// determine whether _Ty is a scalar type
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_scalar_v = is_scalar<_Ty>::value;

	// STRUCT TEMPLATE is_const
template<class _Ty>
	struct is_const
		: false_type
	{	// determine whether _Ty is const qualified
	};

template<class _Ty>
	struct is_const<const _Ty>
		: true_type
	{	// determine whether _Ty is const qualified
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_const_v = is_const<_Ty>::value;

	// STRUCT TEMPLATE is_volatile
template<class _Ty>
	struct is_volatile
		: false_type
	{	// determine whether _Ty is volatile qualified
	};

template<class _Ty>
	struct is_volatile<volatile _Ty>
		: true_type
	{	// determine whether _Ty is volatile qualified
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_volatile_v = is_volatile<_Ty>::value;

	// STRUCT TEMPLATE is_pod
template<class _Ty>
	struct is_pod
		: bool_constant<__is_pod(_Ty)>
	{	// determine whether _Ty is a POD type
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_pod_v = __is_pod(_Ty);

	// STRUCT TEMPLATE is_empty
template<class _Ty>
	struct is_empty
		: bool_constant<__is_empty(_Ty)>
	{	// determine whether _Ty is an empty class
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_empty_v = __is_empty(_Ty);

	// STRUCT TEMPLATE is_polymorphic
template<class _Ty>
	struct is_polymorphic
		: bool_constant<__is_polymorphic(_Ty)>
	{	// determine whether _Ty is a polymorphic type
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_polymorphic_v = __is_polymorphic(_Ty);

	// STRUCT TEMPLATE is_abstract
template<class _Ty>
	struct is_abstract
		: bool_constant<__is_abstract(_Ty)>
	{	// determine whether _Ty is an abstract class
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_abstract_v = __is_abstract(_Ty);

	// STRUCT TEMPLATE is_final
template<class _Ty>
	struct is_final
		: bool_constant<__is_final(_Ty)>
	{	// determine whether _Ty is a final class
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_final_v = __is_final(_Ty);

	// STRUCT TEMPLATE is_standard_layout
template<class _Ty>
	struct is_standard_layout
		: bool_constant<__is_standard_layout(_Ty)>
	{	// determine whether _Ty is standard layout
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_standard_layout_v = __is_standard_layout(_Ty);

	// STRUCT TEMPLATE is_literal_type
template<class _Ty>
	struct _CXX17_DEPRECATE_IS_LITERAL_TYPE is_literal_type
		: bool_constant<__is_literal_type(_Ty)>
	{	// determine whether _Ty is a literal type
	};

#pragma warning(push)
#pragma warning(disable: 4996)	// was declared deprecated
template<class _Ty>
	_CXX17_DEPRECATE_IS_LITERAL_TYPE _INLINE_VAR constexpr bool is_literal_type_v = __is_literal_type(_Ty);
#pragma warning(pop)

	// STRUCT TEMPLATE is_trivial
template<class _Ty>
	struct is_trivial
		: bool_constant<__is_trivial(_Ty)>
	{	// determine whether _Ty is trivial
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_trivial_v = __is_trivial(_Ty);

	// STRUCT TEMPLATE is_trivially_copyable
template<class _Ty>
	struct is_trivially_copyable
		: bool_constant<__is_trivially_copyable(_Ty)>
	{	// determine whether _Ty is trivially copyable
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Ty);

	// STRUCT TEMPLATE has_virtual_destructor
template<class _Ty>
	struct has_virtual_destructor
		: bool_constant<__has_virtual_destructor(_Ty)>
	{	// determine whether _Ty has a virtual destructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Ty);

#if _HAS_CXX17
	// STRUCT TEMPLATE has_unique_object_representations
template<class _Ty>
	struct has_unique_object_representations
		: bool_constant<__has_unique_object_representations(_Ty)>
	{	// determine whether _Ty has unique object representations
	};

template<class _Ty>
	_INLINE_VAR constexpr bool has_unique_object_representations_v = __has_unique_object_representations(_Ty);

	// STRUCT TEMPLATE is_aggregate
template<class _Ty>
	struct is_aggregate
		: bool_constant<__is_aggregate(_Ty)>
	{	// determine whether _Ty is an aggregate
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_aggregate_v = __is_aggregate(_Ty);
#endif /* _HAS_CXX17 */

		// CONSTRUCTIBLE/ASSIGNABLE TRAITS
	// STRUCT TEMPLATE is_constructible
template<class _Ty,
	class... _Args>
	struct is_constructible
		: bool_constant<__is_constructible(_Ty, _Args...)>
	{	// determine whether _Ty(_Args...) is constructible
	};

template<class _Ty,
	class... _Args>
	_INLINE_VAR constexpr bool is_constructible_v = __is_constructible(_Ty, _Args...);

	// STRUCT TEMPLATE is_copy_constructible
template<class _Ty>
	struct is_copy_constructible
		: bool_constant<__is_constructible(_Ty, add_lvalue_reference_t<const _Ty>)>
	{	// determine whether _Ty has a copy constructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_copy_constructible_v = __is_constructible(_Ty, add_lvalue_reference_t<const _Ty>);

	// STRUCT TEMPLATE is_default_constructible
template<class _Ty>
	struct is_default_constructible
		: bool_constant<__is_constructible(_Ty)>
	{	// determine whether _Ty has a default constructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_default_constructible_v = __is_constructible(_Ty);

	// STRUCT TEMPLATE _Is_implicitly_default_constructible
template<class _Ty,
	class = void>
	struct _Is_implicitly_default_constructible
		: false_type
	{	// determine whether _Ty is implicitly default constructible
	};

template<class _Ty>
	void _Implicitly_default_construct(const _Ty&);

template<class _Ty>
	struct _Is_implicitly_default_constructible<_Ty, void_t<decltype(_Implicitly_default_construct<_Ty>({}))>>
		: true_type
	{	// determine whether _Ty is implicitly default constructible
	};

	// STRUCT TEMPLATE is_move_constructible
template<class _Ty>
	struct is_move_constructible
		: bool_constant<__is_constructible(_Ty, _Ty)>
	{	// determine whether _Ty has a move constructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_move_constructible_v = __is_constructible(_Ty, _Ty);

	// STRUCT TEMPLATE is_assignable
template<class _To,
	class _From>
	struct is_assignable
		: bool_constant<__is_assignable(_To, _From)>
	{	// determine whether _From can be assigned to _To
	};

template<class _To,
	class _From>
	_INLINE_VAR constexpr bool is_assignable_v = __is_assignable(_To, _From);

	// STRUCT TEMPLATE is_copy_assignable
template<class _Ty>
	struct is_copy_assignable
		: bool_constant<__is_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t<const _Ty>)>
	{	// determine whether _Ty has a copy assignment operator
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_copy_assignable_v =
		__is_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t<const _Ty>);

	// STRUCT TEMPLATE is_move_assignable
template<class _Ty>
	struct is_move_assignable
		: bool_constant<__is_assignable(add_lvalue_reference_t<_Ty>, _Ty)>
	{	// determine whether _Ty has a move assignment operator
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_move_assignable_v = __is_assignable(add_lvalue_reference_t<_Ty>, _Ty);

	// STRUCT TEMPLATE is_destructible
template<class _Ty>
	struct is_destructible
		: bool_constant<__is_destructible(_Ty)>
	{	// determine whether _Ty has a destructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_destructible_v = __is_destructible(_Ty);

		// TRIVIAL TRAITS
	// STRUCT TEMPLATE is_trivially_constructible
template<class _Ty,
	class... _Args>
	struct is_trivially_constructible
		: bool_constant<__is_trivially_constructible(_Ty, _Args...)>
	{	// determine whether _Ty(_Args...) is trivially constructible
	};

template<class _Ty,
	class... _Args>
	_INLINE_VAR constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Ty, _Args...);

	// STRUCT TEMPLATE is_trivially_copy_constructible
template<class _Ty>
	struct is_trivially_copy_constructible
		: bool_constant<__is_trivially_constructible(_Ty, add_lvalue_reference_t<const _Ty>)>
	{	// determine whether _Ty has a trivial copy constructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_trivially_copy_constructible_v =
		__is_trivially_constructible(_Ty, add_lvalue_reference_t<const _Ty>);

	// STRUCT TEMPLATE is_trivially_default_constructible
template<class _Ty>
	struct is_trivially_default_constructible
		: bool_constant<__is_trivially_constructible(_Ty)>
	{	// determine whether _Ty has a trivial default constructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_trivially_default_constructible_v = __is_trivially_constructible(_Ty);

	// STRUCT TEMPLATE is_trivially_move_constructible
template<class _Ty>
	struct is_trivially_move_constructible
		: bool_constant<__is_trivially_constructible(_Ty, _Ty)>
	{	// determine whether _Ty has a trivial move constructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_trivially_move_constructible_v = __is_trivially_constructible(_Ty, _Ty);

	// STRUCT TEMPLATE is_trivially_assignable
template<class _To,
	class _From>
	struct is_trivially_assignable
		: bool_constant<__is_trivially_assignable(_To, _From)>
	{	// determine whether _From can be assigned to _To, trivially
	};

template<class _To,
	class _From>
	_INLINE_VAR constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_To, _From);

	// STRUCT TEMPLATE is_trivially_copy_assignable
template<class _Ty>
	struct is_trivially_copy_assignable
		: bool_constant<__is_trivially_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t<const _Ty>)>
	{	// determine whether _Ty has a trivial copy assignment operator
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_trivially_copy_assignable_v =
		__is_trivially_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t<const _Ty>);

	// STRUCT TEMPLATE is_trivially_move_assignable
template<class _Ty>
	struct is_trivially_move_assignable
		: bool_constant<__is_trivially_assignable(add_lvalue_reference_t<_Ty>, _Ty)>
	{	// determine whether _Ty has a trivial move assignment operator
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_trivially_move_assignable_v =
		__is_trivially_assignable(add_lvalue_reference_t<_Ty>, _Ty);

	// STRUCT TEMPLATE is_trivially_destructible
template<class _Ty>
	struct is_trivially_destructible
		: bool_constant<__is_trivially_destructible(_Ty)>
	{	// determine whether _Ty has a trivial destructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_trivially_destructible_v = __is_trivially_destructible(_Ty);

		// NOTHROW TRAITS
	// STRUCT TEMPLATE is_nothrow_constructible
template<class _Ty,
	class... _Args>
	struct is_nothrow_constructible
		: bool_constant<__is_nothrow_constructible(_Ty, _Args...)>
	{	// determine whether _Ty(_Args...) is nothrow constructible
	};

template<class _Ty,
	class... _Args>
	_INLINE_VAR constexpr bool is_nothrow_constructible_v = __is_nothrow_constructible(_Ty, _Args...);

	// STRUCT TEMPLATE is_nothrow_copy_constructible
template<class _Ty>
	struct is_nothrow_copy_constructible
		: bool_constant<__is_nothrow_constructible(_Ty, add_lvalue_reference_t<const _Ty>)>
	{	// determine whether _Ty has a nothrow copy constructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_nothrow_copy_constructible_v =
		__is_nothrow_constructible(_Ty, add_lvalue_reference_t<const _Ty>);

	// STRUCT TEMPLATE is_nothrow_default_constructible
template<class _Ty>
	struct is_nothrow_default_constructible
		: bool_constant<__is_nothrow_constructible(_Ty)>
	{	// determine whether _Ty has a nothrow default constructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_nothrow_default_constructible_v = __is_nothrow_constructible(_Ty);

	// STRUCT TEMPLATE is_nothrow_move_constructible
template<class _Ty>
	struct is_nothrow_move_constructible
		: bool_constant<__is_nothrow_constructible(_Ty, _Ty)>
	{	// determine whether _Ty has a nothrow move constructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_nothrow_move_constructible_v = __is_nothrow_constructible(_Ty, _Ty);

	// STRUCT TEMPLATE is_nothrow_assignable
template<class _To,
	class _From>
	struct is_nothrow_assignable
		: bool_constant<__is_nothrow_assignable(_To, _From)>
	{	// determine whether _From can be assigned to _To, nothrow
	};

template<class _To,
	class _From>
	_INLINE_VAR constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_To, _From);

	// STRUCT TEMPLATE is_nothrow_copy_assignable
template<class _Ty>
	struct is_nothrow_copy_assignable
		: bool_constant<__is_nothrow_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t<const _Ty>)>
	{	// determine whether _Ty has a nothrow copy assignment operator
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_nothrow_copy_assignable_v =
		__is_nothrow_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t<const _Ty>);

	// STRUCT TEMPLATE is_nothrow_move_assignable
template<class _Ty>
	struct is_nothrow_move_assignable
		: bool_constant<__is_nothrow_assignable(add_lvalue_reference_t<_Ty>, _Ty)>
	{	// determine whether _Ty has a nothrow move assignment operator
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_nothrow_move_assignable_v = __is_nothrow_assignable(add_lvalue_reference_t<_Ty>, _Ty);

	// STRUCT TEMPLATE is_nothrow_destructible
template<class _Ty>
	struct is_nothrow_destructible
		: bool_constant<__is_nothrow_destructible(_Ty)>
	{	// determine whether _Ty has a nothrow destructor
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_nothrow_destructible_v = __is_nothrow_destructible(_Ty);

	// STRUCT TEMPLATE is_signed
#pragma warning(push)
#pragma warning(disable: 4296)	// expression is always false
template<class _Ty,
	bool = is_integral_v<_Ty>>
	struct _Sign_base
	{	// determine whether integral _Ty is a signed or unsigned type
	using _Uty = remove_cv_t<_Ty>;
	using _Signed = bool_constant<_Uty(-1) < _Uty(0)>;
	using _Unsigned = bool_constant<_Uty(0) < _Uty(-1)>;
	};
#pragma warning(pop)

template<class _Ty>
	struct _Sign_base<_Ty, false>
	{	// floating-point _Ty is signed
		// non-arithmetic _Ty is neither signed nor unsigned
	using _Signed = typename is_floating_point<_Ty>::type;
	using _Unsigned = false_type;
	};

template<class _Ty>
	struct is_signed
		: _Sign_base<_Ty>::_Signed
	{	// determine whether _Ty is a signed type
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_signed_v = is_signed<_Ty>::value;

	// STRUCT TEMPLATE is_unsigned
template<class _Ty>
	struct is_unsigned
		: _Sign_base<_Ty>::_Unsigned
	{	// determine whether _Ty is an unsigned type
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_unsigned_v = is_unsigned<_Ty>::value;

	// ALIAS TEMPLATE _Is_nonbool_integral
template<class _Ty>
	using _Is_nonbool_integral =
		bool_constant<is_integral_v<_Ty>
			&& !is_same_v<remove_cv_t<_Ty>, bool>>;

	// STRUCT TEMPLATE _Change_sign
template<class _Ty>
	struct _Change_sign
	{	// signed/unsigned partners to _Ty
	static_assert(_Is_nonbool_integral<_Ty>::value || is_enum_v<_Ty>,
		"make_signed<T>/make_unsigned<T> require that T shall be a (possibly "
		"cv-qualified) integral type or enumeration but not a bool type.");

	using _Signed =
		conditional_t<_Is_any_of_v<_Ty, long, unsigned long>, long,
		conditional_t<sizeof(_Ty) == 1, signed char,
		conditional_t<sizeof(_Ty) == 2, short,
		conditional_t<sizeof(_Ty) == 4, int,
			long long
		>>>>;

	using _Unsigned =
		conditional_t<_Is_any_of_v<_Ty, long, unsigned long>, unsigned long,
		conditional_t<sizeof(_Ty) == 1, unsigned char,
		conditional_t<sizeof(_Ty) == 2, unsigned short,
		conditional_t<sizeof(_Ty) == 4, unsigned int,
			unsigned long long
		>>>>;
	};

template<class _Ty>
	struct _Change_sign<const _Ty>
	{	// signed/unsigned partners to _Ty
	using _Signed = const typename _Change_sign<_Ty>::_Signed;
	using _Unsigned = const typename _Change_sign<_Ty>::_Unsigned;
	};

template<class _Ty>
	struct _Change_sign<volatile _Ty>
	{	// signed/unsigned partners to _Ty
	using _Signed = volatile typename _Change_sign<_Ty>::_Signed;
	using _Unsigned = volatile typename _Change_sign<_Ty>::_Unsigned;
	};

template<class _Ty>
	struct _Change_sign<const volatile _Ty>
	{	// signed/unsigned partners to _Ty
	using _Signed = const volatile typename _Change_sign<_Ty>::_Signed;
	using _Unsigned = const volatile typename _Change_sign<_Ty>::_Unsigned;
	};

	// STRUCT TEMPLATE make_signed
template<class _Ty>
	struct make_signed
	{	// signed partner to _Ty
	using type = typename _Change_sign<_Ty>::_Signed;
	};

template<class _Ty>
	using make_signed_t = typename make_signed<_Ty>::type;

	// STRUCT TEMPLATE make_unsigned
template<class _Ty>
	struct make_unsigned
	{	// unsigned partner to _Ty
	using type = typename _Change_sign<_Ty>::_Unsigned;
	};

template<class _Ty>
	using make_unsigned_t = typename make_unsigned<_Ty>::type;

	// FUNCTION TEMPLATE _Unsigned_value
template<class _Rep>
	constexpr make_unsigned_t<_Rep> _Unsigned_value(_Rep _Val)
	{	// makes _Val unsigned
	return (static_cast<make_unsigned_t<_Rep>>(_Val));
	}

	// STRUCT TEMPLATE alignment_of
template<class _Ty>
	struct alignment_of
		: integral_constant<size_t, alignof(_Ty)>
	{	// determine alignment of _Ty
	};

template<class _Ty>
	_INLINE_VAR constexpr size_t alignment_of_v = alignof(_Ty);

	// STRUCT TEMPLATE aligned_storage
#define _FITS(_Ty)	_Align <= alignof(_Ty)
#define _NEXT_ALIGN(_Ty)	\
	using type = typename _Aligned<_Len, _Align, _Ty, _FITS(_Ty)>::type

template<class _Ty,
	size_t _Len>
	union _Align_type
	{	// union with size _Len bytes and alignment of _Ty
	_Ty _Val;
	char _Pad[_Len];
	};

template<size_t _Len,
	size_t _Align,
	class _Ty,
	bool _Ok>
	struct _Aligned;

template<size_t _Len,
	size_t _Align,
	class _Ty>
	struct _Aligned<_Len, _Align, _Ty, true>
	{	// define type with size _Len and alignment _Ty
	using type = _Align_type<_Ty, _Len>;
	};

template<size_t _Len,
	size_t _Align>
	struct _Aligned<_Len, _Align, double, false>
	{	// define type with size _Len and alignment _Ty
 #ifdef _ENABLE_EXTENDED_ALIGNED_STORAGE
	struct type
		{
		alignas(_Align) char _Space[_Len];
		};
 #else /* ^^^ _ENABLE_EXTENDED_ALIGNED_STORAGE / !_ENABLE_EXTENDED_ALIGNED_STORAGE vvv */
  #ifndef _DISABLE_EXTENDED_ALIGNED_STORAGE
	static_assert(_Always_false<_Aligned>,
		"You've instantiated std::aligned_storage<Len, Align> with an extended alignment (in other "
		"words, Align > alignof(max_align_t)). Before VS 2017 15.8, the member type would "
		"non-conformingly have an alignment of only alignof(max_align_t). VS 2017 15.8 was fixed to "
		"handle this correctly, but the fix inherently changes layout and breaks binary compatibility "
		"(*only* for uses of aligned_storage with extended alignments). "
		"Please define either "
		"(1) _ENABLE_EXTENDED_ALIGNED_STORAGE to acknowledge that you understand this message and "
		"that you actually want a type with an extended alignment, or "
		"(2) _DISABLE_EXTENDED_ALIGNED_STORAGE to silence this message and get the old non-conformant "
		"behavior.");
  #endif /* !_DISABLE_EXTENDED_ALIGNED_STORAGE */
	using type = _Align_type<max_align_t, _Len>;
 #endif /* _ENABLE_EXTENDED_ALIGNED_STORAGE */
	};

template<size_t _Len,
	size_t _Align>
	struct _Aligned<_Len, _Align, int, false>
	{	// define type with size _Len and alignment _Ty
	_NEXT_ALIGN(double);
	};

template<size_t _Len,
	size_t _Align>
	struct _Aligned<_Len, _Align, short, false>
	{	// define type with size _Len and alignment _Ty
	_NEXT_ALIGN(int);
	};

template<size_t _Len,
	size_t _Align>
	struct _Aligned<_Len, _Align, char, false>
	{	// define type with size _Len and alignment _Ty
	_NEXT_ALIGN(short);
	};

template<size_t _Len,
	size_t _Align = alignof(max_align_t)>
	struct aligned_storage
	{	// define type with size _Len and alignment _Align
	using type = typename _Aligned<_Len, _Align, char, _FITS(char)>::type;
	};

#undef _FITS
#undef _NEXT_ALIGN

template<size_t _Len,
	size_t _Align = alignof(max_align_t)>
	using aligned_storage_t = typename aligned_storage<_Len, _Align>::type;

	// STRUCT TEMPLATE aligned_union
template<size_t... _Vals>
	struct _Maximum;

template<>
	struct _Maximum<>
		: integral_constant<size_t, 0>
	{	// maximum of nothing is 0
	};

template<size_t _Val>
	struct _Maximum<_Val>
		: integral_constant<size_t, _Val>
	{	// maximum of _Val is _Val
	};

template<size_t _First,
	size_t _Second,
	size_t... _Rest>
	struct _Maximum<_First, _Second, _Rest...>
		: _Maximum<(_First < _Second ? _Second : _First), _Rest...>::type
	{	// find maximum value in _First, _Second, _Rest...
	};

template<size_t _Len,
	class... _Types>
	struct aligned_union
	{	// define type with size at least _Len, for storing anything in _Types
	static constexpr size_t _Max_len = _Maximum<_Len, sizeof(_Types)...>::value;	// NOT sizeof...(_Types)
	static constexpr size_t alignment_value = _Maximum<alignof(_Types)...>::value;
	using type = aligned_storage_t<_Max_len, alignment_value>;
	};

template<size_t _Len,
	class... _Types>
	using aligned_union_t = typename aligned_union<_Len, _Types...>::type;

	// STRUCT TEMPLATE underlying_type
template<class _Ty>
	struct underlying_type
	{	// determine type underlying type for enum
	using type = __underlying_type(_Ty);
	};

template<class _Ty>
	using underlying_type_t = typename underlying_type<_Ty>::type;

	// STRUCT TEMPLATE rank
template<class _Ty>
	struct rank
		: integral_constant<size_t, 0>
	{	// determine number of dimensions of array _Ty
	};

template<class _Ty, size_t _Ix>
	struct rank<_Ty[_Ix]>
		: integral_constant<size_t, rank<_Ty>::value + 1>
	{	// determine number of dimensions of array _Ty
	};

template<class _Ty>
	struct rank<_Ty[]>
		: integral_constant<size_t, rank<_Ty>::value + 1>
	{	// determine number of dimensions of array _Ty
	};

template<class _Ty>
	_INLINE_VAR constexpr size_t rank_v = rank<_Ty>::value;

	// STRUCT TEMPLATE extent
template<class _Ty, unsigned int _Nx>
	struct _Extent
		: integral_constant<size_t, 0>
	{	// determine extent of dimension _Nx of array _Ty
	};

template<class _Ty, size_t _Ix>
	struct _Extent<_Ty[_Ix], 0>
		: integral_constant<size_t, _Ix>
	{	// determine extent of dimension _Nx of array _Ty
	};

template<class _Ty, unsigned int _Nx, size_t _Ix>
	struct _Extent<_Ty[_Ix], _Nx>
		: _Extent<_Ty, _Nx - 1>
	{	// determine extent of dimension _Nx of array _Ty
	};

template<class _Ty, unsigned int _Nx>
	struct _Extent<_Ty[], _Nx>
		: _Extent<_Ty, _Nx - 1>
	{	// determine extent of dimension _Nx of array _Ty
	};

template<class _Ty, unsigned int _Nx = 0>
	struct extent
		: _Extent<_Ty, _Nx>
	{	// determine extent of dimension _Nx of array _Ty
	};

template<class _Ty,
	unsigned int _Ix = 0>
	_INLINE_VAR constexpr size_t extent_v = extent<_Ty, _Ix>::value;

	// STRUCT TEMPLATE is_base_of
template<class _Base,
	class _Derived>
	struct is_base_of
		: bool_constant<__is_base_of(_Base, _Derived)>
	{	// determine whether _Base is a base of or the same as _Derived
	};

template<class _Base,
	class _Derived>
	_INLINE_VAR constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);

	// STRUCT TEMPLATE decay
template<class _Ty>
	struct decay
	{	// determines decayed version of _Ty
	using _Ty1 = remove_reference_t<_Ty>;

	using type = conditional_t<is_array_v<_Ty1>,
		add_pointer_t<remove_extent_t<_Ty1>>,
		conditional_t<is_function_v<_Ty1>,
			add_pointer_t<_Ty1>,
			remove_cv_t<_Ty1>>>;
	};

template<class _Ty>
	using decay_t = typename decay<_Ty>::type;

		// STRUCT TEMPLATE common_type
template<class _Ty1,
	class _Ty2,
	class = void>
	struct _Decayed_cond_oper
	{
	};

template<class _Ty1,
	class _Ty2>
	struct _Decayed_cond_oper<_Ty1, _Ty2, void_t<decltype(false ? _STD declval<_Ty1>() : _STD declval<_Ty2>())>>
	{
	using type = decay_t<decltype(false ? _STD declval<_Ty1>() : _STD declval<_Ty2>())>;
	};

template<class... _Ty>
	struct common_type;

template<class... _Ty>
	using common_type_t = typename common_type<_Ty...>::type;

template<>
	struct common_type<>
	{
	};

template<class _Ty1>
	struct common_type<_Ty1>
		: common_type<_Ty1, _Ty1>
	{
	};

template<class _Ty1,
	class _Ty2,
	class _Decayed1 = decay_t<_Ty1>,
	class _Decayed2 = decay_t<_Ty2>>
	struct _Common_type2
		: common_type<_Decayed1, _Decayed2>
	{
	};

template<class _Ty1,
	class _Ty2>
	struct _Common_type2<_Ty1, _Ty2, _Ty1, _Ty2>
		: _Decayed_cond_oper<_Ty1, _Ty2>
	{
	};

template<class _Ty1,
	class _Ty2>
	struct common_type<_Ty1, _Ty2>
		: _Common_type2<_Ty1, _Ty2>
	{
	};

template<class _Void,
	class _Ty1,
	class _Ty2,
	class... _Rest>
	struct _Common_type3
	{
	};

template<class _Ty1,
	class _Ty2,
	class... _Rest>
	struct _Common_type3<void_t<common_type_t<_Ty1, _Ty2>>, _Ty1, _Ty2, _Rest...>
		: common_type<common_type_t<_Ty1, _Ty2>, _Rest...>
	{
	};

template<class _Ty1,
	class _Ty2,
	class... _Rest>
	struct common_type<_Ty1, _Ty2, _Rest...>
		: _Common_type3<void, _Ty1, _Ty2, _Rest...>
	{
	};

#if _HAS_IDENTITY_STRUCT
	// STRUCT TEMPLATE identity
template<class _Ty>
	struct _DEPRECATE_IDENTITY_STRUCT identity
	{	// map _Ty to type unchanged
	using type = _Ty;

	const _Ty& operator()(const _Ty& _Left) const
		{	// apply identity operator to operand
		return (_Left);
		}
	};
#endif /* _HAS_IDENTITY_STRUCT */

	// STRUCT TEMPLATE _Identity
template<class _Ty>
	struct _Identity
	{	// the identity transformation trait
	using type = _Ty;
	};
template<class _Ty>
	using _Identity_t = typename _Identity<_Ty>::type;

	// TRAIT _Is_specialization: TRUE IFF _Type IS A SPECIALIZATION OF _Template
template<class _Type,
	template <class...> class _Template>
	_INLINE_VAR constexpr bool _Is_specialization_v = false;
template<template <class...> class _Template,
	class... _Types>
	_INLINE_VAR constexpr bool _Is_specialization_v<_Template<_Types...>, _Template> = true;

template<class _Type,
	template <class...> class _Template>
	struct _Is_specialization
		: bool_constant<_Is_specialization_v<_Type, _Template>>
	{};

	// FUNCTION TEMPLATE forward
template<class _Ty>
	_NODISCARD constexpr _Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept
	{	// forward an lvalue as either an lvalue or an rvalue
	return (static_cast<_Ty&&>(_Arg));
	}

template<class _Ty>
	_NODISCARD constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept
	{	// forward an rvalue as an rvalue
	static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call");
	return (static_cast<_Ty&&>(_Arg));
	}

		// FUNCTION TEMPLATE move
template<class _Ty>
	_NODISCARD constexpr remove_reference_t<_Ty>&&
		move(_Ty&& _Arg) noexcept
	{	// forward _Arg as movable
	return (static_cast<remove_reference_t<_Ty>&&>(_Arg));
	}

		// FUNCTION TEMPLATE move_if_noexcept
template<class _Ty>
	_NODISCARD constexpr conditional_t<!is_nothrow_move_constructible_v<_Ty> && is_copy_constructible_v<_Ty>,
		const _Ty&, _Ty&&>
	move_if_noexcept(_Ty& _Arg) noexcept
	{	// forward _Arg as movable, sometimes
	return (_STD move(_Arg));
	}

template<class _Ty>
	class reference_wrapper;

#define _CONCATX(x, y) x ## y
#define _CONCAT(x, y) _CONCATX(x, y)

#define _IMPLEMENT_INVOKE(NAME_PREFIX, CONSTEXPR) \
	/* FUNCTION TEMPLATE invoke */ \
struct _CONCAT(NAME_PREFIX, _Invoker_pmf_object) \
	{	/* INVOKE a pointer to member function on an object */ \
	template<class _Decayed, \
		class _Ty1, \
		class... _Types2> \
		static CONSTEXPR auto _Call(_Decayed _Pmf, _Ty1&& _Arg1, _Types2&&... _Args2) \
		_NOEXCEPT_COND(_NOEXCEPT_OPER((_STD forward<_Ty1>(_Arg1).*_Pmf)(_STD forward<_Types2>(_Args2)...))) \
		-> decltype((_STD forward<_Ty1>(_Arg1).*_Pmf)(_STD forward<_Types2>(_Args2)...)) \
		{	/* INVOKE a pointer to member function on an object */ \
		return ((_STD forward<_Ty1>(_Arg1).*_Pmf)(_STD forward<_Types2>(_Args2)...)); \
		} \
	}; \
 \
struct _CONCAT(NAME_PREFIX, _Invoker_pmf_refwrap) \
	{	/* INVOKE a pointer to member function on a reference_wrapper */ \
	template<class _Decayed, \
		class _Ty1, \
		class... _Types2> \
		static CONSTEXPR auto _Call(_Decayed _Pmf, _Ty1&& _Arg1, _Types2&&... _Args2) \
		_NOEXCEPT_COND(_NOEXCEPT_OPER((_STD forward<_Ty1>(_Arg1).get().*_Pmf)(_STD forward<_Types2>(_Args2)...))) \
		-> decltype((_STD forward<_Ty1>(_Arg1).get().*_Pmf)(_STD forward<_Types2>(_Args2)...)) \
		{	/* INVOKE a pointer to member function on a reference_wrapper */ \
		return ((_STD forward<_Ty1>(_Arg1).get().*_Pmf)(_STD forward<_Types2>(_Args2)...)); \
		} \
	}; \
 \
struct _CONCAT(NAME_PREFIX, _Invoker_pmf_pointer) \
	{	/* INVOKE a pointer to member function on a [smart] pointer */ \
	template<class _Decayed, \
		class _Ty1, \
		class... _Types2> \
		static CONSTEXPR auto _Call(_Decayed _Pmf, _Ty1&& _Arg1, _Types2&&... _Args2) \
		_NOEXCEPT_COND(_NOEXCEPT_OPER(((*_STD forward<_Ty1>(_Arg1)).*_Pmf)(_STD forward<_Types2>(_Args2)...))) \
		-> decltype(((*_STD forward<_Ty1>(_Arg1)).*_Pmf)(_STD forward<_Types2>(_Args2)...)) \
		{	/* INVOKE a pointer to member function on a [smart] pointer */ \
		return (((*_STD forward<_Ty1>(_Arg1)).*_Pmf)(_STD forward<_Types2>(_Args2)...)); \
		} \
	}; \
 \
struct _CONCAT(NAME_PREFIX, _Invoker_pmd_object) \
	{	/* INVOKE a pointer to member data on an object */ \
	template<class _Decayed, \
		class _Ty1> \
		static CONSTEXPR auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) \
		_NOEXCEPT_COND(_NOEXCEPT_OPER(_STD forward<_Ty1>(_Arg1).*_Pmd)) \
		-> decltype(_STD forward<_Ty1>(_Arg1).*_Pmd) \
		{	/* INVOKE a pointer to member data on an object */ \
		return (_STD forward<_Ty1>(_Arg1).*_Pmd); \
		} \
	}; \
 \
struct _CONCAT(NAME_PREFIX, _Invoker_pmd_refwrap) \
	{	/* INVOKE a pointer to member data on a reference_wrapper */ \
	template<class _Decayed, \
		class _Ty1> \
		static CONSTEXPR auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) \
		_NOEXCEPT_COND(_NOEXCEPT_OPER(_STD forward<_Ty1>(_Arg1).get().*_Pmd)) \
		-> decltype(_STD forward<_Ty1>(_Arg1).get().*_Pmd) \
		{	/* INVOKE a pointer to member data on a reference_wrapper */ \
		return (_STD forward<_Ty1>(_Arg1).get().*_Pmd); \
		} \
	}; \
 \
struct _CONCAT(NAME_PREFIX, _Invoker_pmd_pointer) \
	{	/* INVOKE a pointer to member data on a [smart] pointer */ \
	template<class _Decayed, \
		class _Ty1> \
		static CONSTEXPR auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) \
		_NOEXCEPT_COND(_NOEXCEPT_OPER((*_STD forward<_Ty1>(_Arg1)).*_Pmd)) \
		-> decltype((*_STD forward<_Ty1>(_Arg1)).*_Pmd) \
		{	/* INVOKE a pointer to member data on a [smart] pointer */ \
		return ((*_STD forward<_Ty1>(_Arg1)).*_Pmd); \
		} \
	}; \
 \
struct _CONCAT(NAME_PREFIX, _Invoker_functor) \
	{	/* INVOKE a function object */ \
	template<class _Callable, \
		class... _Types> \
		static CONSTEXPR auto _Call(_Callable&& _Obj, _Types&&... _Args) \
		_NOEXCEPT_COND(_NOEXCEPT_OPER(_STD forward<_Callable>(_Obj)(_STD forward<_Types>(_Args)...))) \
		-> decltype(_STD forward<_Callable>(_Obj)(_STD forward<_Types>(_Args)...)) \
		{	/* INVOKE a function object */ \
		return (_STD forward<_Callable>(_Obj)(_STD forward<_Types>(_Args)...)); \
		} \
	}; \
 \
template<class _Callable, \
	class _Ty1, \
	class _Removed_cvref = remove_cv_t<remove_reference_t<_Callable>>, \
	bool _Is_pmf = is_member_function_pointer_v<_Removed_cvref>, \
	bool _Is_pmd = is_member_object_pointer_v<_Removed_cvref>> \
	struct _CONCAT(NAME_PREFIX, _Invoker1); \
 \
template<class _Callable, \
	class _Ty1, \
	class _Removed_cvref> \
	struct _CONCAT(NAME_PREFIX, _Invoker1)<_Callable, _Ty1, _Removed_cvref, true, false> \
		: conditional_t<is_base_of_v< \
			typename _Is_memfunptr<_Removed_cvref>::_Class_type, \
			remove_reference_t<_Ty1>>, \
		_CONCAT(NAME_PREFIX, _Invoker_pmf_object), \
		conditional_t<_Is_specialization_v<remove_cv_t<remove_reference_t<_Ty1>>, reference_wrapper>, \
			_CONCAT(NAME_PREFIX, _Invoker_pmf_refwrap), \
			_CONCAT(NAME_PREFIX, _Invoker_pmf_pointer) \
		>> \
	{	/* pointer to member function */ \
	}; \
 \
template<class _Callable, \
	class _Ty1, \
	class _Removed_cvref> \
	struct _CONCAT(NAME_PREFIX, _Invoker1)<_Callable, _Ty1, _Removed_cvref, false, true> \
		: conditional_t<is_base_of_v< \
			typename _Is_member_object_pointer<_Removed_cvref>::_Class_type, \
			remove_reference_t<_Ty1>>, \
		_CONCAT(NAME_PREFIX, _Invoker_pmd_object), \
		conditional_t<_Is_specialization_v<remove_cv_t<remove_reference_t<_Ty1>>, reference_wrapper>, \
			_CONCAT(NAME_PREFIX, _Invoker_pmd_refwrap), \
			_CONCAT(NAME_PREFIX, _Invoker_pmd_pointer) \
		>> \
	{	/* pointer to member data */ \
	}; \
 \
template<class _Callable, \
	class _Ty1, \
	class _Removed_cvref> \
	struct _CONCAT(NAME_PREFIX, _Invoker1)<_Callable, _Ty1, _Removed_cvref, false, false> \
		: _CONCAT(NAME_PREFIX, _Invoker_functor) \
	{	/* function object */ \
	}; \
 \
template<class _Callable, \
	class... _Types> \
	struct _CONCAT(NAME_PREFIX, _Invoker); \
 \
template<class _Callable> \
	struct _CONCAT(NAME_PREFIX, _Invoker)<_Callable> \
		: _CONCAT(NAME_PREFIX, _Invoker_functor) \
	{	/* zero arguments */ \
	}; \
 \
template<class _Callable, \
	class _Ty1, \
	class... _Types2> \
	struct _CONCAT(NAME_PREFIX, _Invoker)<_Callable, _Ty1, _Types2...> \
		: _CONCAT(NAME_PREFIX, _Invoker1)<_Callable, _Ty1> \
	{	/* one or more arguments */ \
	}; \
 \
template<class _Callable, \
	class... _Types> \
	CONSTEXPR auto _CONCAT(NAME_PREFIX, invoke)(_Callable&& _Obj, _Types&&... _Args) \
	_NOEXCEPT_COND(_NOEXCEPT_OPER(_CONCAT(NAME_PREFIX, _Invoker)<_Callable, _Types...>::_Call( \
		_STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...))) \
	-> decltype(_CONCAT(NAME_PREFIX, _Invoker)<_Callable, _Types...>::_Call( \
		_STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...)) \
	{	/* INVOKE a callable object */ \
	return (_CONCAT(NAME_PREFIX, _Invoker)<_Callable, _Types...>::_Call( \
		_STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...)); \
	}

template<class _Callable,
	class... _Types>
	struct _Invoker;

template<class _Callable,
	class... _Types> inline
	auto invoke(_Callable&& _Obj, _Types&&... _Args)
	_NOEXCEPT_COND(_NOEXCEPT_OPER(_Invoker<_Callable, _Types...>::_Call(
		_STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...)))
	-> decltype(_Invoker<_Callable, _Types...>::_Call(
		_STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...));

struct _Unforced
	{	// tag to distinguish bind() from bind<R>()
	};

	// TYPE TRAITS FOR invoke()
template<class _To>
	void _Implicitly_convert_to(_To) noexcept;

template<class _From,
	class _To,
	bool = is_convertible_v<_From, _To>>
	struct _Is_nothrow_convertible
		: bool_constant<_NOEXCEPT_OPER(_Implicitly_convert_to<_To>(_STD declval<_From>()))>
	{	// determine whether _From is nothrow-convertible to _To
	};

template<class _From,
	class _To>
	struct _Is_nothrow_convertible<_From, _To, false>
		: false_type
	{	// determine whether _From is nothrow-convertible to _To
	};

template<class _Void,
	class... _Types>
	struct _Invoke_traits
	{	// selected when _Callable isn't callable with _Args
	using _Is_invocable = false_type;
	using _Is_nothrow_invocable = false_type;
	template<class _Rx>
		using _Is_invocable_r = false_type;
	template<class _Rx>
		using _Is_nothrow_invocable_r = false_type;
	};

template<class... _Types>
	struct _Invoke_traits<void_t<decltype(_STD invoke(_STD declval<_Types>()...))>, _Types...>
	{	// selected when _Callable is callable with _Args
	using type = decltype(_STD invoke(_STD declval<_Types>()...));
	using _Is_invocable = true_type;
	using _Is_nothrow_invocable = bool_constant<_NOEXCEPT_OPER(_STD invoke(_STD declval<_Types>()...))>;
	template<class _Rx>
		using _Is_invocable_r = bool_constant<disjunction_v<is_void<_Rx>, is_convertible<type, _Rx>>>;
	template<class _Rx>
		using _Is_nothrow_invocable_r = bool_constant<conjunction_v<
			_Is_nothrow_invocable,
			disjunction<is_void<_Rx>, _Is_nothrow_convertible<type, _Rx>>>>;
	};

	// STRUCT TEMPLATE result_of
template<class _Fty>
	struct _CXX17_DEPRECATE_RESULT_OF result_of
	{	// explain usage
	static_assert(_Always_false<_Fty>,
		"result_of<CallableType> is invalid; use "
		"result_of<CallableType(zero or more argument types)> instead.");
	};

#define _RESULT_OF(CALL_OPT, X1, X2, X3) \
template<class _Callable, \
	class... _Args> \
	struct _CXX17_DEPRECATE_RESULT_OF result_of<_Callable CALL_OPT (_Args...)> \
		: _Invoke_traits<void, _Callable, _Args...> \
	{	/* template to determine result of call operation */ \
	};

_NON_MEMBER_CALL(_RESULT_OF, X1, X2, X3)
#undef _RESULT_OF

#pragma warning(push)
#pragma warning(disable: 4996)	// was declared deprecated
template<class _Ty>
	using result_of_t _CXX17_DEPRECATE_RESULT_OF = typename result_of<_Ty>::type;
#pragma warning(pop)

template<class _Callable,
	class... _Args>
	using _Invoke_result_t = typename _Invoke_traits<void, _Callable, _Args...>::type;

template<class _Rx,
	class _Callable,
	class... _Args>
	using _Is_invocable_r_ = typename _Invoke_traits<void, _Callable, _Args...>::template _Is_invocable_r<_Rx>;

template<class _Rx,
	class _Callable,
	class... _Args>
	struct _Is_invocable_r
		: _Is_invocable_r_<_Rx, _Callable, _Args...>
	{	// determines whether _Callable is callable with _Args and return type _Rx
	};

#if _HAS_CXX17
	// STRUCT TEMPLATE invoke_result
template<class _Callable,
	class... _Args>
	struct invoke_result
		: _Invoke_traits<void, _Callable, _Args...>
	{	// determine the result type of invoking _Callable with _Args
	};

template<class _Callable,
	class... _Args>
	using invoke_result_t = typename _Invoke_traits<void, _Callable, _Args...>::type;

	// STRUCT TEMPLATE is_invocable
template<class _Callable,
	class... _Args>
	struct is_invocable
		: _Invoke_traits<void, _Callable, _Args...>::_Is_invocable
	{	// determines whether _Callable is callable with _Args
	};

template<class _Callable,
	class... _Args>
	_INLINE_VAR constexpr bool is_invocable_v = _Invoke_traits<void, _Callable, _Args...>::_Is_invocable::value;

	// STRUCT TEMPLATE is_nothrow_invocable
template<class _Callable,
	class... _Args>
	struct is_nothrow_invocable
		: _Invoke_traits<void, _Callable, _Args...>::_Is_nothrow_invocable
	{	// determines whether _Callable is nothrow-callable with _Args
	};

template<class _Callable,
	class... _Args>
	_INLINE_VAR constexpr bool is_nothrow_invocable_v =
		_Invoke_traits<void, _Callable, _Args...>::_Is_nothrow_invocable::value;

	// STRUCT TEMPLATE is_invocable_r
template<class _Rx,
	class _Callable,
	class... _Args>
	struct is_invocable_r
		: _Is_invocable_r_<_Rx, _Callable, _Args...>
	{	// determines whether _Callable is callable with _Args and return type _Rx
	};

template<class _Rx,
	class _Callable,
	class... _Args>
	_INLINE_VAR constexpr bool is_invocable_r_v = _Is_invocable_r_<_Rx, _Callable, _Args...>::value;

	// STRUCT TEMPLATE is_nothrow_invocable_r
template<class _Rx,
	class _Callable,
	class... _Args>
	struct is_nothrow_invocable_r
		: _Invoke_traits<void, _Callable, _Args...>::template _Is_nothrow_invocable_r<_Rx>
	{	// determines whether _Callable is nothrow-callable with _Args and return type _Rx
	};

template<class _Rx,
	class _Callable,
	class... _Args>
	_INLINE_VAR constexpr bool is_nothrow_invocable_r_v =
		_Invoke_traits<void, _Callable, _Args...>::template _Is_nothrow_invocable_r<_Rx>::value;
#endif /* _HAS_CXX17 */


	// STRUCT TEMPLATE _Weak_types
template<class _Ty,
	class = void>
	struct _Weak_result_type
	{	// default definition
	};

#pragma warning(push)
#pragma warning(disable: 4996)	// was declared deprecated
template<class _Ty>
	struct _Weak_result_type<_Ty, void_t<
		typename _Ty::result_type>>
	{	// defined if _Ty::result_type exists
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef typename _Ty::result_type result_type;
	};
#pragma warning(pop)

template<class _Ty,
	class = void>
	struct _Weak_argument_type
		: _Weak_result_type<_Ty>
	{	// default definition
	};

#pragma warning(push)
#pragma warning(disable: 4996)	// was declared deprecated
template<class _Ty>
	struct _Weak_argument_type<_Ty, void_t<
		typename _Ty::argument_type>>
		: _Weak_result_type<_Ty>
	{	// defined if _Ty::argument_type exists
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef typename _Ty::argument_type argument_type;
	};
#pragma warning(pop)

template<class _Ty,
	class = void>
	struct _Weak_binary_args
		: _Weak_argument_type<_Ty>
	{	// default definition
	};

#pragma warning(push)
#pragma warning(disable: 4996)	// was declared deprecated
template<class _Ty>
	struct _Weak_binary_args<_Ty, void_t<
		typename _Ty::first_argument_type,
		typename _Ty::second_argument_type>>
		: _Weak_argument_type<_Ty>
	{	// defined if both types exist
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef typename _Ty::first_argument_type first_argument_type;
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef typename _Ty::second_argument_type second_argument_type;
	};
#pragma warning(pop)

template<class _Ty>
	struct _Weak_types
	{	// provide nested types (sometimes)
	using _Is_f_or_pf = _Is_function<remove_pointer_t<_Ty>>;
	using _Is_pmf = _Is_memfunptr<remove_cv_t<_Ty>>;
	using type = conditional_t<_Is_f_or_pf::_Bool_type::value, _Is_f_or_pf,
		conditional_t<_Is_pmf::_Bool_type::value, _Is_pmf,
		_Weak_binary_args<_Ty>>>;
	};

	// CLASS TEMPLATE reference_wrapper
template<class _Ty>
	void _Refwrap_ctor_fun(_Identity_t<_Ty&>) noexcept;
template<class _Ty>
	void _Refwrap_ctor_fun(_Identity_t<_Ty&&>) = delete;

struct _Unique_tag_refwrap_has_ctor_from
	{	// TRANSITION, VSO#606027
	};

template<class _Ty,
	class _Uty,
	class = void>
	struct _Refwrap_has_ctor_from
		: false_type
	{
	};

template<class _Ty,
	class _Uty>
	struct _Refwrap_has_ctor_from<_Ty, _Uty, void_t<
		_Unique_tag_refwrap_has_ctor_from,	// TRANSITION, VSO#606027
		decltype(_Refwrap_ctor_fun<_Ty>(_STD declval<_Uty>()))>>
		: true_type
	{
	};

template<class _Ty>
	class reference_wrapper
		: public _Weak_types<_Ty>::type
	{	// stand-in for an assignable reference
public:
	static_assert(is_object_v<_Ty> || is_function_v<_Ty>,
		"reference_wrapper<T> requires T to be an object type or a function type.");

	using type = _Ty;

	template<class _Uty,
		enable_if_t<conjunction_v<
			negation<is_same<remove_cv_t<remove_reference_t<_Uty>>, reference_wrapper>>,
			_Refwrap_has_ctor_from<_Ty, _Uty>>, int> = 0>
		reference_wrapper(_Uty&& _Val)
			_NOEXCEPT_COND(_NOEXCEPT_OPER(_Refwrap_ctor_fun<_Ty>(_STD declval<_Uty>())))
			{	// construct
			_Ty& _Ref = _STD forward<_Uty>(_Val);
			_Ptr = _STD addressof(_Ref);
			}

	operator _Ty&() const noexcept
		{	// return reference
		return (*_Ptr);
		}

	_NODISCARD _Ty& get() const noexcept
		{	// return reference
		return (*_Ptr);
		}

	template<class... _Types>
		auto operator()(_Types&&... _Args) const
		-> decltype(_STD invoke(get(), _STD forward<_Types>(_Args)...))
		{	// invoke object/function
		return (_STD invoke(get(), _STD forward<_Types>(_Args)...));
		}

private:
	_Ty * _Ptr;
	};

#if _HAS_CXX17
template<class _Ty>
	reference_wrapper(_Ty&)
		-> reference_wrapper<_Ty>;
#endif /* _HAS_CXX17 */

	// FUNCTION TEMPLATES ref AND cref
template<class _Ty>
	_NODISCARD inline reference_wrapper<_Ty> ref(_Ty& _Val) noexcept
	{	// create reference_wrapper<_Ty> object
	return (reference_wrapper<_Ty>(_Val));
	}

template<class _Ty>
	void ref(const _Ty&&) = delete;

template<class _Ty>
	_NODISCARD inline reference_wrapper<_Ty> ref(reference_wrapper<_Ty> _Val) noexcept
	{	// create reference_wrapper<_Ty> object
	return (_STD ref(_Val.get()));
	}

template<class _Ty>
	_NODISCARD inline reference_wrapper<const _Ty> cref(const _Ty& _Val) noexcept
	{	// create reference_wrapper<const _Ty> object
	return (reference_wrapper<const _Ty>(_Val));
	}

template<class _Ty>
	void cref(const _Ty&&) = delete;

template<class _Ty>
	_NODISCARD inline reference_wrapper<const _Ty> cref(reference_wrapper<_Ty> _Val) noexcept
	{	// create reference_wrapper<const _Ty> object
	return (_STD cref(_Val.get()));
	}

		// STRUCT TEMPLATE _Is_swappable
template<class _Ty>
	struct _Is_swappable;

		// STRUCT TEMPLATE _Is_nothrow_swappable
template<class _Ty>
	struct _Is_nothrow_swappable;

		// FUNCTION TEMPLATE swap
#if _HAS_CXX17
template<class _Ty,
	class = enable_if_t<is_move_constructible_v<_Ty>
		&& is_move_assignable_v<_Ty>>> inline
#else /* _HAS_CXX17 */
template<class _Ty,
	class = void> inline
#endif /* _HAS_CXX17 */
	void swap(_Ty&, _Ty&)
		_NOEXCEPT_COND(is_nothrow_move_constructible_v<_Ty>
			&& is_nothrow_move_assignable_v<_Ty>);

template<class _Ty,
	size_t _Size,
	class = enable_if_t<_Is_swappable<_Ty>::value>> inline
	void swap(_Ty (&)[_Size], _Ty (&)[_Size])
		_NOEXCEPT_COND(_Is_nothrow_swappable<_Ty>::value);

		// STRUCT TEMPLATE _Swappable_with_helper
template<class _Ty1,
	class _Ty2,
	class = void>
	struct _Swappable_with_helper
		: false_type
	{	// swap(declval<_Ty1>(), declval<_Ty2>()) is not valid
	};

template<class _Ty1,
	class _Ty2>
	struct _Swappable_with_helper<_Ty1, _Ty2, void_t<decltype(swap(_STD declval<_Ty1>(), _STD declval<_Ty2>()))>>
		: true_type
	{	// swap(declval<_Ty1>(), declval<_Ty2>()) is valid
	};

		// STRUCT TEMPLATE _Is_swappable_with
template<class _Ty1,
	class _Ty2>
	struct _Is_swappable_with
		: bool_constant<conjunction_v<
			_Swappable_with_helper<_Ty1, _Ty2>,
			_Swappable_with_helper<_Ty2, _Ty1>>>
	{	// Determine if expressions with type and value category _Ty1 and _Ty2
		// can be swapped (and vice versa)
	};

		// STRUCT TEMPLATE _Is_swappable
template<class _Ty>
	struct _Is_swappable
		: _Is_swappable_with<
			add_lvalue_reference_t<_Ty>,
			add_lvalue_reference_t<_Ty>>::type
	{	// Determine if _Ty lvalues satisfy is_swappable_with
	};

		// STRUCT TEMPLATE _Swap_cannot_throw
template<class _Ty1,
	class _Ty2>
	struct _Swap_cannot_throw
		: bool_constant<_NOEXCEPT_OPER(swap(_STD declval<_Ty1>(), _STD declval<_Ty2>()))
					&& _NOEXCEPT_OPER(swap(_STD declval<_Ty2>(), _STD declval<_Ty1>()))>
	{	// Determine if expressions with type and value category _Ty1 and _Ty2
		// (presumed to satisfy is_swappable_with) can be swapped without
		// emitting exceptions
	};

		// STRUCT TEMPLATE _Is_nothrow_swappable_with
template<class _Ty1,
	class _Ty2>
	struct _Is_nothrow_swappable_with
		: bool_constant<conjunction_v<
			_Is_swappable_with<_Ty1, _Ty2>,
			_Swap_cannot_throw<_Ty1, _Ty2>>>
	{	// Determine if expressions with type and value category _Ty1 and _Ty2
		// satisfy is_swappable_with, and can be swapped without emitting exceptions
	};

		// STRUCT TEMPLATE _Is_nothrow_swappable
template<class _Ty>
	struct _Is_nothrow_swappable
		: _Is_nothrow_swappable_with<
			add_lvalue_reference_t<_Ty>,
			add_lvalue_reference_t<_Ty>>::type
	{	// Determine if _Ty lvalues satisfy is_nothrow_swappable_with
	};

#if _HAS_CXX17
		// STRUCT TEMPLATE is_swappable_with
template<class _Ty1,
	class _Ty2>
	struct is_swappable_with
		: _Is_swappable_with<_Ty1, _Ty2>::type
	{	// Determine if expressions with type and value category _Ty1 and _Ty2
		// can be swapped (and vice versa)
	};

template<class _Ty1,
	class _Ty2>
	_INLINE_VAR constexpr bool is_swappable_with_v = is_swappable_with<_Ty1, _Ty2>::value;

		// STRUCT TEMPLATE is_swappable
template<class _Ty>
	struct is_swappable
		: _Is_swappable<_Ty>::type
	{	// Determine if _Ty lvalues satisfy is_swappable_with
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_swappable_v = is_swappable<_Ty>::value;

		// STRUCT TEMPLATE is_nothrow_swappable_with
template<class _Ty1,
	class _Ty2>
	struct is_nothrow_swappable_with
		: _Is_nothrow_swappable_with<_Ty1, _Ty2>::type
	{	// Determine if expressions with type and value category _Ty1 and _Ty2
		// satisfy is_swappable_with, and can be swapped without emitting exceptions
	};

template<class _Ty1,
	class _Ty2>
	_INLINE_VAR constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_Ty1, _Ty2>::value;

		// STRUCT TEMPLATE is_nothrow_swappable
template<class _Ty>
	struct is_nothrow_swappable
		: _Is_nothrow_swappable<_Ty>::type
	{	// Determine if _Ty lvalues satisfy is_nothrow_swappable_with
	};

template<class _Ty>
	_INLINE_VAR constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Ty>::value;
#endif /* _HAS_CXX17 */

	// TYPE TRAIT _Is_trivially_swappable
namespace _Has_ADL_swap_detail {
	void swap(); // undefined (deliberate shadowing)

	template<class,
		class = void>
		struct _Has_ADL_swap
			: false_type
		{};
	template<class _Ty>
		struct _Has_ADL_swap<_Ty, void_t<decltype(swap(_STD declval<_Ty&>(), _STD declval<_Ty&>()))>>
			: true_type
		{};
} // namespace _Has_ADL_swap_detail
using _Has_ADL_swap_detail::_Has_ADL_swap;

template<class _Ty>
	struct _Is_trivially_swappable
		: bool_constant<conjunction_v<
			is_trivially_destructible<_Ty>,
			is_trivially_move_constructible<_Ty>,
			is_trivially_move_assignable<_Ty>,
			negation<_Has_ADL_swap<_Ty>>>>
	{	// true_type if it is valid to swap two _Ty lvalues by exchanging
		// object representations.
	};

template<class _Ty>
	_INLINE_VAR constexpr bool _Is_trivially_swappable_v = _Is_trivially_swappable<_Ty>::value;

		// BITMASK OPERATIONS
 #define _BITMASK_OPS(_BITMASK) \
_NODISCARD constexpr _BITMASK operator&(_BITMASK _Left, _BITMASK _Right) noexcept \
	{	/* return _Left & _Right */ \
	using _IntTy = _STD underlying_type_t<_BITMASK>; \
	return (static_cast<_BITMASK>(static_cast<_IntTy>(_Left) & static_cast<_IntTy>(_Right))); \
	} \
\
_NODISCARD constexpr _BITMASK operator|(_BITMASK _Left, _BITMASK _Right) noexcept \
	{	/* return _Left | _Right */ \
	using _IntTy = _STD underlying_type_t<_BITMASK>; \
	return (static_cast<_BITMASK>(static_cast<_IntTy>(_Left) | static_cast<_IntTy>(_Right))); \
	} \
\
_NODISCARD constexpr _BITMASK operator^(_BITMASK _Left, _BITMASK _Right) noexcept \
	{	/* return _Left ^ _Right */ \
	using _IntTy = _STD underlying_type_t<_BITMASK>; \
	return (static_cast<_BITMASK>(static_cast<_IntTy>(_Left) ^ static_cast<_IntTy>(_Right))); \
	} \
\
constexpr _BITMASK& operator&=(_BITMASK& _Left, _BITMASK _Right) noexcept \
	{	/* return _Left &= _Right */ \
	return (_Left = _Left & _Right); \
	} \
\
constexpr _BITMASK& operator|=(_BITMASK& _Left, _BITMASK _Right) noexcept \
	{	/* return _Left |= _Right */ \
	return (_Left = _Left | _Right); \
	} \
\
constexpr _BITMASK& operator^=(_BITMASK& _Left, _BITMASK _Right) noexcept \
	{	/* return _Left ^= _Right */ \
	return (_Left = _Left ^ _Right); \
	} \
\
_NODISCARD constexpr _BITMASK operator~(_BITMASK _Left) noexcept \
	{	/* return ~_Left */ \
	using _IntTy = _STD underlying_type_t<_BITMASK>; \
	return (static_cast<_BITMASK>(~static_cast<_IntTy>(_Left))); \
	} \
\
_NODISCARD constexpr bool _Bitmask_includes(_BITMASK _Left, _BITMASK _Elements) noexcept \
	{	/* return (_Left & _Elements) != _BITMASK{} */ \
	using _IntTy = _STD underlying_type_t<_BITMASK>; /* TRANSITION, VSO#574589 */ \
	return (static_cast<_IntTy>(_Left & _Elements) != 0); \
	} \
\
_NODISCARD constexpr bool _Bitmask_includes_all(_BITMASK _Left, _BITMASK _Elements) noexcept \
	{	/* return (_Left & _Elements) == _Elements */ \
	return ((_Left & _Elements) == _Elements); \
	}

	// FNV-1a UTILITIES
	// These functions are extremely performance sensitive, check examples like
	// that in VSO#653642 before making changes.
#if defined(_WIN64)
_INLINE_VAR constexpr size_t _FNV_offset_basis = 14695981039346656037ULL;
_INLINE_VAR constexpr size_t _FNV_prime = 1099511628211ULL;
#else /* defined(_WIN64) */
_INLINE_VAR constexpr size_t _FNV_offset_basis = 2166136261U;
_INLINE_VAR constexpr size_t _FNV_prime = 16777619U;
#endif /* defined(_WIN64) */

_NODISCARD inline size_t _Fnv1a_append_bytes(size_t _Val,
	const unsigned char * const _First, const size_t _Count) noexcept
	{	// accumulate range [_First, _First + _Count) into partial FNV-1a hash _Val
	for (size_t _Idx = 0; _Idx < _Count; ++_Idx)
		{
		_Val ^= static_cast<size_t>(_First[_Idx]);
		_Val *= _FNV_prime;
		}

	return (_Val);
	}

template<class _Ty>
	_NODISCARD inline size_t _Fnv1a_append_range(const size_t _Val,
		const _Ty * const _First, const _Ty * const _Last) noexcept
	{	// accumulate range [_First, _Last) into partial FNV-1a hash _Val
	static_assert(is_trivial_v<_Ty>, "Only trivial types can be directly hashed.");
	const auto _Firstb = reinterpret_cast<const unsigned char *>(_First);
	const auto _Lastb = reinterpret_cast<const unsigned char *>(_Last);
	return (_Fnv1a_append_bytes(_Val, _Firstb, static_cast<size_t>(_Lastb - _Firstb)));
	}

template<class _Kty>
	_NODISCARD inline size_t _Fnv1a_append_value(const size_t _Val, const _Kty& _Keyval) noexcept
	{	// accumulate _Keyval into partial FNV-1a hash _Val
	static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed.");
	return (_Fnv1a_append_bytes(_Val,
		&reinterpret_cast<const unsigned char&>(_Keyval), sizeof(_Kty)));
	}

	// FUNCTION TEMPLATE _Hash_representation
template<class _Kty>
	_NODISCARD inline size_t _Hash_representation(const _Kty& _Keyval) noexcept
	{	// bitwise hashes the representation of a key
	return (_Fnv1a_append_value(_FNV_offset_basis, _Keyval));
	}

	// FUNCTION TEMPLATE _Hash_array_representation
template<class _Kty>
	_NODISCARD inline size_t _Hash_array_representation(
		const _Kty * const _First, const size_t _Count) noexcept
	{	// bitwise hashes the representation of an array
	static_assert(is_trivial_v<_Kty>, "Only trivial types can be directly hashed.");
	return (_Fnv1a_append_bytes(_FNV_offset_basis,
		reinterpret_cast<const unsigned char *>(_First), _Count * sizeof(_Kty)));
	}

	// STRUCT TEMPLATE _Conditionally_enabled_hash
template<class _Kty>
	struct hash;

template<class _Kty,
	bool _Enabled>
	struct _Conditionally_enabled_hash
	{	// conditionally enabled hash base
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Kty argument_type;
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef size_t result_type;

	_NODISCARD size_t operator()(const _Kty& _Keyval) const
		_NOEXCEPT_COND(_NOEXCEPT_OPER(hash<_Kty>::_Do_hash(_Keyval)))
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (hash<_Kty>::_Do_hash(_Keyval));
		}
	};

template<class _Kty>
	struct _Conditionally_enabled_hash<_Kty, false>
	{	// conditionally disabled hash base
	_Conditionally_enabled_hash() = delete;
	_Conditionally_enabled_hash(const _Conditionally_enabled_hash&) = delete;
	_Conditionally_enabled_hash(_Conditionally_enabled_hash&&) = delete;
	_Conditionally_enabled_hash& operator=(const _Conditionally_enabled_hash&) = delete;
	_Conditionally_enabled_hash& operator=(_Conditionally_enabled_hash&&) = delete;
	};

	// STRUCT TEMPLATE hash
template<class _Kty>
	struct hash
		: _Conditionally_enabled_hash<_Kty, !is_const_v<_Kty> && !is_volatile_v<_Kty>
			&& (is_enum_v<_Kty> || is_integral_v<_Kty> || is_pointer_v<_Kty>)>
	{	// hash functor primary template (handles enums, integrals, and pointers)
	static size_t _Do_hash(const _Kty& _Keyval) noexcept
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Hash_representation(_Keyval));
		}
	};

template<>
	struct hash<float>
	{	// hash functor for float
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef float argument_type;
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef size_t result_type;
	_NODISCARD size_t operator()(const float _Keyval) const noexcept
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Hash_representation(_Keyval == 0.0F ? 0.0F : _Keyval));	// map -0 to 0
		}
	};

template<>
	struct hash<double>
	{	// hash functor for double
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef double argument_type;
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef size_t result_type;
	_NODISCARD size_t operator()(const double _Keyval) const noexcept
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Hash_representation(_Keyval == 0.0 ? 0.0 : _Keyval));	// map -0 to 0
		}
	};

template<>
	struct hash<long double>
	{	// hash functor for long double
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef long double argument_type;
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef size_t result_type;
	_NODISCARD size_t operator()(const long double _Keyval) const noexcept
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Hash_representation(_Keyval == 0.0L ? 0.0L : _Keyval));	// map -0 to 0
		}
	};

template<>
	struct hash<nullptr_t>
	{	// hash functor for nullptr_t
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef nullptr_t argument_type;
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef size_t result_type;
	_NODISCARD size_t operator()(nullptr_t) const noexcept
		{	// hash nullptr_t to size_t value by pseudorandomizing transform
		void * _Null{};
		return (_Hash_representation(_Null));
		}
	};

		// STRUCT TEMPLATE _Is_nothrow_hashable
template<class _Kty,
	class = void>
	struct _Is_nothrow_hashable
		: false_type
	{	// tests if std::hash can hash _Kty with noexcept
	};

template<class _Kty>
	struct _Is_nothrow_hashable<_Kty, void_t<decltype(hash<_Kty>{}(_STD declval<const _Kty&>()))>>
		: bool_constant<_NOEXCEPT_OPER(hash<_Kty>{}(_STD declval<const _Kty&>()))>
	{	// tests if std::hash can hash _Kty with noexcept
	};

#if _HAS_TR1_NAMESPACE
#pragma warning(push)
#pragma warning(disable: 4996)	// was declared deprecated
namespace _DEPRECATE_TR1_NAMESPACE tr1 {
using _STD add_const;
using _STD add_cv;
using _STD add_pointer;
using _STD add_volatile;
using _STD aligned_storage;
using _STD alignment_of;
using _STD conditional;
using _STD decay;
using _STD enable_if;
using _STD extent;
using _STD false_type;
using _STD has_virtual_destructor;
using _STD integral_constant;
using _STD is_abstract;
using _STD is_arithmetic;
using _STD is_array;
using _STD is_base_of;
using _STD is_class;
using _STD is_compound;
using _STD is_const;
using _STD is_convertible;
using _STD is_empty;
using _STD is_enum;
using _STD is_floating_point;
using _STD is_function;
using _STD is_fundamental;
using _STD is_integral;
using _STD is_member_function_pointer;
using _STD is_member_object_pointer;
using _STD is_member_pointer;
using _STD is_object;
using _STD is_pod;
using _STD is_pointer;
using _STD is_polymorphic;
using _STD is_reference;
using _STD is_same;
using _STD is_scalar;
using _STD is_signed;
using _STD is_union;
using _STD is_unsigned;
using _STD is_void;
using _STD is_volatile;
using _STD make_signed;
using _STD make_unsigned;
using _STD rank;
using _STD remove_all_extents;
using _STD remove_const;
using _STD remove_cv;
using _STD remove_extent;
using _STD remove_pointer;
using _STD remove_reference;
using _STD remove_volatile;
using _STD true_type;
using _STD cref;
using _STD ref;
using _STD reference_wrapper;
using _STD result_of;
using _STD hash;
}
#pragma warning(pop)
#endif /* _HAS_TR1_NAMESPACE */


// EVERYTHING BELOW WILL HAVE STRANGE LINE NUMBERS

#define _DEBUGGER_STEP_OVER 15732479 // 0xf00f00 - 1
#define _DEBUGGER_STEP_INTO 16707565 // 0xfeefee - 1

#ifndef _DEBUG_FUNCTIONAL_MACHINERY
 #line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
_IMPLEMENT_INVOKE(_EMPTY_ARGUMENT, inline)

#if _HAS_CXX17
	// constexpr IMPLEMENTATION OF invoke
 #ifndef _DEBUG_FUNCTIONAL_MACHINERY
  #line _DEBUGGER_STEP_INTO
 #endif /* _DEBUG_FUNCTIONAL_MACHINERY */
_IMPLEMENT_INVOKE(_C_, constexpr)
#endif /* _HAS_CXX17 */

#undef _IMPLEMENT_INVOKE

template<class _Rx,
	bool = is_void_v<_Rx>>
	struct _Invoker_ret
	{	// helper to give INVOKE an explicit return type; avoids undesirable Expression SFINAE
	};

template<class _Cv_void>
	struct _Invoker_ret<_Cv_void, true>
	{	// selected for _Rx being cv void
	template<class... _Valtys>
		static void _Call(_Valtys&&... _Vals)
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		{	// INVOKE, "implicitly" converted to void
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		_STD invoke(_STD forward<_Valtys>(_Vals)...);
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		}
	};

template<class _Rx>
	struct _Invoker_ret<_Rx, false>
	{	// selected for all _Rx other than cv void and _Unforced
	template<class... _Valtys>
		static _Rx _Call(_Valtys&&... _Vals)
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		{	// INVOKE, implicitly converted to _Rx
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		return (_STD invoke(_STD forward<_Valtys>(_Vals)...));
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		}
	};

template<>
	struct _Invoker_ret<_Unforced, false>
	{	// selected for _Rx being _Unforced
	template<class... _Valtys>
		static auto _Call(_Valtys&&... _Vals)
		-> decltype(_STD invoke(_STD forward<_Valtys>(_Vals)...))
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		{	// INVOKE, unchanged
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		return (_STD invoke(_STD forward<_Valtys>(_Vals)...));
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		}
	};

_STD_END

 #pragma pop_macro("new")
 _STL_RESTORE_CLANG_WARNINGS
 #pragma warning(pop)
 #pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _TYPE_TRAITS_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:0009 */
