// // filter_iterator.hpp // iterator // // Created by Sam Jaffe on 6/17/17. // #pragma once #include "end_aware_iterator.hpp" namespace iterator { template class filter_iterator : public end_aware_iterator { private: using super = end_aware_iterator; public: using value_type = typename super::value_type; using reference = typename super::reference; using pointer = typename super::pointer; using difference_type = typename super::difference_type; using iterator_category = typename super::iterator_category; public: filter_iterator() = default; template filter_iterator(std::function && p, Args &&... super_args) : super(std::forward(super_args)...) , pred(std::move(p)) { if (should_advance()) { advance(); } } filter_iterator & operator++() { advance(); return *this; } filter_iterator operator++(int) { filter_iterator tmp{*this}; operator++(); return tmp; } private: bool should_advance() { return !super::done() && !pred(super::operator*()); } void advance() { do { super::operator++(); } while (should_advance()); } std::function pred; }; } template iterator::filter_iterator make_filter_iterator(Pred && p, Iter it, Iter end) { return {p, it, end}; } template auto make_filter_iterator(Pred && p, C & collect) -> iterator::filter_iterator { return { p, std::begin(collect), std::end(collect) }; } template auto make_filter_iterator(Pred && p, C const & collect) -> iterator::filter_iterator { return { p, std::begin(collect), std::end(collect) }; }