There are a plethora of streams and streambuffers available today, none are as fast as a memory streambuf
, that you can use for testing. Shoot away!
#ifndef MEMSTREAMBUF_HPP
# define MEMSTREAMBUF_HPP
# pragma once
#include <cassert>
#include <cstring>
#include <array>
#include <iostream>
#include <streambuf>
template <::std::size_t N>
class memstreambuf : public ::std::streambuf
{
::std::array<char, N> buf_;
public:
memstreambuf()
{
setbuf(buf_.data(), buf_.size());
}
::std::streambuf* setbuf(char_type* const s,
::std::streamsize const n) final
{
auto const begin(s);
auto const end(s + n);
setg(begin, begin, end);
setp(begin, end);
return this;
}
pos_type seekpos(pos_type const pos,
::std::ios_base::openmode const which = ::std::ios_base::in |
::std::ios_base::out) final
{
switch (which)
{
case ::std::ios_base::in:
if (pos < egptr() - eback())
{
setg(eback(), eback() + pos, egptr());
return pos;
}
else
{
break;
}
case ::std::ios_base::out:
if (pos < epptr() - pbase())
{
setp(pbase(), epptr());
pbump(pos);
return pos;
}
else
{
break;
}
default:
assert(0);
}
return pos_type(off_type(-1));
}
::std::streamsize xsgetn(char_type* const s,
::std::streamsize const count) final
{
auto const size(::std::min(egptr() - gptr(), count));
::std::memcpy(s, gptr(), size);
gbump(size);
return egptr() == gptr() ? traits_type::eof() : size;
}
::std::streamsize xsputn(char_type const* s,
::std::streamsize const count) final
{
auto const size(::std::min(epptr() - pptr(), count));
::std::memcpy(pptr(), s, size);
pbump(size);
return epptr() == pptr() ? traits_type::eof() : size;
}
};
template <::std::size_t N = 1024>
class memstream : public memstreambuf<N>,
public ::std::istream,
public ::std::ostream
{
public:
memstream() : ::std::istream(this),
::std::ostream(this)
{
}
};
#endif // MEMSTREAMBUF_HPP