ORIGINAL
Loading...
Searching...
No Matches
filterStream.h
1#ifndef FILTERSTREAM_H
2#define FILTERSTREAM_H
3
4#include "filter.h"
5#include "chain.h"
6
7namespace original{
8 template<typename TYPE>
9 class filterStream
10 {
11 enum class opts{AND = 1, OR = 0, NOT = 2, LEFT_BRACKET = 3, RIGHT_BRACKET = 4};
12
14 mutable chain<opts> ops;
15 mutable bool flag;
16
17 protected:
18 explicit filterStream();
19 void addBrackets();
20 void addAndOpt();
21 void addOrOpt();
22 void addNotOpt();
23 void pushEnd(const filter<TYPE>& f);
24 void pushAll(const filterStream& fs);
25 void toPostFix() const;
26 public:
27 ~filterStream() = default;
28 filterStream& operator&&(const filter<TYPE>& f);
29 filterStream& operator&&(const filterStream& fs);
30 filterStream& operator||(const filter<TYPE>& f);
31 filterStream& operator||(const filterStream& fs);
32 filterStream& operator!();
33 bool operator()(const TYPE& t) const;
34
35 template<typename T>
36 friend filterStream<T> operator&&(const filter<T>& f1, const filter<T>& f2);
37 template<typename T>
38 friend filterStream<T> operator&&(const filter<T>& f, const filterStream<T>& ofs);
39 template<typename T>
40 friend filterStream<T> operator&&(const filterStream<T>& ofs, const filter<T>& f);
41 template<typename T>
42 friend filterStream<T> operator||(const filter<T>& f1, const filter<T>& f2);
43 template<typename T>
44 friend filterStream<T> operator||(const filter<T>& f, const filterStream<T>& ofs);
45 template<typename T>
46 friend filterStream<T> operator||(const filterStream<T>& ofs, const filter<T>& f);
47 template<typename T>
48 friend filterStream<T> operator!(const filter<T>& f);
49 template<typename T>
50 friend filterStream<T> operator!(const filterStream<T>& ofs);
51 template<typename T>
52 friend filterStream<T> group(const filterStream<T>& ofs);
53 template<typename T>
54 friend filterStream<T> group(const filter<T>& f);
55 };
56
57 template<typename T>
58 filterStream<T> operator&&(const filter<T>& f1, const filter<T>& f2);
59 template<typename T>
60 filterStream<T> operator&&(const filter<T>& f, const filterStream<T>& ofs);
61 template<typename T>
62 filterStream<T> operator&&(const filterStream<T>& ofs, const filter<T>& f);
63 template<typename T>
64 filterStream<T> operator||(const filter<T>& f1, const filter<T>& f2);
65 template<typename T>
66 filterStream<T> operator||(const filter<T>& f, const filterStream<T>& ofs);
67 template<typename T>
68 filterStream<T> operator||(const filterStream<T>& ofs, const filter<T>& f);
69 template<typename T>
70 filterStream<T> operator!(const filter<T>& f);
71 template<typename T>
72 filterStream<T> operator!(const filterStream<T>& ofs);
73 template<typename T>
74 filterStream<T> group(const filterStream<T>& ofs);
75 template<typename T>
76 filterStream<T> group(const filter<T>& f);
77} // namespace original
78
79 template <typename TYPE>
80 original::filterStream<TYPE>::filterStream() : stream(), ops(), flag(false) {}
81
82 template <typename TYPE>
83 auto original::filterStream<TYPE>::addBrackets() -> void
84 {
85 this->stream.pushBegin(nullptr);
86 this->stream.pushEnd(nullptr);
87 this->ops.pushBegin(opts::LEFT_BRACKET);
88 this->ops.pushEnd(opts::RIGHT_BRACKET);
89 }
90
91 template <typename TYPE>
92 auto original::filterStream<TYPE>::addAndOpt() -> void
93 {
94 this->stream.pushEnd(nullptr);
95 this->ops.pushEnd(opts::AND);
96 }
97
98 template <typename TYPE>
99 auto original::filterStream<TYPE>::addOrOpt() -> void
100 {
101 this->stream.pushEnd(nullptr);
102 this->ops.pushEnd(opts::OR);
103 }
104
105 template <typename TYPE>
106 auto original::filterStream<TYPE>::addNotOpt() -> void
107 {
108 this->stream.pushBegin(nullptr);
109 this->ops.pushBegin(opts::NOT);
110 }
111
112 template <typename TYPE>
113 auto original::filterStream<TYPE>::pushEnd(const filter<TYPE>& f) -> void
114 {
115 this->stream.pushEnd(std::shared_ptr<filter<TYPE>>(f.clone()));
116 }
117
118 template <typename TYPE>
119 auto original::filterStream<TYPE>::pushAll(const filterStream& fs) -> void
120 {
121 for (const auto& filter: fs.stream)
122 {
123 this->stream.pushEnd(filter);
124 }
125 for (const auto& op: fs.ops)
126 {
127 this->ops.pushEnd(op);
128 }
129 }
130
131 template <typename TYPE>
132 auto original::filterStream<TYPE>::toPostFix() const -> void{
133 this->flag = true;
134
136 chain<opts> ops_post;
137 chain<opts> ops_tmp;
138
139 auto it_stream = this->stream.begins();
140 auto it_ops = this->ops.begins();
141
142 while (it_stream->isValid()){
143 if (it_stream->get() != nullptr){
144 stream_post.pushEnd(it_stream->get());
145 } else if (it_ops->isValid()){
146 switch (it_ops->get()) {
147 case opts::LEFT_BRACKET:
148 ops_tmp.pushEnd(opts::LEFT_BRACKET);
149 break;
150 case opts::RIGHT_BRACKET:
151 while (!ops_tmp.empty() && ops_tmp[-1] != opts::LEFT_BRACKET){
152 stream_post.pushEnd(nullptr);
153 ops_post.pushEnd(ops_tmp.popEnd());
154 }
155 ops_tmp.popEnd();
156 break;
157 case opts::NOT:
158 ops_tmp.pushEnd(opts::NOT);
159 break;
160 default:
161 while (!ops_tmp.empty()
162 && ops_tmp[-1] >= it_ops->get()
163 && ops_tmp[-1] != opts::LEFT_BRACKET){
164 stream_post.pushEnd(nullptr);
165 ops_post.pushEnd(ops_tmp.popEnd());
166 }
167 ops_tmp.pushEnd(it_ops->get());
168 break;
169 }
170 it_ops->next();
171 }
172 it_stream->next();
173 }
174
175 while (!ops_tmp.empty()){
176 stream_post.pushEnd(nullptr);
177 ops_post.pushEnd(ops_tmp.popEnd());
178 }
179 this->stream = stream_post;
180 this->ops = ops_post;
181 }
182
183 template <typename TYPE>
184 auto original::filterStream<TYPE>::operator&&(const filter<TYPE>& f) -> filterStream&
185 {
186 this->addAndOpt();
187 this->pushEnd(f);
188 return *this;
189 }
190
191 template <typename TYPE>
192 auto original::filterStream<TYPE>::operator&&(const filterStream& fs) -> filterStream&
193 {
194 this->addAndOpt();
195 this->pushAll(fs);
196 return *this;
197 }
198
199 template <typename TYPE>
200 auto original::filterStream<TYPE>::operator||(const filter<TYPE>& f) -> filterStream&
201 {
202 this->addOrOpt();
203 this->pushEnd(f);
204 return *this;
205 }
206
207 template <typename TYPE>
208 auto original::filterStream<TYPE>::operator||(const filterStream& fs) -> filterStream&
209 {
210 this->addOrOpt();
211 this->pushAll(fs);
212 return *this;
213 }
214
215 template <typename TYPE>
216 auto original::filterStream<TYPE>::operator!() -> filterStream&
217 {
218 this->addBrackets();
219 this->addNotOpt();
220 return *this;
221 }
222
223 template <typename TYPE>
224 auto original::operator&&(const filter<TYPE> &f1, const filter<TYPE> &f2) -> filterStream<TYPE> {
226 fs.pushEnd(f1);
227 fs.addAndOpt();
228 fs.pushEnd(f2);
229 return fs;
230 }
231
232 template <typename TYPE>
233 auto original::operator&&(const filter<TYPE> &f, const filterStream<TYPE> &ofs) -> filterStream<TYPE> {
235 fs.pushEnd(f);
236 fs.addAndOpt();
237 fs.pushAll(ofs);
238 return fs;
239 }
240
241 template<typename TYPE>
242 auto original::operator&&(const filterStream<TYPE> &ofs, const filter<TYPE> &f) -> filterStream<TYPE> {
243 filterStream<TYPE> fs(ofs);
244 return fs && f;
245 }
246
247 template <typename TYPE>
248 auto original::operator||(const filter<TYPE> &f1, const filter<TYPE> &f2) -> filterStream<TYPE> {
250 fs.pushEnd(f1);
251 fs.addOrOpt();
252 fs.pushEnd(f2);
253 return fs;
254 }
255
256 template <typename TYPE>
257 auto original::operator||(const filter<TYPE> &f, const filterStream<TYPE> &ofs) -> filterStream<TYPE> {
259 fs.pushEnd(f);
260 fs.addOrOpt();
261 fs.pushAll(ofs);
262 return fs;
263 }
264
265 template<typename TYPE>
266 auto original::operator||(const filterStream<TYPE> &ofs, const filter<TYPE> &f) -> filterStream<TYPE> {
267 filterStream<TYPE> fs(ofs);
268 return fs || f;
269 }
270
271 template <typename TYPE>
272 auto original::operator!(const filter<TYPE> &f) -> filterStream<TYPE> {
274 fs.pushEnd(f);
275 fs.addNotOpt();
276 return fs;
277 }
278
279 template<typename TYPE>
280 auto original::operator!(const filterStream<TYPE> &ofs) -> filterStream<TYPE> {
281 filterStream<TYPE> fs(ofs);
282 return !fs;
283 }
284
285 template<typename TYPE>
286 auto original::group(const filterStream<TYPE> &ofs) -> filterStream<TYPE> {
288 fs.pushAll(ofs);
289 fs.addBrackets();
290 return fs;
291 }
292
293 template<typename TYPE>
294 auto original::group(const filter<TYPE> &f) -> filterStream<TYPE> {
296 fs.pushEnd(f);
297 return fs;
298 }
299
300 template <typename TYPE>
301 auto original::filterStream<TYPE>::operator()(const TYPE &t) const -> bool {
302 if (!this->flag) this->toPostFix();
303
304 chain<bool> value_stack;
305 auto it_stream = this->stream.begins();
306 auto it_ops = this->ops.begins();
307
308 while (it_stream->isValid()){
309 if (it_stream->get() != nullptr){
310 value_stack.pushEnd(it_stream->get()->operator()(t));
311 } else if (it_ops->isValid()){
312 switch (it_ops->get()) {
313 case opts::NOT:
314 value_stack[-1] = !value_stack[-1];
315 break;
316 default:
317 const bool right = value_stack.popEnd();
318 const bool left = value_stack.popEnd();
319 value_stack.pushEnd(it_ops->get() == opts::AND ?
320 left && right : left || right);
321 break;
322 }
323 it_ops->next();
324 }
325 it_stream->next();
326 }
327 return value_stack[-1];
328 }
329
330#endif //FILTERSTREAM_H
Definition chain.h:13
Definition filterStream.h:10
Definition filter.h:8