// sstream standard header
#pragma once
#ifndef _SSTREAM_
#define _SSTREAM_
#ifndef RC_INVOKED
#include <string>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)
 #pragma push_macro("new")
 #undef new
_STD_BEGIN
 #pragma warning(disable: 4251)

		// TEMPLATE CLASS basic_stringbuf
template<class _Elem,
	class _Traits,
	class _Alloc>
	class basic_stringbuf
		: public basic_streambuf<_Elem, _Traits>
	{	// stream buffer maintaining an allocated character array
public:
	typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Myt;
	typedef _Alloc allocator_type;
	typedef basic_streambuf<_Elem, _Traits> _Mysb;
	typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;

	explicit basic_stringbuf(ios_base::openmode _Mode =
		ios_base::in | ios_base::out)
		{	// construct empty character buffer from mode
		_Init(0, 0, _Getstate(_Mode));
		}

	explicit basic_stringbuf(const _Mystr& _Str,
		ios_base::openmode _Mode = ios_base::in | ios_base::out)
		{	// construct character buffer from string, mode
		_Init(_Str.c_str(), _Str.size(), _Getstate(_Mode));
		}

	basic_stringbuf(_Myt&& _Right)
		{	// construct by moving _Right
		_Assign_rv(_STD forward<_Myt>(_Right));
		}

	_Myt& operator=(_Myt&& _Right)
		{	// assign from _Right
		_Assign_rv(_STD forward<_Myt>(_Right));
		return (*this);
		}

	void _Assign_rv(_Myt&& _Right)
		{	// assign by moving _Right
		if (this != &_Right)
			{	// different, worth moving
			_Tidy();
			this->swap(_Right);
			}
		}

	void swap(_Myt& _Right)
		{	// swap with _Right
		if (this != &_Right)
			{	// different, worth swapping
			_Mysb::swap(_Right);
			_STD swap(_Seekhigh, _Right._Seekhigh);
			_STD swap(_Mystate, _Right._Mystate);
			_Swap_adl(_Al, _Right._Al);
			}
		}

	basic_stringbuf(const _Myt&) = delete;
	_Myt& operator=(const _Myt&) = delete;

	virtual ~basic_stringbuf() _NOEXCEPT
		{	// destroy the object
		_Tidy();
		}

	enum
		{	// constants for bits in stream state
		_Allocated = 1,	// set if character array storage has been allocated
		_Constant = 2,	// set if character array nonmutable
		_Noread = 4,	// set if character array cannot be read
		_Append = 8,	// set if all writes are appends
		_Atend = 16};	// set if initial writes are appends
	typedef int _Strstate;

	typedef typename _Traits::int_type int_type;
	typedef typename _Traits::pos_type pos_type;
	typedef typename _Traits::off_type off_type;

	_Mystr str() const
		{	// return string copy of character array
		if (!(_Mystate & _Constant) && _Mysb::pptr() != 0)
			{	// writable, make string from write buffer
			_Mystr _Str(_Mysb::pbase(), (_Seekhigh < _Mysb::pptr()
				? _Mysb::pptr() : _Seekhigh) - _Mysb::pbase());
			return (_Str);
			}
		else if (!(_Mystate & _Noread) && _Mysb::gptr() != 0)
			{	// readable, make string from read buffer
			_Mystr _Str(_Mysb::eback(), _Mysb::egptr() - _Mysb::eback());
			return (_Str);
			}
		else
			{	// inaccessible, return empty string
			_Mystr _Nul;
			return (_Nul);
			}
		}

	void str(const _Mystr& _Newstr)
		{	// replace character array from string
		_Tidy();
		_Init(_Newstr.c_str(), _Newstr.size(), _Mystate);
		}

protected:
	virtual int_type overflow(int_type _Meta = _Traits::eof())
		{	// put an element to stream
		if (_Mystate & _Constant)
			return (_Traits::eof());	// array nonmutable, fail
		else if (_Traits::eq_int_type(_Traits::eof(), _Meta))
			return (_Traits::not_eof(_Meta));	// EOF, return success code

		if (_Mystate & _Append
			&& _Mysb::pptr() != 0 && _Mysb::pptr() < _Seekhigh)
			_Mysb::setp(_Mysb::pbase(), _Seekhigh, _Mysb::epptr());

		if (_Mysb::pptr() != 0
			&& _Mysb::pptr() < _Mysb::epptr())
			{	// room in buffer, store it
			*_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
			return (_Meta);
			}
		else
			{	// grow buffer and store element
			size_t _Oldsize = _Mysb::pptr() == 0
				? 0 : _Mysb::epptr() - _Mysb::eback();
			size_t _Newsize = _Oldsize;
			size_t _Inc = _Newsize / 2 < _MINSIZE
				? _MINSIZE : _Newsize / 2;	// grow by 50 per cent

			while (0 < _Inc && INT_MAX - _Inc < _Newsize)
				_Inc /= 2;	// increment causes overflow, halve it
			if (_Inc == 0)
				return (_Traits::eof());	// buffer can't grow, fail

			_Newsize += _Inc;

			_Elem *_Newptr = _Al.allocate(_Newsize);
			_Elem *_Oldptr = _Mysb::eback();

			if (0 < _Oldsize)
				_Traits::copy(_Newptr, _Oldptr, _Oldsize);

			if (_Oldsize == 0)
				{	// first growth, set up pointers
				_Seekhigh = _Newptr;
				_Mysb::setp(_Newptr, _Newptr + _Newsize);
				if (_Mystate & _Noread)
					_Mysb::setg(_Newptr, 0, _Newptr);
				else
					_Mysb::setg(_Newptr, _Newptr, _Newptr + 1);
				}
			else
				{	// not first growth, adjust pointers
				_Seekhigh = _Newptr + (_Seekhigh - _Oldptr);
				_Mysb::setp(_Newptr + (_Mysb::pbase() - _Oldptr),
					_Newptr + (_Mysb::pptr() - _Oldptr),
					_Newptr + _Newsize);
				if (_Mystate & _Noread)
					_Mysb::setg(_Newptr, 0, _Newptr);
				else
					_Mysb::setg(_Newptr,
						_Newptr + (_Mysb::gptr() - _Oldptr),
						_Mysb::pptr() + 1);
				}

			if (_Mystate & _Allocated)
				_Al.deallocate(_Oldptr, _Oldsize);
			_Mystate |= _Allocated;

			*_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
			return (_Meta);
			}
		}

	virtual int_type pbackfail(int_type _Meta = _Traits::eof())
		{	// put an element back to stream
		if (_Mysb::gptr() == 0
			|| _Mysb::gptr() <= _Mysb::eback()
			|| (!_Traits::eq_int_type(_Traits::eof(), _Meta)
			&& !_Traits::eq(_Traits::to_char_type(_Meta), _Mysb::gptr()[-1])
			&& _Mystate & _Constant))
			return (_Traits::eof());	// can't put back, fail
		else
			{	// back up one position and store put-back character
			_Mysb::gbump(-1);
			if (!_Traits::eq_int_type(_Traits::eof(), _Meta))
				*_Mysb::gptr() = _Traits::to_char_type(_Meta);
			return (_Traits::not_eof(_Meta));
			}
		}

	virtual int_type underflow()
		{	// get an element from stream, but don't point past it
		if (_Mysb::gptr() == 0)
			return (_Traits::eof());	// no character buffer, fail
		else if (_Mysb::gptr() < _Mysb::egptr())
			return (_Traits::to_int_type(*_Mysb::gptr()));	// return buffered
		else if (_Mystate & _Noread || _Mysb::pptr() == 0
			|| (_Mysb::pptr() <= _Mysb::gptr() && _Seekhigh <= _Mysb::gptr()))
			return (_Traits::eof());	// can't read, fail
		else
			{	// extend read buffer into written area, then return buffered
			if (_Seekhigh < _Mysb::pptr())
				_Seekhigh = _Mysb::pptr();
			_Mysb::setg(_Mysb::eback(), _Mysb::gptr(), _Seekhigh);
			return (_Traits::to_int_type(*_Mysb::gptr()));
			}
		}

	virtual pos_type seekoff(off_type _Off,
		ios_base::seekdir _Way,
		ios_base::openmode _Which = ios_base::in | ios_base::out)
		{	// change position by _Off, according to _Way, _Mode
		if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
			_Seekhigh = _Mysb::pptr();	// update high-water pointer

		if (_Which & ios_base::in && _Mysb::gptr() != 0)
			{	// position within read buffer
			if (_Way == ios_base::end)
				_Off += (off_type)(_Seekhigh - _Mysb::eback());
			else if (_Way == ios_base::cur
				&& (_Which & ios_base::out) == 0)
				_Off += (off_type)(_Mysb::gptr() - _Mysb::eback());
			else if (_Way != ios_base::beg)
				_Off = _BADOFF;

			if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
				{	// change read position
				_Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
				if (_Which & ios_base::out && _Mysb::pptr() != 0)
					_Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
						_Mysb::epptr());	// change write position to match
				}
			else
				_Off = _BADOFF;
			}
		else if (_Which & ios_base::out && _Mysb::pptr() != 0)
			{	// position within write buffer
			if (_Way == ios_base::end)
				_Off += (off_type)(_Seekhigh - _Mysb::eback());
			else if (_Way == ios_base::cur)
				_Off += (off_type)(_Mysb::pptr() - _Mysb::eback());
			else if (_Way != ios_base::beg)
				_Off = _BADOFF;

			if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
				_Mysb::pbump((int)(_Mysb::eback()
					- _Mysb::pptr() + _Off));	// change write position
			else
				_Off = _BADOFF;
			}

		else if (_Off != 0)


			_Off = _BADOFF;	// neither read nor write buffer selected, fail
		return (pos_type(_Off));
		}

	virtual pos_type seekpos(pos_type _Ptr,
		ios_base::openmode _Mode = ios_base::in | ios_base::out)
		{	// change position to _Pos, according to _Mode
		streamoff _Off = (streamoff)_Ptr;
		if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
			_Seekhigh = _Mysb::pptr();	// update high-water pointer

		if (_Off == _BADOFF)
			;
		else if (_Mode & ios_base::in && _Mysb::gptr() != 0)
			{	// position within read buffer
			if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
				{	// change read position
				_Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
				if (_Mode & ios_base::out && _Mysb::pptr() != 0)
					_Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
						_Mysb::epptr());	// change write position to match
				}
			else
				_Off = _BADOFF;
			}
		else if (_Mode & ios_base::out && _Mysb::pptr() != 0)
			{	// position within write buffer
			if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
				_Mysb::pbump((int)(_Mysb::eback()
					- _Mysb::pptr() + _Off));	// change write position
			else
				_Off = _BADOFF;
			}
		else
			_Off = _BADOFF;	// neither read nor write buffer selected, fail
		return (streampos(_Off));
		}

	void _Init(const _Elem *_Ptr,
		size_t _Count, _Strstate _State)
		{	// initialize buffer to [_Ptr, _Ptr + _Count), set state
		_Seekhigh = 0;
		_Mystate = _State;

		if (_Count != 0
			&& (_Mystate & (_Noread | _Constant)) != (_Noread | _Constant))
			{	// finite buffer that can be read or written, set it up
			_Elem *_Pnew = _Al.allocate(_Count);
			_Traits::copy(_Pnew, _Ptr, _Count);
			_Seekhigh = _Pnew + _Count;

			if (!(_Mystate & _Noread))
				_Mysb::setg(_Pnew, _Pnew,
					_Pnew + _Count);	// setup read buffer
			if (!(_Mystate & _Constant))
				{	// setup write buffer, and maybe read buffer
				_Mysb::setp(_Pnew,
					(_Mystate & (_Atend | _Append)) ? _Pnew + _Count : _Pnew,
					_Pnew + _Count);
				if (_Mysb::gptr() == 0)
					_Mysb::setg(_Pnew, 0, _Pnew);
				}
			_Mystate |= _Allocated;
			}
		}

	void _Tidy()
		{	// discard any allocated buffer and clear pointers
		if (_Mystate & _Allocated)
			_Al.deallocate(_Mysb::eback(),
				(_Mysb::pptr() != 0 ? _Mysb::epptr()
					: _Mysb::egptr()) - _Mysb::eback());
		_Mysb::setg(0, 0, 0);
		_Mysb::setp(0, 0);
		_Seekhigh = 0;
		_Mystate &= ~_Allocated;
		}

private:
	enum
		{	// constant for minimum buffer size
		_MINSIZE = 32};

	_Strstate _Getstate(ios_base::openmode _Mode)
		{	// convert open mode to stream state bits
		_Strstate _State = (_Strstate)0;
		if (!(_Mode & ios_base::in))
			_State |= _Noread;
		if (!(_Mode & ios_base::out))
			_State |= _Constant;
		if (_Mode & ios_base::app)
			_State |= _Append;
		if (_Mode & ios_base::ate)
			_State |= _Atend;
		return (_State);
		}

	_Elem *_Seekhigh;	// the high-water pointer in character array
	_Strstate _Mystate;	// the stream state
	allocator_type _Al;	// the allocator object
	};

	// basic_stringbuf TEMPLATE OPERATORS
template<class _Elem,
	class _Traits,
	class _Alloc> inline
	void swap(basic_stringbuf<_Elem, _Traits, _Alloc>& _Left,
		basic_stringbuf<_Elem, _Traits, _Alloc>& _Right)
	{	// swap _Left and _Right basic_stringbufs
	_Left.swap(_Right);
	}

		// TEMPLATE CLASS basic_istringstream
template<class _Elem,
	class _Traits,
	class _Alloc>
	class basic_istringstream
		: public basic_istream<_Elem, _Traits>
	{	// input stream associated with a character array
public:
	typedef basic_istringstream<_Elem, _Traits, _Alloc> _Myt;
	typedef basic_istream<_Elem, _Traits> _Mybase;
	typedef _Alloc allocator_type;
	typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
	typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;

	explicit basic_istringstream(ios_base::openmode _Mode = ios_base::in)
		: _Mybase(&_Stringbuffer),
			_Stringbuffer(_Mode | ios_base::in)
		{	// construct empty readable character buffer
		}

	explicit basic_istringstream(const _Mystr& _Str,
		ios_base::openmode _Mode = ios_base::in)
		: _Mybase(&_Stringbuffer),
			_Stringbuffer(_Str, _Mode | ios_base::in)
		{	// construct readable character buffer from NTCS
		}

	basic_istringstream(_Myt&& _Right)
		: _Mybase(&_Stringbuffer)
		{	// construct by moving _Right
		_Assign_rv(_STD forward<_Myt>(_Right));
		}

	_Myt& operator=(_Myt&& _Right)
		{	// move from _Right
		_Assign_rv(_STD forward<_Myt>(_Right));
		return (*this);
		}

	void _Assign_rv(_Myt&& _Right)
		{	// assign by moving _Right
		if (this != &_Right)
			{	// different, worth moving
			_Stringbuffer.str(_Mystr());
			this->swap(_Right);
			}
		}

	void swap(_Myt& _Right)
		{	// swap with _Right
		if (this != &_Right)
			{	// different, swap base and buffer
			_Mybase::swap(_Right);
			_Stringbuffer.swap(_Right._Stringbuffer);
			}
		}

	basic_istringstream(const _Myt&) = delete;
	_Myt& operator=(const _Myt&) = delete;

	virtual ~basic_istringstream() _NOEXCEPT
		{	// destroy the object
		}

	_Mysb *rdbuf() const
		{	// return pointer to file buffer
		return ((_Mysb *)&_Stringbuffer);
		}

	_Mystr str() const
		{	// return string copy of character array
		return (_Stringbuffer.str());
		}

	void str(const _Mystr& _Newstr)
		{	// replace character array from string
		_Stringbuffer.str(_Newstr);
		}

private:
	_Mysb _Stringbuffer;	// the string buffer
	};

	// basic_istringstream TEMPLATE OPERATORS
template<class _Elem,
	class _Traits,
	class _Alloc> inline
	void swap(basic_istringstream<_Elem, _Traits, _Alloc>& _Left,
		basic_istringstream<_Elem, _Traits, _Alloc>& _Right)
	{	// swap _Left and _Right basic_istringstreams
	_Left.swap(_Right);
	}

		// TEMPLATE CLASS basic_ostringstream
template<class _Elem,
	class _Traits,
	class _Alloc>
	class basic_ostringstream
		: public basic_ostream<_Elem, _Traits>
	{	// output stream associated with a character array
public:
	typedef basic_ostringstream<_Elem, _Traits, _Alloc> _Myt;
	typedef basic_ostream<_Elem, _Traits> _Mybase;
	typedef _Alloc allocator_type;
	typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
	typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;

	explicit basic_ostringstream(ios_base::openmode _Mode = ios_base::out)
		: _Mybase(&_Stringbuffer),
			_Stringbuffer(_Mode | ios_base::out)
		{	// construct empty writable character buffer
		}

	explicit basic_ostringstream(const _Mystr& _Str,
		ios_base::openmode _Mode = ios_base::out)
		: _Mybase(&_Stringbuffer),
			_Stringbuffer(_Str, _Mode | ios_base::out)
		{	// construct writable character buffer from NTCS
		}

	basic_ostringstream(_Myt&& _Right)
		: _Mybase(&_Stringbuffer)
		{	// construct by moving _Right
		_Assign_rv(_STD forward<_Myt>(_Right));
		}

	_Myt& operator=(_Myt&& _Right)
		{	// move from _Right
		_Assign_rv(_STD forward<_Myt>(_Right));
		return (*this);
		}

	void _Assign_rv(_Myt&& _Right)
		{	// assign by moving _Right
		if (this != &_Right)
			{	// different, worth moving
			_Stringbuffer.str(_Mystr());
			this->swap(_Right);
			}
		}

	void swap(_Myt& _Right)
		{	// swap with _Right
		if (this != &_Right)
			{	// different, swap base and buffer
			_Mybase::swap(_Right);
			_Stringbuffer.swap(_Right._Stringbuffer);
			}
		}

	basic_ostringstream(const _Myt&) = delete;
	_Myt& operator=(const _Myt&) = delete;

	virtual ~basic_ostringstream() _NOEXCEPT
		{	// destroy the object
		}

	_Mysb *rdbuf() const
		{	// return pointer to buffer
		return ((_Mysb *)&_Stringbuffer);
		}

	_Mystr str() const
		{	// return string copy of character array
		return (_Stringbuffer.str());
		}

	void str(const _Mystr& _Newstr)
		{	// replace character array from string
		_Stringbuffer.str(_Newstr);
		}

private:
	_Mysb _Stringbuffer;	// the string buffer
	};

	// basic_ostringstream TEMPLATE OPERATORS
template<class _Elem,
	class _Traits,
	class _Alloc> inline
	void swap(basic_ostringstream<_Elem, _Traits, _Alloc>& _Left,
		basic_ostringstream<_Elem, _Traits, _Alloc>& _Right)
	{	// swap _Left and _Right basic_ostringstreams
	_Left.swap(_Right);
	}

		// TEMPLATE CLASS basic_stringstream
template<class _Elem,
	class _Traits,
	class _Alloc>
	class basic_stringstream
		: public basic_iostream<_Elem, _Traits>
	{	// input/output stream associated with a character array
public:
	typedef basic_stringstream<_Elem, _Traits, _Alloc> _Myt;
	typedef basic_iostream<_Elem, _Traits> _Mybase;
	typedef _Elem char_type;
	typedef _Traits traits_type;
	typedef _Alloc allocator_type;
	typedef typename _Traits::int_type int_type;
	typedef typename _Traits::pos_type pos_type;
	typedef typename _Traits::off_type off_type;
	typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
	typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;

	explicit basic_stringstream(ios_base::openmode _Mode =
		ios_base::in | ios_base::out)
		: _Mybase(&_Stringbuffer),
			_Stringbuffer(_Mode)
		{	// construct empty character buffer
		}

	explicit basic_stringstream(const _Mystr& _Str,
		ios_base::openmode _Mode = ios_base::in | ios_base::out)
		: _Mybase(&_Stringbuffer),
			_Stringbuffer(_Str, _Mode)
		{	// construct character buffer from NTCS
		}

	basic_stringstream(_Myt&& _Right)
		: _Mybase(&_Stringbuffer)
		{	// construct by moving _Right
		_Assign_rv(_STD forward<_Myt>(_Right));
		}

	_Myt& operator=(_Myt&& _Right)
		{	// move from _Right
		_Assign_rv(_STD forward<_Myt>(_Right));
		return (*this);
		}

	void _Assign_rv(_Myt&& _Right)
		{	// assign by moving _Right
		if (this != &_Right)
			{	// different, worth moving
			_Stringbuffer.str(_Mystr());
			this->swap(_Right);
			}
		}

	void swap(_Myt& _Right)
		{	// swap with _Right
		if (this != &_Right)
			{	// different, swap base and buffer
			_Mybase::swap(_Right);
			_Stringbuffer.swap(_Right._Stringbuffer);
			}
		}

	basic_stringstream(const _Myt&) = delete;
	_Myt& operator=(const _Myt&) = delete;

	virtual ~basic_stringstream() _NOEXCEPT
		{	// destroy the object
		}

	_Mysb *rdbuf() const
		{	// return pointer to buffer
		return ((_Mysb *)&_Stringbuffer);
		}

	_Mystr str() const
		{	// return string copy of character array
		return (_Stringbuffer.str());
		}

	void str(const _Mystr& _Newstr)
		{	// replace character array from string
		_Stringbuffer.str(_Newstr);
		}

private:
	_Mysb _Stringbuffer;	// the string buffer
	};

	// basic_stringstream TEMPLATE OPERATORS
template<class _Elem,
	class _Traits,
	class _Alloc> inline
	void swap(basic_stringstream<_Elem, _Traits, _Alloc>& _Left,
		basic_stringstream<_Elem, _Traits, _Alloc>& _Right)
	{	// swap _Left and _Right basic_stringstreams
	_Left.swap(_Right);
	}
_STD_END
 #pragma pop_macro("new")
 #pragma warning(pop)
 #pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _SSTREAM_ */

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