#include <iostream>
#include <vector>
using namespace std;
class BufferedStreamBuf : public streambuf
{
streambuf *buf;
vector<int_type> buffer;
streampos pos;
public:
BufferedStreamBuf(streambuf* buf): buf(buf), pos(0) { }
BufferedStreamBuf(const BufferedStreamBuf&) = delete;
BufferedStreamBuf& operator=(const BufferedStreamBuf&) = delete;
protected:
virtual int_type underflow()
{
if (pos == buffer.size())
{
int_type c = buf->sbumpc();
buffer.push_back(c);
return c;
}
else if (pos < buffer.size())
{
return buffer[pos];
}
else
{
return EOF;
}
}
virtual int_type uflow()
{
if (pos >= buffer.size())
{
int_type c = buf->sbumpc();
buffer.push_back(c);
pos += 1;
return c;
}
else
{
return buffer[pos+=1];
}
}
virtual streampos seekoff(streamoff off, ios_base::seekdir way, ios_base::openmode which)
{
if (which == ios_base::in)
{
if (way == ios_base::beg and off >= 0)
{
while (off >= buffer.size())
uflow();
pos = off;
}
if (way == ios_base::cur)
{
streampos new_pos = off + pos;
while (new_pos >= buffer.size())
uflow();
pos = new_pos;
}
if (way == ios_base::end)
{
// Kann man später noch richtig machen. Erst einmal Fehler
return pos_type(off_type(-1));
}
}
return 0;
}
virtual streampos seekpos(streampos newp, ios_base::openmode which)
{
cerr << "Seekpos called.\n";
if (which == ios_base::in)
{
while (newp >= buffer.size())
uflow();
pos = newp;
}
return 0;
}
};
int main()
{
BufferedStreamBuf buffered_cin_streambuf(cin.rdbuf());
istream buffered_cin(&buffered_cin_streambuf);
int i;
buffered_cin >> i;
cout << i << '\n';
int j;
buffered_cin.seekg(1, ios::beg);
buffered_cin >> j;
cout << j << '\n';
}