// array TR1 header
#pragma once
#ifndef _ARRAY_
#define _ARRAY_
#ifndef RC_INVOKED
#include <algorithm>
#include <iterator>

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

_STD_BEGIN
	namespace tr1 {	// TR1 additions
	// TEMPLATE CLASS array
template<class _Ty,
	size_t _Size>
	class array
	{	// fixed size array of values
public:
	enum {_EEN_SIZE = _Size};	// helper for expression evaluator
	typedef array<_Ty, _Size> _Myt;
	typedef _Ty value_type;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;
	typedef _Ty *pointer;
	typedef const _Ty *const_pointer;
	typedef _Ty& reference;
	typedef const _Ty& const_reference;

	typedef _Array_iterator<_Ty, _Size> iterator;
	typedef _Array_const_iterator<_Ty, _Size> const_iterator;

	typedef _STD reverse_iterator<iterator> reverse_iterator;
	typedef _STD reverse_iterator<const_iterator> const_reverse_iterator;

	void assign(const _Ty& _Value)
		{	// assign value to all elements
		_STD fill_n(_Elems, _Size, _Value);
		}

	void fill(const _Ty& _Value)
		{	// assign value to all elements
		_STD fill_n(_Elems, _Size, _Value);
		}

	void swap(_Myt& _Other)
		{	// swap contents with _Other
		_Swap_ranges(_STD addressof(_Elems[0]), _STD addressof(_Elems[0]) + _Size, _STD addressof(_Other._Elems[0]));
		}

	void swap(_Myt&& _Other)
		{	// swap contents with _Other
		_Move(_Other.begin(), _Other.end(), begin());
		}

	iterator begin()
		{	// return iterator for beginning of mutable sequence
		return (iterator(_STD addressof(_Elems[0]), 0));
		}

	const_iterator begin() const
		{	// return iterator for beginning of nonmutable sequence
		return (const_iterator(_STD addressof(_Elems[0]), 0));
		}

	iterator end()
		{	// return iterator for end of mutable sequence
		return (iterator(_STD addressof(_Elems[0]), _Size));
		}

	const_iterator end() const
		{	// return iterator for beginning of nonmutable sequence
		return (const_iterator(_STD addressof(_Elems[0]), _Size));
		}

	reverse_iterator rbegin()
		{	// return iterator for beginning of reversed mutable sequence
		return (reverse_iterator(end()));
		}

	const_reverse_iterator rbegin() const
		{	// return iterator for beginning of reversed nonmutable sequence
		return (const_reverse_iterator(end()));
		}

	reverse_iterator rend()
		{	// return iterator for end of reversed mutable sequence
		return (reverse_iterator(begin()));
		}

	const_reverse_iterator rend() const
		{	// return iterator for end of reversed nonmutable sequence
		return (const_reverse_iterator(begin()));
		}

 #if _HAS_CPP0X
	const_iterator cbegin() const
		{	// return iterator for beginning of nonmutable sequence
		return (((const _Myt *)this)->begin());
		}

	const_iterator cend() const
		{	// return iterator for end of nonmutable sequence
		return (((const _Myt *)this)->end());
		}

	const_reverse_iterator crbegin() const
		{	// return iterator for beginning of reversed nonmutable sequence
		return (((const _Myt *)this)->rbegin());
		}

	const_reverse_iterator crend() const
		{	// return iterator for ebd of reversed nonmutable sequence
		return (((const _Myt *)this)->rend());
		}
 #endif /* _HAS_CPP0X */

	size_type size() const
		{	// return length of sequence
		return (_Size);
		}

	size_type max_size() const
		{	// return maximum possible length of sequence
		return (_Size);
		}

	bool empty() const
		{	// test if sequence is empty
		return (_Size == 0);
		}

	reference at(size_type _Pos)
		{	// subscript mutable sequence with checking
		if (_Size <= _Pos)
			_Xran();
		return (_Elems[_Pos]);
		}

	const_reference at(size_type _Pos) const
		{	// subscript nonmutable sequence with checking
		if (_Size <= _Pos)
			_Xran();
		return (_Elems[_Pos]);
		}

	reference operator[](size_type _Pos)
		{	// subscript mutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Size <= _Pos)
			_DEBUG_ERROR("array subscript out of range");

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(_Pos < _Size);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		__analysis_assume(_Pos < _Size);

		return (_Elems[_Pos]);
		}

	const_reference operator[](size_type _Pos) const
		{	// subscript nonmutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Size <= _Pos)
			_DEBUG_ERROR("array subscript out of range");

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(_Pos < _Size);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		__analysis_assume(_Pos < _Size);

		return (_Elems[_Pos]);
		}

	reference front()
		{	// return first element of mutable sequence
		return (_Elems[0]);
		}

	const_reference front() const
		{	// return first element of nonmutable sequence
		return (_Elems[0]);
		}

	reference back()
		{	// return last element of mutable sequence
		return (_Elems[_Size - 1]);
		}

	const_reference back() const
		{	// return last element of nonmutable sequence
		return (_Elems[_Size - 1]);
		}

	_Ty *data()
		{	// return pointer to mutable data array
		return (_Elems);
		}

	const _Ty *data() const
		{	// return pointer to nonmutable data array
		return (_Elems);
		}

	__declspec(noreturn) void _Xran() const
		{	// report an out_of_range error
		_STD _Xout_of_range("invalid array<T, N> subscript");
		}

	_Ty _Elems[_Size == 0 ? 1 : _Size];
	};

template<class _Ty>
	class array<_Ty, 0>
	{	// zero size array of values
public:
	enum {_EEN_SIZE = 0};	// helper for expression evaluator
	typedef array<_Ty, 0> _Myt;
	typedef _Ty value_type;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;
	typedef _Ty *pointer;
	typedef const _Ty *const_pointer;
	typedef _Ty& reference;
	typedef const _Ty& const_reference;

	typedef _Array_iterator<_Ty, 0> iterator;
	typedef _Array_const_iterator<_Ty, 0> const_iterator;
	typedef _STD reverse_iterator<iterator> reverse_iterator;
	typedef _STD reverse_iterator<const_iterator> const_reverse_iterator;

	void assign(const _Ty&)
		{	// assign value to all elements
		}

	void fill(const _Ty&)
		{	// assign value to all elements
		}

	void swap(_Myt&)
		{	// swap contents with _Other
		}

	iterator begin()
		{	// return iterator for beginning of mutable sequence
		return (iterator(0, 0));
		}

	const_iterator begin() const
		{	// return iterator for beginning of nonmutable sequence
		return (iterator(0, 0));
		}

	iterator end()
		{	// return iterator for end of mutable sequence
		return (iterator(0, 0));
		}

	const_iterator end() const
		{	// return iterator for beginning of nonmutable sequence
		return (iterator(0, 0));
		}

	reverse_iterator rbegin()
		{	// return iterator for beginning of reversed mutable sequence
		return (reverse_iterator(end()));
		}

	const_reverse_iterator rbegin() const
		{	// return iterator for beginning of reversed nonmutable sequence
		return (const_reverse_iterator(end()));
		}

	reverse_iterator rend()
		{	// return iterator for end of reversed mutable sequence
		return (reverse_iterator(begin()));
		}

	const_reverse_iterator rend() const
		{	// return iterator for end of reversed nonmutable sequence
		return (const_reverse_iterator(begin()));
		}

 #if _HAS_CPP0X
	const_iterator cbegin() const
		{	// return iterator for beginning of nonmutable sequence
		return (iterator(0, 0));
		}

	const_iterator cend() const
		{	// return iterator for end of nonmutable sequence
		return (iterator(0, 0));
		}

	const_reverse_iterator crbegin() const
		{	// return iterator for beginning of reversed nonmutable sequence
		return (((const _Myt *)this)->rbegin());
		}

	const_reverse_iterator crend() const
		{	// return iterator for ebd of reversed nonmutable sequence
		return (((const _Myt *)this)->rend());
		}
 #endif /* _HAS_CPP0X */

	size_type size() const
		{	// return length of sequence
		return (0);
		}

	size_type max_size() const
		{	// return maximum possible length of sequence
		return (0);
		}

	bool empty() const
		{	// test if sequence is empty
		return (true);
		}

	reference at(size_type)
		{	// subscript mutable sequence with checking
		static int _Zero = 0;

		if (_Zero == 0)	// to quiet diagnostics
			_Xran();
		return (_Elems[0]);
		}

	const_reference at(size_type) const
		{	// subscript nonmutable sequence with checking
		static int _Zero = 0;

		if (_Zero == 0)	// to quiet diagnostics
			_Xran();
		return (_Elems[0]);
		}

	reference operator[](size_type)
		{	// subscript mutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		_DEBUG_ERROR("array subscript out of range");

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(false);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (_Elems[0]);
		}

	const_reference operator[](size_type) const
		{	// subscript nonmutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		_DEBUG_ERROR("array subscript out of range");

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(false);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (_Elems[0]);
		}

	reference front()
		{	// return first element of mutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		_DEBUG_ERROR("array<T, 0>::front() invalid");

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(false);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (_Elems[0]);
		}

	const_reference front() const
		{	// return first element of nonmutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		_DEBUG_ERROR("array<T, 0>::front() invalid");

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(false);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (_Elems[0]);
		}

	reference back()
		{	// return last element of mutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		_DEBUG_ERROR("array<T, 0>::back() invalid");

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(false);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (_Elems[0]);
		}

	const_reference back() const
		{	// return last element of nonmutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		_DEBUG_ERROR("array<T, 0>::back() invalid");

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(false);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (_Elems[0]);
		}

	_Ty *data()
		{	// return pointer to mutable data array
		return (_Elems);
		}

	const _Ty *data() const
		{	// return pointer to nonmutable data array
		return (_Elems);
		}

	__declspec(noreturn) void _Xran() const
		{	// report an out_of_range error
		_STD _Xout_of_range("invalid array<T, 0> subscript");
		}

	_Ty _Elems[1];
	};

template<class _Ty,
	size_t _Size>
	void swap(array<_Ty,_Size>& _Left,
		array<_Ty,_Size>& _Right)
	{	// swap arrays
	return (_Left.swap(_Right));
	}

template<class _Ty,
	size_t _Size>
	void swap(array<_Ty,_Size>& _Left,
		array<_Ty,_Size>&& _Right)
	{	// swap arrays
	typedef array<_Ty, _Size> _Myt;
	_Left.swap(_STD forward<_Myt>(_Right));
	}

template<class _Ty,
	size_t _Size>
	void swap(array<_Ty,_Size>&& _Left,
		array<_Ty,_Size>& _Right)
	{	// swap arrays
	typedef array<_Ty, _Size> _Myt;
	_Right.swap(_STD forward<_Myt>(_Left));
	}

template<class _Ty,
	size_t _Size>
	bool operator==(const array<_Ty,_Size>& _Left,
		const array<_Ty,_Size>& _Right)
	{	// test for array equality
	return (_STD equal(_Left.begin(), _Left.end(), _Right.begin()));
	}

template<class _Ty,
	size_t _Size>
	bool operator!=(const array<_Ty,_Size>& _Left,
		const array<_Ty,_Size>& _Right)
	{	// test for array inequality
	return (!(_Left == _Right));
	}

template<class _Ty,
	size_t _Size>
	bool operator<(const array<_Ty,_Size>& _Left,
		const array<_Ty,_Size>& _Right)
	{	// test if _Left < _Right for arrays
	return (_STD lexicographical_compare(_Left.begin(), _Left.end(),
		_Right.begin(), _Right.end()));
	}

template<class _Ty,
	size_t _Size>
	bool operator>(const array<_Ty,_Size>& _Left,
		const array<_Ty,_Size>& _Right)
	{	// test if _Left > _Right for arrays
	return (_Right < _Left);
	}

template<class _Ty,
	size_t _Size>
	bool operator<=(const array<_Ty,_Size>& _Left,
	const array<_Ty,_Size>& _Right)
	{	// test if _Left <= _Right for arrays
	return (!(_Right < _Left));
	}

template<class _Ty,
	size_t _Size>
	bool operator>=(const array<_Ty,_Size>& _Left,
	const array<_Ty,_Size>& _Right)
	{	// test if _Left >= _Right for arrays
	return (!(_Left < _Right));
	}

 #if _HAS_TR1
	// TUPLE INTERFACE TO array
template<class _Tuple>
	struct tuple_size;

template<size_t _Idx,
	class _Tuple>
	struct tuple_element;

template<class _Ty,
	size_t _Size>
	struct tuple_size<array<_Ty, _Size> >
	{	// struct to determine number of elements in array
	static const int value = _Size;
	};

template<size_t _Idx,
	class _Ty,
	size_t _Size>
	struct tuple_element<_Idx, array<_Ty, _Size> >
	{	// struct to determine type of element _Idx in array
	typedef _Ty type;
	};

template<int _Idx,
	class _Ty,
	size_t _Size>
	_Ty& get(array<_Ty, _Size>& _Arr)
	{	// return element at _Idx in array _Arr
	static_assert(0 <= _Idx && _Idx < _Size, "array index out of bounds");
	return (_Arr[_Idx]);
	}

template<int _Idx,
	class _Ty,
	size_t _Size>
	const _Ty& get(const array<_Ty, _Size>& _Arr)
	{	// return element at _Idx in array _Arr
	static_assert(0 <= _Idx && _Idx < _Size, "array index out of bounds");
	return (_Arr[_Idx]);
	}
 #endif /* _HAS_TR1 */
	}	// namespace tr1

 #if _HAS_TR1_IMPORTS
using tr1::array;
using tr1::get;
using tr1::tuple_element;
using tr1::tuple_size;
 #endif /* _HAS_TR1_IMPORTS */
_STD_END

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

#endif /* RC_INVOKED */
#endif /* _ARRAY_ */

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