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
17namespace original{
26 template<typename TYPE>
28 {
29 public:
31 enum class opts{AND = 1, OR = 0, NOT = 2, LEFT_BRACKET = 3, RIGHT_BRACKET = 4};
32 private:
34 static const strongPtr<filter<TYPE>> nullFilter;
35
36 mutable chain<strongPtr<filter<TYPE>>> stream{};
37 mutable chain<opts> ops{};
38 mutable bool flag;
39
40 protected:
45 explicit filterStream();
46
51 void addBrackets();
52
57 void addAndOpt();
58
63 void addOrOpt();
64
69 void addNotOpt();
70
75 void pushEnd(const filter<TYPE>& f);
76
81 void pushAll(const filterStream& fs);
82
87 void toPostFix() const;
88
89 public:
90 ~filterStream() = default;
91
98
105
112
119
126
132 bool operator()(const TYPE& t) const;
133
134 // Friend operator implementations
135 template<typename T>
137 template<typename T>
139 template<typename T>
141 template<typename T>
143 template<typename T>
145 template<typename T>
147 template<typename T>
149 template<typename T>
151 template<typename T>
153 template<typename T>
155 };
156
157 template <typename TYPE>
159
167 template<typename T>
169
177 template<typename T>
179
187 template<typename T>
189
197 template<typename T>
199
207 template<typename T>
209
217 template<typename T>
219
227 template<typename T>
229
237 template<typename T>
239
247 template<typename T>
249
257 template<typename T>
259} // namespace original
260
261 template <typename TYPE>
263
264 template <typename TYPE>
266 {
267 this->stream.pushBegin(nullFilter);
268 this->stream.pushEnd(nullFilter);
269 this->ops.pushBegin(opts::LEFT_BRACKET);
270 this->ops.pushEnd(opts::RIGHT_BRACKET);
271 }
272
273 template <typename TYPE>
275 {
276 this->stream.pushEnd(nullFilter);
277 this->ops.pushEnd(opts::AND);
278 }
279
280 template <typename TYPE>
282 {
283 this->stream.pushEnd(nullFilter);
284 this->ops.pushEnd(opts::OR);
285 }
286
287 template <typename TYPE>
289 {
290 this->stream.pushBegin(nullFilter);
291 this->ops.pushBegin(opts::NOT);
292 }
293
294 template <typename TYPE>
296 {
297 this->stream.pushEnd(strongPtr<filter<TYPE>>(f.clone()));
298 }
299
300 template <typename TYPE>
302 {
303 for (auto& filter: fs.stream)
304 {
305 this->stream.pushEnd(filter);
306 }
307 for (auto& op: fs.ops)
308 {
309 this->ops.pushEnd(op);
310 }
311 }
312
313 template <typename TYPE>
315 this->flag = true;
316
320
321 auto it_stream = this->stream.begins();
322 auto it_ops = this->ops.begins();
323
324 while (it_stream->isValid()){
325 if (it_stream->get() != nullFilter){
326 stream_post.pushEnd(it_stream->get());
327 } else if (it_ops->isValid()){
328 switch (it_ops->get()) {
329 case opts::LEFT_BRACKET:
330 ops_tmp.pushEnd(opts::LEFT_BRACKET);
331 break;
332 case opts::RIGHT_BRACKET:
333 while (!ops_tmp.empty() && ops_tmp[-1] != opts::LEFT_BRACKET){
334 stream_post.pushEnd(nullFilter);
335 ops_post.pushEnd(ops_tmp.popEnd());
336 }
337 ops_tmp.popEnd();
338 break;
339 case opts::NOT:
340 ops_tmp.pushEnd(opts::NOT);
341 break;
342 default:
343 while (!ops_tmp.empty()
344 && ops_tmp[-1] >= it_ops->get()
345 && ops_tmp[-1] != opts::LEFT_BRACKET){
346 stream_post.pushEnd(nullFilter);
347 ops_post.pushEnd(ops_tmp.popEnd());
348 }
349 ops_tmp.pushEnd(it_ops->get());
350 break;
351 }
352 it_ops->next();
353 }
354 it_stream->next();
355 }
356
357 while (!ops_tmp.empty()){
358 stream_post.pushEnd(nullFilter);
359 ops_post.pushEnd(ops_tmp.popEnd());
360 }
361 this->stream = stream_post;
362 this->ops = ops_post;
363 delete it_ops;
364 delete it_stream;
365 }
366
367 template <typename TYPE>
369 {
370 this->addAndOpt();
371 this->pushEnd(f);
372 return *this;
373 }
374
375 template <typename TYPE>
377 {
378 this->addAndOpt();
379 this->pushAll(fs);
380 return *this;
381 }
382
383 template <typename TYPE>
385 {
386 this->addOrOpt();
387 this->pushEnd(f);
388 return *this;
389 }
390
391 template <typename TYPE>
393 {
394 this->addOrOpt();
395 this->pushAll(fs);
396 return *this;
397 }
398
399 template <typename TYPE>
401 {
402 this->addBrackets();
403 this->addNotOpt();
404 return *this;
405 }
406
407 template <typename TYPE>
410 fs.pushEnd(f1);
411 fs.addAndOpt();
412 fs.pushEnd(f2);
413 return fs;
414 }
415
416 template <typename TYPE>
417 auto original::operator&&(const filter<TYPE> &f, const filterStream<TYPE> &ofs) -> filterStream<TYPE> {
418 filterStream<TYPE> fs;
419 fs.pushEnd(f);
420 fs.addAndOpt();
421 fs.pushAll(ofs);
422 return fs;
423 }
424
425 template<typename TYPE>
426 auto original::operator&&(const filterStream<TYPE> &ofs, const filter<TYPE> &f) -> filterStream<TYPE> {
427 filterStream<TYPE> fs(ofs);
428 return fs && f;
429 }
430
431 template <typename TYPE>
432 auto original::operator||(const filter<TYPE> &f1, const filter<TYPE> &f2) -> filterStream<TYPE> {
433 filterStream<TYPE> fs;
434 fs.pushEnd(f1);
435 fs.addOrOpt();
436 fs.pushEnd(f2);
437 return fs;
438 }
439
440 template <typename TYPE>
441 auto original::operator||(const filter<TYPE> &f, const filterStream<TYPE> &ofs) -> filterStream<TYPE> {
442 filterStream<TYPE> fs;
443 fs.pushEnd(f);
444 fs.addOrOpt();
445 fs.pushAll(ofs);
446 return fs;
447 }
448
449 template<typename TYPE>
450 auto original::operator||(const filterStream<TYPE> &ofs, const filter<TYPE> &f) -> filterStream<TYPE> {
451 filterStream<TYPE> fs(ofs);
452 return fs || f;
453 }
454
455 template <typename TYPE>
456 auto original::operator!(const filter<TYPE> &f) -> filterStream<TYPE> {
457 filterStream<TYPE> fs;
458 fs.pushEnd(f);
459 fs.addNotOpt();
460 return fs;
461 }
462
463 template<typename TYPE>
464 auto original::operator!(const filterStream<TYPE> &ofs) -> filterStream<TYPE> {
465 filterStream<TYPE> fs(ofs);
466 return !fs;
467 }
468
469 template<typename TYPE>
470 auto original::group(const filterStream<TYPE> &ofs) -> filterStream<TYPE> {
471 filterStream<TYPE> fs;
472 fs.pushAll(ofs);
473 fs.addBrackets();
474 return fs;
475 }
476
477 template<typename TYPE>
478 auto original::group(const filter<TYPE> &f) -> filterStream<TYPE> {
479 filterStream<TYPE> fs;
480 fs.pushEnd(f);
481 return fs;
482 }
483
484 template <typename TYPE>
486 if (!this->flag) this->toPostFix();
487
489 auto it_stream = this->stream.begins();
490 auto it_ops = this->ops.begins();
491
492 while (it_stream->isValid()){
493 if (it_stream->get() != nullFilter){
494 value_stack.pushEnd(it_stream->get()->operator()(t));
495 } else if (it_ops->isValid()){
496 switch (it_ops->get()) {
497 case opts::NOT:
498 value_stack[-1] = !value_stack[-1];
499 break;
500 default:
501 const bool right = value_stack.popEnd();
502 const bool left = value_stack.popEnd();
503 value_stack.pushEnd(it_ops->get() == opts::AND ?
504 left && right : left || right);
505 break;
506 }
507 it_ops->next();
508 }
509 it_stream->next();
510 }
511 delete it_ops;
512 delete it_stream;
513 return value_stack[-1];
514 }
515
516#endif //FILTERSTREAM_H
Non-cyclic doubly linked list implementation.
const TYPE * get() const
Get managed pointer const version.
Definition autoPtr.h:629
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.
void toPostFix() const
Convert infix notation to postfix.
Definition filterStream.h:314
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:295
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:288
void addBrackets()
Add bracket operators for grouping.
Definition filterStream.h:265
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:400
void addAndOpt()
Add AND operator to the stream.
Definition filterStream.h:274
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:485
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:301
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:281
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()
Protected constructor for stream initialization.
Definition filterStream.h:262
Base class for filter operations.
Definition filter.h:31
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
Shared ownership smart pointer with strong references.
Definition refCntPtr.h:108
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.