#pragma once #include #include /// Similar to boost::filtered_range but a little bit easier and allows to convert ordinary iterators to filtered template struct RangeFiltered : public boost::iterator_range> { using RawIterator = decltype(std::end(C())); using FilterIterator = boost::filter_iterator; using Base = boost::iterator_range; RangeFiltered(const F & filter, const C & container) : Base( FilterIterator(filter, std::begin(container), std::end(container)), FilterIterator(filter, std::end(container), std::end(container))), filter(filter) {} /// Convert ordinary iterator to filtered one /// Real position will be in range [ordinary_iterator; end()], so it is suitable to use with lower[upper]_bound() inline FilterIterator convert(RawIterator ordinary_iterator) const { return {filter, ordinary_iterator, std::end(*this).end()}; } F filter; }; template inline decltype(auto) createRangeFiltered(F && filter, C && container) { return RangeFiltered, std::decay_t>{std::forward(filter), std::forward(container)}; };