// tuple TR1 header
#pragma once
#ifndef _TUPLE_
#define _TUPLE_
#ifndef RC_INVOKED
#include <type_traits>
#include <xutility>
#include <xrefwrap>

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

 #pragma warning(disable: 4522)

_STD_BEGIN
namespace tr1 {	// TR1 additions
	// TEMPLATE STRUCT _Arg_traits
template<class _Ty>
	struct _Arg_traits
	{	// template that transforms argument types
	typedef const _Ty& _CType;
	typedef _Ty& _RType;
	typedef const _Ty& _AType;
	typedef _Ty _VType;
	typedef _Ty _BType;
	};

template<class _Ty>
	struct _Arg_traits<_Ty&>
	{	// template specialization for arguments passed by reference
	typedef _Ty& _CType;
	typedef _Ty& _RType;
	typedef _Ty& _AType;
	typedef _Ty& _VType;
	typedef _Ty _BType;
	};

template<class _Ty>
	struct _Arg_traits<const reference_wrapper<_Ty>&>
	{	// template specialization for reference_wrapper arguments
	typedef const _Ty& _CType;
	typedef _Ty& _RType;
	typedef _Ty& _AType;
	typedef _Ty& _VType;
	typedef _Ty _BType;
	};

	// TEMPLATE FUNCTION _Assign

template<class _Tgt,
	class _Src> inline
	void _Assign(_Tgt& _Tx, _Src&& _Sx)
	{	// assign _Sx to _Tx
	_Tx = _STD forward<_Src>(_Sx);
	}

template<class _Tgt,
	class _Src> inline
	void _Assign(reference_wrapper<_Tgt> _Tx, _Src&& _Sx)
	{	// assign _Sx to _Tx.get()
	_Tx.get() = _STD forward<_Src>(_Sx);
	}

	// TEMPLATE STRUCT _Cons_node
template<class _Car,
	class _Cdr>
	struct _Cons_node
	{	// node for type list
	typedef typename _Arg_traits<_Car>::_VType _Value_type;
	typedef _Cdr _Tail_type;

	_Cons_node()
		: _Value(), _Tail()
		{	// construct
		}

	_Cons_node(const _Cons_node& _Right)
		: _Value(_Right._Value), _Tail(_Right._Tail)
		{	// construct
		}

	template<class _Car1,
		class _Cdr1>
		_Cons_node(const _Cons_node<_Car1, _Cdr1>& _Right)
			: _Value(_Right._Value), _Tail(_Right._Tail)
		{	// construct
		}

	template<_CLASS_FARG0_MAX>
		_Cons_node(_FARG0_F0_CREFIFY_MAX)
			: _Value(_Fx0), _Tail(_F1_F2_MAX, _Nil_obj)
		{	// construct
		}

	_Cons_node& operator=(const _Cons_node& _Right)
		{	// assign
		_Assign(_Value, _Right._Value);
		_Tail = _Right._Tail;
		return (*this);
		}

	template<class _Car1,
		class _Cdr1>
		_Cons_node& operator=(const _Cons_node<_Car1, _Cdr1>& _Right)
		{	// copy _Right to *this
		_Assign(_Value, _Right._Value);
		_Tail = _Right._Tail;
		return (*this);
		}

	void swap(_Cons_node& _Right)
		{	// swap elements
		_Swap_adl(_Value, _Right._Value);
		_Tail.swap(_Right._Tail);
		}

	_Cons_node(_Cons_node&& _Right)
		: _Value(_STD forward<_Value_type>(_Right._Value)),
			_Tail(_STD forward<_Tail_type>(_Right._Tail))
		{	// construct
		}

	template<_CLASS_FARG0_MAX>
		_Cons_node(_FARG0_F0_REFREF_MAX)
		: _Value(_STD forward<_Farg0>(_Fx0)),
			_Tail(_F1_F2_FWD_MAX, _Nil_obj)
		{	// construct
		}

	template<class _Car1,
		class _Cdr1>
		_Cons_node(_Cons_node<_Car1, _Cdr1>&& _Right)
			: _Value(_STD forward<typename _Cons_node<_Car1, _Cdr1>
				::_Value_type>(_Right._Value)),
				_Tail(_STD forward<typename _Cons_node<_Car1, _Cdr1>
					::_Tail_type>(_Right._Tail))
		{	// construct
		}

	template<class _Car1,
		class _Cdr1>
		_Cons_node& operator=(_Cons_node<_Car1, _Cdr1>&& _Right)
		{	// assign
		_Assign(_Value,
			_STD forward<typename _Cons_node<_Car1, _Cdr1>::_Value_type>
				(_Right._Value));
		_Tail =
			_STD forward<typename _Cons_node<_Car1, _Cdr1>::_Tail_type>
				(_Right._Tail);
		return (*this);
		}

	template<class _Car1,
		class _Cdr1>
		bool _Eq(const _Cons_node<_Car1, _Cdr1>& _Right) const
		{	// return true if *this == _Right
		return (_Value == _Right._Value
			&& _Tail._Eq(_Right._Tail));
		}

	template<class _Car1,
		class _Cdr1>
		bool _Lt(const _Cons_node<_Car1, _Cdr1>& _Right) const
		{	// return true if *this < _Right
		return (_Value < _Right._Value ? true
			: _Right._Value < _Value ? false
			: _Tail._Lt(_Right._Tail));
		}

	_Value_type _Value;
	_Tail_type _Tail;
	};

template<>
	struct _Cons_node<_Nil, _Nil>
	{	// node for end of list
	typedef _Nil _Value_type;
	typedef _Nil _Tail_type;

	_Cons_node()
		{	// construct
		}

	_Cons_node(const _Cons_node&)
		{	// construct
		}

	template<class _Car1,
		class _Cdr1>
		_Cons_node(const _Cons_node<_Car1, _Cdr1>&)
		{	// construct
		}

	_Cons_node(_NIL_TAIL_MAX)
		{	// construct
		}

	_Cons_node& operator=(const _Cons_node&)
		{	// assign
		return (*this);
		}

	template<class _Car1,
		class _Cdr1>
		_Cons_node& operator=(const _Cons_node<_Car1, _Cdr1>&)
		{	// assign
		return (*this);
		}

	void swap(_Cons_node&)
		{	// swap
		}

	_Cons_node(_Cons_node&&)
		{	// construct
		}

	template<class _Car1,
		class _Cdr1>
		_Cons_node(_Cons_node<_Car1, _Cdr1>&&)
		{	// construct
		}

	template<_CLASS_FARG0_MAX>
		_Cons_node(_FARG0_F0_REFREF_MAX)
		{	// construct
		}

	_Cons_node& operator=(_Cons_node&&)
		{	// assign
		return (*this);
		}

	template<class _Car1,
		class _Cdr1>
		_Cons_node& operator=(_Cons_node<_Car1, _Cdr1>&&)
		{	// assign
		return (*this);
		}

	bool _Eq(const _Cons_node&) const
		{	// compare
		return (true);
		}

	bool _Lt(const _Cons_node&) const
		{	// compare
		return (false);
		}

	_Value_type _Value;
	_Tail_type _Tail;
	};

	// TEMPLATE STRUCT _Get
template<size_t _Idx,
	class _Node>
	struct _Get
	{	// struct that determines type and value of element at _Idx
	typedef _Get<_Idx - 1, typename _Node::_Tail_type> _Get0;
	typedef typename _Get0::_Type _Type;

	static typename _Arg_traits<_Type>::_RType _Val(_Node& _Nx)
		{	// return value
		return (_Get0::_Val(_Nx._Tail));
		}

	static typename _Arg_traits<_Type>::_CType _Val(const _Node& _Nx)
		{	// return value
		return (_Get0::_Val(_Nx._Tail));
		}
	};

template<class _Ty>
	struct _Not_nil
	{	// defined only if _Ty is not _Nil
	};

template<>
	struct _Not_nil<_Nil>;

template<class _Node>
	struct _Get<0, _Node>
		: public _Not_nil<typename _Node::_Value_type>
	{	// struct that determines type and value of element at index 0
	typedef typename _Node::_Value_type _Type;

	static typename _Arg_traits<_Type>::_RType _Val(_Node& _Nx)
		{	// return value
		return (_Nx._Value);
		}

	static typename _Arg_traits<_Type>::_CType _Val(const _Node& _Nx)
		{	// return value
		return (_Nx._Value);
		}
	};

	// TEMPLATE STRUCT _Size
template<class _Node>
	struct _Size
	{	// struct that determines number of elements in type list
	static const size_t _Value =
		1 + _Size<typename _Node::_Tail_type>::_Value;
	};

template<>
	struct _Size<_Cons_node<_Nil, _Nil> >
	{	// struct that determines number of elements in empty type list
	static const size_t _Value = 0;
	};

	// TEMPLATE STRUCT _Tuple_type
template<class _Arg0,
	_CDR15_MAX(class _Arg, = _Nil)>
	struct _Tuple_type
	{	// struct to determine type for a tuple's implementation
	typedef _Cons_node<_Arg0,
		typename _Tuple_type<_ARG1_ARG2_MAX, _Nil>::_Type> _Type;
	};

template<>
	struct _Tuple_type<_NIL_TAIL_MAX>
	{	// struct to determine type for an empty tuple
	typedef _Cons_node<_Nil, _Nil> _Type;
	};

	// TEMPLATE STRUCT tuple
template<_CLASS_ARG0_DEF_MAX>
	class tuple
	{	// class that holds objects of various types
public:
	typedef tuple<_ARG0_ARG1_MAX> _Myt;
	typedef typename _Tuple_type<_ARG0_ARG1_MAX>::_Type _MyImpl;

	tuple()
		: _Impl()
		{	// construct
		}

	tuple(const _Myt& _Right)
		: _Impl(_Right._Impl)
		{	// construct copy of _Right
		}

	template<_CLASS_FARG0_MAX>
		tuple(const tuple<_FARG0_FARG1_MAX>& _Right)
		: _Impl(_Right._Impl)
		{	// construct copy of _Right
		}

	template<class _Farg0,
		class _Farg1>
		tuple(const pair<_Farg0, _Farg1>& _Right)
		: _Impl(_Right.first, _Right.second, _TAIL_2(_Nil_obj))
		{	// construct copy of _Right
		}

	// construct from one or more arguments
#define _INCL_FILE_xxtuple0
#include <xfwrap>

	tuple& operator=(const tuple& _Right)
		{	// copy from _Right
		_Impl = _Right._Impl;
		return (*this);
		}

	template<_CLASS_FARG0_MAX>
		tuple& operator=(const tuple<_FARG0_FARG1_MAX>& _Right)
		{	// copy from _Right
		_Impl = _Right._Impl;
		return (*this);
		}

	template<class _Farg0,
		class _Farg1>
		tuple& operator=(const pair<_Farg0, _Farg1>& _Right)
		{	// copy from _Right
		_Impl._Value = _Right.first;
		_Impl._Tail._Value = _Right.second;
		_Impl._Tail._Tail._Value = _Nil_obj;	// ensure size == 2
		return (*this);
		}

	template<_CLASS_FARG0_MAX>
		tuple(tuple<_FARG0_FARG1_MAX>& _Right)
		: _Impl(_Right._Impl)
		{	// copy _Right
		}

	template<_CLASS_FARG0_MAX>
		tuple(tuple<_FARG0_FARG1_MAX>&& _Right)
		: _Impl(_STD forward<typename tuple<_FARG0_FARG1_MAX>::_MyImpl>
			(_Right._Impl))
		{	// move _Right
		}

	template<class _Farg0,
		class _Farg1>
		tuple(pair<_Farg0, _Farg1>& _Right)
		: _Impl(_Right.first,
			_Right.second, _TAIL_2(_Nil_obj))
		{	// copy _Right
		}

	template<class _Farg0,
		class _Farg1>
		tuple(pair<_Farg0, _Farg1>&& _Right)
		: _Impl(_STD forward<_Farg0>(_Right.first),
			_STD forward<_Farg1>(_Right.second), _TAIL_2(_Nil_obj))
		{	// move _Right
		}

	tuple& operator=(tuple& _Right)
		{	// copy from _Right
		_Impl = _Right._Impl;
		return (*this);
		}

	tuple& operator=(tuple&& _Right)
		{	// copy from _Right
		_Impl = _STD forward<_MyImpl>(_Right._Impl);
		return (*this);
		}

	template<_CLASS_FARG0_MAX>
		tuple& operator=(tuple<_FARG0_FARG1_MAX>& _Right)
		{	// copy from _Right
		_Impl = _Right._Impl;
		return (*this);
		}

	template<_CLASS_FARG0_MAX>
		tuple& operator=(tuple<_FARG0_FARG1_MAX>&& _Right)
		{	// copy from _Right
		_Impl = _STD forward<typename tuple<_FARG0_FARG1_MAX>::_MyImpl>
			(_Right._Impl);
		return (*this);
		}

	template<class _Farg0,
		class _Farg1>
		tuple& operator=(pair<_Farg0, _Farg1>& _Right)
		{	// copy from _Right
		_Impl._Value = _Right.first;
		_Impl._Tail._Value = _Right.second;
		_Impl._Tail._Tail._Value = _Nil_obj;	// ensure size == 2
		return (*this);
		}

	template<class _Farg0,
		class _Farg1>
		tuple& operator=(pair<_Farg0, _Farg1>&& _Right)
		{	// copy from _Right
		_Impl._Value = _STD forward<_Farg0>(_Right.first);
		_Impl._Tail._Value = _STD forward<_Farg1>(_Right.second);
		_Impl._Tail._Tail._Value = _Nil_obj;	// ensure size == 2
		return (*this);
		}

	void swap(_Myt& _Right)
		{	// swap *this and _Right
		_Impl.swap(_Right._Impl);
		}

	template<_CLASS_FARG0_MAX>
		bool _Eq(const tuple<_FARG0_FARG1_MAX>& _Right) const
		{	// return true if *this == _Right
		return (_Impl._Eq(_Right._Impl));
		}

	template<_CLASS_FARG0_MAX>
		bool _Lt(const tuple<_FARG0_FARG1_MAX>& _Right) const
		{	// return true if *this < _Right
		return (_Impl._Lt(_Right._Impl));
		}

	_MyImpl _Impl;
	};

	// TEMPLATE FUNCTION swap
template<_CLASS_ARG0_MAX> inline
	void swap(
		tuple<_ARG0_ARG1_MAX>& _Left,
		tuple<_ARG0_ARG1_MAX>& _Right)
	{	// swap _Left and _Right
	_Left.swap(_Right);
	}

template<> inline
	void swap(tuple<>&, tuple<>&)
	{	// swap empty tuples
	}

	// TEMPLATE operator==
template<_CLASS_ARG0_MAX,
	_CLASS_FARG0_MAX> inline
	bool operator==(
	const tuple<_ARG0_ARG1_MAX>& _Left,
	const tuple<_FARG0_FARG1_MAX>& _Right)
	{	// return _Left == _Right
	return (_Left._Eq(_Right));
	}

template<> inline
	bool operator==(const tuple<>&, const tuple<>&)
	{	// return true for empty tuples
	return (true);
	}

	// TEMPLATE operator!=
template<_CLASS_ARG0_MAX,
	_CLASS_FARG0_MAX> inline
bool operator!=(
	const tuple<_ARG0_ARG1_MAX>& _Left,
	const tuple<_FARG0_FARG1_MAX>& _Right)
	{	// return _Left != _Right
	return (!_Left._Eq(_Right));
	}

template<> inline
	bool operator!=(const tuple<>&, const tuple<>&)
	{	// return false for empty tuples
	return (false);
	}

	// TEMPLATE operator<
template<_CLASS_ARG0_MAX,
	_CLASS_FARG0_MAX> inline
	bool operator<(
	const tuple<_ARG0_ARG1_MAX>& _Left,
	const tuple<_FARG0_FARG1_MAX>& _Right)
	{	// return _Left < _Right
	return (_Left._Lt(_Right));
	}

template<> inline
	bool operator<(const tuple<>&, const tuple<>&)
	{	// return false for empty tuples
	return (false);
	}

	// TEMPLATE operator<=
template<_CLASS_ARG0_MAX,
	_CLASS_FARG0_MAX> inline
	bool operator<=(
	const tuple<_ARG0_ARG1_MAX>& _Left,
	const tuple<_FARG0_FARG1_MAX>& _Right)
	{	// return _Left <= _Right
	return (!_Right._Lt(_Left));
	}

template<> inline
	bool operator<=(const tuple<>&, const tuple<>&)
	{	// return true for empty tuples
	return (true);
	}

	// TEMPLATE operator>
template<_CLASS_ARG0_MAX,
	_CLASS_FARG0_MAX> inline
	bool operator>(
	const tuple<_ARG0_ARG1_MAX>& _Left,
	const tuple<_FARG0_FARG1_MAX>& _Right)
	{	// return _Left > _Right
	return (_Right._Lt(_Left));
	}

template<> inline
	bool operator>(const tuple<>&, const tuple<>&)
	{	// return false for empty tuples
	return (false);
	}

	// TEMPLATE operator>=
template<_CLASS_ARG0_MAX,
	_CLASS_FARG0_MAX> inline
	bool operator>=(
	const tuple<_ARG0_ARG1_MAX>& _Left,
	const tuple<_FARG0_FARG1_MAX>& _Right)
	{	// return _Left >= _Right
	return (!_Left._Lt(_Right));
	}

template<> inline
	bool operator>=(const tuple<>&, const tuple<>&)
	{	// return true for empty tuples
	return (true);
	}

	// TEMPLATE STRUCT tuple_size
template<class _Tuple>
	struct tuple_size
	{	// struct to determine number of elements in tuple _Tuple
	static const size_t value = _Size<typename _Tuple::_MyImpl>::_Value;
	};

	// TEMPLATE STRUCT tuple_element
template<size_t _Idx,
	class _Tuple>
	struct tuple_element
	{	// struct to determine type of element _Idx in tuple _Tuple
	typedef typename _Get<_Idx, typename _Tuple::_MyImpl>::_Type type;
	};

	// TEMPLATE FUNCTION get
template<size_t _Idx,
	_CLASS_ARG0_MAX> inline
	typename _Arg_traits<typename _Get<_Idx,
		typename tuple<_ARG0_ARG1_MAX>::_MyImpl>::_Type>::_RType
	get(tuple<_ARG0_ARG1_MAX>& _Tuple)
	{	// return element at _Idx in tuple _Tuple
	return (_Get<_Idx,
		typename tuple<_ARG0_ARG1_MAX>::_MyImpl>::_Val(_Tuple._Impl));
	}

template<size_t _Idx,
	_CLASS_ARG0_MAX> inline
	typename _Arg_traits<typename _Get<_Idx,
		typename tuple<_ARG0_ARG1_MAX>::_MyImpl>::_Type>::_CType
	get(const tuple<_ARG0_ARG1_MAX>& _Tuple)
	{	// return element at _Idx in tuple _Tuple
	return (_Get<_Idx,
		typename tuple<_ARG0_ARG1_MAX>::_MyImpl>::_Val(_Tuple._Impl));
	}

	// STRUCT _Ignore
struct _Ignore
	{	// class that ignores assignments
	_Ignore()
		{	// construct
		}

	template<class _Ty>
		void operator=(const _Ty&) const
		{	// do nothing
		}
	};

const _Ignore ignore;

	// TEMPLATE STRUCT _Ttype
template<class _Ty>
	struct _Ttype
	{	// determine tuple element type for tuple returned by make_tuple
	typedef _Ty _Type;
	};

template<class _Ty>
	struct _Ttype<reference_wrapper<_Ty> >
	{	// determine tuple element type for tuple returned by make_tuple
	typedef _Ty& _Type;
	};

template<class _Ty>
	struct _Ttype<const reference_wrapper<_Ty> >
	{	// determine tuple element type for tuple returned by make_tuple
	typedef _Ty& _Type;
	};

template<class _Ty>
	struct _Ttype<volatile reference_wrapper<_Ty> >
	{	// determine tuple element type for tuple returned by make_tuple
	typedef _Ty& _Type;
	};

template<class _Ty>
	struct _Ttype<const volatile reference_wrapper<_Ty> >
	{	// determine tuple element type for tuple returned by make_tuple
	typedef _Ty& _Type;
	};

	// TEMPLATE STRUCT _Make_tuple
template<_CLASS_ARG0_DEF_MAX>
	struct _Make_tuple
	{	// determine tuple element type for tuple returned by make_tuple
	typedef tuple<_LIST15_MAX(typename _Ttype<_Arg, >::_Type)> _Type;
	};

	// TEMPLATE FUNCTION make_tuple, TEMPLATE FUNCTION tie
#define _INCL_FILE_xxtuple1
#include <xfwrap>
	}	// namespace tr1
_STD_END

_STD_BEGIN
 #if _HAS_TR1_IMPORTS
using tr1::get;
using tr1::ignore;
using tr1::make_tuple;
using tr1::ref;
using tr1::tie;
using tr1::tuple;
using tr1::tuple_element;
using tr1::tuple_size;
 #endif /* _HAS_TR1_IMPORTS */

 #if _HAS_CPP0X
template<class _InIt> inline
	_InIt begin(const tuple<_InIt, _InIt>& _Tuple)
	{	// return first element of tuple
	return (get<0>(_Tuple));
	}

template<class _InIt> inline
	_InIt end(const tuple<_InIt, _InIt>& _Tuple)
	{	// return second element of tuple
	return (get<1>(_Tuple));
	}
 #endif /* _HAS_CPP0X */
_STD_END
 #pragma warning(pop)
 #pragma pack(pop)

#endif /* RC_INVOKED */
#endif /* _TUPLE_ */

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