From 68f22134cb35267d6fa01134a385d3854fda1787 Mon Sep 17 00:00:00 2001 From: glx Date: Sat, 14 Dec 2019 17:21:48 +0100 Subject: Add: Allow iteration of pools in range-based for loops --- src/core/pool_type.hpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/core/pool_type.hpp b/src/core/pool_type.hpp index 360bda2d5..565f1500e 100644 --- a/src/core/pool_type.hpp +++ b/src/core/pool_type.hpp @@ -12,6 +12,7 @@ #include "smallvec_type.hpp" #include "enum_type.hpp" +#include /** Various types of a pool. */ enum PoolType { @@ -136,6 +137,47 @@ struct Pool : PoolBase { return ret; } + /** + * Iterator to iterate all valid T of a pool + * @tparam T Type of the class/struct that is going to be iterated + */ + template + struct PoolIterator { + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef size_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + explicit PoolIterator(size_t index, std::function filter = nullptr) : index(index), filter(filter) + { + if (this->filter == nullptr) this->filter = [](size_t) { return true; }; + this->ValidateIndex(); + }; + + bool operator!=(const PoolIterator &other) const { return this->index != other.index; } + T * operator*() const { return T::Get(this->index); } + PoolIterator & operator++() { this->index++; this->ValidateIndex(); return *this; } + + private: + size_t index; + std::function filter; + void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++; } + }; + + /* + * Iterable ensemble of all valid T + * @tparam T Type of the class/struct that is going to be iterated + */ + template + struct IterateWrapper { + size_t from; + std::function filter; + IterateWrapper(size_t from = 0, std::function filter = nullptr) : from(from), filter(filter) {} + PoolIterator begin() { return PoolIterator(this->from, this->filter); } + PoolIterator end() { return PoolIterator(T::GetPoolSize()); } + }; + /** * Base class for all PoolItems * @tparam Tpool The pool this item is going to be part of @@ -144,6 +186,9 @@ struct Pool : PoolBase { struct PoolItem { Tindex index; ///< Index of this pool item + /** Type of the pool this item is going to be part of */ + typedef struct Pool Pool; + /** * Allocates space for new Titem * @param size size of Titem @@ -284,6 +329,13 @@ struct Pool : PoolBase { * @note it's called only when !CleaningPool() */ static inline void PostDestructor(size_t index) { } + + /** + * Returns an iterable ensemble of all valid Titem + * @param from index of the first Titem to consider + * @return an iterable ensemble of all valid Titem + */ + static Pool::IterateWrapper Iterate(size_t from = 0) { return Pool::IterateWrapper(from); } }; private: -- cgit v1.2.3-70-g09d2