// tr1common internal header
#pragma once
#ifndef _TR1_COMMON_
#define _TR1_COMMON_
#ifndef RC_INVOKED
#include "yvals.h"

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)

 #if _HAS_TR1

 #else /* _HAS_TR1 */
  #error TR1 not fully supported
 #endif /* _HAS_TR1 */

  #define _NO_SFINAE 1

	// maximum number of arguments to call wrappers
#define _NMAX 10

#define _XNAME(x, z)			x ## z
#define _YNAME(x, z)			_XNAME(x, z)
#define _YNAME15(x, y, z)		_XNAME(x, z) y
#define _YNAME2(x, y, z)		_XNAME(x, z) _XNAME(y, z)

#define _YCALL3(x, y, z, f)		_STD f<_XNAME(x, z)>(_XNAME(y, z))

#define _CORE_0(x)
#define _CORE15_0(x, y)
#define _CORE2_0_CALL(x, y, f)
#define _CORE2_0(x, y)
#define _NARGSm1_0				0

#define _CORE_1(x)
#define _CORE15_1(x, y)
#define _CORE2_1_CALL(x, y, f)
#define _CORE2_1(x, y)
#define _NARGSm1_1				0

#define _CORE_2(x)
#define _CORE15_2(x, y)
#define _CORE2_2_CALL(x, y, f)
#define _CORE2_2(x, y)
#define _NARGSm1_2				1

#define _CORE_3(x)				_YNAME(x, 1)
#define _CORE15_3(x, y)			_YNAME15(x, y, 1)
#define _CORE2_3_CALL(x, y, f)	_YCALL3(x, y, 1, f)
#define _CORE2_3(x, y)			_YNAME2(x, y, 1)
#define _NARGSm1_3				2

#define _CORE_4(x)				_CORE_3(x), _YNAME(x, 2)
#define _CORE15_4(x, y)			_CORE15_3(x, y), _YNAME15(x, y, 2)
#define _CORE2_4_CALL(x, y, f)	_CORE2_3_CALL(x, y, f), _YCALL3(x, y, 2, f)
#define _CORE2_4(x, y)			_CORE2_3(x, y), _YNAME2(x, y, 2)
#define _NARGSm1_4				3

#define _CORE_5(x)				_CORE_4(x), _YNAME(x, 3)
#define _CORE15_5(x, y)			_CORE15_4(x, y), _YNAME15(x, y, 3)
#define _CORE2_5_CALL(x, y, f)	_CORE2_4_CALL(x, y, f), _YCALL3(x, y, 3, f)
#define _CORE2_5(x, y)			_CORE2_4(x, y), _YNAME2(x, y, 3)
#define _NARGSm1_5				4

#define _CORE_6(x)				_CORE_5(x), _YNAME(x, 4)
#define _CORE15_6(x, y)			_CORE15_5(x, y), _YNAME15(x, y, 4)
#define _CORE2_6_CALL(x, y, f)	_CORE2_5_CALL(x, y, f), _YCALL3(x, y, 4, f)
#define _CORE2_6(x, y)			_CORE2_5(x, y), _YNAME2(x, y, 4)
#define _NARGSm1_6				5

#define _CORE_7(x)				_CORE_6(x), _YNAME(x, 5)
#define _CORE15_7(x, y)			_CORE15_6(x, y), _YNAME15(x, y, 5)
#define _CORE2_7_CALL(x, y, f)	_CORE2_6_CALL(x, y, f), _YCALL3(x, y, 5, f)
#define _CORE2_7(x, y)			_CORE2_6(x, y), _YNAME2(x, y, 5)
#define _NARGSm1_7				6

#define _CORE_8(x)				_CORE_7(x), _YNAME(x, 6)
#define _CORE15_8(x, y)			_CORE15_7(x, y), _YNAME15(x, y, 6)
#define _CORE2_8_CALL(x, y, f)	_CORE2_7_CALL(x, y, f), _YCALL3(x, y, 6, f)
#define _CORE2_8(x, y)			_CORE2_7(x, y), _YNAME2(x, y, 6)
#define _NARGSm1_8				7

#define _CORE_9(x)				_CORE_8(x), _YNAME(x, 7)
#define _CORE15_9(x, y)			_CORE15_8(x, y), _YNAME15(x, y, 7)
#define _CORE2_9_CALL(x, y, f)	_CORE2_8_CALL(x, y, f), _YCALL3(x, y, 7, f)
#define _CORE2_9(x, y)			_CORE2_8(x, y), _YNAME2(x, y, 7)
#define _NARGSm1_9				8

#define _CORE_10(x)				_CORE_9(x), _YNAME(x, 8)
#define _CORE15_10(x, y)		_CORE15_9(x, y), _YNAME15(x, y, 8)
#define _CORE2_10_CALL(x, y, f)	_CORE2_9_CALL(x, y, f), _YCALL3(x, y, 8, f)
#define _CORE2_10(x, y)			_CORE2_9(x, y), _YNAME2(x, y, 8)
#define _NARGSm1_10				9

#define _TAIL_10(x)
#define _TAIL_9(x)				x
#define _TAIL_8(x)				_TAIL_9(x), x
#define _TAIL_7(x)				_TAIL_8(x), x
#define _TAIL_6(x)				_TAIL_7(x), x
#define _TAIL_5(x)				_TAIL_6(x), x
#define _TAIL_4(x)				_TAIL_5(x), x
#define _TAIL_3(x)				_TAIL_4(x), x
#define _TAIL_2(x)				_TAIL_3(x), x
#define _TAIL_1(x)				_TAIL_2(x), x
#define _TAIL_0(x)				_TAIL_1(x), x

#define _ARG_MAX				9
#define _CDR_MAX(x)				_CORE_10(x), _YNAME(x, _ARG_MAX)
#define _CDR15_MAX(x, y)		_CORE15_10(x, y), _YNAME15(x, y, _ARG_MAX)
#define _CDR2_MAX(x, y) 		_CORE2_10(x, y), _YNAME2(x, y, _ARG_MAX)
#define _CDR2_CALL_MAX(x, y, f)	\
	_CORE2_10_CALL(x, y, f), _YCALL3(x, y, _ARG_MAX, f)
#define _LIST_MAX(x)			_YNAME(x, 0), _CDR_MAX(x)
#define _LIST15_MAX(x, y)		_YNAME15(x, y, 0), _CDR15_MAX(x, y)
#define _LIST2_MAX(x, y) 		_YNAME2(x, y, 0), _CDR2_MAX(x, y)
#define _LIST2_CALL_MAX(x, y, f)	\
	_YCALL3(x, y, 0, f), _CDR2_CALL_MAX(x, y, f)

#define _CLASS_ARG0_MAX			_LIST_MAX(class _Arg)
#define _CLASS_FARG0_MAX		_LIST_MAX(class _Farg)
#define _ARG0_A0_REF_MAX		_LIST2_MAX(_Arg, &_Ax)
#define _ARG0_A0_REFREF_MAX		_LIST2_MAX(_Arg, && _Ax)
#define _FARG0_F0_REFREF_MAX	_LIST2_MAX(_Farg, && _Fx)
#define _FARG0_F0_CREFIFY_MAX	\
	_LIST2_MAX(typename _Arg_traits<_Farg, >::_AType _Fx)

#define _CLASS_ARG1_MAX			_CDR_MAX(class _Arg)
#define _ARG1_A1_REF_MAX		_CDR2_MAX(_Arg, &_Ax)
#define _ARG1_A1_CREF_MAX		_CDR2_MAX(const _Arg, &_Ax)
#define _CLASS_FARG1_MAX		_CDR_MAX(class _Farg)
#define _FARG1_F1_MAX			_CDR2_MAX(_Farg, _Fx)
#define _FARG1_F1_REF_MAX		_CDR2_MAX(_Farg, &_Fx)
#define _FARG1_F1_CREF_MAX		_CDR2_MAX(const _Farg, &_Fx)
#define _ARG1_ARG2_MAX			_CDR_MAX(_Arg)
#define _ARG0_ARG1_MAX			_LIST_MAX(_Arg)
#define _FARG1_FARG2_MAX		_CDR_MAX(_Farg)
#define _FARG0_FARG1_MAX		_LIST_MAX(_Farg)

#define _A1_A2_MAX				_CDR_MAX(_Ax)
#define _A1_A2_MOV_MAX			_CDR2_CALL_MAX(_Arg, _Ax, move)
#define _A0_A1_MAX				_LIST_MAX(_Ax)
#define _F1_F2_MAX				_CDR_MAX(_Fx)
#define _F1_F2_FWD_MAX			_CDR2_CALL_MAX(_Farg, _Fx, forward)

#define _NIL_TAIL_MAXm1			_TAIL_1(_Nil)
#define _NIL_TAIL_MAX			_TAIL_0(_Nil)
#define _NIL_TAIL_REFREF_MAX	_TAIL_0(_Nil &&)
#define _TAIL_MAX(x)			_TAIL_0(x)
#define _CLASS_ARG0_DEF_MAX		_LIST15_MAX(class _Arg, = _Nil)

_STD_BEGIN		// C++ standard library
	// TEMPLATE CLASS unary_function
template<class _T1,
	class _Ret>
	struct unary_function;

	// TEMPLATE CLASS binary_function
template<class _T1,
	class _T2,
	class _Ret>
	struct binary_function;

	namespace tr1 {	// TR1 additions
	// STRUCT _Nil
struct _Nil
	{	// empty struct, for unused argument types
	};
static _Nil _Nil_obj;

	// TEMPLATE CLASS integral_constant
template<class _Ty,
	_Ty _Val>
	struct integral_constant
	{	// convenient template for integral constant types
	static const _Ty value = _Val;

	typedef _Ty value_type;
	typedef integral_constant<_Ty, _Val> type;
	};

typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;

	// TEMPLATE CLASS _Or
template<bool _First,
	bool _Second>
	struct _Or;
template<>
	struct _Or<false, false>
		: false_type
		{	// define as false
		};

template<>
	struct _Or<false, true>
		: true_type
		{	// define as true
		};

template<>
	struct _Or<true, false>
		: true_type
		{	// define as true
		};

template<>
	struct _Or<true, true>
		: true_type
		{	// define as true
		};

	// TEMPLATE _Cat_base
template<bool>
	struct _Cat_base;
template<>
	struct _Cat_base<false>
	: false_type
	{	// base class for type predicates
	};

template<>
	struct _Cat_base<true>
	: true_type
	{	// base class for type predicates
	};

	// TEMPLATE CLASS _Is_integral
template<class _Ty>
	struct _Is_integral
		: false_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<bool>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<char>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<unsigned char>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<signed char>
		: true_type
	{	// determine whether _Ty is integral
	};

 #ifdef _NATIVE_WCHAR_T_DEFINED
template<>
	struct _Is_integral<wchar_t>
		: true_type
	{	// determine whether _Ty is integral
	};
 #endif /* _NATIVE_WCHAR_T_DEFINED */

template<>
	struct _Is_integral<unsigned short>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<signed short>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<unsigned int>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<signed int>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<unsigned long>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<signed long>
		: true_type
	{	// determine whether _Ty is integral
	};

 #ifdef _LONGLONG
template<>
	struct _Is_integral<_LONGLONG>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<_ULONGLONG>
		: true_type
	{	// determine whether _Ty is integral
	};
 #endif /* _LONGLONG */

	// TEMPLATE CLASS _Is_floating_point
template<class _Ty>
	struct _Is_floating_point
		: false_type
	{	// determine whether _Ty is floating point
	};

template<>
	struct _Is_floating_point<float>
		: true_type
	{	// determine whether _Ty is floating point
	};

template<>
	struct _Is_floating_point<double>
		: true_type
	{	// determine whether _Ty is floating point
	};

template<>
	struct _Is_floating_point<long double>
		: true_type
	{	// determine whether _Ty is floating point
	};

	// TEMPLATE _Remove_reference
template<class _Ty>
	struct _Remove_reference
	{	// remove reference
	typedef _Ty _Type;
	};

template<class _Ty>
	struct _Remove_reference<_Ty&>
	{	// remove reference
	typedef _Ty _Type;
	};

template<class _Ty>
	struct _Remove_reference<_Ty&&>
	{	// remove rvalue reference
	typedef _Ty _Type;
	};

	// TEMPLATE _Remove_rvalue_reference
template<class _Ty>
	struct _Remove_rvalue_reference
	{	// remove rvalue reference
	typedef _Ty _Type;
	};

template<class _Ty>
	struct _Remove_rvalue_reference<_Ty&&>
	{	// remove rvalue reference
	typedef _Ty _Type;
	};

	// TEMPLATE STRUCT _Copy_cv
template<class _Tgt,
	class _Src>
	struct _Copy_cv
	{	// plain version
	typedef typename _Remove_reference<_Tgt>::_Type _Tgtx;
	typedef _Tgtx& _Type;
	};

template<class _Tgt,
	class _Src>
	struct _Copy_cv<_Tgt, const _Src>
	{	// const version
	typedef typename _Remove_reference<_Tgt>::_Type _Tgtx;
	typedef const _Tgtx& _Type;
	};

template<class _Tgt,
	class _Src>
	struct _Copy_cv<_Tgt, volatile _Src>
	{	// volatile version
	typedef typename _Remove_reference<_Tgt>::_Type _Tgtx;
	typedef volatile _Tgtx& _Type;
	};

template<class _Tgt,
	class _Src>
	struct _Copy_cv<_Tgt, const volatile _Src>
	{	// const volatile version
	typedef typename _Remove_reference<_Tgt>::_Type _Tgtx;
	typedef const volatile _Tgtx& _Type;
	};

template<class _Tgt,
	class _Src>
	struct _Copy_cv<_Tgt, _Src&>
	{	// remove reference from second argument
	typedef typename _Copy_cv<_Tgt, _Src>::_Type _Type;
	};

	// MACRO _IS_YES
 #ifndef _IS_YES
  #define _IS_YES(ty)	(sizeof (ty) == sizeof (_STD tr1::_Yes))

typedef char (&_No)[1];
typedef char (&_Yes)[2];
 #endif /* _IS_YES */

	// FUNCTION _Has_result_type
_No _Has_result_type(...);

template<class _Ty>
	_Yes _Has_result_type(_Ty *,
		typename _Remove_reference<typename _Ty::result_type>::_Type * = 0);

#define _HAS_RESULT_TYPE(_Ty)	\
	_IS_YES(_STD tr1::_Has_result_type((_Ty *)0))
	}	// namespace tr1
_STD_END
 #pragma warning(pop)
 #pragma pack(pop)

#endif /* RC_INVOKED */
#endif /* _TR1_COMMON_ */

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