#include #include #include #include #include #include template class Index_Iterator { using Index_It = std::vector::const_iterator; public: using value_type = typename Value_It::value_type; using reference = typename Value_It::reference; using pointer = typename Value_It::pointer; using difference_type = typename Value_It::difference_type; using iterator_category = std::forward_iterator_tag; reference operator*() { return *std::next(value, *index); } Index_Iterator& operator++() { ++index; return *this; } Index_Iterator operator++(int) { Index_Iterator tmp { *this }; ++(*this); return tmp; } bool operator==(Index_Iterator const& other) const { return index == other.index && value == other.value; } bool operator!=(Index_Iterator const& other) const { return !(*this == other); } private: template friend class Index_Range; Index_Iterator(Index_It index, Value_It value) : index { index }, value { value } { } Index_It index; Value_It value; }; template class Index_Range { public: Index_Range(Container& container, std::initializer_list list) : indices { list.begin(), list.end() }, container { container } { } Index_Iterator begin() { return { std::begin(indices), std::begin(container) }; } Index_Iterator end() { return { std::end(indices), std::begin(container) }; } private: std::vector indices; Container& container; }; template Index_Range select_indices(Container& container, std::initializer_list list) { return { container, list }; } int main() { { int index { 0 }; std::vector v { 0, 1, 2, 3 }; for (auto i : select_indices(v, { 0, 1, 2, 3 })) { assert(i == index++); } } { std::vector v { 1.2, 3.45, 6.78, 9.0 }; auto range { select_indices(v, { 0, 0, 1, 0, 2 }) }; std::vector result { range.begin(), range.end() }; assert(( result == std::vector{ 1.2, 1.2, 3.45, 1.2, 6.78 } )); } { std::set v { "a", "b", "c", "d" }; auto range { select_indices(v, { 0, 1, 1, 0 }) }; std::vector result { range.begin(), range.end() }; assert(( result == std::vector{ "a", "b", "b", "a" } )); } { std::forward_list v { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; auto range { select_indices(v, { 0, 2, 6, 10 }) }; std::vector result { range.begin(), range.end() }; assert(( result == std::vector{ 1, 3, 7, 11 } )); } }