#include <iostream>
	#include <sstream>

	namespace std
	{
		struct substreambuf : public streambuf
		{
			explicit substreambuf(streambuf* sbuf, streampos pos, streampos len) :
			m_sbuf(sbuf),
			m_pos(pos),
			m_len(len),
			m_read(0)
			{
				m_sbuf->pubseekpos(pos);

				setbuf(nullptr, 0);
			}

		protected:
			int underflow()
			{
				if (m_read >= m_len)
				{
					return traits_type::eof();
				}

				return m_sbuf->sgetc();
			}

			int uflow()
			{
				if (m_read >= m_len)
				{
					return traits_type::eof();
				}

				m_read += 1;

				return m_sbuf->sbumpc();
			}

			streampos seekoff(streamoff off, ios_base::seekdir seekdir, ios_base::openmode openmode = ios_base::in | ios_base::out)
			{
				if (seekdir == ios_base::beg)
				{
					off += m_pos;
				}
				else if (seekdir == ios_base::cur)
				{
					off += m_pos + m_read;
				}
				else if (seekdir == ios_base::end)
				{
					off += m_pos + m_len;
				}

				return m_sbuf->pubseekpos(off, openmode) - m_pos;
			}

			streampos seekpos(streampos streampos, ios_base::openmode openmode = ios_base::in | ios_base::out)
			{
				streampos += m_pos;

				if (streampos > m_pos + m_len)
				{
					return -1;
				}

				return m_sbuf->pubseekpos(streampos, openmode) - m_pos;
			}

		private:
			streambuf* m_sbuf;
			streampos m_pos;
			streamsize m_len;
			streampos m_read;
		};
	};

#include <iostream>
	#include <sstream>

	using namespace std;

	int main()
	{
		stringstream ss;

		ss << "Hello, World!";

		substreambuf asd(ss.rdbuf(), 0, 5);

		istream istream(&asd);

		char buffer[6] = { '\0' };
		istream.read(buffer, sizeof(buffer));

		cout << buffer << endl;
	}