diff --git a/src/core/pool_type.hpp b/src/core/pool_type.hpp index 035607a8fb..9e6fc8fecd 100644 --- a/src/core/pool_type.hpp +++ b/src/core/pool_type.hpp @@ -12,7 +12,6 @@ #include "smallvec_type.hpp" #include "enum_type.hpp" -#include /** Various types of a pool. */ enum PoolType { @@ -149,9 +148,8 @@ struct Pool : PoolBase { 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) + explicit PoolIterator(size_t index) : index(index) { - if (this->filter == nullptr) this->filter = [](size_t) { return true; }; this->ValidateIndex(); }; @@ -162,8 +160,7 @@ struct Pool : PoolBase { private: size_t index; - std::function filter; - void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++; } + void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++; } }; /* @@ -173,13 +170,54 @@ struct Pool : PoolBase { 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); } + IterateWrapper(size_t from = 0) : from(from) {} + PoolIterator begin() { return PoolIterator(this->from); } PoolIterator end() { return PoolIterator(T::GetPoolSize()); } bool empty() { return this->begin() == this->end(); } }; + /** + * Iterator to iterate all valid T of a pool + * @tparam T Type of the class/struct that is going to be iterated + */ + template + struct PoolIteratorFiltered { + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef size_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + explicit PoolIteratorFiltered(size_t index, F filter) : index(index), filter(filter) + { + this->ValidateIndex(); + }; + + bool operator==(const PoolIteratorFiltered &other) const { return this->index == other.index; } + bool operator!=(const PoolIteratorFiltered &other) const { return !(*this == other); } + T * operator*() const { return T::Get(this->index); } + PoolIteratorFiltered & operator++() { this->index++; this->ValidateIndex(); return *this; } + + private: + size_t index; + F 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 IterateWrapperFiltered { + size_t from; + F filter; + IterateWrapperFiltered(size_t from, F filter) : from(from), filter(filter) {} + PoolIteratorFiltered begin() { return PoolIteratorFiltered(this->from, this->filter); } + PoolIteratorFiltered end() { return PoolIteratorFiltered(T::GetPoolSize(), this->filter); } + bool empty() { return this->begin() == this->end(); } + }; + /** * Base class for all PoolItems * @tparam Tpool The pool this item is going to be part of diff --git a/src/engine_base.h b/src/engine_base.h index 1328f66a18..203d35f201 100644 --- a/src/engine_base.h +++ b/src/engine_base.h @@ -142,15 +142,21 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { uint32 GetGRFID() const; + struct EngineTypeFilter { + VehicleType vt; + + bool operator() (size_t index) { return Engine::Get(index)->type == this->vt; } + }; + /** * Returns an iterable ensemble of all valid engines of the given type * @param vt the VehicleType for engines to be valid * @param from index of the first engine to consider * @return an iterable ensemble of all valid engines of the given type */ - static Pool::IterateWrapper IterateType(VehicleType vt, size_t from = 0) + static Pool::IterateWrapperFiltered IterateType(VehicleType vt, size_t from = 0) { - return Pool::IterateWrapper(from, [vt](size_t index) { return Engine::Get(index)->type == vt; }); + return Pool::IterateWrapperFiltered(from, EngineTypeFilter{ vt }); } }; diff --git a/src/network/network_admin.h b/src/network/network_admin.h index 98dbab4816..16bd57a4d6 100644 --- a/src/network/network_admin.h +++ b/src/network/network_admin.h @@ -83,15 +83,18 @@ public: return "admin"; } + struct ServerNetworkAdminSocketHandlerFilter { + bool operator() (size_t index) { return ServerNetworkAdminSocketHandler::Get(index)->GetAdminStatus() == ADMIN_STATUS_ACTIVE; } + }; + /** * Returns an iterable ensemble of all active admin sockets * @param from index of the first socket to consider * @return an iterable ensemble of all active admin sockets */ - static Pool::IterateWrapper IterateActive(size_t from = 0) + static Pool::IterateWrapperFiltered IterateActive(size_t from = 0) { - return Pool::IterateWrapper(from, - [](size_t index) { return ServerNetworkAdminSocketHandler::Get(index)->GetAdminStatus() == ADMIN_STATUS_ACTIVE; }); + return Pool::IterateWrapperFiltered(from, ServerNetworkAdminSocketHandlerFilter{}); } };