ORIGINAL
Loading...
Searching...
No Matches
filterStream.h
Go to the documentation of this file.
1#ifndef FILTERSTREAM_H
2#define FILTERSTREAM_H
3
4#include "filter.h"
5#include "chain.h"
6#include "refCntPtr.h"
7
8
16
17namespace original{
26 template<typename TYPE>
28 {
30 static const strongPtr<filter<TYPE>> nullFilter;
31
33 enum class opts{AND = 1, OR = 0, NOT = 2, LEFT_BRACKET = 3, RIGHT_BRACKET = 4};
34
35 mutable chain<strongPtr<filter<TYPE>>> stream;
36 mutable chain<opts> ops;
37 mutable bool flag;
38
39 protected:
44 explicit filterStream();
45
50 void addBrackets();
51
56 void addAndOpt();
57
62 void addOrOpt();
63
68 void addNotOpt();
69
74 void pushEnd(const filter<TYPE>& f);
75
80 void pushAll(const filterStream& fs);
81
86 void toPostFix() const;
87
88 public:
89 ~filterStream() = default;
90
97
104
111
118
125
131 bool operator()(const TYPE& t) const;
132
133 // Friend operator implementations
134 template<typename T>
135 friend filterStream<T> operator&&(const filter<T>& f1, const filter<T>& f2);
136 template<typename T>
138 template<typename T>
140 template<typename T>
141 friend filterStream<T> operator||(const filter<T>& f1, const filter<T>& f2);
142 template<typename T>
144 template<typename T>
146 template<typename T>
148 template<typename T>
150 template<typename T>
152 template<typename T>
154 };
155
156 template <typename TYPE>
157 const strongPtr<filter<TYPE>> filterStream<TYPE>::nullFilter{};
158
166 template<typename T>
168
176 template<typename T>
178
186 template<typename T>
188
196 template<typename T>
198
206 template<typename T>
208
216 template<typename T>
218
226 template<typename T>
228
236 template<typename T>
238
246 template<typename T>
248
256 template<typename T>
258} // namespace original
259
260 template <typename TYPE>
261 original::filterStream<TYPE>::filterStream() : stream(), ops(), flag(false) {}
262
263 template <typename TYPE>
265 {
266 this->stream.pushBegin(nullFilter);
267 this->stream.pushEnd(nullFilter);
268 this->ops.pushBegin(opts::LEFT_BRACKET);
269 this->ops.pushEnd(opts::RIGHT_BRACKET);
270 }
271
272 template <typename TYPE>
274 {
275 this->stream.pushEnd(nullFilter);
276 this->ops.pushEnd(opts::AND);
277 }
278
279 template <typename TYPE>
281 {
282 this->stream.pushEnd(nullFilter);
283 this->ops.pushEnd(opts::OR);
284 }
285
286 template <typename TYPE>
288 {
289 this->stream.pushBegin(nullFilter);
290 this->ops.pushBegin(opts::NOT);
291 }
292
293 template <typename TYPE>
295 {
296 this->stream.pushEnd(strongPtr<filter<TYPE>>(f.clone()));
297 }
298
299 template <typename TYPE>
301 {
302 for (auto& filter: fs.stream)
303 {
304 this->stream.pushEnd(filter);
305 }
306 for (auto& op: fs.ops)
307 {
308 this->ops.pushEnd(op);
309 }
310 }
311
312 template <typename TYPE>
314 this->flag = true;
315
316 chain<strongPtr<filter<TYPE>>> stream_post;
317 chain<opts> ops_post;
318 chain<opts> ops_tmp;
319
320 auto it_stream = this->stream.begins();
321 auto it_ops = this->ops.begins();
322
323 while (it_stream->isValid()){
324 if (it_stream->get() != nullFilter){
325 stream_post.pushEnd(it_stream->get());
326 } else if (it_ops->isValid()){
327 switch (it_ops->get()) {
328 case opts::LEFT_BRACKET:
329 ops_tmp.pushEnd(opts::LEFT_BRACKET);
330 break;
331 case opts::RIGHT_BRACKET:
332 while (!ops_tmp.empty() && ops_tmp[-1] != opts::LEFT_BRACKET){
333 stream_post.pushEnd(nullFilter);
334 ops_post.pushEnd(ops_tmp.popEnd());
335 }
336 ops_tmp.popEnd();
337 break;
338 case opts::NOT:
339 ops_tmp.pushEnd(opts::NOT);
340 break;
341 default:
342 while (!ops_tmp.empty()
343 && ops_tmp[-1] >= it_ops->get()
344 && ops_tmp[-1] != opts::LEFT_BRACKET){
345 stream_post.pushEnd(nullFilter);
346 ops_post.pushEnd(ops_tmp.popEnd());
347 }
348 ops_tmp.pushEnd(it_ops->get());
349 break;
350 }
351 it_ops->next();
352 }
353 it_stream->next();
354 }
355
356 while (!ops_tmp.empty()){
357 stream_post.pushEnd(nullFilter);
358 ops_post.pushEnd(ops_tmp.popEnd());
359 }
360 this->stream = stream_post;
361 this->ops = ops_post;
362 delete it_ops;
363 delete it_stream;
364 }
365
366 template <typename TYPE>
368 {
369 this->addAndOpt();
370 this->pushEnd(f);
371 return *this;
372 }
373
374 template <typename TYPE>
376 {
377 this->addAndOpt();
378 this->pushAll(fs);
379 return *this;
380 }
381
382 template <typename TYPE>
384 {
385 this->addOrOpt();
386 this->pushEnd(f);
387 return *this;
388 }
389
390 template <typename TYPE>
392 {
393 this->addOrOpt();
394 this->pushAll(fs);
395 return *this;
396 }
397
398 template <typename TYPE>
400 {
401 this->addBrackets();
402 this->addNotOpt();
403 return *this;
404 }
405
406 template <typename TYPE>
409 fs.pushEnd(f1);
410 fs.addAndOpt();
411 fs.pushEnd(f2);
412 return fs;
413 }
414
415 template <typename TYPE>
416 auto original::operator&&(const filter<TYPE> &f, const filterStream<TYPE> &ofs) -> filterStream<TYPE> {
417 filterStream<TYPE> fs;
418 fs.pushEnd(f);
419 fs.addAndOpt();
420 fs.pushAll(ofs);
421 return fs;
422 }
423
424 template<typename TYPE>
426 filterStream<TYPE> fs(ofs);
427 return fs && f;
428 }
429
430 template <typename TYPE>
433 fs.pushEnd(f1);
434 fs.addOrOpt();
435 fs.pushEnd(f2);
436 return fs;
437 }
438
439 template <typename TYPE>
442 fs.pushEnd(f);
443 fs.addOrOpt();
444 fs.pushAll(ofs);
445 return fs;
446 }
447
448 template<typename TYPE>
450 filterStream<TYPE> fs(ofs);
451 return fs || f;
452 }
453
454 template <typename TYPE>
457 fs.pushEnd(f);
458 fs.addNotOpt();
459 return fs;
460 }
461
462 template<typename TYPE>
464 filterStream<TYPE> fs(ofs);
465 return !fs;
466 }
467
468 template<typename TYPE>
471 fs.pushAll(ofs);
472 fs.addBrackets();
473 return fs;
474 }
475
476 template<typename TYPE>
479 fs.pushEnd(f);
480 return fs;
481 }
482
483 template <typename TYPE>
484 auto original::filterStream<TYPE>::operator()(const TYPE &t) const -> bool {
485 if (!this->flag) this->toPostFix();
486
487 chain<bool> value_stack;
488 auto it_stream = this->stream.begins();
489 auto it_ops = this->ops.begins();
490
491 while (it_stream->isValid()){
492 if (it_stream->get() != nullFilter){
493 value_stack.pushEnd(it_stream->get()->operator()(t));
494 } else if (it_ops->isValid()){
495 switch (it_ops->get()) {
496 case opts::NOT:
497 value_stack[-1] = !value_stack[-1];
498 break;
499 default:
500 const bool right = value_stack.popEnd();
501 const bool left = value_stack.popEnd();
502 value_stack.pushEnd(it_ops->get() == opts::AND ?
503 left && right : left || right);
504 break;
505 }
506 it_ops->next();
507 }
508 it_stream->next();
509 }
510 delete it_ops;
511 delete it_stream;
512 return value_stack[-1];
513 }
514
515#endif //FILTERSTREAM_H
Non-cyclic doubly linked list implementation.
Non-cyclic doubly linked list container.
Definition chain.h:36
TYPE popEnd() override
Pops an element from the end of the chain.
Definition chain.h:836
Iterator * begins() const override
Gets an iterator to the beginning of the chain.
Definition chain.h:858
TYPE get(integer index) const override
Gets the element at the specified index.
Definition chain.h:698
void pushEnd(const TYPE &e) override
Pushes an element to the end of the chain.
Definition chain.h:776
bool empty() const
Checks if the container is empty.
Definition container.h:155
Composite filter builder with logical operator chaining.
Definition filterStream.h:28
friend filterStream< T > operator&&(const filter< T > &f, const filterStream< T > &ofs)
AND operator between filter and filterStream.
filterStream & operator&&(const filter< TYPE > &f)
AND operator with single filter.
Definition filterStream.h:367
void toPostFix() const
Convert infix notation to postfix.
Definition filterStream.h:313
friend filterStream< T > operator!(const filter< T > &f)
Create negated filterStream from filter.
void pushEnd(const filter< TYPE > &f)
Append filter to the stream.
Definition filterStream.h:294
friend filterStream< T > operator!(const filterStream< T > &ofs)
Create negated filterStream from existing stream.
friend filterStream< T > operator||(const filterStream< T > &ofs, const filter< T > &f)
OR operator between filterStream and filter.
void addNotOpt()
Add NOT operator to the stream.
Definition filterStream.h:287
void addBrackets()
Add bracket operators for grouping.
Definition filterStream.h:264
friend filterStream< T > operator||(const filter< T > &f1, const filter< T > &f2)
Create OR filterStream from two filters.
filterStream & operator!()
Logical NOT operator.
Definition filterStream.h:399
void addAndOpt()
Add AND operator to the stream.
Definition filterStream.h:273
friend filterStream< T > operator&&(const filterStream< T > &ofs, const filter< T > &f)
AND operator between filterStream and filter.
bool operator()(const TYPE &t) const
Filter evaluation operator.
Definition filterStream.h:484
friend filterStream< T > operator&&(const filter< T > &f1, const filter< T > &f2)
Create AND filterStream from two filters.
void pushAll(const filterStream &fs)
Merge another filterStream into this one.
Definition filterStream.h:300
friend filterStream< T > group(const filterStream< T > &ofs)
Create grouped filterStream from existing stream.
void addOrOpt()
Add OR operator to the stream.
Definition filterStream.h:280
friend filterStream< T > group(const filter< T > &f)
Create grouped filterStream from single filter.
friend filterStream< T > operator||(const filter< T > &f, const filterStream< T > &ofs)
OR operator between filter and filterStream.
filterStream & operator||(const filter< TYPE > &f)
OR operator with single filter.
Definition filterStream.h:383
filterStream()
Protected constructor for stream initialization.
Definition filterStream.h:261
Base class for filter operations.
Definition filter.h:31
Shared ownership smart pointer with strong references.
Definition refCntPtr.h:100
Filter base class and derived filter classes for various matching operations.
Main namespace for the project Original.
Definition algorithms.h:21
filterStream< T > operator&&(const filter< T > &f1, const filter< T > &f2)
Create AND filterStream from two filters.
filterStream< T > operator!(const filter< T > &f)
Create negated filterStream from filter.
filterStream< T > operator||(const filter< T > &f1, const filter< T > &f2)
Create OR filterStream from two filters.
filterStream< T > group(const filterStream< T > &ofs)
Create grouped filterStream from existing stream.
Reference-counted smart pointer hierarchy.