#pragma once #include "utils/crtp.hpp" #include "utils/iterator/count.hpp" #include "utils/option.hpp" // class EdgeType; namespace iter { template auto make_map(I &&iter, OP &&op); template auto make_filter(I &&iter, OP &&op); template void for_all(I &&iter, C &&consumer); template auto make_flat_map(I &&iter, OP &&op); template auto make_inspect(I &&iter, OP &&op); template auto make_limited_map(I &&iter, OP &&op); template auto make_virtual(I &&iter); template auto make_combined(IT1 &&iter1, IT2 &&iter2); // Class for creating easy composable iterators fo querying. // Derived - type of derived class // T - return type template class Composable : public Crtp { // Moves self Derived &&move() { return std::move(this->derived()); } public: auto virtualize() { return iter::make_virtual(move()); } template auto combine(IT &&it) { return iter::make_combined(move(), std::move(it)); } template auto map(OP &&op) { return iter::make_map(move(), std::move(op)); } template auto filter(OP &&op) { return iter::make_filter(move(), std::move(op)); } // Replaces every item with item taken from n if it exists. template auto replace(Option &n) { return iter::make_limited_map( move(), [&](auto v) mutable { return std::move(n); }); } // Maps with call to method to() and filters with call to fill. auto to() { return map([](auto er) { return er.to(); }).fill(); } // Maps with call to method from() and filters with call to fill. auto from() { return map([](auto er) { return er.from(); }).fill(); } // Combines out iterators into one iterator. auto out() { return iter::make_flat_map( move(), [](auto vr) { return vr.out().fill(); }); } // Filters with label on from vertex. template auto from_label(LABEL const &label) { return filter([&](auto &ra) { auto va = ra.from(); return va.fill() && va.has_label(label); }); } // Calls update on values and returns resoult. auto update() { return map([](auto ar) { return ar.update(); }); } // Filters with property under given key template auto has_property(KEY &key) { return filter([&](auto &va) { return !va.at(key).is_empty(); }); } // Filters with property under given key template auto has_property(KEY &key, PROP const &prop) { return filter([&](auto &va) { return va.at(key) == prop; }); } // Copy-s pasing value to t before they are returned. auto clone_to(Option &t) { return iter::make_inspect( move(), [&](auto &v) mutable { t = Option(v); }); } // Filters with call to method fill() auto fill() { return filter([](auto &ra) { return ra.fill(); }); } // Filters with type template auto type(TYPE const &type) { return filter([&](auto &ra) { return ra.edge_type() == type; }); } // Filters with label. template auto label(LABEL const &label) { return filter([&](auto &va) { return va.has_label(label); }); } // Filters out vertices which are connected. auto isolated() { return filter([&](auto &ra) { return ra.isolated(); }); } // For all items calls OP. template void for_all(OP &&op) { iter::for_all(move(), std::move(op)); } // All items must satisfy given predicate for this function to return true. // Otherwise stops calling predicate on firts false and returns fasle. template bool all(OP &&op) { auto iter = move(); auto e = iter.next(); while (e.is_present()) { if (!op(e.take())) { return false; } e = iter.next(); } return true; } }; }