// type_traits TR1 header
#pragma once
#ifndef _TYPE_TRAITS_
#define _TYPE_TRAITS_
#ifndef RC_INVOKED
#include <xstddef>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)
 #pragma push_macro("new")
 #undef new
 #pragma warning(disable: 4180 4296)

	// COMPILER SUPPORT MACROS

		// VC++ V11 SUPPORT
  #define _IS_BASE_OF(_Base, _Der)	\
	: _Cat_base<__is_base_of(_Base, _Der)>
  #define _IS_CONVERTIBLE(_From, _To)	\
	: _Cat_base<is_void<_From>::value && is_void<_To>::value \
		|| __is_convertible_to(_From, _To)>
  #define _IS_UNION(_Ty)	\
	: _Cat_base<__is_union(_Ty)>
  #define _IS_CLASS(_Ty)	\
	: _Cat_base<__is_class(_Ty)>
  #define _IS_POD(_Ty)	\
	: _Cat_base<is_void<_Ty>::value \
		|| is_scalar<_Ty>::value \
		|| __has_trivial_constructor(_Ty) && __is_pod(_Ty)>
  #define _IS_EMPTY(_Ty)	\
	: _Cat_base<__is_empty(_Ty)>
  #define _IS_POLYMORPHIC(_Ty)	\
	: _Cat_base<__is_polymorphic(_Ty)>
  #define _IS_ABSTRACT(_Ty)	\
	: _Cat_base<__is_abstract(_Ty)>
  #define _IS_STANDARD_LAYOUT(_Ty)	\
	: _Cat_base<__is_standard_layout(_Ty)>
  #define _IS_TRIVIAL(_Ty)	\
	: _Cat_base<__is_trivial(_Ty)>

  #define _HAS_TRIVIAL_CONSTRUCTOR(_Ty)	\
	: _Cat_base<is_pod<_Ty>::value \
		|| !is_array<_Ty>::value \
			&& __has_trivial_constructor(_Ty)>
  #define _HAS_TRIVIAL_COPY(_Ty)	\
	: _Cat_base<is_pod<typename remove_reference<_Ty>::type>::value \
		|| !is_array<_Ty>::value \
			&& __is_trivially_copyable(typename remove_reference<_Ty>::type)>
  #define _HAS_TRIVIAL_MOVE_CONSTRUCTOR(_Ty)	\
	: _Cat_base<is_pod<typename remove_reference<_Ty>::type>::value \
		|| !is_array<_Ty>::value \
			&& __has_trivial_move_constructor(_Ty)>
  #define _HAS_TRIVIAL_ASSIGN(_Ty)	\
	: _Cat_base<is_pod<typename remove_reference<_Ty>::type>::value \
		|| __has_trivial_assign(typename remove_reference<_Ty>::type)>
  #define _HAS_TRIVIAL_MOVE_ASSIGN(_Ty)	\
	: _Cat_base<__has_trivial_move_assign(_Ty)>
  #define _HAS_TRIVIAL_DESTRUCTOR(_Ty)	\
	: _Cat_base<is_pod<typename remove_reference<_Ty>::type>::value \
		|| __has_trivial_destructor(typename remove_reference<_Ty>::type)>

  #define _HAS_NOTHROW_CONSTRUCTOR(_Ty)	\
	: _Cat_base<is_pod<_Ty>::value \
		|| __has_nothrow_constructor(_Ty)>
  #define _HAS_NOTHROW_COPY(_Ty)	\
	: _Cat_base<is_pod<typename remove_reference<_Ty>::type>::value \
		|| __has_nothrow_copy(typename remove_reference<_Ty>::type)>
  #define _HAS_NOTHROW_ASSIGN(_Ty)	\
	: _Cat_base<is_pod<typename remove_reference<_Ty>::type>::value \
		|| __has_nothrow_assign(typename remove_reference<_Ty>::type)>
  #define _HAS_NOTHROW_MOVE_ASSIGN(_Ty)	\
	: _Cat_base<__has_nothrow_move_assign(_Ty)>
  #define _HAS_VIRTUAL_DESTRUCTOR(_Ty)	\
	: _Cat_base<__has_virtual_destructor(_Ty)>

  #define _UNDERLYING_TYPE(_Ty)	\
	__underlying_type(_Ty)
  #define _IS_LITERAL_TYPE(_Ty)	\
	: _Cat_base<__is_literal_type(_Ty)>

// optional
// _ALIGN_OF(_Ty)
  #define _IS_ENUM(_Ty)	\
	: _Cat_base<__is_enum(_Ty)>
//  #define _IS_CONSTRUCTIBLE	\
//	__is_constructible
//  #define _IS_NOTHROW_CONSTRUCTIBLE	\
//	__is_nothrow_constructible
// _IS_TRIVIALLY_CONSTRUCTIBLE(_Ty, _Args...)

		// ADDITIONAL INTRINSICS
// _IS_ASSIGNABLE(_To, _From)
// _IS_DESTRUCTIBLE(_Ty)

// _IS_NOTHROW_ASSIGNABLE(_To, _From)
// _IS_NOTHROW_DESTRUCTIBLE(_Ty)

// _IS_TRIVIALLY_ASSIGNABLE(_To, _From)
// _IS_TRIVIALLY_DESTRUCTIBLE(_Ty)

_STD_BEGIN
	// TEMPLATE CLASS _Ptr_traits
template<class _Ty>
	struct _Ptr_traits
	{	// basic definition
	};

template<class _Ty>
	struct _Ptr_traits<_Ty *>
	{	// pointer properties
	static const bool _Is_const = false;
	static const bool _Is_volatile = false;
	};

template<class _Ty>
	struct _Ptr_traits<const _Ty *>
	{	// pointer to const properties
	static const bool _Is_const = true;
	static const bool _Is_volatile = false;
	};

template<class _Ty>
	struct _Ptr_traits<volatile _Ty *>
	{	// pointer to volatile properties
	static const bool _Is_const = false;
	static const bool _Is_volatile = true;
	};

template<class _Ty>
	struct _Ptr_traits<const volatile _Ty *>
	{	// pointer to const volatile properties
	static const bool _Is_const = true;
	static const bool _Is_volatile = true;
	};

template<class _Ty>
	struct _Is_funptr
		: false_type
	{	// base class for function pointer predicates
	};

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

#define _CLASS_IS_FUNPTR( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<class _Ret COMMA LIST(_CLASS_TYPE)> \
	struct _Is_funptr<_Ret (*)(LIST(_TYPE))> \
		: true_type \
	{	/* base class for function pointer predicates */ \
	}; \
template<class _Ret, \
	class _Arg0 COMMA LIST(_CLASS_TYPE)> \
	struct _Is_memfunptr<_Ret (_Arg0::*)(LIST(_TYPE))> \
		: true_type \
	{	/* base class for member function pointer predicates */ \
	}; \
template<class _Ret, \
	class _Arg0 COMMA LIST(_CLASS_TYPE)> \
	struct _Is_memfunptr<_Ret (_Arg0::*)(LIST(_TYPE)) const> \
		: true_type \
	{	/* base class for member function pointer predicates */ \
	}; \
template<class _Ret, \
	class _Arg0 COMMA LIST(_CLASS_TYPE)> \
	struct _Is_memfunptr<_Ret (_Arg0::*)(LIST(_TYPE)) volatile> \
		: true_type \
	{	/* base class for member function pointer predicates */ \
	}; \
template<class _Ret, \
	class _Arg0 COMMA LIST(_CLASS_TYPE)> \
	struct _Is_memfunptr<_Ret (_Arg0::*)(LIST(_TYPE)) const volatile> \
		: true_type \
	{	/* base class for member function pointer predicates */ \
	}; \
template<class _Ret COMMA LIST(_CLASS_TYPE)> \
	struct _Is_funptr<_Ret (*)(LIST(_TYPE)...)> \
		: true_type \
	{	/* base class for function pointer predicates */ \
	}; \
template<class _Ret, \
	class _Arg0 COMMA LIST(_CLASS_TYPE)> \
	struct _Is_memfunptr<_Ret (_Arg0::*)(LIST(_TYPE)...)> \
		: true_type \
	{	/* base class for member function pointer predicates */ \
	}; \
template<class _Ret, \
	class _Arg0 COMMA LIST(_CLASS_TYPE)> \
	struct _Is_memfunptr<_Ret (_Arg0::*)(LIST(_TYPE)...) const> \
		: true_type \
	{	/* base class for member function pointer predicates */ \
	}; \
template<class _Ret, \
	class _Arg0 COMMA LIST(_CLASS_TYPE)> \
	struct _Is_memfunptr<_Ret (_Arg0::*)(LIST(_TYPE)...) volatile> \
		: true_type \
	{	/* base class for member function pointer predicates */ \
	}; \
template<class _Ret, \
	class _Arg0 COMMA LIST(_CLASS_TYPE)> \
	struct _Is_memfunptr<_Ret (_Arg0::*)(LIST(_TYPE)...) const volatile> \
		: true_type \
	{	/* base class for member function pointer predicates */ \
	};

_VARIADIC_EXPAND_0X(_CLASS_IS_FUNPTR, , , , )
#undef _CLASS_IS_FUNPTR

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

template<class _Ty>
	struct add_const<_Ty&>
	{	// add top level const qualifier
	typedef _Ty& type;
	};

	// TEMPLATE CLASS add_volatile
template<class _Ty>
	struct add_volatile
	{	// add top level volatile qualifier
	typedef volatile _Ty type;
	};

template<class _Ty>
	struct add_volatile<_Ty&>
	{	// add top level volatile qualifier
	typedef _Ty& type;
	};

	// TEMPLATE CLASS add_cv
template<class _Ty>
	struct add_cv
	{	// add top level const and volatile qualifiers
	typedef typename add_const<typename add_volatile<_Ty>::type>::type type;
	};

	// TEMPLATE CLASS add_reference -- retained
template<class _Ty>
	struct add_reference
	{	// add reference
	typedef typename remove_reference<_Ty>::type& type;
	};

template<>
	struct add_reference<void>
	{	// add reference
	typedef void type;
	};

template<>
	struct add_reference<const void>
	{	// add reference
	typedef const void type;
	};

template<>
	struct add_reference<volatile void>
	{	// add reference
	typedef volatile void type;
	};

template<>
	struct add_reference<const volatile void>
	{	// add reference
	typedef const volatile void type;
	};

 #if _HAS_CPP0X
	// TEMPLATE CLASS add_lvalue_reference
template<class _Ty>
	struct add_lvalue_reference
	{	// add lvalue reference
	typedef typename add_reference<_Ty>::type type;
	};

	// TEMPLATE CLASS add_rvalue_reference
template<class _Ty>
	struct add_rvalue_reference
	{	// add rvalue reference
	typedef typename remove_reference<_Ty>::type&& type;
	};

template<class _Ty>
	struct add_rvalue_reference<_Ty&>
	{	// add rvalue reference to reference
	typedef _Ty& type;
	};

template<>
	struct add_rvalue_reference<void>
	{	// add reference
	typedef void type;
	};

template<>
	struct add_rvalue_reference<const void>
	{	// add reference
	typedef const void type;
	};

template<>
	struct add_rvalue_reference<volatile void>
	{	// add reference
	typedef volatile void type;
	};

template<>
	struct add_rvalue_reference<const volatile void>
	{	// add reference
	typedef const volatile void type;
	};

	// TEMPLATE FUNCTION declval
template<class _Ty>
	typename add_rvalue_reference<_Ty>::type
		declval(int = 0) _NOEXCEPT;
 #endif /* _HAS_CPP0X */

	// TEMPLATE CLASS remove_extent
template<class _Ty>
	struct remove_extent
	{	// remove array extent
	typedef _Ty type;
	};

template<class _Ty, unsigned int _Ix>
	struct remove_extent<_Ty[_Ix]>
	{	// remove array extent
	typedef _Ty type;
	};

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

	// TEMPLATE CLASS remove_all_extents
template<class _Ty>
	struct remove_all_extents
	{	// remove all array extents
	typedef _Ty type;
	};

template<class _Ty, unsigned int _Ix>
	struct remove_all_extents<_Ty[_Ix]>
	{	// remove all array extents
	typedef typename remove_all_extents<_Ty>::type type;
	};

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

	// TEMPLATE CLASS remove_pointer
template<class _Ty>
	struct remove_pointer
	{	// remove pointer
	typedef _Ty type;
	};

template<class _Ty>
	struct remove_pointer<_Ty *>
	{	// remove pointer
	typedef _Ty type;
	};

template<class _Ty>
	struct remove_pointer<_Ty *const>
	{	// remove pointer
	typedef _Ty type;
	};

template<class _Ty>
	struct remove_pointer<_Ty *volatile>
	{	// remove pointer
	typedef _Ty type;
	};

template<class _Ty>
	struct remove_pointer<_Ty *const volatile>
	{	// remove pointer
	typedef _Ty type;
	};

	// TEMPLATE CLASS add_pointer
template<class _Ty>
	struct add_pointer
	{	// add pointer
	typedef typename remove_reference<_Ty>::type *type;
	};

	// TYPE PREDICATES
	// TEMPLATE CLASS is_void
template<class _Ty>
	struct _Is_void
		: false_type
	{	// determine whether _Ty is void
	};

template<>
	struct _Is_void<void>
		: true_type
	{	// determine whether _Ty is void
	};

template<class _Ty>
	struct is_void
		: _Is_void<typename remove_cv<_Ty>::type>
	{	// determine whether _Ty is void
	};

	// TEMPLATE CLASS 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
	};

 #if _HAS_CPP0X
	// TEMPLATE CLASS 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 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 is_reference -- retained
template<class _Ty>
	struct is_reference
		: _Cat_base<is_lvalue_reference<_Ty>::value
		|| is_rvalue_reference<_Ty>::value>
	{	// determine whether _Ty is a reference
	};

 #else /* _HAS_CPP0X */
	// TEMPLATE CLASS 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
	};
 #endif /* _HAS_CPP0X */

	// TEMPLATE CLASS is_member_object_pointer
template<class _Ty>
	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::*>
		: _Cat_base<!_Is_memfunptr<_Ty1 _Ty2::*>::value>
	{	// determine whether _Ty is a pointer to member object
	};

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

	// TEMPLATE CLASS is_member_function_pointer
template<class _Ty>
	struct is_member_function_pointer
		: _Cat_base<_Is_memfunptr<typename remove_cv<_Ty>::type>::value>
	{	// determine whether _Ty is a pointer to member function
	};

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

template<class _Ty>
	struct _Is_pointer<_Ty *>
		: _Cat_base<!is_member_object_pointer<_Ty *>::value
		&& !is_member_function_pointer<_Ty *>::value>
	{	// determine whether _Ty is a pointer
	};

template<class _Ty>
	struct is_pointer
		: _Is_pointer<typename remove_cv<_Ty>::type>
	{	// determine whether _Ty is a pointer
	};

	// TEMPLATE CLASS is_union
template<class _Ty>
	struct is_union _IS_UNION(_Ty)
	{	// determine whether _Ty is a union
	};

	// TEMPLATE CLASS is_class
template<class _Ty>
	struct is_class _IS_CLASS(_Ty)
	{	// determine whether _Ty is a class
	};

	// TEMPLATE CLASS is_function
template<class _Ty>
	struct is_function
		: _Cat_base<_Is_funptr<typename remove_cv<_Ty>::type *>::value>
	{	// determine whether _Ty is a function
	};

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

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

	// TEMPLATE CLASS is_arithmetic
template<class _Ty>
	struct is_arithmetic
		: _Cat_base<is_integral<_Ty>::value
		|| is_floating_point<_Ty>::value>
	{	// determine whether _Ty is an arithmetic type
	};

	// TEMPLATE CLASS is_fundamental
template<class _Ty>
	struct is_fundamental
		: _Cat_base<is_arithmetic<_Ty>::value
		|| is_void<_Ty>::value>
	{	// determine whether _Ty is a fundamental type
	};

	// TEMPLATE CLASS is_object
template<class _Ty>
	struct is_object
		: _Cat_base<!is_function<_Ty>::value
		&& !is_reference<_Ty>::value
		&& !is_void<_Ty>::value>
	{	// determine whether _Ty is an object type
	};

	// TEMPLATE CLASS is_convertible

template<class _From, class _To>
	struct is_convertible
		_IS_CONVERTIBLE(_From, _To)
	{	// determine whether _From is convertible to _To
	};

	// TEMPLATE CLASS is_enum
 #ifndef _IS_ENUM
		// TEMPLATE STRUCT _Is_composite
template<class _Ty>
	struct _Is_composite
	{	// determines whether _Ty is a struct/class/union
	template<class _Uty>
		static auto _Fn(int)
			-> typename decltype((const volatile int _Uty::*)0, true_type());
	template<class _Uty>
		static auto _Fn(_Wrap_int)
			-> false_type;

	typedef decltype(_Fn<_Ty>(0)) type;

	static const bool value = type::value;
	};

template<class _Ty>
	struct _Is_enum
		: _Cat_base<!is_void<_Ty>::value
			&& !is_arithmetic<_Ty>::value
			&& !is_array<_Ty>::value
			&& !_Is_composite<_Ty>::value
			&& is_convertible<_Ty, int>::value>
	{	// determine whether _Ty is an enumerated type
	};

template<class _Ty>
	struct _Is_enum<_Ty&>
		: false_type
	{	// determine whether _Ty is an enumerated type
	};

  #define _IS_ENUM(_Ty)	: _Is_enum<_Ty>
 #endif /* _IS_ENUM */

template<class _Ty>
	struct is_enum
		_IS_ENUM(_Ty)
	{	// determine whether _Ty is an enumerated type
	};

	// TEMPLATE CLASS is_compound
template<class _Ty>
	struct is_compound
		: _Cat_base<!is_fundamental<_Ty>::value>
	{	// determine whether _Ty is a compound type
	};

	// TEMPLATE CLASS is_member_pointer
template<class _Ty>
	struct is_member_pointer
		: _Cat_base<is_member_object_pointer<_Ty>::value
		|| is_member_function_pointer<_Ty>::value>
	{	// determine whether _Ty is a pointer to member
	};

	// TEMPLATE CLASS is_scalar
template<class _Ty>
	struct is_scalar
		: _Cat_base<is_arithmetic<_Ty>::value
		|| is_enum<_Ty>::value
		|| is_pointer<_Ty>::value
		|| is_member_pointer<_Ty>::value>
	{	// determine whether _Ty is a scalar type
	};

template<class _Ty>
	struct is_scalar<_Ty&>
		: false_type
	{	// references are not scalar
	};

	// TEMPLATE CLASS is_const
template<class _Ty>
	struct is_const
		: _Cat_base<_Ptr_traits<_Ty *>::_Is_const
		&& !is_function<_Ty>::value>
	{	// determine whether _Ty is const qualified
	};

template<class _Ty, unsigned int _Nx>
	struct is_const<_Ty[_Nx]>
		: false_type
	{	// determine whether _Ty is const qualified
	};

template<class _Ty, unsigned int _Nx>
	struct is_const<const _Ty[_Nx]>
		: true_type
	{	// determine whether _Ty is const qualified
	};

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

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

	// TEMPLATE CLASS is_volatile
template<class _Ty>
	struct is_volatile
		: _Cat_base<_Ptr_traits<_Ty *>::_Is_volatile
		&& !is_function<_Ty>::value>
	{	// determine whether _Ty is volatile qualified
	};

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

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

	// TEMPLATE CLASS is_pod
template<class _Ty>
	struct _Is_pod _IS_POD(_Ty)
	{	// determine whether _Ty is a POD type
	};

template<class _Ty>
	struct is_pod
		: _Is_pod<typename remove_all_extents<_Ty>::type>
	{	// determine whether _Ty is a POD type
	};

	// TEMPLATE CLASS is_empty
template<class _Ty>
	struct is_empty _IS_EMPTY(_Ty)
	{	// determine whether _Ty is an empty class
	};

	// TEMPLATE CLASS is_polymorphic
template<class _Ty>
	struct is_polymorphic _IS_POLYMORPHIC(_Ty)
	{	// determine whether _Ty is a polymorphic type
	};

	// TEMPLATE CLASS is_abstract
template<class _Ty>
	struct is_abstract _IS_ABSTRACT(_Ty)
	{	// determine whether _Ty is an abstract class
	};

 #if _HAS_CPP0X
	// TEMPLATE CLASS is_standard_layout
template<class _Ty>
	struct is_standard_layout _IS_STANDARD_LAYOUT(_Ty)
	{	// determine whether _Ty is standard layout
	};

	// TEMPLATE CLASS is_literal_type
template<class _Ty>
	struct is_literal_type _IS_LITERAL_TYPE(_Ty)
	{	// determine whether _Ty is a literal type
	};

	// TEMPLATE CLASS is_trivial
template<class _Ty>
	struct is_trivial _IS_TRIVIAL(_Ty)
	{	// determine whether _Ty is trivial
	};

	// TEMPLATE CLASS has_virtual_destructor
template<class _Ty>
	struct has_virtual_destructor
		_HAS_VIRTUAL_DESTRUCTOR(_Ty)
	{	// determine whether _Ty has a virtual destructor
	};

		// CONSTRUCTIBLE/ASSIGNABLE TRAITS
	// TEMPLATE CLASS is_constructible
template<class, _MAX_CLASS_LIST>
	struct is_constructible;

 #if defined(_IS_CONSTRUCTIBLE)
#define _CLASS_IS_CONSTRUCTIBLE0( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<class _Ty COMMA LIST(_CLASS_TYPE)> \
	struct is_constructible<_Ty,  LIST(_TYPE) COMMA PADDING_LIST(_NIL_PAD)> \
		: _Cat_base<_IS_CONSTRUCTIBLE(_Ty COMMA LIST(_TYPE))> \
	{	/* determine whether _Ty(_Args...) is constructible */ \
	};

_VARIADIC_EXPAND_0X(_CLASS_IS_CONSTRUCTIBLE0, , , , )
#undef _CLASS_IS_CONSTRUCTIBLE0

 #else /* defined(_IS_CONSTRUCTIBLE) */
template<bool, class, _MAX_CLASS_LIST>
	struct _Is_constructible;

#define _CLASS_IS_CONSTRUCTIBLE0( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<class _Ty COMMA LIST(_CLASS_TYPE)> \
	struct _Is_constructible<false, _Ty \
		COMMA LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
		: false_type \
	{	/* not constructible if not object type */ \
	}; \
template<class _Ty COMMA LIST(_CLASS_TYPE)> \
	struct _Is_constructible<true, _Ty \
		COMMA LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
	{	/* tests for valid constructor -- APPROXIMATION */ \
	template<class _Uty> \
		static auto _Fn(int) \
			-> decltype(_Uty(LIST(_DECLVAL)), true_type()); \
	template<class _Uty> \
		static auto _Fn(_Wrap_int) \
			-> false_type; \
	typedef decltype(_Fn<_Ty>(0)) type; \
	}; \
template<class _Ty COMMA LIST(_CLASS_TYPE)> \
	struct is_constructible<_Ty \
		COMMA LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
		: _If<is_void<_Ty>::value, \
			true_type, \
			typename _Is_constructible<is_object<_Ty>::value \
				&& (!is_scalar<_Ty>::value \
					|| _Sizeof<int COMMA LIST(_TYPE)>::value <= 2), \
			typename remove_all_extents<_Ty>::type \
				COMMA LIST(_TYPE)>::type>::type \
	{	/* determine whether _Ty(_Args...) is constructible */ \
	};

_VARIADIC_EXPAND_0X(_CLASS_IS_CONSTRUCTIBLE0, , , , )
#undef _CLASS_IS_CONSTRUCTIBLE0
 #endif /* defined(_IS_CONSTRUCTIBLE) */

	// TEMPLATE CLASS is_copy_constructible
template<class _Ty>
	struct is_copy_constructible
		: _Cat_base<!is_array<_Ty>::value
			&& is_constructible<
				typename remove_volatile<_Ty>::type,
				typename add_lvalue_reference<
				typename add_const<
				typename remove_volatile<_Ty>::type>::type>::type>::value>
	{	// determine whether _Ty has a copy constructor
	};

	// TEMPLATE CLASS has_copy_constructor -- retained
template<class _Ty>
	struct has_copy_constructor
		: is_copy_constructible<_Ty>::type
	{	// determine whether _Ty has a copy constructor
	};

	// TEMPLATE CLASS is_default_constructible
template<class _Ty>
	struct is_default_constructible
		: is_constructible<_Ty>::type
	{	// determine whether _Ty has a default constructor
	};

	// TEMPLATE CLASS has_default_constructor -- retained
template<class _Ty>
	struct has_default_constructor
		: is_default_constructible<_Ty>::type
	{	// determine whether _Ty has a default constructor
	};

	// TEMPLATE CLASS is_move_constructible
template<class _Ty>
	struct is_move_constructible
		: _Cat_base<!is_array<_Ty>::value
			&& is_constructible<
				typename remove_volatile<_Ty>::type,
				typename add_rvalue_reference<
				typename remove_cv<_Ty>::type>::type>::value>
	{	// determine whether _Ty has a move constructor
	};

	// TEMPLATE CLASS has_move_constructor -- retained
template<class _Ty>
	struct has_move_constructor
		: is_move_constructible<_Ty>::type
	{	// determine whether _Ty has a move constructor
	};

	// TEMPLATE CLASS is_assignable
template<bool,
	class _To,
	class _From>
	struct _Is_assignable
		: false_type
	{	// invalid assign expression
	};

template<class _To,
	class _From>
	struct _Is_assignable<true, _To, _From>
	{	// tests for valid assign expression
	template<class _Uty>
		static auto _Fn(int)
			-> decltype((declval<_Uty>() = declval<_From>()), true_type());

	template<class _Uty>
		static auto _Fn(_Wrap_int)
			-> false_type;

	typedef decltype(_Fn<_To>(0)) type;
	};

template<class _To,
	class _From>
	struct is_assignable
		: _If<is_void<_To>::value && is_void<_From>::value
			|| is_scalar<_To>::value && is_scalar<_From>::value,
			true_type,
			typename _Is_assignable<
				is_object<typename remove_reference<_To>::type>::value
				&& !is_array<typename remove_reference<_To>::type>::value
				&& is_object<typename remove_reference<_From>::type>::value
				&& !is_array<typename remove_reference<_From>::type>::value,
				_To, _From>::type>::type
//		_IS_ASSIGNABLE(_To, _From)
	{	// determine whether _From can be assigned to _To
	};

	// TEMPLATE CLASS is_copy_assignable
template<class _Ty>
	struct is_copy_assignable
		: is_assignable<typename add_lvalue_reference<
				typename remove_volatile<_Ty>::type>::type,
			typename add_lvalue_reference<
				typename add_const<
					typename remove_volatile<_Ty>::type>::type>::type>::type
	{	// determine whether _Ty has a copy assignment operator
	};

	// TEMPLATE CLASS has_copy_assign -- retained
template<class _Ty>
	struct has_copy_assign
		: is_copy_assignable<_Ty>::type
	{	// determine whether _Ty has a copy assignment operator
	};

	// TEMPLATE CLASS is_move_assignable
template<class _Ty>
	struct is_move_assignable
		: is_assignable<typename add_lvalue_reference<
				typename remove_volatile<_Ty>::type>::type,
			typename remove_volatile<_Ty>::type>::type
	{	// determine whether _Ty has a move assignment operator
	};

template<class _Ty>
	struct has_move_assign
		: is_move_assignable<_Ty>::type
	{	// determine whether _Ty has a move assignment operator
	};

	// TEMPLATE CLASS is_destructible
template<class _Ty>
	struct is_destructible
		: true_type	// APPROXIMATION
//		_IS_DESTRUCTIBLE(_Ty)
	{	// determine whether _Ty has a destructor
	};

		// TRIVIAL TRAITS
	// TEMPLATE CLASS is_trivially_constructible

 #if defined(_IS_TRIVIALLY_CONSTRUCTIBLE)
template<class, _MAX_CLASS_LIST>
	struct is_trivially_constructible;

#define _CLASS_IS_TRIVIALLY_CONSTRUCTIBLE0( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<class _Ty COMMA LIST(_CLASS_TYPE)> \
	struct is_trivially_constructible<_Ty \
		 COMMA LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
		: _Cat_base<_IS_TRIVIALLY_CONSTRUCTIBLE(_Ty COMMA LIST(_TYPE))> \
	{	/* determine whether _Ty(_Args...) is trivially constructible */ \
	};

_VARIADIC_EXPAND_0X(_CLASS_IS_TRIVIALLY_CONSTRUCTIBLE0, , , , )
#undef _CLASS_IS_TRIVIALLY_CONSTRUCTIBLE0

 #else /* defined(_IS_TRIVIALLY_CONSTRUCTIBLE) */
template<class, class = _Nil, _MAX_CLASS_LIST>
	struct is_trivially_constructible;

#define _CLASS_IS_TRIVIALLY_CONSTRUCTIBLE0( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<class _Ty, \
	class _Xarg0 COMMA LIST(_CLASS_TYPE)> \
	struct is_trivially_constructible<_Ty, _Xarg0 \
		COMMA LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
		: is_constructible<_Ty, _Xarg0 \
			COMMA LIST(_TYPE)>	/* APPROXIMATION */ \
/*		_IS_TRIVIALLY_CONSTRUCTIBLE(_Ty, _Args...) */ \
	{	/* determine whether _Ty(_Args...) is trivially constructible */ \
	};

_VARIADIC_EXPAND_0X(_CLASS_IS_TRIVIALLY_CONSTRUCTIBLE0, , , , )
#undef _CLASS_IS_TRIVIALLY_CONSTRUCTIBLE0

template<class _Ty>
	struct is_trivially_constructible<_Ty, _Ty, _MAX_NIL_LIST>
		_HAS_TRIVIAL_COPY(_Ty)
//		_IS_TRIVIALLY_CONSTRUCTIBLE(_Ty, _Ty)
	{	// determine whether _Ty is trivially copy constructible
	};

template<class _Ty>
	struct is_trivially_constructible<_Ty, _Nil, _MAX_NIL_LIST>
		_HAS_TRIVIAL_CONSTRUCTOR(_Ty)
//		_IS_TRIVIALLY_CONSTRUCTIBLE(_Ty)
	{	// determine whether _Ty is trivially default constructible
	};
 #endif /* defined(_IS_TRIVIALLY_CONSTRUCTIBLE) */

	// TEMPLATE CLASS is_trivially_copy_constructible
template<class _Ty>
	struct is_trivially_copy_constructible
		_HAS_TRIVIAL_COPY(_Ty)
//		: is_trivially_constructible<
//			typename remove_volatile<_Ty>::type,
//			typename add_lvalue_reference<
//				typename add_const<
//					typename remove_volatile<_Ty>::type>::type>::type>::type
	{	// determine whether _Ty has a trivial copy constructor
	};

	// TEMPLATE CLASS is_trivially_copyable
template<class _Ty>
	struct is_trivially_copyable
		: is_trivially_copy_constructible<_Ty>::type
	{	// determine whether _Ty has a trivial copy constructor
	};

	// TEMPLATE CLASS has_trivial_copy_constructor -- retained
template<class _Ty>
	struct has_trivial_copy_constructor
		_HAS_TRIVIAL_COPY(_Ty)
//		: is_trivially_copy_constructible<_Ty>::type
	{	// determine whether _Ty has a trivial copy constructor
	};

	// TEMPLATE CLASS is_trivially_default_constructible
template<class _Ty>
	struct is_trivially_default_constructible
		: is_trivially_constructible<_Ty>::type
	{	// determine whether _Ty has a trivial default constructor
	};

	// TEMPLATE CLASS has_trivial_default_constructor -- retained
template<class _Ty>
	struct has_trivial_default_constructor
		: is_trivially_default_constructible<_Ty>::type
	{	// determine whether _Ty has a trivial constructor
	};

	// TEMPLATE CLASS is_trivially_move_constructible
template<class _Ty>
	struct is_trivially_move_constructible
		_HAS_TRIVIAL_MOVE_CONSTRUCTOR(_Ty)
	{	// determine whether _Ty has a trivial move constructor
	};

	// TEMPLATE CLASS has_trivial_move_constructor -- retained
template<class _Ty>
	struct has_trivial_move_constructor
		: is_trivially_move_constructible<_Ty>::type
	{	// determine whether _Ty has a trivial move constructor
	};

	// TEMPLATE CLASS is_trivially_assignable
template<class _To,
	class _From>
	struct is_trivially_assignable
		: is_assignable<_To, _From>::type	// APPROXIMATION
//		_IS_TRIVIALLY_ASSIGNABLE(_To, _From)
	{	// determine whether _From can be assigned to _To, trivially
	};

	// TEMPLATE CLASS is_trivially_copy_assignable
template<class _Ty>
	struct is_trivially_copy_assignable
		_HAS_TRIVIAL_ASSIGN(_Ty)
//		: is_trivially_assignable<typename add_lvalue_reference<
//				typename remove_volatile<_Ty>::type>::type,
//			typename add_lvalue_reference<
//				typename add_const<
//					typename remove_volatile<_Ty>::type>::type>::type>::type
	{	// determine whether _Ty has a trivial copy assignment operator
	};

	// TEMPLATE CLASS has_trivial_copy_assign -- retained
template<class _Ty>
	struct has_trivial_copy_assign
		: is_trivially_copy_assignable<_Ty>::type
	{	// determine whether _Ty has a trivial copy assignment operator
	};

	// TEMPLATE CLASS is_trivially_move_assignable
template<class _Ty>
	struct is_trivially_move_assignable
		_HAS_TRIVIAL_MOVE_ASSIGN(_Ty)
	{	// determine whether _Ty has a trivial move assignment operator
	};

	// TEMPLATE CLASS has_trivial_move_assign -- retained
template<class _Ty>
	struct has_trivial_move_assign
		: is_trivially_move_assignable<_Ty>::type
	{	// determine whether _Ty has a trivial move assignment operator
	};

	// TEMPLATE CLASS is_trivially_destructible
template<class _Ty>
	struct is_trivially_destructible
		_HAS_TRIVIAL_DESTRUCTOR(_Ty)
	{	// determine whether _Ty has a trivial destructor
	};

		// NOTHROW TRAITS
	// TEMPLATE CLASS is_nothrow_constructible

 #if defined(_IS_NOTHROW_CONSTRUCTIBLE)
template<class, _MAX_CLASS_LIST>
	struct is_nothrow_constructible;

#define _CLASS_IS_NOTHROW_CONSTRUCTIBLE0( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<class _Ty COMMA LIST(_CLASS_TYPE)> \
	struct is_nothrow_constructible<class _Ty \
		COMMA LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
		: _Cat_base<_IS_NOTHROW_CONSTRUCTIBLE(_Ty COMMA LIST(_TYPE))> \
	{	/* determine whether _Ty(_Args...) is nothrow constructible */ \
	};

_VARIADIC_EXPAND_0X(_CLASS_IS_NOTHROW_CONSTRUCTIBLE0, , , , )
#undef _CLASS_IS_NOTHROW_CONSTRUCTIBLE0

 #else /* defined(_IS_NOTHROW_CONSTRUCTIBLE) */
template<class, class = _Nil, _MAX_CLASS_LIST>
	struct is_nothrow_constructible;

#define _CLASS_IS_NOTHROW_CONSTRUCTIBLE0( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<class _Ty, \
	class _Xarg0 COMMA LIST(_CLASS_TYPE)> \
	struct is_nothrow_constructible<_Ty, _Xarg0 \
		COMMA LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
		: is_constructible<_Ty, _Xarg0 COMMA LIST(_TYPE)> \
/*		_IS_NOTHROW_CONSTRUCTIBLE(_Ty, _Args...)	APPROXIMATION */ \
	{	/* determine whether _Ty(_Args...) is nothrow constructible */ \
	};

_VARIADIC_EXPAND_0X(_CLASS_IS_NOTHROW_CONSTRUCTIBLE0, , , , )
#undef _CLASS_IS_NOTHROW_CONSTRUCTIBLE0

template<class _Ty>
	struct is_nothrow_constructible<_Ty, _Ty, _MAX_NIL_LIST>
		_HAS_NOTHROW_COPY(_Ty)
//		_IS_NOTHROW_CONSTRUCTIBLE(_Ty, _Ty)
	{	// determine whether _Ty is nothrow copy constructible
	};

template<class _Ty>
	struct is_nothrow_constructible<_Ty, _Nil, _MAX_NIL_LIST>
		_HAS_NOTHROW_CONSTRUCTOR(_Ty)
//		_IS_NOTHROW_CONSTRUCTIBLE(_Ty)
	{	// determine whether _Ty is nothrow default constructible
	};
 #endif /* defined(_IS_NOTHROW_CONSTRUCTIBLE) */

	// TEMPLATE CLASS is_nothrow_copy_constructible
template<class _Ty>
	struct is_nothrow_copy_constructible
		: _Cat_base<!is_array<_Ty>::value
			&& is_nothrow_constructible<
				typename remove_volatile<_Ty>::type,
				typename add_lvalue_reference<
				typename add_const<
					typename remove_volatile<_Ty>::type>::type>::type>::value>
	{	// determine whether _Ty has a nothrow copy constructor
	};

	// TEMPLATE CLASS has_nothrow_copy_constructor -- retained
template<class _Ty>
	struct has_nothrow_copy_constructor
		_HAS_NOTHROW_COPY(_Ty)
//		: is_nothrow_copy_constructible<_Ty>::type
	{	// determine whether _Ty has a nothrow copy constructor
	};

	// TEMPLATE CLASS is_nothrow_default_constructible
template<class _Ty>
	struct is_nothrow_default_constructible
		: is_nothrow_constructible<_Ty>::type
	{	// determine whether _Ty has a nothrow default constructor
	};

	// TEMPLATE CLASS has_nothrow_default_constructor -- retained
template<class _Ty>
	struct has_nothrow_default_constructor
		: is_nothrow_default_constructible<_Ty>::type
	{	// determine whether _Ty has a nothrow default constructor
	};

	// TEMPLATE CLASS is_nothrow_move_constructible
template<class _Ty>
	struct is_nothrow_move_constructible
		: _Cat_base<!is_array<_Ty>::value
			&& is_nothrow_constructible<
				typename remove_volatile<_Ty>::type,
				typename add_rvalue_reference<
				typename remove_volatile<_Ty>::type>::type>::value>
	{	// determine whether _Ty has a nothrow move constructor
	};

	// TEMPLATE CLASS has_nothrow_move_constructor -- retained
template<class _Ty>
	struct has_nothrow_move_constructor
		: is_nothrow_move_constructible<_Ty>::type
	{	// determine whether _Ty has a nothrow move constructor
	};

	// TEMPLATE CLASS is_nothrow_assignable
template<class _To,
	class _From>
	struct is_nothrow_assignable
		: is_assignable<_To, _From>::type	// APPROXIMATION
//		_IS_NOTHROW_ASSIGNABLE(_To, _From)
	{	// determine whether _From can be assigned to _To, nothrow
	};

	// TEMPLATE CLASS is_nothrow_copy_assignable
template<class _Ty>
	struct is_nothrow_copy_assignable
		_HAS_NOTHROW_ASSIGN(_Ty)
//		: is_nothrow_assignable<typename add_lvalue_reference<
//				typename remove_volatile<_Ty>::type>::type,
//			typename add_lvalue_reference<
///				typename add_const<
//					typename remove_volatile<_Ty>::type>::type>::type>::type
	{	// determine whether _Ty has a nothrow copy assignment operator
	};

	// TEMPLATE CLASS has_nothrow_copy_assign -- retained
template<class _Ty>
	struct has_nothrow_copy_assign
		: is_nothrow_copy_assignable<_Ty>::type
	{	// determine whether _Ty has a nothrow copy assignment operator
	};

	// TEMPLATE CLASS is_nothrow_move_assignable
template<class _Ty>
	struct is_nothrow_move_assignable
		_HAS_NOTHROW_MOVE_ASSIGN(_Ty)
	{	// determine whether _Ty has a nothrow move assignment operator
	};

	// TEMPLATE CLASS has_nothrow_move_assign -- retained
template<class _Ty>
	struct has_nothrow_move_assign
		: is_nothrow_move_assignable<_Ty>::type
	{	// determine whether _Ty has a nothrow move assignment operator
	};

	// TEMPLATE CLASS is_nothrow_destructible
template<class _Ty>
	struct is_nothrow_destructible
		: true_type	// APPROXIMATION
//		_IS_NOTHROW_DESTRUCTIBLE(_Ty)
	{	// determine whether _Ty has a nothrow destructor
	};
 #endif /* _HAS_CPP0X */

	// TEMPLATE CLASS has_trivial_constructor -- retained
template<class _Ty>
	struct has_trivial_constructor _HAS_TRIVIAL_CONSTRUCTOR(_Ty)
	{	// determine whether _Ty has a trivial default constructor
	};

	// TEMPLATE CLASS has_trivial_copy -- retained
template<class _Ty>
	struct has_trivial_copy _HAS_TRIVIAL_COPY(_Ty)
	{	// determine whether _Ty has a trivial copy constructor
	};

	// TEMPLATE CLASS has_trivial_assign -- retained
template<class _Ty>
	struct has_trivial_assign _HAS_TRIVIAL_ASSIGN(_Ty)
	{	// determine whether _Ty has a trivial assignment operator
	};

	// TEMPLATE CLASS has_trivial_destructor -- retained
template<class _Ty>
	struct has_trivial_destructor
		_HAS_TRIVIAL_DESTRUCTOR(_Ty)
	{	// determine whether _Ty has a trivial destructor
	};

	// TEMPLATE CLASS has_nothrow_constructor -- retained
template<class _Ty>
	struct has_nothrow_constructor _HAS_NOTHROW_CONSTRUCTOR(_Ty)
	{	// determine whether _Ty has a nothrow default constructor
	};

	// TEMPLATE CLASS has_nothrow_copy -- retained
template<class _Ty>
	struct has_nothrow_copy _HAS_NOTHROW_COPY(_Ty)
	{	// determine whether _Ty has a nothrow copy constructor
	};

	// TEMPLATE CLASS has_nothrow_assign -- retained
template<class _Ty>
	struct has_nothrow_assign _HAS_NOTHROW_ASSIGN(_Ty)
	{	// determine whether _Ty has a nothrow assignment operator
	};

	// TEMPLATE CLASS is_signed
template<class _Ty>
	struct _Has_signed_vals
		: _Cat_base<(typename remove_cv<_Ty>::type)(-1)
		< (typename remove_cv<_Ty>::type)(0)>
	{	// integral type can represent negative values
	};

template<class _Ty>
	struct is_signed
		: _Cat_base<is_floating_point<_Ty>::value || is_integral<_Ty>::value
		&& _Has_signed_vals<
			typename _If<is_integral<_Ty>::value, _Ty, int>::type>::value>
	{	// determine whether _Ty is a signed type
	};

	// TEMPLATE CLASS is_unsigned
template<class _Ty>
	struct is_unsigned
		: _Cat_base<is_integral<_Ty>::value
		&& !_Has_signed_vals<
			typename _If<is_integral<_Ty>::value, _Ty, int>::type>::value>
	{	// determine whether _Ty is an unsigned type
	};

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

	typedef
		typename _If<is_same<_Ty, signed char>::value
			|| is_same<_Ty, unsigned char     >::value, signed char,
		typename _If<is_same<_Ty, short       >::value
			|| is_same<_Ty, unsigned short    >::value, short,
		typename _If<is_same<_Ty, int         >::value
			|| is_same<_Ty, unsigned int      >::value, int,
		typename _If<is_same<_Ty, long        >::value
			|| is_same<_Ty, unsigned long     >::value, long,
		typename _If<is_same<_Ty, long long   >::value
			|| is_same<_Ty, unsigned long long>::value, long long,
		typename _If<sizeof (_Ty) == sizeof (signed char), signed char,
		typename _If<sizeof (_Ty) == sizeof (short      ), short,
		typename _If<sizeof (_Ty) == sizeof (int        ), int,
		typename _If<sizeof (_Ty) == sizeof (long       ), long,
			long long
		>::type>::type>::type>::type>::type>::type>::type>::type>::type
			_Signed;

	typedef
		typename _If<is_same<_Signed, signed char>::value, unsigned char,
		typename _If<is_same<_Signed, short      >::value, unsigned short,
		typename _If<is_same<_Signed, int        >::value, unsigned int,
		typename _If<is_same<_Signed, long       >::value, unsigned long,
			unsigned long long
		>::type>::type>::type>::type
			_Unsigned;
	};

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

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

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

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

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

	// TEMPLATE CLASS alignment_of
 #ifndef _ALIGN_OF
template<class _Ty>
	struct _Get_align
	{	// struct used to determine alignment of _Ty
	_Ty _Elt0;
	char _Elt1;
	_Ty _Elt2;

	_Get_align();	// silence warning C4610
	};

#define _ALIGN_OF(_Ty) (sizeof (_Get_align<_Ty>) - 2 * sizeof (_Ty))
 #endif /* _ALIGN_OF */

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

template<class _Ty>
	struct alignment_of<_Ty&>
		: integral_constant<size_t, _ALIGN_OF(_Ty *)>
	{	// assume references are aligned like pointers
	};

	// TEMPLATE CLASS aligned_storage
#define _FITS(_Ty)	_Align <= _ALIGN_OF(_Ty)
#define _NEXT_ALIGN(_Ty)	\
	typedef typename _Aligned<_Len, _Align, _Ty, _FITS(_Ty)>::type 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
	typedef _Align_type<_Ty, _Len> type;
	};

template<size_t _Len,
	size_t _Align>
	struct _Aligned<_Len, _Align, double, false>
	{	// define type with size _Len and alignment _Ty
 #if _HAS_CPP0X
	typedef _Align_type<max_align_t, _Len> type;

 #else /* _HAS_CPP0X */
	typedef _Align_type<double, _Len> type;
 #endif /* _HAS_CPP0X */
	};

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 = alignment_of<max_align_t>::value>
	struct aligned_storage
	{	// define type with size _Len and alignment _Align
	typedef typename _Aligned<_Len, _Align, char, _FITS(char)>::type type;
	};

#undef _FITS
#undef _NEXT_ALIGN

 #if _HAS_CPP0X
	// TEMPLATE CLASS aligned_union
template<size_t _Len, class = _Nil, _MAX_CLASS_LIST>
	struct aligned_union;

template<size_t _Len>
	struct aligned_union<_Len, _Nil, _MAX_NIL_LIST>
	{	// define type with size _Len and alignment of char
	typedef typename aligned_storage<_Len, _ALIGN_OF(char)>::type type;
	};

#define _CLASS_ALIGNED_UNION( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<size_t _Len, \
	class _Xty0 COMMA LIST(_CLASS_TYPE)> \
	struct aligned_union<_Len, _Xty0 \
		COMMA LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
	{	/* define type with size _Len and alignment of _Xty0, _Rest... */ \
	typedef union \
		{	/* holds all argument types, recursively */ \
		typename aligned_storage<_Len, _ALIGN_OF(_Xty0)>::type _Obj1; \
		typename aligned_union<_Len COMMA LIST(_TYPE)>::type _Obj2; \
		} type; \
	};

_VARIADIC_EXPAND_0X(_CLASS_ALIGNED_UNION, , , , )
#undef _CLASS_ALIGNED_UNION

template<class _Ty>
	struct underlying_type
	{	// determine type underlying type for enum
	typedef _UNDERLYING_TYPE(_Ty) type;
	};
 #endif /* _HAS_CPP0X */

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

template<class _Ty, unsigned int _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 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, unsigned int _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, unsigned int _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 is_base_of
template<class _Base, class _Der>
	struct is_base_of _IS_BASE_OF(_Base, _Der)
	{	// determine whether _Base is a base of or the same as _Der
	};

	// TEMPLATE CLASS decay
template<class _Ty>
	struct decay
	{	// determines decayed version of _Ty
	typedef typename remove_reference<_Ty>::type _Ty1;

	typedef typename _If<is_array<_Ty1>::value,
		typename remove_extent<_Ty1>::type *,
		typename _If<is_function<_Ty1>::value,
			typename add_pointer<_Ty1>::type,
			typename remove_cv<_Ty1>::type>::type>::type type;
	};

namespace tr1 {	// TR1 additions
using _STD add_const;
using _STD add_cv;
using _STD add_pointer;
using _STD add_reference;	// retained
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_nothrow_assign;	// retained
using _STD has_nothrow_constructor;	// retained
using _STD has_nothrow_copy;	// retained
using _STD has_trivial_assign;
using _STD has_trivial_constructor;	// retained
using _STD has_trivial_copy;	// retained
using _STD has_trivial_destructor;	// retained
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;	// retained
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;
	}	// namespace tr1

		// TEMPLATE STRUCT _Common_type
template<bool,
	class _Ty0,
	class _Ty1>
	struct _Common_type
	{	// no common type
	typedef void type;
	};

template<class _Ty0,
	class _Ty1>
	struct _Common_type<true, _Ty0, _Ty1>
	{	// type is common type of _Ty0 and _Ty1 for two arguments
	typedef decltype(_Always_false<_Ty0>::value
		? declval<_Ty0>() : declval<_Ty1>()) type;
	};

		// TEMPLATE STRUCT common_type
template<class, class = _Nil, _MAX_CLASS_LIST>
	struct common_type;

template<class _Xty0>
	struct common_type<_Xty0, _Nil, _MAX_NIL_LIST>
	{	// type is _Xty0 for one argument
	typedef _Xty0 type;
	};

#define _CLASS_COMMON_TYPE( \
	TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
template<class _Xty0, \
	class _Xty1 COMMA LIST(_CLASS_TYPE)> \
	struct common_type<_Xty0, _Xty1 \
		COMMA LIST(_TYPE), PADDING_LIST(_NIL_PAD)> \
	{	/* type is defined recursively for more than two arguments */ \
	typedef typename _Common_type<_Is_numeric<_Xty0>::value \
		&& _Is_numeric<_Xty1>::value, \
		_Xty0, _Xty1>::type _Xty01; \
	typedef typename common_type<_Xty01 COMMA LIST(_TYPE)>::type type; \
	};

_VARIADIC_EXPAND_0X(_CLASS_COMMON_TYPE, , , , )
#undef _CLASS_COMMON_TYPE

	// CLASS _Unrefwrap
template<class _Ty>
	class reference_wrapper;

template<class _Ty>
	struct _Unrefwrap_helper
	{	// leave unchanged if not a reference_wrapper
	typedef _Ty type;
	};

template<class _Ty>
	struct _Unrefwrap_helper<reference_wrapper<_Ty> >
	{	// make a reference from a reference_wrapper
	typedef _Ty& type;
	};

template<class _Ty>
	struct _Unrefwrap
	{	// decay, then unwrap a reference_wrapper
	typedef typename decay<_Ty>::type _Ty1;
	typedef typename _Unrefwrap_helper<_Ty1>::type type;
	};

	// TEMPLATE CLASS identity
template<class _Ty>
	struct identity
	{	// map _Ty to type unchanged
	typedef _Ty type;

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

	// TEMPLATE FUNCTION forward
template<class _Ty> inline
	_Ty&& forward(typename remove_reference<_Ty>::type& _Arg)
	{	// forward an lvalue
	return (static_cast<_Ty&&>(_Arg));
	}

template<class _Ty> inline
	_Ty&& forward(typename remove_reference<_Ty>::type&& _Arg) _NOEXCEPT
	{	// forward anything
	static_assert(!is_lvalue_reference<_Ty>::value, "bad forward call");
	return (static_cast<_Ty&&>(_Arg));
	}

		// TEMPLATE FUNCTION move
template<class _Ty> inline
	typename remove_reference<_Ty>::type&&
		move(_Ty&& _Arg) _NOEXCEPT
	{	// forward _Arg as movable
	return ((typename remove_reference<_Ty>::type&&)_Arg);
	}

		// TEMPLATE FUNCTION _Move
template<class _Ty> inline
	typename remove_reference<_Ty>::type&&
		_Move(_Ty&& _Arg) _NOEXCEPT
	{	// forward _Arg as movable
	return ((typename remove_reference<_Ty>::type&&)_Arg);
	}

		// TEMPLATE FUNCTION move_if_noexcept
template<class _Ty> inline
	typename _If<!has_nothrow_move_constructor<_Ty>::value
		&& has_copy_constructor<_Ty>::value,
			const _Ty&, _Ty&&>::type
	move_if_noexcept(_Ty& _Arg) _NOEXCEPT
	{	// forward _Arg if moveable
	return (_STD move(_Arg));
	}

 	// TEMPLATE FUNCTION _Decay_copy
template<class _Ty> inline
	typename decay<_Ty>::type _Decay_copy(_Ty&& _Arg)
	{	// forward _Arg as value of decayed type
	return (_STD forward<_Ty>(_Arg));
	}
_STD_END

#include <xrefwrap>	/* sic */
 #pragma pop_macro("new")
 #pragma warning(pop)
 #pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _TYPE_TRAITS_ */

/*
 * Copyright (c) 1992-2012 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
V6.00:0009 */
