// xrefwrap internal header
#pragma once
#ifndef _XREFWRAP_
#define _XREFWRAP_
#ifndef RC_INVOKED

// NOTE: included only at the end of type_traits

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)
 #pragma push_macro("new")
 #undef new

 #pragma warning(disable: 4180)

_STD_BEGIN
template<class _Ty>
	class reference_wrapper;

	// TEMPLATE CLASS _Fun_class_base
template<class _Ret,
	class... _Types>
	struct _Fun_class_base
	{	// base if no arguments
	};

template<class _Ret,
	class _Farg0>
	struct _Fun_class_base<_Ret, _Farg0>
		: public unary_function<_Farg0, _Ret>
	{	// base if one argument
	};

template<class _Ret,
	class _Farg0,
	class _Farg1>
	struct _Fun_class_base<_Ret, _Farg0, _Farg1>
		: public binary_function<_Farg0, _Farg1, _Ret>
	{	// base if two arguments
	};

template<class _Ret,
	class _Farg0,
	class _Farg1,
	class... _Types>
	struct _Fun_class_base<_Ret, _Farg0, _Farg1, _Types...>
	{	// base if more than two arguments
	};


// IMPLEMENT result_of

template<class _Fty,
	class... _Args>
	struct _Result_of
	{	// template to determine result of call operation
	typedef decltype(
		_STD declval<_Fty>()(_STD declval<_Args>()...)) type;
	};

#define _RESULT_OF_PMF(CALL_OPT, CONST_OPT, CV_OPT) \
template<class _Ret, \
	class _Ty, \
	class... _Mfargs, \
	class _Obj, \
	class... _Args> \
	struct _Result_of<_Ret (CALL_OPT _Ty::* CONST_OPT)(_Mfargs...) CV_OPT, \
		_Obj, _Args...> \
	{	/* template to determine result of call operation */ \
		/* on pointer to member function */ \
	typedef _Ret type; \
	};

_MEMBER_CALL_CONST_CV(_RESULT_OF_PMF)
#undef _RESULT_OF_PMF

template<class _Ret,
	class _Ty,
	class _Obj,
	class... _Args>
	struct _Result_of<_Ret _Ty::*, _Obj, _Args...>
	{	// template to determine result of call operation
		// on pointer to member data
	typedef typename _Copy_cv<_Ret,
		typename remove_pointer<
			typename remove_reference<_Obj>::type>::type>::type type;
	};

template<class _Ret,
	class _Ty,
	class _Obj,
	class... _Args>
	struct _Result_of<_Ret _Ty::*const, _Obj, _Args...>
	{	// template to determine result of call operation
		// on pointer to member data
	typedef typename _Copy_cv<_Ret,
		typename remove_pointer<
			typename remove_reference<_Obj>::type>::type>::type const type;
	};

template<class _Fty>
	struct result_of;	// not defined

#define _RESULT_OF(CALL_OPT, X1) \
template<class _Fty, \
	class... _Args> \
	struct result_of<_Fty CALL_OPT (_Args...)> \
	{	/* template to determine result of call operation */ \
	typedef typename _Result_of<_Fty, _Args...>::type type; \
	}; \
template<class _Fty, \
	class... _Args> \
	struct result_of<reference_wrapper<_Fty> CALL_OPT (_Args...)> \
	{	/* template to determine result of call operation */ \
	typedef typename _Result_of<_Fty, _Args...>::type type; \
	};

_NON_MEMBER_CALL(_RESULT_OF, )
#undef _RESULT_OF


// SUPPORT CLASSES FOR CALL WRAPPERS

	// TEMPLATE STRUCT _Pmd_caller
template<class _Ret,
	class _Arg0>
	struct _Pmd_caller
	{	// bind object and pointer to member data
	template<class _Pmd,
		class _Farg0>
		static _Ret& _Call_pmd(_Pmd _Pm, _Farg0&& _Fx0, true_type)
		{	// apply to object
		return ((_Ret&)(_Fx0.*_Pm));
		}

	template<class _Pmd,
		class _Farg0>
		static _Ret& _Call_pmd(_Pmd _Pm, _Farg0&& _Fx0, false_type)
		{	// apply to (possibly smart) pointer
		return ((_Ret&)((*_Fx0).*_Pm));
		}

	template<class _Pmd,
		class _Farg0>
		static _Ret& _Apply_pmd(_Pmd _Pm, _Farg0&& _Fx0)
		{	// apply to object
		typedef typename remove_cv<
			typename remove_reference<_Arg0>::type>::type _Arg0_bare;
		typedef typename remove_cv<
			typename remove_reference<_Farg0>::type>::type _Farg0_bare;
		typedef _Cat_base<is_same<_Arg0_bare, _Farg0_bare>::value
			|| (is_base_of<_Arg0_bare, _Farg0_bare>::value
				&& is_same<typename add_reference<_Farg0_bare>::type,
					_Farg0>::value)> _Is_obj;

		return (_Call_pmd<_Pmd, _Farg0>(_Pm,
			_STD forward<_Farg0>(_Fx0), _Is_obj()));
		}
	};

	// TEMPLATE STRUCT _Callable_base
template<class _Ty,
	bool _Indirect>
	struct _Callable_base;

template<class _Ty>
	struct _Callable_base<_Ty, false>
	{	// base types for callable object wrappers
	enum {_EEN_INDIRECT = 0};	// helper for expression evaluator
	typedef _Ty _MyTy;
	typedef const _Ty& _MyCnstTy;

	_Callable_base(const _Ty& _Val)
		: _Object(_Val)
		{	// construct from value
		}

	const _Ty& _Get() const
		{	// return reference to stored object
		return (_Object);
		}

	_Ty& _Get()
		{	// return reference to stored object
		return (_Object);
		}

	void _Reset(_Ty& _Val)
		{	// reseat reference (disallowed)
		static_assert(_Always_false<_Ty>::value,
			"can't assign to reference_wrapper<T&>");
		}

private:
	_Callable_base& operator=(const _Callable_base&);

	_Ty _Object;
};

template<class _Ty>
	struct _Callable_base<_Ty, true>
	{	// base types for callable object wrappers holding references
		// (used by reference_wrapper)
	enum {_EEN_INDIRECT = 1};	// helper for expression evaluator
	typedef _Ty _MyTy;
	typedef _Ty& _MyCnstTy;

	_Callable_base(_Ty& _Val)
		: _Ptr(_STD addressof(_Val))
		{	// construct
		}

	_MyCnstTy _Get() const
		{	// return reference to stored object
		return (*_Ptr);
		}

	_Ty& _Get()
		{	// return reference to stored object
		return (*_Ptr);
		}

	void _Reset(_Ty& _Val)
		{	// reseat reference
		_Ptr = _STD addressof(_Val);
		}

private:
	_Ty *_Ptr;
};

	// TEMPLATE STRUCT _Callable_pmd
template<class _Ty,
	class _Memty,
	bool _Indirect = false>
	struct _Callable_pmd
		: _Callable_base<_Ty, _Indirect>
	{	// wrap pointer to member data
	_Callable_pmd(const _Callable_pmd& _Right)
		: _Callable_base<_Ty, _Indirect>(_Right._Get())
		{	// construct
		}

	_Callable_pmd(_Ty& _Val)
		: _Callable_base<_Ty, _Indirect>(_Val)
		{	// construct
		}

	template<class _Ret,
		class _Arg0>
		_Ret& _ApplyX(_Arg0&& _A0) const
		{	// apply
		return (_Pmd_caller<_Ret, _Memty>::
			_Apply_pmd(this->_Get(), _STD forward<_Arg0>(_A0)));
		}
	};

	// TEMPLATE STRUCT _Callable_obj
template<class _Ty,
	bool _Indirect = false>
	struct _Callable_obj
		: _Callable_base<_Ty, _Indirect>
	{	// wrap function object
	typedef _Callable_base<_Ty, _Indirect> _Mybase;

	template<class _Ty2>
		_Callable_obj(_Ty2&& _Val)
		: _Mybase(_STD forward<_Ty2>(_Val))
		{	// construct
		}

	template<class _Ret,
		class... _Types>
		_Ret _ApplyX(_Types&&... _Args) const
		{ // apply to UDT object
		return (this->_Get()(_STD forward<_Types>(_Args)...));
		}

	template<class _Ret,
		class... _Types>
		_Ret _ApplyX(_Types&&... _Args)
		{ // apply to UDT object
		return (this->_Get()(_STD forward<_Types>(_Args)...));
		}

	};

	// TEMPLATE STRUCT _Pmf_caller

template<class _Ret,
	class _Arg0>
	struct _Pmf_caller
	{	// bind object and pointer to member function
	template<class _Pmf,
		class _Farg0,
		class... _Ftypes>
		static _Ret _Call_pmf(_Pmf _Pm, _Farg0&& _Fx0, true_type,
			_Ftypes&&... _Fargs)
		{	// apply to object
		typedef typename _Copy_cv<_Arg0, _Farg0>::type
			_Funobj_cv;
		return (((_Funobj_cv)_Fx0.*_Pm)(_STD forward<_Ftypes>(_Fargs)...));
		}

	template<class _Pmf,
		class _Farg0,
		class... _Ftypes>
		static _Ret _Call_pmf(_Pmf _Pm, _Farg0&& _Fx0, false_type,
			_Ftypes&&... _Fargs)
		{	// apply to (possibly smart) pointer
		return (((*_Fx0).*_Pm)(_STD forward<_Ftypes>(_Fargs)...));
		}

	template<class _Pmf,
		class _Farg0,
		class... _Ftypes>
		static _Ret _Apply_pmf(_Pmf _Pm, _Farg0&& _Fx0,
			_Ftypes&&... _Fargs)
		{	// apply to object
		typedef typename remove_reference<_Arg0>::type _Arg0_bare0;
		typedef typename remove_cv<_Arg0_bare0>::type _Arg0_bare;
		typedef typename remove_reference<_Farg0>::type _Farg0_bare;
		typedef _Cat_base<is_same<_Arg0_bare, _Farg0_bare>::value
			|| (is_base_of<_Arg0_bare, _Farg0_bare>::value
				&& is_same<typename add_reference<_Farg0_bare>::type,
					_Farg0>::value)> _Is_obj;

		return (_Call_pmf<_Pmf, _Farg0&&, _Ftypes&&...>(_Pm,
			_STD forward<_Farg0>(_Fx0), _Is_obj(),
				_STD forward<_Ftypes>(_Fargs)...));
		}
	};


	// TEMPLATE STRUCT _Callable_pmf
template<class _Ty,
	class _Memty,
	bool _Indirect = false>
	struct _Callable_pmf
		: _Callable_base<_Ty, _Indirect>
	{	// wrap pointer to member function
	_Callable_pmf(const _Callable_pmf& _Right)
		: _Callable_base<_Ty, _Indirect>(_Right._Get())
		{	// construct
		}

	_Callable_pmf(_Ty& _Val)
		: _Callable_base<_Ty, _Indirect>(_Val)
		{	// construct
		}

	template<class _Ret,
		class... _Types>
		_Ret _ApplyX(_Types&&... _Args) const
		{ // call pointer to member function
		return (_Pmf_caller<_Ret, _Memty>::
			_Apply_pmf(this->_Get(), _STD forward<_Types>(_Args)...));
		}

	};

	// TEMPLATE STRUCT _Callable_fun
template<class _Ty,
	bool _Indirect = false>
	struct _Callable_fun
		: _Callable_base<_Ty, _Indirect>
	{	// wrap pointer to function
	_Callable_fun(const _Callable_fun& _Right)
		: _Callable_base<_Ty, _Indirect>(_Right._Get())
		{	// construct
		}

	_Callable_fun(_Ty& _Val)
		: _Callable_base<_Ty, _Indirect>(_Val)
		{	// construct
		}

	template<class _Ret,
		class... _Types>
		_Ret _ApplyX(_Types&&... _Args) const
		{ // call pointer to function
		return (this->_Get()(_STD forward<_Types>(_Args)...));
		}

	};

	// TEMPLATE STRUCT _Call_wrapper_base
template<class _Callable>
	struct _Call_wrapper_base
	{	// wrap callable object
	typedef typename _Callable::_MyTy _MyTy;
	typedef typename _Callable::_MyCnstTy _MyCnstTy;

	_Call_wrapper_base(_MyTy& _Val)
		: _Callee(_Val)
		{	// construct
		}

	void _Reset(_MyTy& _Val)
		{	// reset
		_Callee._Reset(_Val);
		}

	_MyCnstTy _Get() const
		{	// get
		return (_Callee._Get());
		}

	_MyCnstTy _Get()
		{	// get
		return (_Callee._Get());
		}

	_Callable _Callee;
	};

	// TEMPLATE STRUCT _Call_wrapper
template<class _Callable,
	bool _Is_abstract = false>
	struct _Call_wrapper
	: _Call_wrapper_base<_Callable>
	{	// wrap callable object
	typedef _Call_wrapper_base<_Callable> _Mybase;

	_Call_wrapper(typename _Call_wrapper_base<_Callable>::_MyTy& _Val)
		: _Call_wrapper_base<_Callable>(_Val)
		{	// construct
		}

	template<class... _Types>
		typename result_of<
			typename _Callable::_MyTy(_Types...)>::type
			operator()(_Types&&... _Args) const
		{ // call target object
		typedef typename result_of<
			typename _Callable::_MyTy(_Types...)>::type _Ret;
		return (this->_Callee.template _ApplyX<_Ret>(
			_STD forward<_Types>(_Args)...));
		}

	};

template<class _Callable>
	struct _Call_wrapper<_Callable, true>
	: _Call_wrapper_base<_Callable>
	{	// wrap abstract callable object
	typedef _Call_wrapper_base<_Callable> _Mybase;

	_Call_wrapper(typename _Call_wrapper_base<_Callable>::_MyTy& _Val)
		: _Call_wrapper_base<_Callable>(_Val)
		{	// construct
		}
	};

		// TEMPLATE STRUCT _Has_result_and_arg_type
template<class _Ty>
	struct _Has_result_and_arg_type
		_HAS_TYPES(argument_type, result_type, result_type);

		// TEMPLATE STRUCT _Has_result_and_2arg_type
template<class _Ty>
	struct _Has_result_and_2arg_type
		_HAS_TYPES(first_argument_type, second_argument_type, result_type);

	// TEMPLATE CLASS _Refwrap_result0
template<class _Ty,
	bool>
	struct _Refwrap_result0
	{	// define result_type when target object defines it
	typedef typename _Ty::result_type result_type;
	};

template<class _Ty>
	struct _Refwrap_result0<_Ty, false>
	{	// no result_type when not defined by target object
	};

// TEMPLATE CLASS _Refwrap_result1_helper
template<class _Ty,
	bool>
	struct _Refwrap_result1_helper
		: _Refwrap_result0<_Ty, _Has_result_type<_Ty>::type::value>
	{	// select _Refwrap_result0 specialization
	};

template<class _Ty>
	struct _Refwrap_result1_helper<_Ty, true>
		: unary_function<typename _Ty::argument_type,
			typename _Ty::result_type>
	{	// derive from unary_function
	};

	// TEMPLATE CLASS _Refwrap_result1
template<class _Ty,
	bool>
	struct _Refwrap_result1
		: _Refwrap_result0<_Ty, _Has_result_type<_Ty>::type::value>
	{	// select base for type without typedefs for result and one argument
	};

template<class _Ty>
	struct _Refwrap_result1<_Ty, true>
		: _Refwrap_result1_helper<_Ty,
			is_base_of<unary_function<
				typename _Ty::argument_type,
				typename _Ty::result_type>, _Ty>::value>
	{	// select base for type with typedefs for result and one argument
	};

	// TEMPLATE CLASS _Refwrap_result2_helper
template<class _Ty,
	bool>
	struct _Refwrap_result2_helper
		: _Refwrap_result1<_Ty, _Has_result_and_arg_type<_Ty>::type::value>
	{	// select base
	};

template<class _Ty>
	struct _Refwrap_result2_helper<_Ty, true>
		: binary_function<typename _Ty::first_argument_type,
			typename _Ty::second_argument_type,
			typename _Ty::result_type>,
		_Refwrap_result1<_Ty, _Has_result_and_arg_type<_Ty>::type::value>
	{	// base for type derived from binary_function
	};

	// TEMPLATE CLASS _Refwrap_result2
template<class _Ty,
	bool>
	struct _Refwrap_result2
		: _Refwrap_result1<_Ty, _Has_result_and_arg_type<_Ty>::type::value>
	{	// select base for type without typedefs for result and two arguments
	};

template<class _Ty>
	struct _Refwrap_result2<_Ty, true>
		: _Refwrap_result2_helper<_Ty,
			is_base_of<binary_function<
				typename _Ty::first_argument_type,
				typename _Ty::second_argument_type,
				typename _Ty::result_type>, _Ty>::value>
	{	// select base for type with typedefs for result and two arguments
	};

	// TEMPLATE CLASS _Refwrap_impl
template<class _Ty>
	struct _Refwrap_impl
		: _Call_wrapper<_Callable_obj<_Ty, true>,
			is_abstract<_Ty>::value>,
			_Refwrap_result2<_Ty, _Has_result_and_2arg_type<_Ty>::type::value>
	{	// reference_wrapper implementation for UDT
	_Refwrap_impl(_Ty& _Val)
		: _Call_wrapper<_Callable_obj<_Ty, true>,
			is_abstract<_Ty>::value>(_Val)
		{	// construct
		}
	};

template<class _Rx,
	class _Arg0>
	struct _Refwrap_impl<_Rx _Arg0::*>
		: _Call_wrapper<_Callable_pmd<_Rx _Arg0::*, _Arg0, false> >
	{	// reference_wrapper implementation for pointer to member data
	typedef _Rx _Arg0::* _Fty;
	typedef _Rx result_type;

	_Refwrap_impl(_Fty& _Val)
		: _Call_wrapper<_Callable_pmd<_Fty, _Arg0, false> >(_Val)
		{	// construct
		}
	};

template<class _Rx,
	class _Arg0>
	struct _Refwrap_impl<_Rx _Arg0::*const>
		: _Call_wrapper<_Callable_pmd<_Rx _Arg0::*const, _Arg0, false> >
	{	// reference_wrapper implementation for const pointer to member data
	typedef _Rx _Arg0::*const _Fty;
	typedef _Rx result_type;
	_Refwrap_impl(_Fty& _Val)
		: _Call_wrapper<_Callable_pmd<_Fty, _Arg0, false> >(_Val)
		{	// construct
		}
	};

	// TEMPLATE CLASS _Refwrap_impl FOR FUNCTIONS
#define _REFWRAP_IMPL_FUN(CALL_OPT, X1) \
template<class _Rx, \
	class... _Types> \
	struct _Refwrap_impl<_Rx CALL_OPT (_Types...)> \
		: _Call_wrapper<_Callable_fun< \
				_Rx(CALL_OPT *)(_Types...), false> >, \
			_Fun_class_base<_Rx, _Types...> \
	{	/* implement for function */ \
	typedef _Rx(CALL_OPT *_Fty)(_Types...); \
	typedef _Rx result_type; \
	_Refwrap_impl(_Fty _Val) \
		: _Call_wrapper<_Callable_fun<_Fty, false> >(_Val) \
		{	/* construct */ \
		} \
	};

_NON_MEMBER_CALL(_REFWRAP_IMPL_FUN, )
#undef _REFWRAP_IMPL_FUN

	// TEMPLATE CLASS _Refwrap_impl FOR POINTERS TO FUNCTIONS
#define _REFWRAP_IMPL_PF(CALL_OPT, CONST_OPT) \
template<class _Rx, \
	class... _Types> \
	struct _Refwrap_impl<_Rx(CALL_OPT *CONST_OPT)(_Types...)> \
		: _Call_wrapper<_Callable_fun< \
				_Rx(CALL_OPT *CONST_OPT)(_Types...), true> >, \
			_Fun_class_base<_Rx, _Types...> \
	{	/* implement for CONST_OPT pointer to function */ \
	typedef _Rx(CALL_OPT *CONST_OPT _Fty)(_Types...); \
	typedef _Rx result_type; \
	_Refwrap_impl(_Fty& _Val) \
		: _Call_wrapper<_Callable_fun<_Fty, true> >(_Val) \
		{	/* construct */ \
		} \
	};

_NON_MEMBER_CALL_CONST(_REFWRAP_IMPL_PF)
#undef _REFWRAP_IMPL_PF

	// TEMPLATE CLASS _Refwrap_impl FOR POINTERS TO MEMBER FUNCTIONS
#define _REFWRAP_IMPL_PMF(CALL_OPT, CONST_OPT, CV_OPT) \
template<class _Rx, \
	class _Arg0, \
	class... _Types> \
	struct _Refwrap_impl<_Rx(CALL_OPT _Arg0::* CONST_OPT)(_Types...) CV_OPT> \
		: _Call_wrapper<_Callable_pmf< \
			_Rx(CALL_OPT _Arg0::* CONST_OPT)(_Types...) CV_OPT, \
				_Arg0, true> >, \
			_Fun_class_base<_Rx, CV_OPT _Arg0 *, _Types...> \
	{	/* implement for pointer to member function */ \
	typedef _Rx(CALL_OPT _Arg0::* CONST_OPT _Fty)(_Types...) CV_OPT; \
	typedef _Rx result_type; \
	_Refwrap_impl(_Fty& _Val) \
		: _Call_wrapper<_Callable_pmf<_Fty, _Arg0, true> >(_Val) \
		{	/* construct */ \
		} \
	};

_MEMBER_CALL_CONST_CV(_REFWRAP_IMPL_PMF)
#undef _REFWRAP_IMPL_PMF


	// TEMPLATE CLASS reference_wrapper
template<class _Ty>
	class reference_wrapper
	: public _Refwrap_impl<_Ty>
	{	// stand-in for an assignable reference
public:
	typedef reference_wrapper<_Ty> _Myt;
	typedef _Refwrap_impl<_Ty> _Mybase;
	typedef _Ty type;

	reference_wrapper(_Ty& _Val) _NOEXCEPT
		: _Mybase(_Val)
		{	// construct
		}

	reference_wrapper(const _Myt& _Right) _NOEXCEPT
		: _Mybase(_Right.get())
		{	// construct by copying _Right
		}

	_Myt& operator=(const _Myt& _Right) _NOEXCEPT
		{	// assign _Right
		this->_Reset(_Right.get());
		return (*this);
		}

	operator _Ty&() const _NOEXCEPT
		{	// return reference
		return (this->_Get());
		}

	_Ty& get() const _NOEXCEPT
		{	// return reference
		return (this->_Get());
		}

	reference_wrapper(_Ty&&) = delete;
	};

	// TEMPLATE FUNCTIONS ref AND cref
template<class _Ty>
	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>
	reference_wrapper<_Ty>
		ref(reference_wrapper<_Ty> _Val) _NOEXCEPT
	{	// create reference_wrapper<_Ty> object
	return (_Val);
	}

template<class _Ty>
	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>
	reference_wrapper<const _Ty>
		cref(reference_wrapper<_Ty> _Val) _NOEXCEPT
	{	// create reference_wrapper<const _Ty> object
	return (reference_wrapper<const _Ty>(_Val.get()));
	}

namespace tr1 {	// TR1 additions
using _STD cref;
using _STD ref;
using _STD reference_wrapper;
using _STD result_of;
	}	// namespace tr1
_STD_END

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

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