Zen C++ Libraries
Zero-dependency re-usable components for C++
Loading...
Searching...
No Matches
stream.hpp
1#ifndef ZEN_STREAM_HPP
2#define ZEN_STREAM_HPP
3
4#include <cstdint>
5#include <deque>
6#include <iterator>
7#include <type_traits>
8#include <string>
9
10#include "zen/config.hpp"
11#include "zen/error.hpp"
12#include "zen/maybe.hpp"
13
14ZEN_NAMESPACE_START
15
16template<typename T, typename Error = error>
17class stream {
18public:
19
20 virtual result<maybe<T>> get() = 0;
21 virtual result<maybe<T>> peek(std::size_t offset = 1) = 0;
22
23 virtual result<void> skip(std::size_t count = 1) {
24 for (std::size_t i = 0; i < count; i++) {
25 ZEN_TRY_DISCARD(get());
26 }
27 return right();
28 }
29
30};
31
32template<typename T>
33class buffered_stream : public stream<T> {
34
35 std::deque<T> buffer;
36
37public:
38
39 using value_type = T;
40
41 result<maybe<T>> get() override {
42 T element;
43 if (buffer.empty()) {
44 auto result = read();
45 ZEN_TRY(result);
46 if (!result->has_value()) {
47 return right(std::nullopt);
48 }
49 element = **result;
50 } else {
51 element = buffer.front();
52 buffer.pop_front();
53 }
54 return right(element);
55 }
56
57 result<maybe<T>> peek(std::size_t offset) override {
58 while (buffer.size() < offset) {
59 auto result = read();
60 ZEN_TRY(result);
61 if (!result->has_value()) {
62 return right(std::nullopt);
63 }
64 buffer.push_back(**result);
65 }
66 return right(buffer[offset-1]);
67 }
68
69 virtual result<maybe<T>> read() = 0;
70
71};
72
73template<typename IterT, typename T = typename std::iterator_traits<IterT>::value_type>
74class iterator_stream : public stream<T> {
75public:
76
77 using value_type = T;
78
79private:
80
81 IterT current;
82 IterT end;
83
84public:
85
86 iterator_stream(IterT begin, IterT end):
87 current(begin), end(end) {}
88
89 result<maybe<value_type>> get() override {
90 if (current == end) {
91 return right(std::nullopt);
92 }
93 return right(*(current++));
94 }
95
96 result<maybe<value_type>> peek(std::size_t offset = 1) override {
97 if (current == end) {
98 return right(std::nullopt);
99 }
100 return right(*current);
101 }
102
103};
104
105inline iterator_stream<std::string::const_iterator, int> make_stream(const std::string& str) {
107 str.begin(),
108 str.end(),
109 };
110}
111
112inline iterator_stream<std::string_view::const_iterator, int> make_stream(const std::string_view& str) {
114 str.begin(),
115 str.end(),
116 };
117}
118
119using char_stream = stream<int>;
120
121ZEN_NAMESPACE_END
122
123#endif // of #ifndef ZEN_STREAM_HPP
Definition stream.hpp:33
Definition stream.hpp:74
Definition stream.hpp:17
right_t< void > right()
Definition either.hpp:329
#define ZEN_TRY_DISCARD(expr)
The same as ZEN_TRY but the expression is immediately dropped.
Definition either.hpp:370
#define ZEN_TRY(value)
Return a left-valued immediately so only a right-valued either type remains.
Definition either.hpp:364