#ifndef ITER_SORTED_HPP_ #define ITER_SORTED_HPP_ #include "internal/iterbase.hpp" #include "internal/iteratoriterator.hpp" #include #include #include namespace iter { namespace impl { template class SortedView; } template impl::SortedView sorted(Container&&, CompareFunc); } template class iter::impl::SortedView { private: using IterIterWrap = IterIterWrapper>>; using ItIt = iterator_type; template friend SortedView iter::sorted(C&&, F); Container container; IterIterWrap sorted_iters; template SortedView(Container&& in_container, CompareFunc compare_func) : container(std::forward(in_container)) { // Fill the sorted_iters vector with an iterator to each // element in the container for (auto iter = std::begin(this->container); iter != std::end(this->container); ++iter) { this->sorted_iters.get().push_back(iter); } // sort by comparing the elements that the iterators point to std::sort(std::begin(sorted_iters.get()), std::end(sorted_iters.get()), [compare_func](const iterator_type& it1, const iterator_type& it2) { return compare_func(*it1, *it2); }); } public: SortedView(SortedView&&) = default; ItIt begin() { return std::begin(sorted_iters); } ItIt end() { return std::end(sorted_iters); } }; template iter::impl::SortedView iter::sorted( Container&& container, CompareFunc compare_func) { return {std::forward(container), compare_func}; } namespace iter { template auto sorted(Container&& container) { return sorted(std::forward(container), std::less>()); } } #endif