// string_view header
#ifndef _XSTRING_VIEW_
#define _XSTRING_VIEW_

#if defined(__ghs)
 #include <yvals.h>
#endif /* __ghs */

#include <xmemory0>

 #if defined(__ghs)
  #pragma ghs start_cxx_lib_header
  #pragma ghs startdata
  #if defined(__ghs_max_pack_value)
   #pragma pack (push, __ghs_max_pack_value)
  #endif /* defined(__ghs_max_pack_value) */
 #endif /* defined(__ghs) */

 #if defined(__ghs) && _HAS_CPP17
  #define __cpp_lib_string_view 201606L
 #endif /* defined(__ghs) && _HAS_CPP17 */

_STD_BEGIN
template<class _Elem,
	class _Traits,
	class _Alloc>
	class basic_string;

template<class _Elem,
	class _Traits = char_traits<_Elem> >
	class basic_string_view
	{	// constant, transparent contiguout sequence of elements
public:
	typedef _Traits traits_type;
	typedef _Elem value_type;
	typedef _Elem *pointer;
	typedef const _Elem *const_pointer;
	typedef _Elem& reference;
	typedef const _Elem& const_reference;
	typedef const _Elem *const_iterator;
	typedef const_iterator iterator;
	typedef reverse_iterator<const_iterator> const_reverse_iterator;
	typedef const_reverse_iterator reverse_iterator;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;
	static _CONST_FUN size_type npos = size_type(-1);

	_CONST_FUN basic_string_view() _NOEXCEPT
		: _Data(nullptr),
		_Size(0)
		{	// default construct
		}

	_CONST_FUN basic_string_view(
		const basic_string_view&) _NOEXCEPT = default;

	basic_string_view& operator=(
		const basic_string_view&) _NOEXCEPT = default;

	template<class _Alloc>
		basic_string_view(
			const basic_string<_Elem, _Traits, _Alloc>& _Str) _NOEXCEPT
		: _Data(_Str.data()),
		_Size(_Str.size())
		{	// construct from basic_string
		}

	_CONST_FUN basic_string_view(const _Elem *_Str)
		: _Data(_Str),
		_Size(_Traits::length(_Str))
		{	// construct from NTCS
		}

	_CONST_FUN basic_string_view(const _Elem *_Str, size_type _Len)
		: _Data(_Str),
		_Size(_Len)
		{	// construct from pointer and length
		}

	_CONST_FUN const_iterator begin() const _NOEXCEPT
		{	// get begin iterator
		return (const_iterator(_Data));
		}
	_CONST_FUN const_iterator end() const _NOEXCEPT
		{	// get end iterator
		return (const_iterator(_Data + _Size));
		}
	_CONST_FUN const_iterator cbegin() const _NOEXCEPT
		{	// get begin iterator
		return (const_iterator(_Data));
		}
	_CONST_FUN const_iterator cend() const _NOEXCEPT
		{	// get end iterator
		return (const_iterator(_Data + _Size));
		}

	_GHS_CONST_FUN17 const_reverse_iterator rbegin() const _NOEXCEPT
		{	// get reverse begin iterator
		return (const_reverse_iterator(end()));
		}
	_GHS_CONST_FUN17 const_reverse_iterator rend() const _NOEXCEPT
		{	// get reverse end iterator
		return (const_reverse_iterator(begin()));
		}
	_GHS_CONST_FUN17 const_reverse_iterator crbegin() const _NOEXCEPT
		{	// get reverse begin iterator
		return (const_reverse_iterator(end()));
		}
	_GHS_CONST_FUN17 const_reverse_iterator crend() const _NOEXCEPT
		{	// get reverse end iterator
		return (const_reverse_iterator(begin()));
		}

	_CONST_FUN size_type size() const _NOEXCEPT
		{	// get size
		return (_Size);
		}
	_CONST_FUN size_type length() const _NOEXCEPT
		{	// get length
		return (_Size);
		}
	_CONST_FUN size_type max_size() const _NOEXCEPT
		{	// get maximum possible length
		return (sizeof (_Elem) == 1 ? (size_type)(-1) - 1
			: (size_type)(-1) / sizeof (_Elem));
		}
	_CONST_FUN bool empty() const _NOEXCEPT
		{	// test for empty string
		return (_Size == 0);
		}

	_CONST_FUN const_reference operator[](size_type _Off) const
		{	// get reference to element at _Off
		return (const_reference(_Data[_Off]));
		}
	_CONST_FUNX const_reference at(size_type _Off) const
		{	// get reference to element at _Off
		if (size() <= _Off)
			_Xout_of_range("basic_string_view::at(offset) out of range");
		return (const_reference(_Data[_Off]));
		}

	_CONST_FUN const_reference front() const
		{	// get reference to first element
		return (const_reference(_Data[0]));
		}
	_CONST_FUN const_reference back() const
		{	// get reference to last element
		return (const_reference(_Data[_Size - 1]));
		}

	_CONST_FUN const_pointer data() const _NOEXCEPT
		{	// get pointer to first element
		return (_Data);
		}

	_CONST_FUNX void remove_prefix(size_type _Off)
		{	// remove first _Off elements
		_Data += _Off;
		_Size -= _Off;
		}
	_CONST_FUNX void remove_suffix(size_type _Off)
		{	// remove last _Off elements
		_Size -= _Off;
		}

	_CONST_FUNX void swap(basic_string_view& _Right) _NOEXCEPT
		{	// swap *this and _Right
#if defined(__ghs)
		// std::swap is not constexpr until C++20, but this function
		// needs to be constexpr in C++17, so use a manual swap.
		const_pointer _Temp_ptr{};
		size_type     _Temp_size{};

		_Temp_ptr  = this->_Data;
		_Temp_size = this->_Size;
		this->_Data = _Right._Data;
		this->_Size = _Right._Size;
		_Right._Data = _Temp_ptr;
		_Right._Size = _Temp_size;
#else
		_STD swap(_Data, _Right._Data);
		_STD swap(_Size, _Right._Size);
#endif /* defined(__ghs) */
		}

	size_type copy(_Elem *_Str, size_type _Len, size_type _Off = 0) const
		{	// copy out substring to _Str
		if (size() < _Off)
			_Xout_of_range("basic_string_view::copy bad beginning offset");
#if defined(__ghs)
		if (size() - _Off < _Len)
			_Len = _Size - _Off;
		_Traits::copy(_Str, _Data + _Off, _Len);
#else
		if (size() - _Off < size())
			_Len = _Size - _Off;
		_STD copy_n(_Data + _Off, _Len, _Str);
#endif /* defined(__ghs) */
		return (_Len);
		}

	_CONST_FUNX basic_string_view substr(
		size_type _Off = 0, size_type _Len = npos) const
		{	// copy out substring as a basic_string_view
		if (size() < _Off)
			_Xout_of_range("basic_string_view::substr bad beginning offset");
		if (size() - _Off < _Len)
			_Len = _Size - _Off;
		return (basic_string_view(_Data + _Off, _Len));
		}

	_CONST_FUNX int compare(basic_string_view _Str) const _NOEXCEPT
		{	// compare with basic_string_view
		size_type _Len = size() < _Str.size() ? size() : _Str.size();
		int _Cmp = _Traits::compare(data(), _Str.data(), _Len);
		return (_Cmp != 0 ? _Cmp : size() < _Str.size() ? -1
			: size() == _Str.size() ? 0 : 1);
		}
	_CONST_FUN int compare(size_type _Off, size_type _Len,
		basic_string_view _Str) const
		{	// compare with [_Off, _Off + _Len)
		return (substr(_Off, _Len).compare(_Str));
		}
	_CONST_FUN int compare(size_type _Off1, size_type _Len1,
		basic_string_view _Str, size_type _Off2, size_type _Len2) const
		{	// compare [_Off1, _Len1) with [_Off2, _Off2 + _Len)
		return (substr(_Off1, _Len1).compare(_Str.substr(_Off2, _Len2)));
		}
	_CONST_FUN int compare(const _Elem *_Str) const
		{	// compare with basic_string_view(_Str)
		return (compare(basic_string_view(_Str)));
		}
	_CONST_FUN int compare(size_type _Off, size_type _Len,
		const _Elem *_Str) const
		{	// compare substr(_Off, _Len) with basic_string_view(_Str)
		return (substr(_Off, _Len).compare(basic_string_view(_Str)));
		}
	_CONST_FUN int compare(size_type _Off1, size_type _Len1,
#if defined(__ghs)
		const _Elem *_Str, size_type _Len2) const
#else
		const char *_Str, size_type _Len2) const
#endif
		{	// compare basic_string_view(_Str) with [_Off2, _Off2 + _Len)
		return (substr(_Off1, _Len1).compare(basic_string_view(_Str, _Len2)));
		}

	_CONST_FUNX size_type find(basic_string_view _Str,
		size_type _Off = 0) const _NOEXCEPT
		{	// find first substring
		if (size() < _Str.size())
			return (npos);	// can't possibly match
		size_t _Last = size() - _Str.size();
		for (size_type _Idx1 = _Off; _Idx1 <= _Last; ++_Idx1)
			{	// look for substring beginning at _Off
			size_type _Idx2 = 0;
			for (; _Idx2 < _Str.size(); ++_Idx2)
				if (!_Traits::eq(at(_Idx1 + _Idx2), _Str.at(_Idx2)))
					break;
			if (_Str.size() <= _Idx2)
				return (_Idx1);	// success
			}
		return (npos);	// failure
		}

	_CONST_FUN size_type find(_Elem _Ch,
		size_type _Off = 0) const _NOEXCEPT
		{	// find first basic_string_view(&_Ch, 1) substring
		return (find(basic_string_view(&_Ch, 1), _Off));
		}

	_CONST_FUN size_type find(const _Elem *_Ptr,
		size_type _Off, size_type _Len) const
		{	// find first basic_string_view(_Ptr, _Len) substring
		return (find(basic_string_view(_Ptr, _Len), _Off));
		}

	_CONST_FUN size_type find(const _Elem *_Ptr,
		size_type _Off = 0) const
		{	// find first basic_string_view(_Ptr) substring
		return (find(basic_string_view(_Ptr), _Off));
		}

	_CONST_FUNX size_type rfind(basic_string_view _Str,
		size_type _Off = npos) const _NOEXCEPT
		{	// find last substring
		if (size() < _Str.size())
			return (npos);	// can't possibly match
		size_t _Last = size() - _Str.size();
		if (_Off < _Last)
			_Last = _Off;
		for (size_type _Idx1 = _Last; ; --_Idx1)
			{	// look for substring beginning at or before _Off
			size_type _Idx2 = 0;
			for (; _Idx2 < _Str.size(); ++_Idx2)
				if (!_Traits::eq(at(_Idx1 + _Idx2), _Str.at(_Idx2)))
					break;
			if (_Str.size() <= _Idx2)
				return (_Idx1);	// success
			if (_Idx1 == 0)
				return (npos);	// failure
			}
		}

#if !defined(__ghs)
	_CONST_FUN size_type rfind(_Elem _Ch,
		size_type _Off = 0) const _NOEXCEPT
#else
	_CONST_FUN size_type rfind(_Elem _Ch,
		size_type _Off = npos) const _NOEXCEPT
#endif
		{	// find last basic_string_view(&_Ch, 1) substring
		return (rfind(basic_string_view(&_Ch, 1), _Off));
		}

	_CONST_FUN size_type rfind(const _Elem *_Ptr,
		size_type _Off, size_type _Len) const
		{	// find last basic_string_view(_Ptr, _Len) substring
		return (rfind(basic_string_view(_Ptr, _Len), _Off));
		}

#if !defined(__ghs)
	_CONST_FUN size_type rfind(const _Elem *_Ptr,
		size_type _Off = 0) const
#else
	_CONST_FUN size_type rfind(const _Elem *_Ptr,
		size_type _Off = npos) const
#endif
		{	// find last basic_string_view(_Ptr) substring
		return (rfind(basic_string_view(_Ptr), _Off));
		}

	_CONST_FUNX size_type find_first_of(basic_string_view _Str,
		size_type _Off = 0) const _NOEXCEPT
		{	// find first instance in string
		for (size_type _Idx1 = _Off; _Idx1 < size(); ++_Idx1)
			{	// look for instance in _Str matching at(_Idx1)
			for (size_type _Idx2 = 0; _Idx2 < _Str.size(); ++_Idx2)
				if (_Traits::eq(at(_Idx1), _Str.at(_Idx2)))
					return (_Idx1);	// success;
			}
		return (npos);	// failure
		}

	_CONST_FUN size_type find_first_of(_Elem _Ch,
		size_type _Off = 0) const _NOEXCEPT
		{	// find first instance in basic_string_view(&_Ch, 1)
		return (find_first_of(basic_string_view(&_Ch, 1), _Off));
		}

	_CONST_FUN size_type find_first_of(const _Elem *_Ptr,
		size_type _Off, size_type _Len) const
		{	// find first instance in basic_string_view(_Ptr, _Len)
		return (find_first_of(basic_string_view(_Ptr, _Len), _Off));
		}

	_CONST_FUN size_type find_first_of(const _Elem *_Ptr,
		size_type _Off = 0) const
		{	// find first instance in basic_string_view(_Ptr)
		return (find_first_of(basic_string_view(_Ptr), _Off));
		}

#if defined(__ghs)
	_CONST_FUNX size_type find_last_of(basic_string_view _Str,
		size_type _Off = npos) const _NOEXCEPT
		{	// find last instance in string
	        size_type _Idx1 = size();
		if (_Off != npos && _Idx1 > _Off+1)
			_Idx1 = _Off+1;
		while ( _Idx1-- )
			{	// look for instance in _Str matching at(_Idx1)
			for (size_type _Idx2 = 0; _Idx2 < _Str.size(); ++_Idx2)
				if (_Traits::eq(at(_Idx1), _Str.at(_Idx2)))
					return (_Idx1);	// success;
			}
		return (npos);	// failure
		}
#else
	_CONST_FUNX size_type find_last_of(basic_string_view _Str,
		size_type _Off = 0) const _NOEXCEPT
		{	// find last instance in string
		for (size_type _Idx1 = size(); _Off < _Idx1; )
			{	// look for instance in _Str matching at(_Idx1)
			--_Idx1;
			for (size_type _Idx2 = 0; _Idx2 < _Str.size(); ++_Idx2)
				if (_Traits::eq(at(_Idx1), _Str.at(_Idx2)))
					return (_Idx1);	// success;
			}
		return (npos);	// failure
		}
#endif

	_CONST_FUN size_type find_last_of(_Elem _Ch,
#if defined(__ghs)
		size_type _Off = npos) const _NOEXCEPT
#else
		size_type _Off = 0) const _NOEXCEPT
#endif
		{	// find last instance in basic_string_view(&_Ch, 1)
		return (find_last_of(basic_string_view(&_Ch, 1), _Off));
		}

	_CONST_FUN size_type find_last_of(const _Elem *_Ptr,
		size_type _Off, size_type _Len) const
		{	// find last instance in basic_string_view(_Ptr, _Len)
		return (find_last_of(basic_string_view(_Ptr, _Len), _Off));
		}

	_CONST_FUN size_type find_last_of(const _Elem *_Ptr,
#if defined(__ghs)
		size_type _Off = npos) const
#else
		size_type _Off = 0) const
#endif
		{	// find last instance in basic_string_view(_Ptr)
		return (find_last_of(basic_string_view(_Ptr), _Off));
		}

	_CONST_FUNX size_type find_first_not_of(basic_string_view _Str,
		size_type _Off = 0) const _NOEXCEPT
		{	// find first instance not in string
		for (size_type _Idx1 = _Off; _Idx1 < size(); ++_Idx1)
			{	// look for instance in _Str matching at(_Idx1)
			size_type _Idx2 = 0;
			for (; _Idx2 < _Str.size(); ++_Idx2)
				if (_Traits::eq(at(_Idx1), _Str.at(_Idx2)))
					break;
			if (_Str.size() <= _Idx2)
				return (_Idx1);	// success
			}
		return (npos);	// failure
		}

	_CONST_FUN size_type find_first_not_of(_Elem _Ch,
		size_type _Off = 0) const _NOEXCEPT
		{	// find first instance not in basic_string_view(&_Ch, 1)
		return (find_first_not_of(basic_string_view(&_Ch, 1), _Off));
		}

	_CONST_FUN size_type find_first_not_of(const _Elem *_Ptr,
		size_type _Off, size_type _Len) const
		{	// find first instance not in basic_string_view(_Ptr, _Len)
		return (find_first_not_of(basic_string_view(_Ptr, _Len), _Off));
		}

	_CONST_FUN size_type find_first_not_of(const _Elem *_Ptr,
		size_type _Off = 0) const
		{	// find first instance not in basic_string_view(_Ptr)
		return (find_first_not_of(basic_string_view(_Ptr), _Off));
		}

#if defined(__ghs)
	_CONST_FUNX size_type find_last_not_of(basic_string_view _Str,
		size_type _Off = npos) const _NOEXCEPT
		{	// find last instance not in string
	        size_type _Idx1 = size();
		if (_Off != npos && _Idx1 > _Off+1)
			_Idx1 = _Off+1;
		while ( _Idx1-- )
			{	// look for instance in _Str matching at(_Idx1)
			size_type _Idx2 = 0;
			for (; _Idx2 < _Str.size(); ++_Idx2)
				if (_Traits::eq(at(_Idx1), _Str.at(_Idx2)))
					break;
			if (_Str.size() <= _Idx2)
				return (_Idx1);	// success
			}
		return (npos);	// failure
		}
#else
	_CONST_FUNX size_type find_last_not_of(basic_string_view _Str,
		size_type _Off = 0) const _NOEXCEPT
		{	// find last instance not in string
		for (size_type _Idx1 = size(); _Off < _Idx1; )
			{	// look for instance in _Str matching at(_Idx1)
			--_Idx1;
			size_type _Idx2 = 0;
			for (; _Idx2 < _Str.size(); ++_Idx2)
				if (_Traits::eq(at(_Idx1), _Str.at(_Idx2)))
					break;
			if (_Str.size() <= _Idx2)
				return (_Idx1);	// success
			}
		return (npos);	// failure
		}
#endif

	_CONST_FUN size_type find_last_not_of(_Elem _Ch,
#if defined(__ghs)
		size_type _Off = npos) const _NOEXCEPT
#else
		size_type _Off = 0) const _NOEXCEPT
#endif
		{	// find last instance not in basic_string_view(&_Ch, 1)
		return (find_last_not_of(basic_string_view(&_Ch, 1), _Off));
		}

	_CONST_FUN size_type find_last_not_of(const _Elem *_Ptr,
		size_type _Off, size_type _Len) const
		{	// find last instance not in basic_string_view(_Ptr, _Len)
		return (find_last_not_of(basic_string_view(_Ptr, _Len), _Off));
		}

	_CONST_FUN size_type find_last_not_of(const _Elem *_Ptr,
#if defined(__ghs)
		size_type _Off = npos) const
#else
		size_type _Off = 0) const
#endif
		{	// find last instance not in basic_string_view(_Ptr)
#if !defined(__ghs)
		return (find_last_of(basic_string_view(_Ptr), _Off));
#else
		return (find_last_not_of(basic_string_view(_Ptr), _Off));
#endif
		}

 private:
	const_pointer _Data;
	size_type _Size;
	};

	// COMPARISON TEMPLATE FUNCTIONS
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator==(basic_string_view<_Elem, _Traits> _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left == _Right
	return (_Left.compare(_Right) == 0);
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator==(decay_t<basic_string_view<_Elem, _Traits> > _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left == _Right
	return (_Left.compare(_Right) == 0);
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator==(basic_string_view<_Elem, _Traits> _Left,
	decay_t<basic_string_view<_Elem, _Traits> > _Right) _NOEXCEPT
	{	// test if _Left == _Right
	return (_Left.compare(_Right) == 0);
	}

template<class _Elem,
	class _Traits>
_CONST_FUN bool operator!=(basic_string_view<_Elem, _Traits> _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left != _Right
	return (!(_Left.compare(_Right) == 0));
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator!=(decay_t<basic_string_view<_Elem, _Traits> > _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left != _Right
	return (!(_Left.compare(_Right) == 0));
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator!=(basic_string_view<_Elem, _Traits> _Left,
	decay_t<basic_string_view<_Elem, _Traits> > _Right) _NOEXCEPT
	{	// test if _Left != _Right
	return (!(_Left.compare(_Right) == 0));
	}

template<class _Elem,
	class _Traits>
_CONST_FUN bool operator<(basic_string_view<_Elem, _Traits> _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left < _Right
	return (_Left.compare(_Right) < 0);
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator<(decay_t<basic_string_view<_Elem, _Traits> > _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left < _Right
	return (_Left.compare(_Right) < 0);
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator<(basic_string_view<_Elem, _Traits> _Left,
	decay_t<basic_string_view<_Elem, _Traits> > _Right) _NOEXCEPT
	{	// test if _Left < _Right
	return (_Left.compare(_Right) < 0);
	}

template<class _Elem,
	class _Traits>
_CONST_FUN bool operator>(basic_string_view<_Elem, _Traits> _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left > _Right
	return (0 < _Left.compare(_Right));
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator>(decay_t<basic_string_view<_Elem, _Traits> > _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left > _Right
	return (0 < _Left.compare(_Right));
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator>(basic_string_view<_Elem, _Traits> _Left,
	decay_t<basic_string_view<_Elem, _Traits> > _Right) _NOEXCEPT
	{	// test if _Left > _Right
	return (0 < _Left.compare(_Right));
	}

template<class _Elem,
	class _Traits>
_CONST_FUN bool operator<=(basic_string_view<_Elem, _Traits> _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left <= _Right
	return (!(0 < _Left.compare(_Right)));
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator<=(decay_t<basic_string_view<_Elem, _Traits> > _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left <= _Right
	return (!(0 < _Left.compare(_Right)));
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator<=(basic_string_view<_Elem, _Traits> _Left,
	decay_t<basic_string_view<_Elem, _Traits> > _Right) _NOEXCEPT
	{	// test if _Left <= _Right
	return (!(0 < _Left.compare(_Right)));
	}

template<class _Elem,
	class _Traits>
_CONST_FUN bool operator>=(basic_string_view<_Elem, _Traits> _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left >= _Right
	return (!(_Left.compare(_Right) < 0));
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator>=(decay_t<basic_string_view<_Elem, _Traits> > _Left,
	basic_string_view<_Elem, _Traits> _Right) _NOEXCEPT
	{	// test if _Left >= _Right
	return (!(_Left.compare(_Right) < 0));
	}
template<class _Elem,
	class _Traits>
_CONST_FUN bool operator>=(basic_string_view<_Elem, _Traits> _Left,
	decay_t<basic_string_view<_Elem, _Traits> > _Right) _NOEXCEPT
	{	// test if _Left >= _Right
	return (!(_Left.compare(_Right) < 0));
	}

using string_view  = basic_string_view<char>;
using u16string_view = basic_string_view<char16_t>;
using u32string_view = basic_string_view<char32_t>;
using wstring_view = basic_string_view<wchar_t>;

 #if _HAS_LITERALS
	// basic_string_view LITERALS
	inline namespace literals {
		inline namespace string_view_literals {
inline _CONST_FUN string_view operator ""sv(const char *_Str, size_t _Len)
	_NOEXCEPT
	{	// construct literal from [_Str, _Str + _Len)
	return (string_view(_Str, _Len));
	}

inline _CONST_FUN u16string_view operator""sv(const char16_t *_Str, size_t _Len)
	_NOEXCEPT
	{	// construct literal from [_Str, _Str + _Len)
	return (u16string_view(_Str, _Len));
	}

inline _CONST_FUN u32string_view operator""sv(const char32_t *_Str, size_t _Len)
	_NOEXCEPT
	{	// construct literal from [_Str, _Str + _Len)
	return (u32string_view(_Str, _Len));
	}

inline _CONST_FUN wstring_view operator""sv(const wchar_t *_Str, size_t _Len)
	_NOEXCEPT
	{	// construct literal from [_Str, _Str + _Len)
	return (wstring_view(_Str, _Len));
	}
		}	// inline namespace string_view_literals
	}	// inline namespace literals
 #endif /* _HAS_LITERALS */
_STD_END

namespace std {
	// TEMPLATE STRUCT SPECIALIZATION hash
template<class _Traits>
	struct hash;

template<>
	struct hash<string_view>
	{	// hash functor for string_view
	typedef string_view argument_type;
	typedef size_t result_type;
	typedef char _Elem;

	size_t operator()(const argument_type& _Keyval) const _THROW0()
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Hash_seq((const unsigned char *)_Keyval.data(),
			_Keyval.size() * sizeof (_Elem)));
		}
	};

template<>
	struct hash<u16string_view>
	{	// hash functor for string_view
	typedef u16string_view argument_type;
	typedef size_t result_type;
	typedef char16_t _Elem;

	size_t operator()(const argument_type& _Keyval) const _THROW0()
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Hash_seq((const unsigned char *)_Keyval.data(),
			_Keyval.size() * sizeof (_Elem)));
		}
	};

template<>
	struct hash<u32string_view>
	{	// hash functor for string_view
	typedef u32string_view argument_type;
	typedef size_t result_type;
	typedef char32_t _Elem;

	size_t operator()(const argument_type& _Keyval) const _THROW0()
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Hash_seq((const unsigned char *)_Keyval.data(),
			_Keyval.size() * sizeof (_Elem)));
		}
	};

template<>
	struct hash<wstring_view>
	{	// hash functor for string_view
	typedef wstring_view argument_type;
	typedef size_t result_type;
	typedef wchar_t _Elem;

	size_t operator()(const argument_type& _Keyval) const _THROW0()
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		return (_Hash_seq((const unsigned char *)_Keyval.data(),
			_Keyval.size() * sizeof (_Elem)));
		}
	};
} // namespace std


 #if defined(__ghs)
  #if defined(__ghs_max_pack_value)
   #pragma pack(pop)
  #endif /* defined(__ghs_max_pack_value) */
  #pragma ghs enddata
  #pragma ghs end_cxx_lib_header
 #endif /* defined(__ghs) */

#endif /* _XSTRING_VIEW_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V8.03b/17:0063 */
