LeviLamina
Loading...
Searching...
No Matches
FunctionStream.h
1#pragma once
2
3#include <functional>
4#include <iostream>
5#include <utility>
6
7namespace ll::io {
8
9template <class Char, class Traits = std::char_traits<Char>>
10struct basic_functionbuf;
11
12template <class Char, class Traits = std::char_traits<Char>>
13struct basic_ofuncstream;
14
15using ofuncstream = basic_ofuncstream<char>;
16using functionbuf = basic_functionbuf<char>;
17using wofuncstream = basic_ofuncstream<wchar_t>;
18using wfunctionbuf = basic_functionbuf<wchar_t>;
19
20template <class Char, class Traits>
21struct basic_functionbuf : public std::basic_streambuf<Char, Traits> {
22
23 using base = std::basic_streambuf<Char, Traits>;
24 using view = std::basic_string_view<Char>;
25 using int_type = typename Traits::int_type;
26
27 explicit basic_functionbuf(std::function<void(view)> const& function) : function(std::move(function)) {
28 this->setp(buffer, buffer + sizeof(buffer) - 1);
29 }
30
31
32private:
33 Char buffer[0x1000]{};
34
35 std::function<void(view)> function;
36
37 int_type overflow(int_type c) override {
38 if (!Traits::eq_int_type(c, Traits::eof())) {
39 *this->pptr() = Traits::to_char_type(c);
40 this->pbump(1);
41 }
42 return sync() ? Traits::not_eof(c) : Traits::eof();
43 }
44
45 int_type sync() override {
46 if (this->pbase() != this->pptr()) {
47 function(view(this->pbase(), this->pptr()));
48 this->setp(this->pbase(), this->epptr());
49 }
50 return 0;
51 }
52};
53
54template <class Char, class Traits>
55struct basic_ofuncstream : private virtual basic_functionbuf<Char, Traits>, public std::basic_ostream<Char, Traits> {
56
57 using view = typename basic_functionbuf<Char, Traits>::view;
58
59 explicit basic_ofuncstream(std::function<void(view)> const& function)
60 : basic_functionbuf<Char, Traits>(std::move(function)),
61 std::basic_ostream<Char, Traits>(this) {
62 this->setf(std::ios_base::unitbuf);
63 }
64};
65} // namespace ll::io
Definition buffer.h:5
Definition FunctionStream.h:21
Definition FunctionStream.h:55