// xrefwrap internal header
#pragma once
#ifndef _XREFWRAP_
#define _XREFWRAP_
#ifndef RC_INVOKED
#include <xtr1common>

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

 #pragma warning(disable: 4180)

_STD_BEGIN
 namespace tr1 {	// TR1 additions
// IMPLEMENT _STD tr1::result_of

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

 #define _INCL_FILE_xxresult
 #include <xfwrap>

	// TEMPLATE STRUCT result_of
template<class _Fty>
	struct result_of
	{	// template to determine result of call operation
	typedef typename _Result_of<_Fty>::_Type type;
	};

// 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(const volatile _Arg0*, _Pmd _Pm, _Farg0 _F0)
		{	// apply to object
		return ((_Ret)(_F0.*_Pm));
		}

	template<class _Pmd,
		class _Farg0>
		static _Ret _Call_pmd(const volatile void *, _Pmd _Pm, _Farg0 _F0)
		{	// apply to smart pointer of type _Farg0
		return ((*_F0).*_Pm);
		}

	template<class _Pmd,
		class _Farg0>
		static _Ret _Apply_pmd(_Pmd _Pm, _Farg0& _F0)
		{	// apply to object
		return (_Call_pmd<_Pmd, _Farg0&>(&_F0, _Pm, _F0));
		}
	};

	// 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(_Ty& _Val)
		: _Object(_Val)
		{	// construct
		}

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

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

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(&_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 = &_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(_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(), _A0));
		}
	};

	// TEMPLATE STRUCT _Callable_obj
template<class _Ty,
	bool _Indirect = false>
	struct _Callable_obj
		: _Callable_base<_Ty, _Indirect>
	{	// wrap function object
	_Callable_obj(_Ty& _Val)
		: _Callable_base<_Ty, _Indirect>(_Val)
		{	// construct
		}

 #define _INCL_FILE_xxcallobj
 #include <xfwrap>
	};

	// TEMPLATE STRUCT _Pmf_caller

 #define _INCL_FILE_xxpmfcaller
 #include <xfwrap>

	// 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(_Ty& _Val)
		: _Callable_base<_Ty, _Indirect>(_Val)
		{	// construct
		}

 #define _INCL_FILE_xxcallpmf
 #include <xfwrap>
	};

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

 #define _INCL_FILE_xxcallfun
 #include <xfwrap>
	};

	// 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>
	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
		}

 #define _INCL_FILE_xxcallwrap
 #include <xawrap>
	};

	// FUNCTION _Has_result_and_arg_type
template<class _Ty>
	_No _Has_result_and_arg_type(const volatile void *);

template<class _Ty>
	_Yes _Has_result_and_arg_type(_Ty *,
		typename _Ty::argument_type * = 0, typename _Ty::result_type * = 0);

#define _HAS_RESULT_AND_ARG_TYPE(_Ty) \
	_IS_YES(_STD tr1::_Has_result_and_arg_type<_Ty>((_Ty *)0))

	// FUNCTION _Has_result_and_2arg_type
template<class _Ty>
	_No _Has_result_and_2arg_type(const volatile void *);

template<class _Ty>
	_Yes _Has_result_and_2arg_type(_Ty *,
		typename _Ty::first_argument_type * = 0,
		typename _Ty::second_argument_type * = 0,
		typename _Ty::result_type * = 0);

#define _HAS_RESULT_AND_2ARG_TYPE(_Ty) \
	_IS_YES(_STD tr1::_Has_result_and_2arg_type<_Ty>((_Ty *)0))

	// FUNCTION _Has_unary_base
template<class _T1,
	class _Ret>
	_No _Has_unary_base(const volatile void *);

template<class _T1,
	class _Ret>
	_Yes _Has_unary_base(const volatile unary_function<_T1, _Ret> *);

#define _HAS_UNARY_BASE(_Ty) \
	_IS_YES((_Has_unary_base<typename _Ty::argument_type, \
		typename _Ty::result_type>((_Ty *)0)))

	// FUNCTION _Has_binary_base
template<class _T1,
	class _T2,
	class _Ret>
	_No _Has_binary_base(const volatile void *);

template<class _T1,
	class _T2,
	class _Ret>
	_Yes _Has_binary_base(const volatile binary_function<_T1, _T2, _Ret> *);

#define _HAS_BINARY_BASE(_Ty) \
	_IS_YES((_Has_binary_base<typename _Ty::first_argument_type, \
		typename _Ty::second_argument_type, \
			typename _Ty::result_type>((_Ty *)0)))

	// 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)>
	{	// 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)>
	{	// select base for type without typedefs for result and one argument
	};

template<class _Ty>
	struct _Refwrap_result1<_Ty, true>
		: _Refwrap_result1_helper<_Ty, _HAS_UNARY_BASE(_Ty)>
	{	// 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)>
	{	// 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)>
	{	// 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)>
	{	// select base for type without typedefs for result and two arguments
	};

template<class _Ty>
	struct _Refwrap_result2<_Ty, true>
		: _Refwrap_result2_helper<_Ty, _HAS_BINARY_BASE(_Ty)>
	{	// 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> >,
			_Refwrap_result2<_Ty, _HAS_RESULT_AND_2ARG_TYPE(_Ty)>
	{	// reference_wrapper implementation for UDT
	_Refwrap_impl(_Ty& _Val)
		: _Call_wrapper<_Callable_obj<_Ty, true> >(_Val)
		{	// construct
		}
	};

template<class _Rx,
	class _Arg0>
	struct _Refwrap_impl<_Rx _Arg0::*>
		: _Call_wrapper<_Callable_pmd<_Rx _Arg0::*const, _Arg0, false> >
	{	// reference_wrapper implementation for 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 _Rx,
	class _Arg0>
	struct _Refwrap_impl<_Rx _Arg0::*const>
		: _Call_wrapper<_Callable_pmd<_Rx _Arg0::*, _Arg0, false> >
	{	// reference_wrapper implementation for const 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 _Refwrap_impl

 #define _INCL_FILE_xxrefwrap
 #include <xfwrap>

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

	reference_wrapper(_Ty& _Val)
		: _MyBase(_Val)
		{	// construct
		}

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

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

	// TEMPLATE FUNCTIONS ref AND cref
template<class _Ty>
	reference_wrapper<_Ty> ref(_Ty& _Val)
	{	// create reference_wrapper<_Ty> object
	return (reference_wrapper<_Ty>(_Val));
	}

template<class _Ty>
	void ref(const _Ty&& _Val);	// not defined

template<class _Ty>
	reference_wrapper<_Ty> ref(reference_wrapper<_Ty> _Val)
	{	// create reference_wrapper<_Ty> object
	return (_Val);
	}

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

//template<class _Ty>
//	void cref(const _Ty&& _Val);	// not defined

template<class _Ty>
	reference_wrapper<const _Ty> cref(reference_wrapper<const _Ty> _Val)
	{	// create reference_wrapper<const _Ty> object
	return (_Val);
	}
	}	// namespace tr1
_STD_END

 #pragma warning(pop)
 #pragma pack(pop)

#endif /* RC_INVOKED */
#endif /* _XREFWRAP_ */

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