| 86 | public: |
| 87 | template <typename BitVectorT, typename DataIteratorT, typename ReferenceT> |
| 88 | class IteratorImpl { |
| 89 | private: |
| 90 | friend class BitVector; |
| 91 | |
| 92 | uint64_t m_offset = 0; |
| 93 | BitVectorT *m_bit_vector; |
| 94 | |
| 95 | // cached derived values |
| 96 | uint64_t m_index = 0; |
| 97 | uint64_t m_shift = 0; |
| 98 | DataIteratorT m_data_iterator; |
| 99 | |
| 100 | IteratorImpl(BitVectorT *bit_vector, uint64_t offset) |
| 101 | : m_bit_vector(bit_vector), |
| 102 | m_data_iterator(bit_vector->m_data.begin()) { |
| 103 | *this += offset; |
| 104 | } |
| 105 | |
| 106 | public: |
| 107 | inline IteratorImpl& operator++() { |
| 108 | ++m_offset; |
| 109 | |
| 110 | uint64_t index; |
| 111 | compute_index(m_offset, &index, &m_shift); |
| 112 | |
| 113 | ceph_assert(index == m_index || index == m_index + 1); |
| 114 | if (index > m_index) { |
| 115 | m_index = index; |
| 116 | ++m_data_iterator; |
| 117 | } |
| 118 | return *this; |
| 119 | } |
| 120 | inline IteratorImpl& operator+=(uint64_t offset) { |
| 121 | m_offset += offset; |
| 122 | compute_index(m_offset, &m_index, &m_shift); |
| 123 | if (m_offset < m_bit_vector->size()) { |
| 124 | m_data_iterator.seek(m_index); |
| 125 | } else { |
| 126 | m_data_iterator = m_bit_vector->m_data.end(); |
| 127 | } |
| 128 | return *this; |
| 129 | } |
| 130 | |
| 131 | inline IteratorImpl operator++(int) { |
| 132 | IteratorImpl iterator_impl(*this); |
| 133 | ++*this; |
| 134 | return iterator_impl; |
| 135 | } |
| 136 | inline IteratorImpl operator+(uint64_t offset) { |
| 137 | IteratorImpl iterator_impl(*this); |
| 138 | iterator_impl += offset; |
| 139 | return iterator_impl; |
| 140 | } |
| 141 | |
| 142 | inline bool operator==(const IteratorImpl& rhs) const { |
| 143 | return (m_offset == rhs.m_offset && m_bit_vector == rhs.m_bit_vector); |
| 144 | } |
| 145 | inline bool operator!=(const IteratorImpl& rhs) const { |