10 class fbuf final :
public std::streambuf {
13 constexpr
static size_t bufsz = 4096;
20 std::streambuf *setbuf(char_type *
s, std::streamsize
n)
override;
22 int_type underflow()
override;
25 class cfstream final :
public std::istream {
34 FILE *
f = popen(
cmdline.c_str(),
"r");
37 return std::unique_ptr<std::istream>(
new cfstream(
f));
40 fbuf::fbuf(FILE *
f) :
file(
f),
buf(new char[bufsz]) { this->setg(this->
buf, this->
buf + bufsz, this->
buf + bufsz); }
47 std::streambuf *fbuf::setbuf(char_type *
s, std::streamsize
n) {
return nullptr; }
50 if (fflush(this->
file) != 0)
55 fbuf::int_type fbuf::underflow() {
56 if (this->gptr() < this->egptr()) {
57 char c = *this->gptr();
58 this->setg(this->eback(), this->gptr() + 1, this->egptr());
59 return traits_type::to_int_type(
c);
61 size_t n = fread(this->
buf, 1,
sizeof(this->
buf), this->
file);
63 return traits_type::eof();
64 this->setg(this->
buf, this->
buf, this->
buf + n);
65 return traits_type::to_int_type(*this->gptr());
68 cfstream::cfstream(FILE *
f) :
std::istream(&
buf),
buf(
f) {}
std::unique_ptr< std::istream > popenCPP(const std::string &cmdline)