| 30 | template <typename Key, typename Value, |
| 31 | typename Equal = fl::SmallMapEqualTo<Key>> |
| 32 | class unordered_map_small { |
| 33 | public: |
| 34 | enum insert_result { inserted = 0, exists = 1, at_capacity = 2 }; |
| 35 | |
| 36 | using key_type = Key; |
| 37 | using mapped_type = Value; |
| 38 | using value_type = fl::pair<Key, Value>; |
| 39 | using size_type = fl::size; |
| 40 | using key_equal = Equal; |
| 41 | using vector_type = fl::vector<value_type>; |
| 42 | |
| 43 | // Forward iterator that skips unoccupied slots. |
| 44 | struct iterator { |
| 45 | using reference = value_type&; |
| 46 | using pointer = value_type*; |
| 47 | using iterator_category = fl::forward_iterator_tag; |
| 48 | |
| 49 | iterator() FL_NOEXCEPT : mMap(nullptr), mIdx(0) {} |
| 50 | iterator(unordered_map_small* map, size_type idx) FL_NOEXCEPT |
| 51 | : mMap(map), mIdx(idx) { advance_to_occupied(); } |
| 52 | |
| 53 | reference operator*() const FL_NOEXCEPT { return mMap->mData[mIdx]; } |
| 54 | pointer operator->() const FL_NOEXCEPT { return &mMap->mData[mIdx]; } |
| 55 | |
| 56 | iterator& operator++() FL_NOEXCEPT { ++mIdx; advance_to_occupied(); return *this; } |
| 57 | iterator operator++(int) FL_NOEXCEPT { iterator t = *this; ++(*this); return t; } |
| 58 | |
| 59 | bool operator==(const iterator& o) const FL_NOEXCEPT { return mIdx == o.mIdx; } |
| 60 | bool operator!=(const iterator& o) const FL_NOEXCEPT { return mIdx != o.mIdx; } |
| 61 | |
| 62 | private: |
| 63 | void advance_to_occupied() FL_NOEXCEPT { |
| 64 | if (!mMap) return; |
| 65 | size_type cap = mMap->mData.size(); |
| 66 | while (mIdx < cap && !mMap->mOccupied.test(mIdx)) ++mIdx; |
| 67 | } |
| 68 | unordered_map_small* mMap; |
| 69 | size_type mIdx; |
| 70 | friend class unordered_map_small; |
| 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 |
nothing calls this directly
no test coverage detected