#pragma once #include "utils/iterator/iterator_base.hpp" #include "utils/option.hpp" namespace iter { // Class which inspects values returned by I iterator before passing thenm as // result. // function. // T - type of return value // I - iterator type // OP - type of inspector function. OP: T&->void template class Inspect : public IteratorBase { public: Inspect() = delete; // Inspect operation is designed to be used in chained calls which operate // on a // iterator. Inspect will in that usecase receive other iterator by value // and // std::move is a optimization for it. Inspect(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {} Inspect(Inspect &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {} ~Inspect() final {} Option next() final { auto item = iter.next(); if (item.is_present()) { op(item.get()); return std::move(item); } else { return Option(); } } Count count() final { return iter.count(); } private: I iter; OP op; }; template auto make_inspect(I &&iter, OP &&op) { // Compiler cant deduce type T. decltype is here to help with it. return Inspect(std::move(iter), std::move(op)); } }