| 71 | }; |
| 72 | |
| 73 | struct const_iterator { |
| 74 | using reference = const value_type&; |
| 75 | using pointer = const value_type*; |
| 76 | using iterator_category = fl::forward_iterator_tag; |
| 77 | |
| 78 | const_iterator() FL_NOEXCEPT : mMap(nullptr), mIdx(0) {} |
| 79 | const_iterator(const unordered_map_small* map, size_type idx) FL_NOEXCEPT |
| 80 | : mMap(map), mIdx(idx) { advance_to_occupied(); } |
| 81 | const_iterator(const iterator& it) FL_NOEXCEPT |
| 82 | : mMap(it.mMap), mIdx(it.mIdx) {} |
| 83 | |
| 84 | reference operator*() const FL_NOEXCEPT { return mMap->mData[mIdx]; } |
| 85 | pointer operator->() const FL_NOEXCEPT { return &mMap->mData[mIdx]; } |
| 86 | |
| 87 | const_iterator& operator++() FL_NOEXCEPT { ++mIdx; advance_to_occupied(); return *this; } |
| 88 | const_iterator operator++(int) FL_NOEXCEPT { const_iterator t = *this; ++(*this); return t; } |
| 89 | |
| 90 | bool operator==(const const_iterator& o) const FL_NOEXCEPT { return mIdx == o.mIdx; } |
| 91 | bool operator!=(const const_iterator& o) const FL_NOEXCEPT { return mIdx != o.mIdx; } |
| 92 | |
| 93 | private: |
| 94 | void advance_to_occupied() FL_NOEXCEPT { |
| 95 | if (!mMap) return; |
| 96 | size_type cap = mMap->mData.size(); |
| 97 | while (mIdx < cap && !mMap->mOccupied.test(mIdx)) ++mIdx; |
| 98 | } |
| 99 | const unordered_map_small* mMap; |
| 100 | size_type mIdx; |
| 101 | friend class unordered_map_small; |
| 102 | }; |
| 103 | |
| 104 | private: |
| 105 | vector_type mData; |