#pragma once #include #include namespace ext { /// \brief Strip type off top level reference and cv-qualifiers thus allowing storage in containers template using unqualified_t = std::remove_cv_t>; template using apply_t = typename std::result_of::type; template struct map_iterator : std::iterator< typename It::iterator_category, std::remove_reference_t>, std::ptrdiff_t, std::add_pointer_t>>, apply_t> { using base_iterator = std::iterator< typename It::iterator_category, std::remove_reference_t>, std::ptrdiff_t, std::add_pointer>>, apply_t>; It current; Mapper mapper; map_iterator(const It it, const Mapper mapper) : current{it}, mapper{mapper} {} typename base_iterator::reference operator*() { return mapper(*current); } map_iterator & operator++() { return ++current, *this; } map_iterator & operator--() { return --current, *this; } bool operator==(const map_iterator & other) { return current == other.current; } bool operator!=(const map_iterator & other) { return current != other.current; } typename base_iterator::difference_type operator-(const map_iterator & other) { return current - other.current; } }; template auto make_map_iterator(const It it, const Mapper mapper) -> ext::map_iterator { return { it, mapper }; } /** \brief Returns collection of the same container-type as the input collection, * with each element transformed by the application of `mapper`. */ template