1 /** 2 * This code is part of Qiskit. 3 * 4 * (C) Copyright IBM 2018, 2019. 5 * 6 * This code is licensed under the Apache License, Version 2.0. You may 7 * obtain a copy of this license in the LICENSE.txt file in the root directory 8 * of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. 9 * 10 * Any modifications or derivative works of this code must retain this 11 * copyright notice, and modified files need to carry a notice indicating 12 * that they have been altered from the originals. 13 */ 14 15 #ifndef _ITERATORS_HPP 16 #define _ITERATORS_HPP 17 18 template <typename T> 19 struct iterator_extractor { using type = typename T::iterator; }; 20 21 template <typename T> 22 struct iterator_extractor<T const> { using type = typename T::const_iterator; }; 23 24 /** 25 * Python-like `enumerate()` for C++14 ranged-for 26 * 27 * I wish I'd had this included in the STL :) 28 * 29 * Usage: 30 * ```c++ 31 * for(auto& elem: index(vec)){ 32 * std::cout << "Index: " << elem.first << " Element: " << elem.second; 33 * } 34 * ``` 35 **/ 36 template <typename T> 37 class Indexer { 38 public: 39 class _Iterator { 40 using inner_iterator = typename iterator_extractor<T>::type; 41 using inner_reference = typename std::iterator_traits<inner_iterator>::reference; 42 public: 43 using reference = std::pair<size_t, inner_reference>; 44 _Iterator(inner_iterator it)45 _Iterator(inner_iterator it): _pos(0), _it(it) {} 46 operator *() const47 reference operator*() const { 48 return reference(_pos, *_it); 49 } 50 operator ++()51 _Iterator& operator++() { 52 ++_pos; 53 ++_it; 54 return *this; 55 } 56 operator ++(int)57 _Iterator operator++(int) { 58 _Iterator tmp(*this); 59 ++*this; 60 return tmp; 61 } 62 operator ==(_Iterator const & it) const63 bool operator==(_Iterator const& it) const { 64 return _it == it._it; 65 } operator !=(_Iterator const & it) const66 bool operator!=(_Iterator const& it) const { 67 return !(*this == it); 68 } 69 70 private: 71 size_t _pos; 72 inner_iterator _it; 73 }; 74 Indexer(T & t)75 Indexer(T& t): _container(t) {} 76 begin() const77 _Iterator begin() const { 78 return _Iterator(_container.begin()); 79 } end() const80 _Iterator end() const { 81 return _Iterator(_container.end()); 82 } 83 84 private: 85 T& _container; 86 }; // class Indexer 87 88 template <typename T> enumerate(T & t)89Indexer<T> enumerate(T& t) { return Indexer<T>(t); } 90 91 #endif