diff --git a/include/utils/iterator/filter.hpp b/include/utils/iterator/filter.hpp new file mode 100644 index 000000000..2a45d23fe --- /dev/null +++ b/include/utils/iterator/filter.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "utils/iterator/iterator_base.hpp" +#include "utils/option.hpp" + +namespace iter +{ + +// Class which filters values T returned by I iterator if OP returns true for +// them. +// T - type of return value +// I - iterator type +// OP - type of filter function +template <class T, class I, class OP> +class Filter : public IteratorBase<T> +{ + +public: + Filter() = delete; + + // Filter operation is designed to be used in chained calls which operate on + // a + // iterator. Filter will in that usecase receive other iterator by value and + // std::move is a optimization for it. + Filter(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {} + + Option<T> next() final + { + auto item = iter.next(); + if (item.is_present() && op(item.get())) { + return std::move(item); + } else { + return Option<T>(); + } + } + +private: + I iter; + OP op; +}; + +template <class I, class OP> +auto make_filter(I &&iter, OP &&op) +{ + // Compiler cant deduce type T. decltype is here to help with it. + return Filter<decltype(iter.next().take()), I, OP>(std::move(iter), + std::move(op)); +} +} diff --git a/include/utils/iterator/iterator.hpp b/include/utils/iterator/iterator.hpp index 93e48a67d..8a42b10ac 100644 --- a/include/utils/iterator/iterator.hpp +++ b/include/utils/iterator/iterator.hpp @@ -1,6 +1,7 @@ #pragma once #include "utils/iterator/accessor.hpp" +#include "utils/iterator/filter.hpp" #include "utils/iterator/for_all.hpp" #include "utils/iterator/iterator_accessor.hpp" #include "utils/iterator/iterator_base.hpp" diff --git a/include/utils/iterator/query.hpp b/include/utils/iterator/query.hpp new file mode 100644 index 000000000..b3fa64365 --- /dev/null +++ b/include/utils/iterator/query.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "storage/vertex_accessor.hpp" +#include "utils/iterator/iterator.hpp" +#include "utils/option.hpp" + +namespace query_help +{ + +template <class A> +bool fill(A &a) +{ + return a.fill(); +} +}; + +// Base iterator for next() kind iterator. +// Vertex::Accessor - type of return value +template <> +class IteratorBase<Vertex::Accessor> +{ +public: + virtual Option<Vertex::Accessor> next() = 0; + + auto fill() + { + return iter::make_filter(std::move(*this), query_help::fill); + } +}; diff --git a/poc/tool.cpp b/poc/tool.cpp index 616db34f2..a60ee9ae7 100644 --- a/poc/tool.cpp +++ b/poc/tool.cpp @@ -13,6 +13,7 @@ #include "storage/record_accessor.cpp" #include "storage/vertex_accessor.cpp" #include "utils/command_line/arguments.hpp" +#include "utils/iterator/query.hpp" using namespace std; @@ -164,7 +165,7 @@ void oportunity_employe_company( const EdgeType &type_created, const EdgeType &type_works_in, const Label &label_company) { - iter::for_all_fill(va.in(), [&](auto opp_e) { + iter::for_all(va.in().fill(), [&](auto opp_e) { // cout << " oec.in()" << endl; from_fill(opp_e, type_created, [&](auto creator) { // cout << " type_created" << endl;