From e7274f9f2d4191b3b1b77448e2c1ea6f1f4aa97c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 30 Apr 2021 16:17:16 +0200 Subject: BLI: add a common base class for Map iterators This is useful for an upcoming commit that allows removing an element based on an iterator. --- source/blender/blenlib/BLI_map.hh | 71 ++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 27 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh index 376bf5df06f..c69d5986885 100644 --- a/source/blender/blenlib/BLI_map.hh +++ b/source/blender/blenlib/BLI_map.hh @@ -621,19 +621,23 @@ class Map { } } - /** - * A utility iterator that reduces the amount of code when implementing the actual iterators. - * This uses the "curiously recurring template pattern" (CRTP). - */ - template struct BaseIterator { + /* Common base class for all iterators below. */ + struct BaseIterator { + public: using iterator_category = std::forward_iterator_tag; using difference_type = std::ptrdiff_t; + protected: + /* We could have separate base iterators for const and non-const iterators, but that would add + * more complexity than benefits right now. */ Slot *slots_; int64_t total_slots_; int64_t current_slot_; - BaseIterator(const Slot *slots, int64_t total_slots, int64_t current_slot) + friend Map; + + public: + BaseIterator(const Slot *slots, const int64_t total_slots, const int64_t current_slot) : slots_(const_cast(slots)), total_slots_(total_slots), current_slot_(current_slot) { } @@ -667,11 +671,29 @@ class Map { return !(a != b); } + protected: + Slot ¤t_slot() const + { + return slots_[current_slot_]; + } + }; + + /** + * A utility iterator that reduces the amount of code when implementing the actual iterators. + * This uses the "curiously recurring template pattern" (CRTP). + */ + template class BaseIteratorRange : public BaseIterator { + public: + BaseIteratorRange(const Slot *slots, int64_t total_slots, int64_t current_slot) + : BaseIterator(slots, total_slots, current_slot) + { + } + SubIterator begin() const { - for (int64_t i = 0; i < total_slots_; i++) { - if (slots_[i].is_occupied()) { - return SubIterator(slots_, total_slots_, i); + for (int64_t i = 0; i < this->total_slots_; i++) { + if (this->slots_[i].is_occupied()) { + return SubIterator(this->slots_, this->total_slots_, i); } } return this->end(); @@ -679,23 +701,18 @@ class Map { SubIterator end() const { - return SubIterator(slots_, total_slots_, total_slots_); - } - - Slot ¤t_slot() const - { - return slots_[current_slot_]; + return SubIterator(this->slots_, this->total_slots_, this->total_slots_); } }; - class KeyIterator final : public BaseIterator { + class KeyIterator final : public BaseIteratorRange { public: using value_type = Key; using pointer = const Key *; using reference = const Key &; KeyIterator(const Slot *slots, int64_t total_slots, int64_t current_slot) - : BaseIterator(slots, total_slots, current_slot) + : BaseIteratorRange(slots, total_slots, current_slot) { } @@ -705,14 +722,14 @@ class Map { } }; - class ValueIterator final : public BaseIterator { + class ValueIterator final : public BaseIteratorRange { public: using value_type = Value; using pointer = const Value *; using reference = const Value &; ValueIterator(const Slot *slots, int64_t total_slots, int64_t current_slot) - : BaseIterator(slots, total_slots, current_slot) + : BaseIteratorRange(slots, total_slots, current_slot) { } @@ -722,14 +739,14 @@ class Map { } }; - class MutableValueIterator final : public BaseIterator { + class MutableValueIterator final : public BaseIteratorRange { public: using value_type = Value; using pointer = Value *; using reference = Value &; - MutableValueIterator(const Slot *slots, int64_t total_slots, int64_t current_slot) - : BaseIterator(slots, total_slots, current_slot) + MutableValueIterator(Slot *slots, int64_t total_slots, int64_t current_slot) + : BaseIteratorRange(slots, total_slots, current_slot) { } @@ -754,14 +771,14 @@ class Map { } }; - class ItemIterator final : public BaseIterator { + class ItemIterator final : public BaseIteratorRange { public: using value_type = Item; using pointer = Item *; using reference = Item &; ItemIterator(const Slot *slots, int64_t total_slots, int64_t current_slot) - : BaseIterator(slots, total_slots, current_slot) + : BaseIteratorRange(slots, total_slots, current_slot) { } @@ -772,14 +789,14 @@ class Map { } }; - class MutableItemIterator final : public BaseIterator { + class MutableItemIterator final : public BaseIteratorRange { public: using value_type = MutableItem; using pointer = MutableItem *; using reference = MutableItem &; - MutableItemIterator(const Slot *slots, int64_t total_slots, int64_t current_slot) - : BaseIterator(slots, total_slots, current_slot) + MutableItemIterator(Slot *slots, int64_t total_slots, int64_t current_slot) + : BaseIteratorRange(slots, total_slots, current_slot) { } -- cgit v1.2.3