// xiter internal header
#ifndef _XITER_
#define _XITER_

#include <climits>
#include <cstdlib>
#include <utility>


 #if defined(__ghs)
  #pragma ghs start_cxx_lib_header
  #pragma ghs startdata
  #pragma ghs nowarning 76
  #if defined(__ghs_max_pack_value)
   #pragma pack (push, __ghs_max_pack_value)
  #endif /* defined(__ghs_max_pack_value) */
 #endif /* defined(__ghs) */

_STD_BEGIN
 #ifndef _SCL_SECURE_ALWAYS_VALIDATE
  #define _SCL_SECURE_ALWAYS_VALIDATE(pred)
 #endif /* _SCL_SECURE_ALWAYS_VALIDATE */

 #if __EDG__	/* compiler test */
  #pragma diag_suppress non_pod_passed_to_ellipsis
 #endif /* __EDG__ */

 #ifdef _SCL_SECURE_VALIDATE

 #elif 0 < _ITERATOR_DEBUG_LEVEL
  #define _SCL_INSECURE_DEPRECATE	/* ISSUE WARNING */

  #define _SCL_SECURE_VALIDATE(pred) \
	{	/* test for valid argument */ \
	if (!(pred)) \
		_SCL_SECURE_INVALID_ARGUMENT; \
	}

  #define _SCL_SECURE_VALIDATE_RANGE(pred)  \
	{	/* test for valid range */ \
	if (!(pred)) \
		_SCL_SECURE_OUT_OF_RANGE; \
	}

  #define _SCL_SECURE_INVALID_ARGUMENT  \
	_DEBUG_ERROR("invalid argument")

  #define _SCL_SECURE_OUT_OF_RANGE  \
	_DEBUG_ERROR("out_of_range")

 #else /* 0 < _ITERATOR_DEBUG_LEVEL */
  #define _SCL_INSECURE_DEPRECATE

  #define _SCL_SECURE_VALIDATE(pred)
  #define _SCL_SECURE_VALIDATE_RANGE(pred)
  #define _SCL_SECURE_INVALID_ARGUMENT
  #define _SCL_SECURE_OUT_OF_RANGE
 #endif /* 0 < _ITERATOR_DEBUG_LEVEL */

		// MACRO _ITERATOR_DEBUG_LEVEL

#ifndef _ITERATOR_DEBUG_LEVEL

 #if _HAS_ITERATOR_DEBUGGING		/* set level to 0, 1, or 2 */
 #define _ITERATOR_DEBUG_LEVEL  2

 #else /* _HAS_ITERATOR_DEBUGGING, set level */

 #if _SECURE_SCL
  #define _ITERATOR_DEBUG_LEVEL 1

 #else /* _SECURE_SCL */
  #define _ITERATOR_DEBUG_LEVEL 0
 #endif /* _SECURE_SCL */

 #endif /* _HAS_ITERATOR_DEBUGGING, set level */

#endif /* !defined(_ITERATOR_DEBUG_LEVEL) */

		// MACRO _DEBUG_ERROR

 #if _ITERATOR_DEBUG_LEVEL == 2
  #define _DEBUG_ERROR(mesg) \
	_DEBUG_ERROR2(mesg, __FILE__, __LINE__)
  #define _DEBUG_ERROR2(mesg, file, line) \
	_Debug_message(mesg, file, line)

typedef const char *_Dbfile_t;
typedef unsigned int _Dbline_t;

void _Debug_message(const char *, const char *, unsigned int);

 #else /* _ITERATOR_DEBUG_LEVEL == 2 */
  #define _DEBUG_ERROR(mesg)
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

		// CLASSES _Container_base *, _Iterator_base *
struct _Container_proxy;
struct _Container_base12;
struct _Iterator_base12;

struct _Container_base0
	{	// base of all containers
	void _Orphan_all()
		{	// orphan all iterators
		}

	void _Swap_all(_Container_base0&)
		{	// swap all iterators
		}

 #if _HAS_DEBUG_COMPATIBILITY
	_Container_proxy *_Myproxy;
 #endif /* _HAS_DEBUG_COMPATIBILITY */
	};

struct _Iterator_base0
	{	// base of all iterators
	void _Adopt(const void *)
		{	// adopt this iterator by parent
		}

	const _Container_base0 *_Getcont() const
		{	// get owning container
		return (0);
		}

 #if _HAS_DEBUG_COMPATIBILITY
	_Container_proxy *_Myproxy;
	_Iterator_base12 *_Mynextiter;
 #endif /* _HAS_DEBUG_COMPATIBILITY */
	};

		// CLASS _Container_proxy
struct _Container_proxy
	{	// store head of iterator chain and back pointer
	_Container_proxy()
		: _Mycont(0), _Myfirstiter(0)
		{	// construct from pointers
		}

	const _Container_base12 *_Mycont;
	_Iterator_base12 *_Myfirstiter;
	};

struct _Container_base12
	{	// store pointer to _Container_proxy
public:
	_Container_base12()
		: _Myproxy(0)
		{	// construct childless container
		}

	_Container_base12(const _Container_base12&)
		: _Myproxy(0)
		{	// copy a container
		}

	_Container_base12& operator=(const _Container_base12&)
		{	// assign a container
		return (*this);
		}

	~_Container_base12() _NOEXCEPT
		{	// destroy the container
		_Orphan_all();
		}

	_Iterator_base12 **_Getpfirst() const
		{	// get address of iterator chain
		return (_Myproxy == 0 ? 0 : &_Myproxy->_Myfirstiter);
		}

	void _Orphan_all(); // orphan all iterators
	void _Swap_all(_Container_base12&); // swap all iterators

	_Container_proxy *_Myproxy;
	};

struct _Iterator_base12
	{	// store links to container proxy, next iterator
public:
	_Iterator_base12()
		: _Myproxy(0), _Mynextiter(0)
		{	// construct orphaned iterator
		}

	_Iterator_base12(const _Iterator_base12& _Right)
		: _Myproxy(0), _Mynextiter(0)
		{	// copy an iterator
		*this = _Right;
		}

	_Iterator_base12& operator=(const _Iterator_base12& _Right)
		{	// assign an iterator
		if (_Myproxy == _Right._Myproxy)
			;
		else if (_Right._Myproxy != 0)
			_Adopt(_Right._Myproxy->_Mycont);
		else
			{	// becoming invalid, disown current parent
 #if _ITERATOR_DEBUG_LEVEL == 2
			_Lockit _Lock(_LOCK_DEBUG);
			_Orphan_me();
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
			}
		return (*this);
		}

	~_Iterator_base12() _NOEXCEPT
		{	// destroy the iterator
 #if _ITERATOR_DEBUG_LEVEL == 2
		_Lockit _Lock(_LOCK_DEBUG);
		_Orphan_me();
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
		}

	void _Adopt(const _Container_base12 *_Parent)
		{	// adopt this iterator by parent
		if (_Parent == 0)
			{	// no future parent, just disown current parent
 #if _ITERATOR_DEBUG_LEVEL == 2
			_Lockit _Lock(_LOCK_DEBUG);
			_Orphan_me();
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
			}
		else
			{	// have a parent, do adoption
			_Container_proxy *_Parent_proxy = _Parent->_Myproxy;

 #if _ITERATOR_DEBUG_LEVEL == 2
			if (_Myproxy != _Parent_proxy)
				{	// change parentage
				_Lockit _Lock(_LOCK_DEBUG);
				_Orphan_me();
				_Mynextiter = _Parent_proxy->_Myfirstiter;
				_Parent_proxy->_Myfirstiter = this;
				_Myproxy = _Parent_proxy;
				}

 #else /* _ITERATOR_DEBUG_LEVEL == 2 */
			_Myproxy = _Parent_proxy;
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
			}
		}

	void _Clrcont()
		{	// disown owning container
		_Myproxy = 0;
		}

	const _Container_base12 *_Getcont() const
		{	// get owning container
		return (_Myproxy == 0 ? 0 : _Myproxy->_Mycont);
		}

	_Iterator_base12 **_Getpnext()
		{	// get address of remaining iterator chain
		return (&_Mynextiter);
		}

	void _Orphan_me()
		{	// cut ties with parent
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Myproxy != 0)
			{	// adopted, remove self from list
			_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;
			while (*_Pnext != 0 && *_Pnext != this)
				_Pnext = &(*_Pnext)->_Mynextiter;

			if (*_Pnext == 0)
				_DEBUG_ERROR("ITERATOR LIST CORRUPTED!");
			*_Pnext = _Mynextiter;
			_Myproxy = 0;
			}
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
		}

	_Container_proxy *_Myproxy;
	_Iterator_base12 *_Mynextiter;
	};

		// MEMBER FUNCTIONS FOR _Container_base12
inline void _Container_base12::_Orphan_all()
	{	// orphan all iterators
 #if _ITERATOR_DEBUG_LEVEL == 2
	if (_Myproxy != 0)
		{	// proxy allocated, drain it
		_Lockit _Lock(_LOCK_DEBUG);

		for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;
			*_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter)
			(*_Pnext)->_Myproxy = 0;
		_Myproxy->_Myfirstiter = 0;
		}
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
	}

inline void _Container_base12::_Swap_all(_Container_base12& _Right)
	{	// swap all iterators
 #if _ITERATOR_DEBUG_LEVEL == 2
	_Lockit _Lock(_LOCK_DEBUG);
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

	_Container_proxy *_Temp = _Myproxy;
	_Myproxy = _Right._Myproxy;
	_Right._Myproxy = _Temp;

	if (_Myproxy != 0)
		_Myproxy->_Mycont = (_Container_base12 *)this;
	if (_Right._Myproxy != 0)
		_Right._Myproxy->_Mycont = (_Container_base12 *)&_Right;
	}

 #if _ITERATOR_DEBUG_LEVEL == 0
typedef _Container_base0 _Container_base;
typedef _Iterator_base0 _Iterator_base;

 #else /* _ITERATOR_DEBUG_LEVEL == 0 */
typedef _Container_base12 _Container_base;
typedef _Iterator_base12 _Iterator_base;
 #endif /* _ITERATOR_DEBUG_LEVEL == 0 */

		// TEMPLATE CLASS _Compressed_pair
struct _Zero_then_variadic_args_t
	{	// tag type for value-initializing first,
	};  // constructing second from remaining args

struct _One_then_variadic_args_t
	{	// tag type for constructing first from one arg,
	};  // constructing second from remaining args

template<class _Ty1,
	class _Ty2,
	bool = is_empty<_Ty1>::value
#if defined(__ghs) && _HAS_CPP11
		&& !is_final<_Ty1>::value
#endif /* defined(__ghs) && _HAS_CPP11 */
	>
	class _Compressed_pair
		: private _Ty1
	{	// store a pair of values, deriving from empty first
private:
	_Ty2 _Myval2;

public:
	_Compressed_pair()
		{	// construct from no forwarded values
		}
 #if _HAS_VARIADIC_TEMPLATES
	template<class... _Other2>
		_CONST_FUN explicit _Compressed_pair(_Zero_then_variadic_args_t,
			_Other2&&... _Val2)
		: _Ty1(), _Myval2(_STD forward<_Other2>(_Val2)...)
		{	// construct from forwarded values
		}

	template<class _Other1,
		class... _Other2>
		_Compressed_pair(_One_then_variadic_args_t,
			_Other1&& _Val1, _Other2&&... _Val2)
		: _Ty1(_STD forward<_Other1>(_Val1)),
			_Myval2(_STD forward<_Other2>(_Val2)...)
		{	// construct from forwarded values
		}
 #else /* _HAS_VARIADIC_TEMPLATES */
	explicit _Compressed_pair(_Zero_then_variadic_args_t)
		: _Ty1(), _Myval2()
		{	// construct from no forwarded values
		}

#define _COMPRESSED_PAIR_CONSTRUCTOR0( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	template<LIST(_CLASS_TYPE)> \
		explicit _Compressed_pair( \
			_Zero_then_variadic_args_t _EX(C) LIST(_TYPE_REFREF_ARG)) \
		: _Ty1(), _Myval2(LIST(_FORWARD_ARG)) \
		{	/* construct from forwarded values */ \
		}

_VARIADIC_EXPAND_1X(_COMPRESSED_PAIR_CONSTRUCTOR0, , , , )
#undef _COMPRESSED_PAIR_CONSTRUCTOR0

#define _COMPRESSED_PAIR_CONSTRUCTOR1( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	template<class _Other _EX(C) LIST(_CLASS_TYPE)> \
		_Compressed_pair(_One_then_variadic_args_t, \
			_Other _REFREF _Val1 _EX(C) LIST(_TYPE_REFREF_ARG)) \
		: _Ty1(_STD forward<_Other>(_Val1)), \
			_Myval2(LIST(_FORWARD_ARG)) \
		{	/* construct from forwarded values */ \
		}

_VARIADIC_EXPAND_0X(_COMPRESSED_PAIR_CONSTRUCTOR1, , , , )
#undef _COMPRESSED_PAIR_CONSTRUCTOR1
 #endif /* _HAS_VARIADIC_TEMPLATES */

	_Compressed_pair(const _Compressed_pair& _Right)
		: _Ty1(_Right),
			_Myval2(_Right._Myval2)
		{	// move construct
		}
 #if !defined(__ghs) || _HAS_CPP11
	_Compressed_pair(_Compressed_pair&& _Right)
		: _Ty1(_STD move(_Right)),
			_Myval2(_STD move(_Right._Myval2))
		{	// move construct
		}

	_Compressed_pair& operator=(_Compressed_pair&& _Right)
		{	// move assign
		*this = _STD move(_Right);
		return (*this);
		}
 #endif
	_Ty1& _Get_first() _NOEXCEPT
		{	// return reference to first
		return (*this);
		}

	const _Ty1& _Get_first() const _NOEXCEPT
		{	// return const reference to first
		return (*this);
		}

	volatile _Ty1& _Get_first() volatile _NOEXCEPT
		{	// return volatile reference to first
		return (*this);
		}

	const volatile _Ty1& _Get_first() const volatile _NOEXCEPT
		{	// return const volatile reference to first
		return (*this);
		}

	_Ty2& _Get_second() _NOEXCEPT
		{	// return reference to second
		return (_Myval2);
		}

	const _Ty2& _Get_second() const _NOEXCEPT
		{	// return const reference to second
		return (_Myval2);
		}

	volatile _Ty2& _Get_second() volatile _NOEXCEPT
		{	// return volatile reference to second
		return (_Myval2);
		}

	const volatile _Ty2& _Get_second() const volatile _NOEXCEPT
		{	// return const volatile reference to second
		return (_Myval2);
		}
	};

template<class _Ty1,
	class _Ty2>
	class _Compressed_pair<_Ty1, _Ty2, false>
	{	// store a pair of values, not deriving from first
private:
	_Ty1 _Myval1;
	_Ty2 _Myval2;

public:
	_Compressed_pair()
		{	// construct from no forwarded values
		}

#if _HAS_VARIADIC_TEMPLATES
	template<class... _Other2>
		_CONST_FUN explicit _Compressed_pair(_Zero_then_variadic_args_t,
			_Other2&&... _Val2)
		: _Myval1(), _Myval2(_STD forward<_Other2>(_Val2)...)
		{	// construct from forwarded values
		}

	template<class _Other1,
		class... _Other2>
		_Compressed_pair(_One_then_variadic_args_t,
			_Other1&& _Val1, _Other2&&... _Val2)
		: _Myval1(_STD forward<_Other1>(_Val1)),
			_Myval2(_STD forward<_Other2>(_Val2)...)
		{	// construct from forwarded values
		}
 #else /* _HAS_VARIADIC_TEMPLATES */
	explicit _Compressed_pair(_Zero_then_variadic_args_t)
#if defined(__ghs) // PJP-N00
		: _Myval1(), _Myval2()
#else
		: _Ty1(), _Myval2()
#endif
		{	// construct from no forwarded values
		}

#if defined(__ghs) // PJP-N00
#define _COMPRESSED_PAIR_CONSTRUCTOR0X( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	template<LIST(_CLASS_TYPE)> \
		explicit _Compressed_pair( \
			_Zero_then_variadic_args_t _EX(C) LIST(_TYPE_REFREF_ARG)) \
		: _Myval1(), _Myval2(LIST(_FORWARD_ARG)) \
		{	/* construct from forwarded values */ \
		}
#else
#define _COMPRESSED_PAIR_CONSTRUCTOR0X( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	template<LIST(_CLASS_TYPE)> \
		explicit _Compressed_pair( \
			_Zero_then_variadic_args_t _EX(C) LIST(_TYPE_REFREF_ARG)) \
		: _Ty1(), _Myval2(LIST(_FORWARD_ARG)) \
		{	/* construct from forwarded values */ \
		}
#endif /* __ghs */

_VARIADIC_EXPAND_1X(_COMPRESSED_PAIR_CONSTRUCTOR0X, , , , )
#undef _COMPRESSED_PAIR_CONSTRUCTOR0X

#define _COMPRESSED_PAIR_CONSTRUCTOR1X( \
	TEMPLATE_LIST, PADDING_LIST, LIST, C, X1, X2, X3, X4) \
	template<class _Other _EX(C) LIST(_CLASS_TYPE)> \
		_Compressed_pair(_One_then_variadic_args_t, \
			_Other _REFREF _Val1 _EX(C) LIST(_TYPE_REFREF_ARG)) \
		: _Myval1(_STD forward<_Other>(_Val1)), \
			_Myval2(LIST(_FORWARD_ARG)) \
		{	/* construct from forwarded values */ \
		}

_VARIADIC_EXPAND_0X(_COMPRESSED_PAIR_CONSTRUCTOR1X, , , , )
#undef _COMPRESSED_PAIR_CONSTRUCTOR1X
 #endif /* _HAS_VARIADIC_TEMPLATES */

 #if _HAS_CPP11
	_Compressed_pair& operator=(_Compressed_pair&& _Right)
		{	// move assign
		_Myval1 = _STD forward<_Ty1>(_Right._Myval1);
		_Myval2 = _STD forward<_Ty2>(_Right._Myval2);
		return (*this);
		}
 #endif
	_Compressed_pair(const _Compressed_pair& _Right)
		: _Myval1(_STD move(_Right._Myval1)),
			_Myval2(_STD move(_Right._Myval2))
		{	// move construct
		}
 #if _HAS_CPP11
	_Compressed_pair(_Compressed_pair&& _Right)
		: _Myval1(_STD move(_Right._Myval1)),
			_Myval2(_STD move(_Right._Myval2))
		{	// move construct
		}
 #endif
	_Ty1& _Get_first() _NOEXCEPT
		{	// return reference to first
		return (_Myval1);
		}

	const _Ty1& _Get_first() const _NOEXCEPT
		{	// return const reference to first
		return (_Myval1);
		}

	volatile _Ty1& _Get_first() volatile _NOEXCEPT
		{	// return volatile reference to first
		return (_Myval1);
		}

	const volatile _Ty1& _Get_first() const volatile _NOEXCEPT
		{	// return const volatile reference to first
		return (_Myval1);
		}

	_Ty2& _Get_second() _NOEXCEPT
		{	// return reference to second
		return (_Myval2);
		}

	const _Ty2& _Get_second() const _NOEXCEPT
		{	// return const reference to second
		return (_Myval2);
		}

	volatile _Ty2& _Get_second() volatile _NOEXCEPT
		{	// return volatile reference to second
		return (_Myval2);
		}

	const volatile _Ty2& _Get_second() const volatile _NOEXCEPT
		{	// return const volatile reference to second
		return (_Myval2);
		}
	};
		// TEMPLATE FUNCTION _Is_checked AND FRIENDS
		// TEMPLATE STRUCT _Get_unchecked_type AND FRIENDS
 #define _UNCHECKED_TYPE(_Iter) \
	typename _Get_unchecked_type<_Iter>::type

		// TEMPLATE STRUCT _Get_unchecked_type
template<class _Ty>
	struct _Get_unchecked_type
		_GET_TYPE_OR_DEFAULT(_Unchecked_type,
			_Ty);

		// TEMPLATE STRUCT _Is_checked_helper
template<class _Ty,
	class = void>
	struct _Is_checked_helper
		: false_type
	{	// default definition
	};

template<class _Ty>
	struct _Is_checked_helper<_Ty, typename _Param_tester<
		typename _Ty::_Unchecked_type>::type>
		: true_type
	{	// defined if _Ty::_Unchecked_type exists
	};

		// TEMPLATE FUNCTION _Is_checked
template<class _Iter> inline
	typename _Is_checked_helper<_Iter>::type _Is_checked(_Iter)
	{	// return type is derived from true_type if iterator is checked
	return (typename _Is_checked_helper<_Iter>::type());
	}

		// TEMPLATE FUNCTION _Unchecked
template<class _Iter> inline
#if defined(__ghs)
	_CONST_FUN1
#endif /* defined(__ghs) */
	_Iter _Unchecked(_Iter _Src)
	{	// construct unchecked from checked, generic
	return (_Src);
	}

		// TEMPLATE FUNCTION _Rechecked
template<class _Iter,
	class _UIter> inline
#if defined(__ghs)
	_CONST_FUN1
#endif /* defined(__ghs) */
	_Iter& _Rechecked(_Iter& _Dest, _UIter _Src)
	{	// reset checked from unchecked, generic
	_Dest = _Src;
	return (_Dest);
	}

		//  ITERATOR STUFF (from <iterator>)
		// ITERATOR TAGS (from <iterator>)
struct input_iterator_tag
	{	// identifying tag for input iterators
	};

struct _Mutable_iterator_tag
	{	// identifying tag for mutable iterators
	};

struct output_iterator_tag
	: _Mutable_iterator_tag
	{	// identifying tag for output iterators
	};

struct forward_iterator_tag
	: input_iterator_tag, _Mutable_iterator_tag
	{	// identifying tag for forward iterators
	};

struct bidirectional_iterator_tag
	: forward_iterator_tag
	{	// identifying tag for bidirectional iterators
	};

struct random_access_iterator_tag
	: bidirectional_iterator_tag
	{	// identifying tag for random-access iterators
	};

		// POINTER ITERATOR TAGS
struct _Nonscalar_ptr_iterator_tag
	{	// pointer to unknown type
	};
struct _Scalar_ptr_iterator_tag
	{	// pointer to scalar type
	};

		// TEMPLATE CLASS iterator
template<class _Category,
	class _Ty,
	class _Diff = ptrdiff_t,
	class _Pointer = _Ty *,
	class _Reference = _Ty&>
	struct iterator
	{	// base type for iterator classes
	typedef _Category iterator_category;
	typedef _Ty value_type;
	typedef _Diff difference_type;
	typedef _Diff distance_type;	// retained
	typedef _Pointer pointer;
	typedef _Reference reference;
	};

template<class _Category,
	class _Ty,
	class _Diff,
	class _Pointer,
	class _Reference,
	class _Base>
	struct _Iterator012
		: public _Base
	{	// base type for debugging iterator classes
	typedef _Category iterator_category;
	typedef _Ty value_type;
	typedef _Diff difference_type;
	typedef _Diff distance_type;	// retained
	typedef _Pointer pointer;
	typedef _Reference reference;
	};

// base for output iterators
typedef iterator<output_iterator_tag, void, void, void, void> _Outit;

		// TEMPLATE CLASS _Is_iterator
template<class,
	class = void>
	struct _Is_iterator
		: false_type
	{	// default definition
	};

template<class _Ty>
	struct _Is_iterator<_Ty, typename _Param_tester<
		typename _Ty::iterator_category,
		typename _Ty::value_type,
		typename _Ty::difference_type,
		typename _Ty::pointer,
		typename _Ty::reference
		>::type>
		: true_type
	{	// defined if _Ty::* types exist
	};

template<class _Ty>
	struct _Is_iterator<_Ty *>
		: true_type
	{	// defined for pointers
	};

		// TEMPLATE CLASS iterator_traits
template<class _Iter,
	bool = _Is_iterator<_Iter>::value>
	struct _Iterator_traits_base
	{	// get traits from iterator _Iter
	typedef typename _Iter::iterator_category iterator_category;
	typedef typename _Iter::value_type value_type;
	typedef typename _Iter::difference_type difference_type;
	typedef difference_type distance_type;  // retained
	typedef typename _Iter::pointer pointer;
	typedef typename _Iter::reference reference;
	};

template<class _Iter>
	struct _Iterator_traits_base<_Iter, false>
	{	// empty for non-iterators
	};

template<class _Iter>
	struct iterator_traits
		: _Iterator_traits_base<_Iter>
	{	// get traits from iterator _Iter, if possible
	};

template<class _Ty>
	struct iterator_traits<_Ty *>
	{	// get traits from pointer
	typedef random_access_iterator_tag iterator_category;
	typedef _Ty value_type;
	typedef ptrdiff_t difference_type;
	typedef ptrdiff_t distance_type;	// retained
	typedef _Ty *pointer;
	typedef _Ty& reference;
	};

template<class _Ty>
	struct iterator_traits<const _Ty *>
	{	// get traits from const pointer
	typedef random_access_iterator_tag iterator_category;
	typedef _Ty value_type;
	typedef ptrdiff_t difference_type;
	typedef ptrdiff_t distance_type;	// retained
	typedef const _Ty *pointer;
	typedef const _Ty& reference;
	};

		// TEMPLATE FUNCTION _Iter_cat
template<class _Iter> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	typename iterator_traits<_Iter>::iterator_category
		_Iter_cat(const _Iter&)
	{	// return category from iterator argument
#if defined(__ghs) && _HAS_CPP11
	typename iterator_traits<_Iter>::iterator_category _Cat{};
#else
	typename iterator_traits<_Iter>::iterator_category _Cat;
#endif
	return (_Cat);
	}

		// TEMPLATE FUNCTION _Ptr_cat
template<class _Iter1,
	class _Iter2> inline
	_Nonscalar_ptr_iterator_tag _Ptr_cat(_Iter1&, _Iter2&)
	{	// return pointer category from arbitrary arguments
	_Nonscalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

 #if !defined(__BORLANDC__) && (!defined(__GNUC__) || 3 <= __GNUC__)
template<class _Ty> inline
	_Scalar_ptr_iterator_tag _Ptr_cat(_Ty **, _Ty **)
	{	// return pointer category from pointer to pointer arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

template<class _Ty> inline
	_Scalar_ptr_iterator_tag _Ptr_cat(_Ty *const *, _Ty **)
	{	// return pointer category from pointer to pointer arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

template<class _Ty> inline
	_Scalar_ptr_iterator_tag _Ptr_cat(_Ty **, const _Ty **)
	{	// return pointer category from pointer to pointer arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

template<class _Ty> inline
	_Scalar_ptr_iterator_tag _Ptr_cat(_Ty *const *, const _Ty **)
	{	// return pointer category from pointer to pointer arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}
 #endif /* !defined(__BORLANDC__) && (!defined(__GNUC__) || 3 <= __GNUC__) */

		// INTEGER FUNCTION _Ptr_cat
inline _Scalar_ptr_iterator_tag _Ptr_cat(bool *, bool *)
	{	// return pointer category from pointer to bool arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const bool *, bool *)
	{	// return pointer category from pointer to bool arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(char *, char *)
	{	// return pointer category from pointer to char arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const char *, char *)
	{	// return pointer category from pointer to char arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(signed char *, signed char *)
	{	// return pointer category from pointer to signed char arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const signed char *, signed char *)
	{	// return pointer category from pointer to signed char arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(unsigned char *,
	unsigned char *)
	{	// return pointer category from pointer to unsigned char arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned char *,
	unsigned char *)
	{	// return pointer category from pointer to unsigned char arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(short *, short *)
	{	// return pointer category from pointer to short arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const short *, short *)
	{	// return pointer category from pointer to short arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(unsigned short *,
	unsigned short *)
	{	// return pointer category from pointer to unsigned short arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned short *,
	unsigned short *)
	{	// return pointer category from pointer to unsigned short arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(int *, int *)
	{	// return pointer category from pointer to int arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const int *, int *)
	{	// return pointer category from pointer to int arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(unsigned int *, unsigned int *)
	{	// return pointer category from pointer to unsigned int arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned int *, unsigned int *)
	{	// return pointer category from pointer to unsigned int arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(long *, long *)
	{	// return pointer category from pointer to long arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const long *, long *)
	{	// return pointer category from pointer to long arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(unsigned long *,
	unsigned long *)
	{	// return pointer category from pointer to unsigned long arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned long *,
	unsigned long *)
	{	// return pointer category from pointer to unsigned long arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}
 #if !defined(__NoFloat) || !defined(__ghs__)
inline _Scalar_ptr_iterator_tag _Ptr_cat(float *, float *)
	{	// return pointer category from pointer to float arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const float *, float *)
	{	// return pointer category from pointer to float arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(double *, double *)
	{	// return pointer category from pointer to double arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const double *, double *)
	{	// return pointer category from pointer to double arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(long double *, long double *)
	{	// return pointer category from pointer to long double arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const long double *, long double *)
	{	// return pointer category from pointer to long double arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}
 #endif /* !__NoFloat || !__ghs__ */
 #ifdef _LONGLONG
inline _Scalar_ptr_iterator_tag _Ptr_cat(_LONGLONG *, _LONGLONG *)
	{	// return pointer category from pointer to long long arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const _LONGLONG *, _LONGLONG *)
	{	// return pointer category from pointer to long long arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(_ULONGLONG *, _ULONGLONG *)
	{	// return pointer category from pointer to ulong long arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}

inline _Scalar_ptr_iterator_tag _Ptr_cat(const _ULONGLONG *, _ULONGLONG *)
	{	// return pointer category from pointer to ulong long arguments
	_Scalar_ptr_iterator_tag _Cat;
	return (_Cat);
	}
 #endif /* _LONGLONG */

		// DEBUG TESTING MACROS

 #if _ITERATOR_DEBUG_LEVEL < 2
  #define _DEBUG_LT(x, y)   ((x) < (y))
  #define _DEBUG_LT_PRED(pred, x, y)	pred(x, y)
  #define _DEBUG_ORDER_PRED(first, last, pred)
  #define _DEBUG_POINTER(first)
  #define _DEBUG_POINTER_IF(test, first)
  #define _DEBUG_POINTER2(first, file, line)
  #define _DEBUG_RANGE(first, last)
  #define _DEBUG_RANGE2(first, last, file, line)
  #define _DEBUG_RANGE_PTR(first, last, ptr)
  #define _DEBUG_RANGE_PTR2(first, last, ptr, file, line)

 #else /* _ITERATOR_DEBUG_LEVEL < 2 */
  #define _FILENAME __FILE__

  #ifndef _DEBUG_LT_IMPL
   #define _DEBUG_LT_IMPL   _Debug_lt
  #endif /* _DEBUG_LT_IMPL */

  #define _DEBUG_LT(x, y) \
	_DEBUG_LT_IMPL(x, y, _FILENAME, __LINE__)

  #ifndef _DEBUG_LT_PRED_IMPL
   #define _DEBUG_LT_PRED_IMPL  _Debug_lt_pred
  #endif /* _DEBUG_LT_PRED_IMPL */

  #define _DEBUG_LT_PRED(pred, x, y) \
	_DEBUG_LT_PRED_IMPL(pred, x, y, _FILENAME, __LINE__)

  #ifndef _DEBUG_ORDER_IMPL
   #define _DEBUG_ORDER_IMPL	_Debug_order
  #endif /* _DEBUG_ORDER_IMPL */

  #define _DEBUG_ORDER_PRED(first, last, pred)  \
	_DEBUG_ORDER_IMPL(first, last, pred, _FILENAME, __LINE__)

  #ifndef _DEBUG_POINTER_IMPL
   #define _DEBUG_POINTER_IMPL  _Debug_pointer
  #endif /* _DEBUG_POINTER_IMPL */

  #define _DEBUG_POINTER(first) \
	_DEBUG_POINTER_IMPL(first, _FILENAME, __LINE__)
  #define _DEBUG_POINTER2(first, file, line)	\
	_DEBUG_POINTER_IMPL(first, file, line)

  #ifndef _DEBUG_POINTER_IF_IMPL
   #define _DEBUG_POINTER_IF_IMPL   _Debug_pointer_if
  #endif /* _DEBUG_POINTER_IF_IMPL */

  #define _DEBUG_POINTER_IF(test, first)	\
	_DEBUG_POINTER_IF_IMPL(test, first, _FILENAME, __LINE__)

  #ifndef _DEBUG_RANGE_IMPL
   #define _DEBUG_RANGE_IMPL	_Debug_range
  #endif /* _DEBUG_RANGE_IMPL */

  #define _DEBUG_RANGE(first, last) \
	_DEBUG_RANGE_IMPL(first, last, _FILENAME, __LINE__)
  #define _DEBUG_RANGE2(first, last, file, line)	\
	_DEBUG_RANGE_IMPL(first, last, file, line)

  #ifndef _DEBUG_RANGE_PTR_IMPL
   #define _DEBUG_RANGE_PTR_IMPL	_Debug_range_ptr
  #endif /* _DEBUG_RANGE_PTR_IMPL */

  #define _DEBUG_RANGE_PTR(first, last, ptr)	\
	_DEBUG_RANGE_PTR_IMPL(first, last, ptr, _FILENAME, __LINE__)
  #define _DEBUG_RANGE_PTR2(first, last, ptr, file, line)   \
	_DEBUG_RANGE_PTR_IMPL(first, last, ptr, file, line)

		// TEMPLATE FUNCTION _Debug_lt_pred
template<class _Pr,
	class _Ty1,
	class _Ty2> inline
	_CONST_FUN bool _Debug_lt_pred(_Pr _Pred,
		_Ty1&& _Left, _Ty2&& _Right,
		_Dbfile_t _File, _Dbline_t _Line)
	{	// test if _Pred(_Left, _Right) and _Pred is strict weak ordering
	return (!_Pred(_Left, _Right)
		? false
		: _Pred(_Right, _Left)
			? (_DEBUG_ERROR2("invalid comparator", _File, _Line), true)
			: true);
	}

		// TEMPLATE FUNCTION _Debug_lt
template<class _Ty1,
	class _Ty2> inline
	_CONST_FUN bool _Debug_lt(_Ty1&& _Left, _Ty2&& _Right,
		_Dbfile_t _File, _Dbline_t _Line)
	{	// test if _Left < _Right and operator< is strict weak ordering
	return (_Debug_lt_pred(less<>(),
		_STD forward<_Ty1>(_Left), _STD forward<_Ty2>(_Right), _File, _Line));
	}

		// TEMPLATE FUNCTION _Debug_pointer
template<class _InIt> inline
	void _Debug_pointer(_InIt&, _Dbfile_t, _Dbline_t)
	{	// (don't) test non-pointer for non-singularity, arbitrary type
	}

template<class _Ty> inline
	void _Debug_pointer(_Ty *_Ptr, _Dbfile_t _File, _Dbline_t _Line)
	{	// test pointer for non-singularity, pointers
	if (_Ptr == 0)
		_DEBUG_ERROR2("invalid null pointer", _File, _Line);
	}

		// TEMPLATE FUNCTION _Debug_pointer_if
template<class _InIt> inline
	void _Debug_pointer_if(bool, _InIt&, _Dbfile_t, _Dbline_t)
	{	// (don't) test non-pointer for non-singularity, arbitrary type
	}

template<class _Ty> inline
	void _Debug_pointer_if(bool _Test, _Ty *_Ptr,
		_Dbfile_t _File, _Dbline_t _Line)
	{	// conditionally test pointer for non-singularity, pointers
	if (_Test && _Ptr == 0)
		_DEBUG_ERROR2("invalid null pointer", _File, _Line);
	}

		// TEMPLATE FUNCTION _Debug_range
template<class _InIt> inline
	void _Debug_range2(_InIt _First, _InIt _Last,
		_Dbfile_t, _Dbline_t, input_iterator_tag)
	{	// test iterator pair for valid range, arbitrary iterators
	bool _Ans = _First == _Last;	// make sure they're comparable
	_Ans = _Ans;	// to quiet diagnostics
	}

template<class _RanIt> inline
	void _Debug_range2(_RanIt _First, _RanIt _Last,
		_Dbfile_t _File, _Dbline_t _Line, random_access_iterator_tag)
	{	// test iterator pair for valid range, random-access iterators
	if (_First != _Last)
		{	// check for non-null pointers, valid range
		_DEBUG_POINTER2(_First, _File, _Line);
		_DEBUG_POINTER2(_Last, _File, _Line);
		if (_Last < _First)
			_DEBUG_ERROR2("invalid iterator range", _File, _Line);
		}
	}

template<class _InIt> inline
	void _Debug_range(_InIt _First, _InIt _Last,
		_Dbfile_t _File, _Dbline_t _Line)
	{	// test iterator pair for valid range
	_Debug_range2(_First, _Last, _File, _Line, _Iter_cat(_First));
	}

		// TEMPLATE FUNCTION _Debug_range_ptr
template<class _InIt,
	class _Pty> inline
	void _Debug_range_ptr2(_InIt _First, _InIt _Last, _Pty& _Ptr,
		_Dbfile_t _File, _Dbline_t _Line, input_iterator_tag)
	{	// test iterator pair for valid range/pointer, arbitrary iterators
	if (_First != _Last)
		_DEBUG_POINTER2(_Ptr, _File, _Line);	// test only if used
	}

template<class _RanIt,
	class _Pty> inline
	void _Debug_range_ptr2(_RanIt _First, _RanIt _Last, _Pty& _Ptr,
		_Dbfile_t _File, _Dbline_t _Line, random_access_iterator_tag)
	{	// test iterator pair for valid range/pointer, random-access iterators
	if (_First != _Last)
		{	// check for non-null pointers, valid range
		_DEBUG_POINTER2(_First, _File, _Line);
		_DEBUG_POINTER2(_Last, _File, _Line);
		if (_Last < _First)
			_DEBUG_ERROR2("invalid iterator range", _File, _Line);
		_DEBUG_POINTER2(_Ptr, _File, _Line);	// test only if used
		}
	}

template<class _InIt,
	class _Pty> inline
	void _Debug_range_ptr(_InIt _First, _InIt _Last, _Pty& _Ptr,
		_Dbfile_t _File, _Dbline_t _Line)
	{	// test iterator pair for valid range/pointer
	_Debug_range_ptr2(_First, _Last, _Ptr, _File, _Line, _Iter_cat(_First));
	}

		// TEMPLATE FUNCTION _Debug_order WITH PRED
template<class _InIt,
	class _Pr> inline
	void _Debug_order2(_InIt, _InIt, _Pr,
		_Dbfile_t, _Dbline_t, input_iterator_tag)
	{	// test if range is ordered by predicate, input iterators
	}

template<class _FwdIt,
	class _Pr> inline
	void _Debug_order2(_FwdIt _First, _FwdIt _Last, _Pr _Pred,
		_Dbfile_t _File, _Dbline_t _Line, forward_iterator_tag)
	{	// test if range is ordered by predicate, forward iterators
	for (_FwdIt _Next = _First; _First != _Last && ++_Next != _Last; ++_First)
		if (_DEBUG_LT_PRED(_Pred, *_Next, *_First))
			_DEBUG_ERROR2("sequence not ordered", _File, _Line);
	}

template<class _InIt,
	class _Pr> inline
	void _Debug_order(_InIt _First, _InIt _Last, _Pr _Pred,
		_Dbfile_t _File, _Dbline_t _Line)
	{	// test if range is ordered by predicate
	_DEBUG_RANGE_PTR2(_First, _Last, _Pred, _File, _Line);
	_Debug_order2(_First, _Last, _Pred, _File, _Line, _Iter_cat(_First));
	}
 #endif /* _ITERATOR_DEBUG_LEVEL < 2 */

		// MORE ITERATOR STUFF (from <iterator>)
		// TEMPLATE FUNCTION _Val_type
template<class _Iter> inline
	typename iterator_traits<_Iter>::value_type *_Val_type(_Iter)
	{	// return value type from arbitrary argument
	return (0);
	}

		// TEMPLATE FUNCTION advance
template<class _InIt,
	class _Diff> inline
	void _Advance(_InIt& _Where, _Diff _Off, input_iterator_tag)
	{	// increment iterator by offset, input iterators
 #if _ITERATOR_DEBUG_LEVEL == 2
	if (_Off < 0)
		_DEBUG_ERROR("negative offset in advance");
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

	for (; 0 < _Off; --_Off)
		++_Where;
	}

template<class _FwdIt,
	class _Diff> inline
	void _Advance(_FwdIt& _Where, _Diff _Off, forward_iterator_tag)
	{	// increment iterator by offset, forward iterators
 #if _ITERATOR_DEBUG_LEVEL == 2
	if (_Off < 0)
		_DEBUG_ERROR("negative offset in advance");
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

	for (; 0 < _Off; --_Off)
		++_Where;
	}

template<class _BidIt,
	class _Diff> inline
	void _Advance(_BidIt& _Where, _Diff _Off, bidirectional_iterator_tag)
	{	// increment iterator by offset, bidirectional iterators
	for (; 0 < _Off; --_Off)
		++_Where;
	for (; _Off < 0; ++_Off)
		--_Where;
	}

template<class _RanIt,
	class _Diff> inline
	void _Advance(_RanIt& _Where, _Diff _Off, random_access_iterator_tag)
	{	// increment iterator by offset, random-access iterators
	_Where += _Off;
	}

template<class _InIt,
	class _Diff> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	void advance(_InIt& _Where, _Diff _Off)
	{	// increment iterator by offset, arbitrary iterators
	_Advance(_Where, _Off, _Iter_cat(_Where));
	}

		// TEMPLATE FUNCTION _Dist_type
template<class _Iter> inline
	typename iterator_traits<_Iter>::difference_type
		*_Dist_type(_Iter)
	{	// return distance type from arbitrary argument
	return (0);
	}

		// TEMPLATE FUNCTIONS distance and _Distance
template<class _InIt,
	class _Diff> inline
		void _Distance2(_InIt _First, _InIt _Last, _Diff& _Off,
			input_iterator_tag)
	{	// add to _Off distance between input iterators
	for (; _First != _Last; ++_First)
		++_Off;
	}

template<class _FwdIt,
	class _Diff> inline
		void _Distance2(_FwdIt _First, _FwdIt _Last, _Diff& _Off,
			forward_iterator_tag)
	{	// add to _Off distance between forward iterators (redundant)
	for (; _First != _Last; ++_First)
		++_Off;
	}

template<class _BidIt,
	class _Diff> inline
		void _Distance2(_BidIt _First, _BidIt _Last, _Diff& _Off,
			bidirectional_iterator_tag)
	{	// add to _Off distance between bidirectional iterators (redundant)
	for (; _First != _Last; ++_First)
		++_Off;
	}

template<class _RanIt,
	class _Diff> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
		void _Distance2(_RanIt _First, _RanIt _Last, _Diff& _Off,
			random_access_iterator_tag)
	{	// add to _Off distance between random-access iterators
 #if _ITERATOR_DEBUG_LEVEL == 2
	if (_First != _Last)
		{	// check for null pointers
		_DEBUG_POINTER(_First);
		_DEBUG_POINTER(_Last);
		}
 #endif /* _ITERATOR_DEBUG_LEVEL == 2 */

	_Off += _Last - _First;
	}

template<class _InIt> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	typename iterator_traits<_InIt>::difference_type
		distance(_InIt _First, _InIt _Last)
	{	// return distance between iterators
	typename iterator_traits<_InIt>::difference_type _Off = 0;
	_Distance2(_First, _Last, _Off, _Iter_cat(_First));
	return (_Off);
	}

template<class _InIt,
	class _Diff> inline
		void _Distance(_InIt _First, _InIt _Last, _Diff& _Off)
	{	// add to _Off distance between iterators
	_Distance2(_First, _Last, _Off, _Iter_cat(_First));
	}

		// TEMPLATE FUNCTION next
template<class _FwdIt> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	_FwdIt next(_FwdIt _First,
		typename iterator_traits<_FwdIt>::difference_type _Off = 1)
	{	// increment iterator
	_STATIC_ASSERT2((is_base_of<forward_iterator_tag,
		typename iterator_traits<_FwdIt>::iterator_category>::value),
		"next requires forward iterator");

	_STD advance(_First, _Off);
	return (_First);
	}

		// TEMPLATE FUNCTION prev
template<class _BidIt> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	_BidIt prev(_BidIt _First,
		typename iterator_traits<_BidIt>::difference_type _Off = 1)
	{	// decrement iterator
	_STATIC_ASSERT2((is_base_of<bidirectional_iterator_tag,
		typename iterator_traits<_BidIt>::iterator_category>::value),
		"prev requires bidirectional iterator");

	_STD advance(_First, -_Off);
	return (_First);
	}

		// TEMPLATE CLASS _Revranit
template<class _Ty>
	struct pointer_traits;

template<class _RanIt,
	class _Base>
	class _Revranit
		: public _Base
	{	// wrap iterator to run it backwards
public:
	typedef _Revranit<_RanIt, _Base> _Myt;
	typedef typename _Base::difference_type difference_type;
	typedef typename _Base::pointer pointer;
	typedef typename _Base::reference reference;
	typedef _RanIt iterator_type;

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Revranit()
		: current()
		{	// construct with value-initialized wrapped iterator
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	explicit _Revranit(_RanIt _Right)
		: current(_Right)
		{	// construct wrapped iterator from _Right
		}

	template<class _RanIt2,
		class _Base2>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
		_Revranit(const _Revranit<_RanIt2, _Base2>& _Right)
		: current(_Right.base())
		{	// initialize with compatible base
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_RanIt base() const
		{	// return wrapped iterator
		return (current);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	reference operator*() const
		{	// return designated value
		_RanIt _Tmp = current;
		return (*--_Tmp);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	pointer operator->() const
		{	// return pointer to class object
		return (_POINTER_TO(**this));
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt& operator++()
		{	// preincrement
		--current;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt operator++(int)
		{	// postincrement
		_Myt _Tmp = *this;
		--current;
		return (_Tmp);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt& operator--()
		{	// predecrement
		++current;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt operator--(int)
		{	// postdecrement
		_Myt _Tmp = *this;
		++current;
		return (_Tmp);
		}

	template<class _RanIt2,
		class _Base2>
		bool _Equal(const _Revranit<_RanIt2, _Base2>& _Right) const
		{	// test for iterator equality
		return (current == _Right.base());
		}

// N.B. functions valid for random-access iterators only beyond this point

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt& operator+=(difference_type _Off)
		{	// increment by integer
		current -= _Off;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt operator+(difference_type _Off) const
		{	// return this + integer
		return (_Myt(current - _Off));
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt& operator-=(difference_type _Off)
		{	// decrement by integer
		current += _Off;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt operator-(difference_type _Off) const
		{	// return this - integer
		return (_Myt(current + _Off));
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	reference operator[](difference_type _Off) const
		{	// subscript
		return (*(*this + _Off));
		}

	template<class _RanIt2,
		class _Base2>
		bool _Less(const _Revranit<_RanIt2, _Base2>& _Right) const
		{	// test if this < _Right
		return (_Right.base() < current);
		}

	difference_type operator-(const _Myt& _Right) const
		{	// return difference of iterators
		return (_Right.base() - current);
		}

protected:
	_RanIt current; // the wrapped iterator
	};

		// TEMPLATE CLASS reverse_iterator
template<class _RanIt>
	class reverse_iterator
		: public _Revranit<_RanIt, iterator<
			typename iterator_traits<_RanIt>::iterator_category,
			typename iterator_traits<_RanIt>::value_type,
			typename iterator_traits<_RanIt>::difference_type,
			typename iterator_traits<_RanIt>::pointer,
			typename iterator_traits<_RanIt>::reference> >
	{	// wrap iterator to run it backwards
	typedef reverse_iterator<_RanIt> _Myt;
	typedef _Revranit<_RanIt, iterator<
		typename iterator_traits<_RanIt>::iterator_category,
		typename iterator_traits<_RanIt>::value_type,
		typename iterator_traits<_RanIt>::difference_type,
		typename iterator_traits<_RanIt>::pointer,
		typename iterator_traits<_RanIt>::reference> > _Mybase;

public:
	typedef typename iterator_traits<_RanIt>::difference_type difference_type;
	typedef typename iterator_traits<_RanIt>::pointer pointer;
	typedef typename iterator_traits<_RanIt>::reference reference;
	typedef _RanIt iterator_type;

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif 
	reverse_iterator()
		{	// construct with default wrapped iterator
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	explicit reverse_iterator(_RanIt _Right)
		: _Mybase(_Right)
		{	// construct wrapped iterator from _Right
		}

	template<class _Other>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
		reverse_iterator(const reverse_iterator<_Other>& _Right)
		: _Mybase(_Right.base())
		{	// initialize with compatible base
		}

	reverse_iterator(_Mybase _Right)
		: _Mybase(_Right)
		{	// construct wrapped iterator from base object
		}

	template<class _Other>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
		_Myt& operator=(const reverse_iterator<_Other>& _Right)
		{	// assign from compatible base
		this->current = _Right.base();
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt& operator++()
		{	// preincrement
		++*((_Mybase *)this);
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt operator++(int)
		{	// postincrement
		_Myt _Tmp = *this;
		++*this;
		return (_Tmp);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt& operator--()
		{	// predecrement
		--*((_Mybase *)this);
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt operator--(int)
		{	// postdecrement
		_Myt _Tmp = *this;
		--*this;
		return (_Tmp);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt& operator+=(difference_type _Off)
		{	// increment by integer
		*((_Mybase *)this) += _Off;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt operator+(difference_type _Off) const
		{	// return this + integer
		_Myt _Tmp = *this;
		return (_Tmp += _Off);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt& operator-=(difference_type _Off)
		{	// decrement by integer
		*((_Mybase *)this) -= _Off;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif	
	_Myt operator-(difference_type _Off) const
		{	// return this - integer
		_Myt _Tmp = *this;
		return (_Tmp -= _Off);
		}
	};

template<class _RanIt>
	struct _Is_checked_helper<reverse_iterator<_RanIt> >
		: public _Is_checked_helper<_RanIt>
	{	// mark reverse_iterator as checked if its wrapped iterator is checked
	};

		// reverse_iterator TEMPLATE OPERATORS
template<class _RanIt> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	reverse_iterator<_RanIt> operator+(
		typename reverse_iterator<_RanIt>::difference_type _Off,
		const reverse_iterator<_RanIt>& _Right)
	{	// return reverse_iterator + integer
	return (_Right + _Off);
	}

#if defined(__ghs)
template<class _RanIt> inline
	typename reverse_iterator<_RanIt>::difference_type
		operator-(const reverse_iterator<_RanIt>& _Left,
			const reverse_iterator<_RanIt>& _Right)
	{	// return difference of reverse_iterators
	return (_Right.base() - _Left.base());
	}
#endif /* defined(__ghs) */

 #if _HAS_DECLTYPE
template<class _RanIt1,
	class _RanIt2>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline operator-(const reverse_iterator<_RanIt1>& _Left,
		const reverse_iterator<_RanIt2>& _Right)
			-> decltype(_Right.base() - _Left.base())
	{	// return difference of reverse_iterators
	return (_Right.base() - _Left.base());
	}
 #else /* _HAS_DECLTYPE */
template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	typename reverse_iterator<_RanIt1>::difference_type
		operator-(const reverse_iterator<_RanIt1>& _Left,
			const reverse_iterator<_RanIt2>& _Right)
	{	// return difference of reverse_iterators
	return (_Right.base() - _Left.base());
	}
 #endif /* _HAS_DECLTYPE */

#if defined(__ghs)
template<class _RanIt> inline
#if _HAS_CPP17
        _CONST_FUN
#endif	
	bool operator==(const reverse_iterator<_RanIt>& _Left,
		const reverse_iterator<_RanIt>& _Right)
	{	// test for reverse_iterator equality
	return (_Left.base() == _Right.base());
	}
#endif /* defined(__ghs) */

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator==(const reverse_iterator<_RanIt1>& _Left,
		const reverse_iterator<_RanIt2>& _Right)
	{	// test for reverse_iterator equality
	return (_Left.base() == _Right.base());
	}

#if defined(__ghs)
template<class _RanIt> inline
#if _HAS_CPP17
        _CONST_FUN
#endif	
	bool operator!=(const reverse_iterator<_RanIt>& _Left,
		const reverse_iterator<_RanIt>& _Right)
	{	// test for reverse_iterator inequality
	return (!(_Left == _Right));
	}
#endif /* defined(__ghs) */

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator!=(const reverse_iterator<_RanIt1>& _Left,
		const reverse_iterator<_RanIt2>& _Right)
	{	// test for reverse_iterator inequality
	return (!(_Left == _Right));
	}

#if defined(__ghs)
template<class _RanIt> inline
#if _HAS_CPP17
        _CONST_FUN
#endif	
	bool operator<(const reverse_iterator<_RanIt>& _Left,
		const reverse_iterator<_RanIt>& _Right)
	{	// test for reverse_iterator < reverse_iterator
	return (_Right.base() < _Left.base());
	}
#endif /* defined(__ghs) */

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator<(const reverse_iterator<_RanIt1>& _Left,
		const reverse_iterator<_RanIt2>& _Right)
	{	// test for reverse_iterator < reverse_iterator
	return (_Right.base() < _Left.base());
	}

#if defined(__ghs)
template<class _RanIt> inline
#if _HAS_CPP17
        _CONST_FUN
#endif	
	bool operator>(const reverse_iterator<_RanIt>& _Left,
		const reverse_iterator<_RanIt>& _Right)
	{	// test for reverse_iterator > reverse_iterator
	return (_Right < _Left);
	}
#endif /* defined(__ghs) */

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator>(const reverse_iterator<_RanIt1>& _Left,
		const reverse_iterator<_RanIt2>& _Right)
	{	// test for reverse_iterator > reverse_iterator
	return (_Right < _Left);
	}

#if defined(__ghs)
template<class _RanIt> inline
#if _HAS_CPP17
        _CONST_FUN
#endif	
	bool operator<=(const reverse_iterator<_RanIt>& _Left,
		const reverse_iterator<_RanIt>& _Right)
	{	// test for reverse_iterator <= reverse_iterator
	return (!(_Right < _Left));
	}
#endif /* defined(__ghs) */

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator<=(const reverse_iterator<_RanIt1>& _Left,
		const reverse_iterator<_RanIt2>& _Right)
	{	// test for reverse_iterator <= reverse_iterator
	return (!(_Right < _Left));
	}

#if defined(__ghs)
template<class _RanIt> inline
#if _HAS_CPP17
        _CONST_FUN
#endif	
	bool operator>=(const reverse_iterator<_RanIt>& _Left,
		const reverse_iterator<_RanIt>& _Right)
	{	// test for reverse_iterator >= reverse_iterator
	return (!(_Left < _Right));
	}
#endif /* defined(__ghs) */

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator>=(const reverse_iterator<_RanIt1>& _Left,
		const reverse_iterator<_RanIt2>& _Right)
	{	// test for reverse_iterator >= reverse_iterator
	return (!(_Left < _Right));
	}

 #if _HAS_CPP11
		// TEMPLATE FUNCTION make_reverse_iterator
template<class _RanIt> inline
	reverse_iterator<_RanIt> make_reverse_iterator(_RanIt _Iter)
	{	// make reverse_iterator from iterator
	return (reverse_iterator<_RanIt>(_Iter));
	}

		// TEMPLATE FUNCTIONS begin AND end

template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline begin(_Container& _Cont) -> decltype(_Cont.begin())
	{	// get beginning of sequence
	return (_Cont.begin());
	}

template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline begin(const _Container& _Cont) -> decltype(_Cont.begin())
	{	// get beginning of sequence
	return (_Cont.begin());
	}

template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline end(_Container& _Cont) -> decltype(_Cont.end())
	{	// get end of sequence
	return (_Cont.end());
	}

template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline end(const _Container& _Cont) -> decltype(_Cont.end())
	{	// get end of sequence
	return (_Cont.end());
	}

template<class _Ty,
	size_t _Size> inline
	_CONST_FUN _Ty *begin(_Ty (&_Array)[_Size]) _NOEXCEPT
	{	// get beginning of array
	return (_Array);
	}

template<class _Ty,
	size_t _Size> inline
	_CONST_FUN _Ty *end(_Ty (&_Array)[_Size]) _NOEXCEPT
	{	// get end of array
	return (_Array + _Size);
	}

		// TEMPLATE FUNCTIONS cbegin AND cend
template<class _Ty>
	class valarray;
template<class _Ty>
	_Ty *begin(valarray<_Ty>&);
template<class _Ty>
	const _Ty *begin(const valarray<_Ty>&);
template<class _Ty>
	_Ty *end(valarray<_Ty>&);
template<class _Ty>
	const _Ty *end(const valarray<_Ty>&);

template<class _Container>
	_CONST_FUN auto inline cbegin(const _Container& _Cont)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_STD begin(_Cont)))
		-> decltype(_STD begin(_Cont))
	{	// get beginning of sequence
	return (_STD begin(_Cont));
	}

template<class _Container>
	_CONST_FUN auto inline cend(const _Container& _Cont)
		_NOEXCEPT_OP(_NOEXCEPT_OP(_STD end(_Cont)))
		-> decltype(_STD end(_Cont))
	{	// get end of sequence
	return (_STD end(_Cont));
	}

		// TEMPLATE FUNCTIONS rbegin AND rend
template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline rbegin(_Container& _Cont) -> decltype(_Cont.rbegin())
	{	// get beginning of reversed sequence
	return (_Cont.rbegin());
	}

template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline rbegin(const _Container& _Cont) -> decltype(_Cont.rbegin())
	{	// get beginning of reversed sequence
	return (_Cont.rbegin());
	}

template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline rend(_Container& _Cont) -> decltype(_Cont.rend())
	{	// get end of reversed sequence
	return (_Cont.rend());
	}

template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline rend(const _Container& _Cont) -> decltype(_Cont.rend())
	{	// get end of reversed sequence
	return (_Cont.rend());
	}

template<class _Ty,
	size_t _Size> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	reverse_iterator<_Ty *> rbegin(_Ty (&_Array)[_Size])
	{	// get beginning of reversed array
	return (reverse_iterator<_Ty *>(_Array + _Size));
	}

template<class _Ty,
	size_t _Size> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	reverse_iterator<_Ty *> rend(_Ty (&_Array)[_Size])
	{	// get end of reversed array
	return (reverse_iterator<_Ty *>(_Array));
	}

template<class _Elem> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	reverse_iterator<const _Elem *>
		rbegin(_XSTD initializer_list<_Elem> _Ilist)
	{	// get beginning of reversed sequence
	return (reverse_iterator<const _Elem *>(_Ilist.end()));
	}

template<class _Elem> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	reverse_iterator<const _Elem *>
		rend(_XSTD initializer_list<_Elem> _Ilist)
	{	// get end of reversed sequence
	return (reverse_iterator<const _Elem *>(_Ilist.begin()));
	}

		// TEMPLATE FUNCTIONS crbegin AND crend
template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline crbegin(const _Container& _Cont)
		-> decltype(_STD rbegin(_Cont))
	{	// get beginning of reversed sequence
	return (_STD rbegin(_Cont));
	}

template<class _Container>
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	auto inline crend(const _Container& _Cont)
		-> decltype(_STD rend(_Cont))
	{	// get end of reversed sequence
	return (_STD rend(_Cont));
	}

 #else /* _HAS_CPP11 */
template<class _Ty,
	size_t _Size> inline
	_Ty *begin(_Ty (&_Array)[_Size]) _NOEXCEPT
	{	// get beginning of array
	return (_Array);
	}

template<class _Ty,
	size_t _Size> inline
	_Ty *end(_Ty (&_Array)[_Size]) _NOEXCEPT
	{	// get end of array
	return (_Array + _Size);
	}
#endif /* _HAS_CPP11 */

#if !defined(__ghs) || _HAS_CPP17
// begin: added with C++17
		// TEMPLATE FUNCTION size
template<class _Container>
	_CONST_FUN auto inline size(const _Container& _Cont)
		-> decltype(_Cont.size())
	{	// get size() for container
	return (_Cont.size());
	}

template<class _Ty,
	size_t _Size> inline
	_CONST_FUN size_t size(const _Ty(&)[_Size]) _NOEXCEPT
	{	// get dimension for array
	return (_Size);
	}

		// TEMPLATE FUNCTION empty
template<class _Container>
	_CONST_FUN auto inline empty(const _Container& _Cont)
		-> decltype(_Cont.empty())
	{	// get empty() for container
	return (_Cont.empty());
	}

template<class _Ty,
	size_t _Size> inline
	_CONST_FUN bool empty(const _Ty(&)[_Size]) _NOEXCEPT
	{	// get dimension==0 for array (can't happen)
	return (false);
	}

template<class _Elem> inline
	_CONST_FUN bool empty(
		_XSTD initializer_list<_Elem> _Ilist) _NOEXCEPT
	{	// get dimension==0 for initializer_list
	return (_Ilist.size() == 0);
	}

		// TEMPLATE FUNCTION date
template<class _Container>
	_CONST_FUN auto inline data(_Container& _Cont)
		-> decltype(_Cont.data())
	{	// get data() for container
	return (_Cont.data());
	}

template<class _Container>
	_CONST_FUN auto inline data(const _Container& _Cont)
		-> decltype(_Cont.data())
	{	// get pointer to data of const container
	return (_Cont.data());
	}

template<class _Ty,
	size_t _Size> inline
	_CONST_FUN _Ty *data(_Ty(&_Array)[_Size]) _NOEXCEPT
	{	// get pointer to data of array
	return (_Array);
	}

template<class _Elem> inline
	_CONST_FUN const _Elem *data(
		_XSTD initializer_list<_Elem> _Ilist) _NOEXCEPT
	{	// get pointer to data of initializer_list
	return (_Ilist.begin());
	}

		// TEMPLATE FUNCTION _Erase_nodes_if
template<class _Container,
	class _Pr> inline
	void _Erase_nodes_if(_Container& _Cont, _Pr _Pred)
	{	// erase each element satisfying _Pred
	auto _First = _Cont.begin();
	auto _Last = _Cont.end();
	_DEBUG_POINTER_IF(_First != _Last, _Pred);
	while (_First != _Last)
		if (_Pred(*_First))
			_First = _Cont.erase(_First);
		else
			++_First;
	}
// end: added with C++17
#endif /* !defined(__ghs) || _HAS_CPP17 */

		// TEMPLATE CLASS _Array_const_iterator
template<class _Ty,
	size_t _Size>
	class _Array_const_iterator
		: public _Iterator012<random_access_iterator_tag,
			_Ty,
			ptrdiff_t,
			const _Ty *,
			const _Ty&,
			_Iterator_base>
	{	// iterator for nonmutable array
public:
	typedef _Array_const_iterator<_Ty, _Size> _Myiter;
	typedef random_access_iterator_tag iterator_category;

	typedef _Ty value_type;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;
	typedef const _Ty *pointer;
	typedef const _Ty& reference;

 #if _ITERATOR_DEBUG_LEVEL == 0
#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif
	_Array_const_iterator()
#if defined(__ghs)
		: _Ptr(0)
#endif
		{	// construct with null pointer
#if !defined(_ghs)
		_Ptr = 0;
#endif
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif
	explicit _Array_const_iterator(pointer _Parg, size_t _Off = 0)
#if defined(__ghs)
		: _Ptr(_Parg + _Off)
#endif
		{	// construct with pointer and offset
#if !defined(_ghs)
		_Ptr = _Parg + _Off;
#endif
		}

	typedef pointer _Unchecked_type;

	_Myiter& _Rechecked(_Unchecked_type _Right)
		{	// reset from unchecked iterator
		_Ptr = _Right;
		return (*this);
		}

	_Unchecked_type _Unchecked() const
		{	// make an unchecked iterator
		return (_Ptr);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif
	reference operator*() const
		{	// return designated object
		return (*_Ptr);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif
	pointer operator->() const
		{	// return pointer to class object
		return (_POINTER_TO(**this));
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter& operator++()
		{	// preincrement
		++_Ptr;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter operator++(int)
		{	// postincrement
		_Myiter _Tmp = *this;
		++*this;
		return (_Tmp);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter& operator--()
		{	// predecrement
		--_Ptr;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter operator--(int)
		{	// postdecrement
		_Myiter _Tmp = *this;
		--*this;
		return (_Tmp);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter& operator+=(difference_type _Off)
		{	// increment by integer
		_Ptr += _Off;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter operator+(difference_type _Off) const
		{	// return this + integer
		_Myiter _Tmp = *this;
		return (_Tmp += _Off);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter& operator-=(difference_type _Off)
		{	// decrement by integer
		return (*this += -_Off);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter operator-(difference_type _Off) const
		{	// return this - integer
		_Myiter _Tmp = *this;
		return (_Tmp -= _Off);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	difference_type operator-(const _Myiter& _Right) const
		{	// return difference of iterators
		return (_Ptr - _Right._Ptr);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	reference operator[](difference_type _Off) const
		{	// subscript
		return (*(*this + _Off));
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	bool operator==(const _Myiter& _Right) const
		{	// test for iterator equality
		return (_Ptr == _Right._Ptr);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	bool operator!=(const _Myiter& _Right) const
		{	// test for iterator inequality
		return (!(*this == _Right));
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	bool operator<(const _Myiter& _Right) const
		{	// test if this < _Right
		return (_Ptr < _Right._Ptr);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	bool operator>(const _Myiter& _Right) const
		{	// test if this > _Right
		return (_Right < *this);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	bool operator<=(const _Myiter& _Right) const
		{	// test if this <= _Right
		return (!(_Right < *this));
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	bool operator>=(const _Myiter& _Right) const
		{	// test if this >= _Right
		return (!(*this < _Right));
		}

	pointer _Ptr;   // beginning of array

 #else /* _ITERATOR_DEBUG_LEVEL == 0 */
	_Array_const_iterator()
		{	// construct with null pointer
		_Ptr = 0;
		_Idx = 0;
		}

	explicit _Array_const_iterator(pointer _Parg, size_t _Off = 0)
		{	// construct with pointer and offset
		_Ptr = _Parg;
		_Idx = _Off;
		}

	typedef pointer _Unchecked_type;

	_Myiter& _Rechecked(_Unchecked_type _Right)
		{	// reset from unchecked iterator
		_Idx = _Right - _Ptr;
		return (*this);
		}

	_Unchecked_type _Unchecked() const
		{	// make an unchecked iterator
		return (_Ptr + _Idx);
		}

	reference operator*() const
		{	// return designated object
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Ptr == 0
			|| _Size <= _Idx)
			{	// report error
			_DEBUG_ERROR("array iterator not dereferencable");
			_SCL_SECURE_OUT_OF_RANGE;
			}

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE(_Ptr != 0);
		_SCL_SECURE_VALIDATE_RANGE(_Idx < _Size);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (_Ptr[_Idx]);
		}

	pointer operator->() const
		{	// return pointer to class object
		return (_POINTER_TO(**this));
		}

	_Myiter& operator++()
		{	// preincrement
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Ptr == 0
			|| _Size <= _Idx)
			{	// report error
			_DEBUG_ERROR("array iterator not incrementable");
			_SCL_SECURE_OUT_OF_RANGE;
			}

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE(_Ptr != 0);
		_SCL_SECURE_VALIDATE_RANGE(_Idx < _Size);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		++_Idx;
		return (*this);
		}

	_Myiter operator++(int)
		{	// postincrement
		_Myiter _Tmp = *this;
		++*this;
		return (_Tmp);
		}

	_Myiter& operator--()
		{	// predecrement
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Ptr == 0
			|| _Idx <= 0)
			{	// report error
			_DEBUG_ERROR("array iterator not decrementable");
			_SCL_SECURE_OUT_OF_RANGE;
			}

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE(_Ptr != 0);
		_SCL_SECURE_VALIDATE_RANGE(0 < _Idx);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		--_Idx;
		return (*this);
		}

	_Myiter operator--(int)
		{	// postdecrement
		_Myiter _Tmp = *this;
		--*this;
		return (_Tmp);
		}

	_Myiter& operator+=(difference_type _Off)
		{	// increment by integer
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (_Size < _Idx + _Off)
			{	// report error
			_DEBUG_ERROR("array iterator + offset out of range");
			_SCL_SECURE_OUT_OF_RANGE;
			}

 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(_Idx + _Off <= _Size);
 #endif /* _ITERATOR_DEBUG_LEVEL */

		_Idx += _Off;
		return (*this);
		}

	_Myiter operator+(difference_type _Off) const
		{	// return this + integer
		_Myiter _Tmp = *this;
		return (_Tmp += _Off);
		}

	_Myiter& operator-=(difference_type _Off)
		{	// decrement by integer
		return (*this += -_Off);
		}

	_Myiter operator-(difference_type _Off) const
		{	// return this - integer
		_Myiter _Tmp = *this;
		return (_Tmp -= _Off);
		}

	difference_type operator-(const _Myiter& _Right) const
		{	// return difference of iterators
		_Compat(_Right);
		return (_Idx < _Right._Idx
			? -(difference_type)(_Right._Idx - _Idx)
			: (difference_type)_Idx - _Right._Idx);
		}

	reference operator[](difference_type _Off) const
		{	// subscript
		return (*(*this + _Off));
		}

	bool operator==(const _Myiter& _Right) const
		{	// test for iterator equality
		_Compat(_Right);
		return (_Idx == _Right._Idx);
		}

	bool operator!=(const _Myiter& _Right) const
		{	// test for iterator inequality
		return (!(*this == _Right));
		}

	bool operator<(const _Myiter& _Right) const
		{	// test if this < _Right
		_Compat(_Right);
		return (_Idx < _Right._Idx);
		}

	bool operator>(const _Myiter& _Right) const
		{	// test if this > _Right
		return (_Right < *this);
		}

	bool operator<=(const _Myiter& _Right) const
		{	// test if this <= _Right
		return (!(_Right < *this));
		}

	bool operator>=(const _Myiter& _Right) const
		{	// test if this >= _Right
		return (!(*this < _Right));
		}

 #if _ITERATOR_DEBUG_LEVEL == 2
	void _Compat(const _Myiter& _Right) const
		{	// test for compatible iterator pair
		if (_Ptr != _Right._Ptr)
			{	// report error
			_DEBUG_ERROR("array iterators incompatible");
			_SCL_SECURE_INVALID_ARGUMENT;
			}
		}

 #elif _ITERATOR_DEBUG_LEVEL == 1
	void _Compat(const _Myiter& _Right) const
		{	// test for compatible iterator pair
		_SCL_SECURE_VALIDATE_RANGE(_Ptr == _Right._Ptr);
		}
 #endif /* _ITERATOR_DEBUG_LEVEL */

	pointer _Ptr;   // beginning of array
	size_t _Idx;	// offset into array
 #endif /* _ITERATOR_DEBUG_LEVEL == 0 */
	};

template<class _Ty,
	size_t _Size> inline
	typename _Array_const_iterator<_Ty, _Size>::_Unchecked_type
		_Unchecked(_Array_const_iterator<_Ty, _Size> _Iter)
	{	// convert to unchecked
	return (_Iter._Unchecked());
	}

template<class _Ty,
	size_t _Size> inline
	_Array_const_iterator<_Ty, _Size>&
		_Rechecked(_Array_const_iterator<_Ty, _Size>& _Iter,
			typename _Array_const_iterator<_Ty, _Size>
				::_Unchecked_type _Right)
	{	// convert to checked
	return (_Iter._Rechecked(_Right));
	}

template<class _Ty,
	size_t _Size> inline
#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif
	_Array_const_iterator<_Ty, _Size> operator+(
		typename _Array_const_iterator<_Ty, _Size>::difference_type _Off,
		_Array_const_iterator<_Ty, _Size> _Next)
	{	// add offset to iterator
	return (_Next += _Off);
	}

		// TEMPLATE CLASS _Array_iterator
template<class _Ty,
	size_t _Size>
	class _Array_iterator
		: public _Array_const_iterator<_Ty, _Size>
	{	// iterator for mutable array
public:
	typedef _Array_iterator<_Ty, _Size> _Myiter;
	typedef _Array_const_iterator<_Ty, _Size> _Mybase;
	typedef random_access_iterator_tag iterator_category;

	typedef _Ty value_type;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;
	typedef _Ty *pointer;
	typedef _Ty& reference;

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif
	_Array_iterator()
		{	// construct with null pointer
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	explicit _Array_iterator(pointer _Parg, size_t _Off = 0)
		: _Mybase(_Parg, _Off)
		{	// construct with pointer and offset
		}

	typedef pointer _Unchecked_type;

	_Myiter& _Rechecked(_Unchecked_type _Right)
		{	// reset from unchecked iterator
		((_Mybase *)this)->_Rechecked(_Right);
		return (*this);
		}

	_Unchecked_type _Unchecked() const
		{	// make an unchecked iterator
		return ((pointer)((_Mybase *)this)->_Unchecked());
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	reference operator*() const
		{	// return designated object
		return ((reference)**(_Mybase *)this);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	pointer operator->() const
		{	// return pointer to class object
		return (_POINTER_TO(**this));
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter& operator++()
		{	// preincrement
		++*(_Mybase *)this;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter operator++(int)
		{	// postincrement
		_Myiter _Tmp = *this;
		++*this;
		return (_Tmp);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter& operator--()
		{	// predecrement
		--*(_Mybase *)this;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter operator--(int)
		{	// postdecrement
		_Myiter _Tmp = *this;
		--*this;
		return (_Tmp);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif
	_Myiter& operator+=(difference_type _Off)
		{	// increment by integer
		*(_Mybase *)this += _Off;
		return (*this);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter operator+(difference_type _Off) const
		{	// return this + integer
		_Myiter _Tmp = *this;
		return (_Tmp += _Off);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter& operator-=(difference_type _Off)
		{	// decrement by integer
		return (*this += -_Off);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	_Myiter operator-(difference_type _Off) const
		{	// return this - integer
		_Myiter _Tmp = *this;
		return (_Tmp -= _Off);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	difference_type operator-(const _Mybase& _Right) const
		{	// return difference of iterators
		return (*(_Mybase *)this - _Right);
		}

#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif	
	reference operator[](difference_type _Off) const
		{	// subscript
		return (*(*this + _Off));
		}
	};

template<class _Ty,
	size_t _Size> inline
	typename _Array_iterator<_Ty, _Size>::_Unchecked_type
		_Unchecked(_Array_iterator<_Ty, _Size> _Iter)
	{	// convert to unchecked
	return (_Iter._Unchecked());
	}

template<class _Ty,
	size_t _Size> inline
	_Array_iterator<_Ty, _Size>&
		_Rechecked(_Array_iterator<_Ty, _Size>& _Iter,
			typename _Array_iterator<_Ty, _Size>
				::_Unchecked_type _Right)
	{	// convert to checked
	return (_Iter._Rechecked(_Right));
	}

template<class _Ty,
	size_t _Size> inline
#if defined(__ghs) && _HAS_CPP17
	_CONST_FUN
#endif
	_Array_iterator<_Ty, _Size> operator+(
		typename _Array_iterator<_Ty, _Size>::difference_type _Off,
		_Array_iterator<_Ty, _Size> _Next)
	{	// add offset to iterator
	return (_Next += _Off);
	}
#if !defined(__ghs) || _HAS_CPP11
		// TEMPLATE CLASS move_iterator
template<class _RanIt>
	class move_iterator
	{	// wrap iterator to move rvalues
public:
	typedef move_iterator<_RanIt> _Myt;
	typedef typename iterator_traits<_RanIt>::iterator_category
		iterator_category;
	typedef typename iterator_traits<_RanIt>::value_type
		value_type;
	typedef typename iterator_traits<_RanIt>::difference_type
		difference_type;
	typedef _RanIt pointer;
	typedef typename iterator_traits<_RanIt>::reference _Reftype;
	typedef typename _If<is_reference<_Reftype>::value,
		typename remove_reference<_Reftype>::type&&,
		_Reftype>::type reference;
	typedef _RanIt iterator_type;

	move_iterator()
		: current()
		{	// construct with value-initialized wrapped iterator
		}

	explicit move_iterator(iterator_type _Right)
		: current(_Right)
		{	// construct wrapped iterator from _Right
		}

	template<class _RanIt2>
		move_iterator(const move_iterator<_RanIt2>& _Right)
		: current(_Right.base())
		{	// initialize with compatible base
		}

	template<class _RanIt2>
		_Myt& operator=(const move_iterator<_RanIt2>& _Right)
		{	// assign with compatible base
		current = _Right.base();
		return (*this);
		}

	_RanIt base() const
		{	// return wrapped iterator
		return (current);
		}

	reference operator*() const
		{	// return designated value
		return (_STD move(*current));
		}

	pointer operator->() const
		{	// return pointer to class object
		return (current);
		}

	_Myt& operator++()
		{	// preincrement
		++current;
		return (*this);
		}

	_Myt operator++(int)
		{	// postincrement
		_Myt _Tmp = *this;
		++current;
		return (_Tmp);
		}

	_Myt& operator--()
		{	// predecrement
		--current;
		return (*this);
		}

	_Myt operator--(int)
		{	// postdecrement
		_Myt _Tmp = *this;
		--current;
		return (_Tmp);
		}

	template<class _RanIt2>
		bool _Equal(const move_iterator<_RanIt2>& _Right) const
		{	// test for iterator equality
		return (current == _Right.base());
		}

// N.B. functions valid for random-access iterators only beyond this point

	_Myt& operator+=(difference_type _Off)
		{	// increment by integer
		current += _Off;
		return (*this);
		}

	_Myt operator+(difference_type _Off) const
		{	// return this + integer
		return (_Myt(current + _Off));
		}

	_Myt& operator-=(difference_type _Off)
		{	// decrement by integer
		current -= _Off;
		return (*this);
		}

	_Myt operator-(difference_type _Off) const
		{	// return this - integer
		return (_Myt(current - _Off));
		}

	reference operator[](difference_type _Off) const
		{	// subscript
		return (_STD move(current[_Off]));
		}

	template<class _RanIt2>
		bool _Less(const move_iterator<_RanIt2>& _Right) const
		{	// test if this < _Right
		return (current < _Right.base());
		}

	difference_type operator-(const _Myt& _Right) const
		{	// return difference of iterators
		return (current - _Right.base());
		}

protected:
	iterator_type current;  // the wrapped iterator
	};

template<class _RanIt>
	struct _Is_checked_helper<move_iterator<_RanIt> >
		: public _Is_checked_helper<_RanIt>
	{	// mark move_iterator as checked if its wrapped iterator is checked
	};

		// move_iterator TEMPLATE OPERATORS
template<class _RanIt,
	class _Diff> inline
	move_iterator<_RanIt>
		operator+(_Diff _Off,
		const move_iterator<_RanIt>& _Right)
	{	// return move_iterator + integer
	return (_Right + _Off);
	}

 #if _HAS_DECLTYPE
template<class _RanIt1,
	class _RanIt2>
	auto inline operator-(
		move_iterator<_RanIt1>& _Left,
		const move_iterator<_RanIt2>& _Right)
			-> decltype(_Left.base() - _Right.base())
	{	// test for move_iterator equality
	return (_Left.base() - _Right.base());
	}
 #else
template<class _RanIt1,
	class _RanIt2> inline
	typename _RanIt1::difference_type operator-(
		move_iterator<_RanIt1>& _Left,
		const move_iterator<_RanIt2>& _Right)
	{	// test for move_iterator equality
	return (_Left.base() - _Right.base());
	}
 #endif

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator==(
		const move_iterator<_RanIt1>& _Left,
		const move_iterator<_RanIt2>& _Right)
	{	// test for move_iterator equality
	return (_Left._Equal(_Right));
	}

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator!=(
		const move_iterator<_RanIt1>& _Left,
		const move_iterator<_RanIt2>& _Right)
	{	// test for move_iterator inequality
	return (!(_Left == _Right));
	}

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator<(
		const move_iterator<_RanIt1>& _Left,
		const move_iterator<_RanIt2>& _Right)
	{	// test for move_iterator < move_iterator
	return (_Left._Less(_Right));
	}

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator>(
		const move_iterator<_RanIt1>& _Left,
		const move_iterator<_RanIt2>& _Right)
	{	// test for move_iterator > move_iterator
	return (_Right < _Left);
	}

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator<=(
		const move_iterator<_RanIt1>& _Left,
		const move_iterator<_RanIt2>& _Right)
	{	// test for move_iterator <= move_iterator
	return (!(_Right < _Left));
	}

template<class _RanIt1,
	class _RanIt2> inline
#if defined(__ghs) && _HAS_CPP17
        _CONST_FUN
#endif
	bool operator>=(
		const move_iterator<_RanIt1>& _Left,
		const move_iterator<_RanIt2>& _Right)
	{	// test for move_iterator >= move_iterator
	return (!(_Left < _Right));
	}

		// TEMPLATE FUNCTION make_move_iterator
template<class _RanIt> inline
	move_iterator<_RanIt> make_move_iterator(_RanIt _Iter)
	{	// make move_iterator from iterator
	return (move_iterator<_RanIt>(_Iter));
	}
#endif /* !defined(__ghs) || _HAS_CPP11 */
_STD_END

 #if defined(__ghs)
  #if defined(__ghs_max_pack_value)
   #pragma pack(pop)
  #endif /* defined(__ghs_max_pack_value) */
  #pragma ghs endnowarning 76
  #pragma ghs enddata
  #pragma ghs end_cxx_lib_header
 #endif /* defined(__ghs) */

#endif /* _XITER_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V8.03b/17:0063 */
