#ifndef ITER_COMPRESS_H_ #define ITER_COMPRESS_H_ #include "internal/iterbase.hpp" #include #include namespace iter { namespace impl { template class Compressed; } template impl::Compressed compress(Container&&, Selector&&); } template class iter::impl::Compressed { private: Container container; Selector selectors; friend Compressed iter::compress( Container&&, Selector&&); // Selector::Iterator type using selector_iter_type = decltype(std::begin(selectors)); Compressed(Container&& in_container, Selector&& in_selectors) : container(std::forward(in_container)), selectors(std::forward(in_selectors)) {} public: Compressed(Compressed&&) = default; class Iterator : public std::iterator> { private: iterator_type sub_iter; iterator_type sub_end; selector_iter_type selector_iter; selector_iter_type selector_end; void increment_iterators() { ++this->sub_iter; ++this->selector_iter; } void skip_failures() { while (this->sub_iter != this->sub_end && this->selector_iter != this->selector_end && !*this->selector_iter) { this->increment_iterators(); } } public: Iterator(iterator_type&& cont_iter, iterator_type&& cont_end, selector_iter_type&& sel_iter, selector_iter_type&& sel_end) : sub_iter{std::move(cont_iter)}, sub_end{std::move(cont_end)}, selector_iter{std::move(sel_iter)}, selector_end{std::move(sel_end)} { this->skip_failures(); } iterator_deref operator*() { return *this->sub_iter; } iterator_arrow operator->() { return apply_arrow(this->sub_iter); } Iterator& operator++() { this->increment_iterators(); this->skip_failures(); return *this; } Iterator operator++(int) { auto ret = *this; ++*this; return ret; } bool operator!=(const Iterator& other) const { return this->sub_iter != other.sub_iter && this->selector_iter != other.selector_iter; } bool operator==(const Iterator& other) const { return !(*this != other); } }; Iterator begin() { return {std::begin(this->container), std::end(this->container), std::begin(this->selectors), std::end(this->selectors)}; } Iterator end() { return {std::end(this->container), std::end(this->container), std::end(this->selectors), std::end(this->selectors)}; } }; template iter::impl::Compressed iter::compress( Container&& container, Selector&& selectors) { return { std::forward(container), std::forward(selectors)}; } #endif