From 1636998e4def7f589a391cffa657492ee8579964 Mon Sep 17 00:00:00 2001 From: ubpa Date: Mon, 22 Mar 2021 13:28:20 +0800 Subject: [PATCH] RTDCmptTraits -> CmptTraits --- README.md | 6 ++- .../{RTDCmptTraits.hpp => CmptTraits.hpp} | 44 +++++++++------- include/UECS/EntityMngr.hpp | 8 +-- include/UECS/UECS.hpp | 2 +- include/UECS/World.hpp | 2 +- .../{RTDCmptTraits.inl => CmptTraits.inl} | 51 ++++++++++++------- src/core/Archetype.cpp | 16 +++--- src/core/Archetype.hpp | 10 ++-- src/core/ArchetypeCmptTraits.cpp | 4 +- src/core/ArchetypeCmptTraits.hpp | 4 +- .../{RTDCmptTraits.cpp => CmptTraits.cpp} | 48 ++++++++--------- src/core/EntityMngr.cpp | 4 +- 12 files changed, 110 insertions(+), 89 deletions(-) rename include/UECS/{RTDCmptTraits.hpp => CmptTraits.hpp} (72%) rename include/UECS/details/{RTDCmptTraits.inl => CmptTraits.inl} (66%) rename src/core/{RTDCmptTraits.cpp => CmptTraits.cpp} (69%) diff --git a/README.md b/README.md index 98bd6c6..f97d26c 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ ## Example ```c++ -#include +#include using namespace Ubpa::UECS; @@ -62,8 +62,9 @@ struct MoverSystem { int main() { World w; + w.entityMngr.cmptTraits.Register(); w.systemMngr.RegisterAndActivate(); - w.entityMngr.Create(); + w.entityMngr.Create(Ubpa::TypeIDs_of); w.Update(); } ``` @@ -87,6 +88,7 @@ int main() { - [directly run execution](src/test/19_direct_run/main.cpp) - [system lifecycle](src/test/20_system_lifecycle/main.cpp) - [random access components](src/test/21_random/main.cpp) +- [change filter](src/test/22_change_filter/main.cpp) ## Licensing diff --git a/include/UECS/RTDCmptTraits.hpp b/include/UECS/CmptTraits.hpp similarity index 72% rename from include/UECS/RTDCmptTraits.hpp rename to include/UECS/CmptTraits.hpp index b07851a..564933b 100644 --- a/include/UECS/RTDCmptTraits.hpp +++ b/include/UECS/CmptTraits.hpp @@ -19,27 +19,27 @@ namespace Ubpa::UECS { // - move assignment: memcpy as default // - destructor: do nothing as default // - name - class RTDCmptTraits { + class CmptTraits { public: static constexpr std::size_t default_alignment = alignof(std::max_align_t); - RTDCmptTraits(); - RTDCmptTraits(const RTDCmptTraits& other); - RTDCmptTraits(RTDCmptTraits&& other) noexcept = default; - RTDCmptTraits& operator=(const RTDCmptTraits & other); - RTDCmptTraits& operator=(RTDCmptTraits&& other) noexcept = default; + CmptTraits(); + CmptTraits(const CmptTraits& other); + CmptTraits(CmptTraits&& other) noexcept = default; + CmptTraits& operator=(const CmptTraits & other); + CmptTraits& operator=(CmptTraits&& other) noexcept = default; - RTDCmptTraits& Clear(); + CmptTraits& Clear(); - RTDCmptTraits& RegisterName(Type); - RTDCmptTraits& RegisterTrivial(TypeID); - RTDCmptTraits& RegisterSize(TypeID, std::size_t size); - RTDCmptTraits& RegisterAlignment(TypeID, std::size_t alignment); - RTDCmptTraits& RegisterDefaultConstructor(TypeID, std::function); - RTDCmptTraits& RegisterCopyConstructor(TypeID, std::function); - RTDCmptTraits& RegisterMoveConstructor(TypeID, std::function); - RTDCmptTraits& RegisterMoveAssignment(TypeID, std::function); - RTDCmptTraits& RegisterDestructor(TypeID, std::function); + CmptTraits& RegisterName(Type); + CmptTraits& RegisterTrivial(TypeID); + CmptTraits& RegisterSize(TypeID, std::size_t size); + CmptTraits& RegisterAlignment(TypeID, std::size_t alignment); + CmptTraits& RegisterDefaultConstructor(TypeID, std::function); + CmptTraits& RegisterCopyConstructor(TypeID, std::function); + CmptTraits& RegisterMoveConstructor(TypeID, std::function); + CmptTraits& RegisterMoveAssignment(TypeID, std::function); + CmptTraits& RegisterDestructor(TypeID, std::function); const auto& GetSizeofs() const noexcept { return sizeofs; } const auto& GetAlignments() const noexcept { return alignments; }; @@ -60,11 +60,14 @@ namespace Ubpa::UECS { void Destruct(TypeID, void* cmpt) const; std::string_view Nameof(TypeID) const; - RTDCmptTraits& Deregister(TypeID) noexcept; + CmptTraits& Deregister(TypeID) noexcept; template void Register(); + template + void UnsafeRegister(); + template void Deregister(); @@ -78,7 +81,10 @@ namespace Ubpa::UECS { // - is_destructible_v template void RegisterOne(); - + + template + void UnsafeRegisterOne(); + std::unique_ptr rsrc; std::unordered_set trivials; std::unordered_map names; @@ -92,4 +98,4 @@ namespace Ubpa::UECS { }; } -#include "details/RTDCmptTraits.inl" +#include "details/CmptTraits.inl" diff --git a/include/UECS/EntityMngr.hpp b/include/UECS/EntityMngr.hpp index 0294bfe..87f5ae6 100644 --- a/include/UECS/EntityMngr.hpp +++ b/include/UECS/EntityMngr.hpp @@ -1,6 +1,6 @@ #pragma once -#include "RTDCmptTraits.hpp" +#include "CmptTraits.hpp" #include "EntityQuery.hpp" #include "SingletonLocator.hpp" #include "CmptPtr.hpp" @@ -24,7 +24,7 @@ namespace Ubpa::UECS { // - Singleton: IsSingleton, GetSingletonEntity, GetSingleton // - other: EntityNum, AddCommand // [important] - // - some API with TypeID need RTDCmptTraits to get {size|alignment|lifecycle function} (throw std::logic_error) + // - some API with TypeID need CmptTraits to get {size|alignment|lifecycle function} (throw std::logic_error) // - API with Entity require Entity exist (throw std::invalid_argument) // [details] // - when free entries is empty, use new entity entry (version is 0) @@ -35,7 +35,7 @@ namespace Ubpa::UECS { EntityMngr(EntityMngr&&) noexcept; ~EntityMngr(); - RTDCmptTraits cmptTraits; + CmptTraits cmptTraits; Entity Create(std::span types = {}); @@ -95,7 +95,7 @@ namespace Ubpa::UECS { // types not contain Entity Archetype* GetOrCreateArchetypeOf(std::span types); - small_vector LocateSingletons(const SingletonLocator&) const; + small_vector LocateSingletons(const SingletonLocator&) const; const std::set& QueryArchetypes(const EntityQuery&) const; mutable std::unordered_map> queryCache; diff --git a/include/UECS/UECS.hpp b/include/UECS/UECS.hpp index b91ff09..beffa2f 100644 --- a/include/UECS/UECS.hpp +++ b/include/UECS/UECS.hpp @@ -8,13 +8,13 @@ #include "CmptPtr.hpp" #include "CmptsView.hpp" #include "CmptTag.hpp" +#include "CmptTraits.hpp" #include "config.hpp" #include "Entity.hpp" #include "EntityMngr.hpp" #include "EntityQuery.hpp" #include "IListener.hpp" #include "RandomAccessor.hpp" -#include "RTDCmptTraits.hpp" #include "Schedule.hpp" #include "SingletonLocator.hpp" #include "SingletonsView.hpp" diff --git a/include/UECS/World.hpp b/include/UECS/World.hpp index d1f9f1b..c7721e1 100644 --- a/include/UECS/World.hpp +++ b/include/UECS/World.hpp @@ -39,7 +39,7 @@ namespace Ubpa::UECS { std::string DumpUpdateJobGraph() const; // after running Update() - // use RTDCmptTraits' registered component name + // use CmptTraits' registered component name UGraphviz::Graph GenUpdateFrameGraph() const; void Accept(IListener*) const; diff --git a/include/UECS/details/RTDCmptTraits.inl b/include/UECS/details/CmptTraits.inl similarity index 66% rename from include/UECS/details/RTDCmptTraits.inl rename to include/UECS/details/CmptTraits.inl index 17d8986..36ae6a2 100644 --- a/include/UECS/details/RTDCmptTraits.inl +++ b/include/UECS/details/CmptTraits.inl @@ -1,23 +1,19 @@ #pragma once -#include "../RTDCmptTraits.hpp" +#include "../CmptTraits.hpp" namespace Ubpa::UECS { template - void RTDCmptTraits::Register() { + void CmptTraits::Register() { (RegisterOne(), ...); } + template + void CmptTraits::UnsafeRegister() { + (UnsafeRegisterOne(), ...); + } template - void RTDCmptTraits::RegisterOne() { - static_assert(!IsTaggedCmpt_v, " should not be tagged"); - static_assert(std::is_default_constructible_v, " must be default-constructible"); - static_assert(std::is_copy_constructible_v || std::is_constructible_v, - " must be copy-constructible or constructible with "); - static_assert(std::is_move_constructible_v, " must be move-constructible"); - static_assert(std::is_move_assignable_v, " must be move-assignable"); - static_assert(std::is_destructible_v, " must be destructible"); - + void CmptTraits::UnsafeRegisterOne() { constexpr Type type = Type_of; if constexpr (std::is_trivial_v) @@ -27,25 +23,30 @@ namespace Ubpa::UECS { alignments.emplace(type.GetID(), alignof(Cmpt)); names.emplace(type.GetID(), type.GetName()); - default_constructors.emplace(type.GetID(), [](void* cmpt) { - new(cmpt)Cmpt{}; - }); - if constexpr (!std::is_trivially_destructible_v) { + if constexpr (std::is_default_constructible_v) { + default_constructors.emplace(type.GetID(), [](void* cmpt) { + new(cmpt)Cmpt{}; + }); + } + + if constexpr (std::is_destructible_v && !std::is_trivially_destructible_v) { destructors.emplace(type.GetID(), [](void* cmpt) { static_cast(cmpt)->~Cmpt(); }); } - if constexpr (!std::is_trivially_move_constructible_v) { + + if constexpr (std::is_move_constructible_v && !std::is_trivially_move_constructible_v) { move_constructors.emplace(type.GetID(), [](void* dst, void* src) { new(dst)Cmpt(std::move(*static_cast(src))); }); } - if constexpr (!std::is_trivially_move_assignable_v) { + + if constexpr (std::is_move_assignable_v && !std::is_trivially_move_assignable_v) { move_assignments.emplace(type.GetID(), [](void* dst, void* src) { *static_cast(dst) = std::move(*static_cast(src)); }); } - if constexpr (!std::is_trivially_copy_constructible_v) { + if constexpr (std::is_copy_constructible_v && !std::is_trivially_copy_constructible_v) { copy_constructors.emplace(type.GetID(), [](void* dst, void* src) { new(dst)Cmpt(*static_cast(src)); }); @@ -53,7 +54,19 @@ namespace Ubpa::UECS { } template - void RTDCmptTraits::Deregister() { + void CmptTraits::RegisterOne() { + static_assert(!IsTaggedCmpt_v, " should not be tagged"); + static_assert(std::is_default_constructible_v, " must be default-constructible"); + static_assert(std::is_copy_constructible_v, " must be copy-constructible"); + static_assert(std::is_move_constructible_v, " must be move-constructible"); + static_assert(std::is_move_assignable_v, " must be move-assignable"); + static_assert(std::is_destructible_v, " must be destructible"); + + UnsafeRegisterOne(); + } + + template + void CmptTraits::Deregister() { constexpr TypeID type = TypeID_of; sizeofs.erase(type); diff --git a/src/core/Archetype.cpp b/src/core/Archetype.cpp index 8a5604d..c028bbe 100644 --- a/src/core/Archetype.cpp +++ b/src/core/Archetype.cpp @@ -129,7 +129,7 @@ void Archetype::SetLayout() { } } -Archetype* Archetype::New(RTDCmptTraits& rtdCmptTraits, std::pmr::memory_resource* rsrc, std::span types, std::uint64_t version) { +Archetype* Archetype::New(CmptTraits& rtdCmptTraits, std::pmr::memory_resource* rsrc, std::span types, std::uint64_t version) { assert(std::find(types.begin(), types.end(), TypeID_of) == types.end()); auto* rst = new Archetype{ rsrc, version }; @@ -143,7 +143,7 @@ Archetype* Archetype::New(RTDCmptTraits& rtdCmptTraits, std::pmr::memory_resourc return rst; } -Archetype* Archetype::Add(RTDCmptTraits& rtdCmptTraits, const Archetype* from, std::span types) { +Archetype* Archetype::Add(CmptTraits& rtdCmptTraits, const Archetype* from, std::span types) { assert(std::find(types.begin(), types.end(), TypeID_of) == types.end()); assert(std::find_if_not(types.begin(), types.end(), [&](const auto& type) { return from->cmptTraits.GetTypes().contains(type); }) != types.end()); @@ -271,9 +271,9 @@ std::size_t Archetype::Instantiate(Entity e, std::size_t srcIdx) { } std::tuple< - Ubpa::small_vector, - Ubpa::small_vector, 16>, - Ubpa::small_vector + Ubpa::small_vector, + Ubpa::small_vector>, + Ubpa::small_vector > Archetype::Locate(std::span cmpts) const { assert(std::find_if_not(cmpts.begin(), cmpts.end(), [this](const TypeID& type) { return cmptTraits.GetTypes().contains(type); }) == cmpts.end()); @@ -283,8 +283,8 @@ Archetype::Locate(std::span cmpts) const { const std::size_t entityIdx = static_cast(std::distance(cmptTraits.GetTypes().begin(), cmptTraits.GetTypes().find(TypeID_of))); const std::size_t offsetEntity = offsets[entityIdx]; - Ubpa::small_vector, 16> chunkCmpts(numChunk); - Ubpa::small_vector chunkEntity(numChunk); + Ubpa::small_vector> chunkCmpts(numChunk); + Ubpa::small_vector chunkEntity(numChunk); for (std::size_t i = 0; i < numChunk; i++) { Chunk* chunk = chunks[i]; @@ -300,7 +300,7 @@ Archetype::Locate(std::span cmpts) const { chunkEntity[i] = reinterpret_cast(data + offsetEntity); } - Ubpa::small_vector sizes; + Ubpa::small_vector sizes; sizes.reserve(numType); for (const auto& type : cmpts) sizes.push_back(cmptTraits.GetTrait(type).size); diff --git a/src/core/Archetype.hpp b/src/core/Archetype.hpp index a3da980..0289c17 100644 --- a/src/core/Archetype.hpp +++ b/src/core/Archetype.hpp @@ -25,18 +25,18 @@ namespace Ubpa::UECS { ~Archetype(); // auto add Entity - static Archetype* New(RTDCmptTraits&, std::pmr::memory_resource* rsrc, std::span types, std::uint64_t version); + static Archetype* New(CmptTraits&, std::pmr::memory_resource* rsrc, std::span types, std::uint64_t version); - static Archetype* Add(RTDCmptTraits&, const Archetype* from, std::span types); + static Archetype* Add(CmptTraits&, const Archetype* from, std::span types); // auto add Entity static Archetype* Remove(const Archetype* from, std::span types); // Entity + Components std::tuple< - small_vector, - small_vector, 16>, - small_vector + small_vector, + small_vector>, + small_vector > Locate(std::span cmpts) const; diff --git a/src/core/ArchetypeCmptTraits.cpp b/src/core/ArchetypeCmptTraits.cpp index 9421f94..61f62af 100644 --- a/src/core/ArchetypeCmptTraits.cpp +++ b/src/core/ArchetypeCmptTraits.cpp @@ -2,7 +2,7 @@ #include "ArchetypeCmptTraits.hpp" -#include +#include #include @@ -51,7 +51,7 @@ ArchetypeCmptTraits::CmptTrait& ArchetypeCmptTraits::GetTrait(TypeID ID) noexcep return cmpt_traits[GetTypeIndex(ID)]; } -void ArchetypeCmptTraits::Register(const RTDCmptTraits& rtdct, TypeID type) { +void ArchetypeCmptTraits::Register(const CmptTraits& rtdct, TypeID type) { auto size_target = rtdct.GetSizeofs().find(type); if (size_target == rtdct.GetSizeofs().end()) throw std::logic_error("ArchetypeCmptTraits::Register: RTDCmptTrait hasn't registered "); diff --git a/src/core/ArchetypeCmptTraits.hpp b/src/core/ArchetypeCmptTraits.hpp index 7ed2c7d..ebab3de 100644 --- a/src/core/ArchetypeCmptTraits.hpp +++ b/src/core/ArchetypeCmptTraits.hpp @@ -8,7 +8,7 @@ #include namespace Ubpa::UECS { - class RTDCmptTraits; + class CmptTraits; struct EntityQuery; // run-time static component traits @@ -44,7 +44,7 @@ namespace Ubpa::UECS { const CmptTrait& GetTrait(TypeID ID) const noexcept { return const_cast(this)->GetTrait(ID); } - void Register(const RTDCmptTraits&, TypeID); + void Register(const CmptTraits&, TypeID); void Deregister(TypeID) noexcept; diff --git a/src/core/RTDCmptTraits.cpp b/src/core/CmptTraits.cpp similarity index 69% rename from src/core/RTDCmptTraits.cpp rename to src/core/CmptTraits.cpp index e3294ac..240c3b7 100644 --- a/src/core/RTDCmptTraits.cpp +++ b/src/core/CmptTraits.cpp @@ -1,14 +1,14 @@ -#include +#include using namespace Ubpa; using namespace Ubpa::UECS; -RTDCmptTraits::RTDCmptTraits() : rsrc {std::make_unique()} +CmptTraits::CmptTraits() : rsrc {std::make_unique()} { Register(); } -RTDCmptTraits::RTDCmptTraits(const RTDCmptTraits& other) : +CmptTraits::CmptTraits(const CmptTraits& other) : rsrc{ std::make_unique() }, sizeofs{other.sizeofs}, trivials{other.trivials}, @@ -28,7 +28,7 @@ RTDCmptTraits::RTDCmptTraits(const RTDCmptTraits& other) : } } -RTDCmptTraits& RTDCmptTraits::operator=(const RTDCmptTraits& rhs) { +CmptTraits& CmptTraits::operator=(const CmptTraits& rhs) { sizeofs = rhs.sizeofs; trivials = rhs.trivials; alignments = rhs.alignments; @@ -49,30 +49,30 @@ RTDCmptTraits& RTDCmptTraits::operator=(const RTDCmptTraits& rhs) { } -bool RTDCmptTraits::IsTrivial(TypeID type) const { +bool CmptTraits::IsTrivial(TypeID type) const { return trivials.contains(type); } -std::size_t RTDCmptTraits::Sizeof(TypeID type) const { +std::size_t CmptTraits::Sizeof(TypeID type) const { auto target = sizeofs.find(type); assert(target != sizeofs.end()); return target->second; } -std::size_t RTDCmptTraits::Alignof(TypeID type) const { +std::size_t CmptTraits::Alignof(TypeID type) const { auto target = alignments.find(type); return target != alignments.end() ? target->second : default_alignment; } -void RTDCmptTraits::DefaultConstruct(TypeID type, void* cmpt) const { +void CmptTraits::DefaultConstruct(TypeID type, void* cmpt) const { auto target = default_constructors.find(type); if (target != default_constructors.end()) target->second(cmpt); } -void RTDCmptTraits::CopyConstruct(TypeID type, void* dst, void* src) const { +void CmptTraits::CopyConstruct(TypeID type, void* dst, void* src) const { auto target = copy_constructors.find(type); if (target != copy_constructors.end()) @@ -81,7 +81,7 @@ void RTDCmptTraits::CopyConstruct(TypeID type, void* dst, void* src) const { memcpy(dst, src, Sizeof(type)); } -void RTDCmptTraits::MoveConstruct(TypeID type, void* dst, void* src) const { +void CmptTraits::MoveConstruct(TypeID type, void* dst, void* src) const { auto target = move_constructors.find(type); if (target != move_constructors.end()) @@ -90,7 +90,7 @@ void RTDCmptTraits::MoveConstruct(TypeID type, void* dst, void* src) const { memcpy(dst, src, Sizeof(type)); } -void RTDCmptTraits::MoveAssign(TypeID type, void* dst, void* src) const { +void CmptTraits::MoveAssign(TypeID type, void* dst, void* src) const { auto target = move_assignments.find(type); if (target != move_assignments.end()) @@ -99,13 +99,13 @@ void RTDCmptTraits::MoveAssign(TypeID type, void* dst, void* src) const { memcpy(dst, src, Sizeof(type)); } -void RTDCmptTraits::Destruct(TypeID type, void* cmpt) const { +void CmptTraits::Destruct(TypeID type, void* cmpt) const { auto target = destructors.find(type); if (target != destructors.end()) target->second(cmpt); } -std::string_view RTDCmptTraits::Nameof(TypeID type) const { +std::string_view CmptTraits::Nameof(TypeID type) const { auto target = names.find(type); if (target != names.end()) return target->second; @@ -113,42 +113,42 @@ std::string_view RTDCmptTraits::Nameof(TypeID type) const { return {}; } -RTDCmptTraits& RTDCmptTraits::RegisterSize(TypeID type, std::size_t size) { +CmptTraits& CmptTraits::RegisterSize(TypeID type, std::size_t size) { sizeofs.emplace(type, size); return *this; } -RTDCmptTraits& RTDCmptTraits::RegisterAlignment(TypeID type, std::size_t alignment) { +CmptTraits& CmptTraits::RegisterAlignment(TypeID type, std::size_t alignment) { alignments.emplace(type, alignment); return *this; } -RTDCmptTraits& RTDCmptTraits::RegisterDefaultConstructor(TypeID type, std::function f) { +CmptTraits& CmptTraits::RegisterDefaultConstructor(TypeID type, std::function f) { default_constructors.emplace(type, std::move(f)); return *this; } -RTDCmptTraits& RTDCmptTraits::RegisterCopyConstructor(TypeID type, std::function f) { +CmptTraits& CmptTraits::RegisterCopyConstructor(TypeID type, std::function f) { copy_constructors.emplace(type, std::move(f)); return *this; } -RTDCmptTraits& RTDCmptTraits::RegisterMoveConstructor(TypeID type, std::function f) { +CmptTraits& CmptTraits::RegisterMoveConstructor(TypeID type, std::function f) { move_constructors.emplace(type, std::move(f)); return *this; } -RTDCmptTraits& RTDCmptTraits::RegisterMoveAssignment(TypeID type, std::function f) { +CmptTraits& CmptTraits::RegisterMoveAssignment(TypeID type, std::function f) { move_assignments.emplace(type, std::move(f)); return *this; } -RTDCmptTraits& RTDCmptTraits::RegisterDestructor(TypeID type, std::function f) { +CmptTraits& CmptTraits::RegisterDestructor(TypeID type, std::function f) { destructors.emplace(type, std::move(f)); return *this; } -RTDCmptTraits& RTDCmptTraits::RegisterName(Type type) { +CmptTraits& CmptTraits::RegisterName(Type type) { auto target = names.find(type); if (target != names.end()) { assert(type.Is(target->second)); @@ -163,12 +163,12 @@ RTDCmptTraits& RTDCmptTraits::RegisterName(Type type) { return *this; } -RTDCmptTraits& RTDCmptTraits::RegisterTrivial(TypeID type) { +CmptTraits& CmptTraits::RegisterTrivial(TypeID type) { trivials.insert(type); return *this; } -RTDCmptTraits& RTDCmptTraits::Deregister(TypeID type) noexcept { +CmptTraits& CmptTraits::Deregister(TypeID type) noexcept { names.erase(type); trivials.erase(type); sizeofs.erase(type); @@ -181,7 +181,7 @@ RTDCmptTraits& RTDCmptTraits::Deregister(TypeID type) noexcept { return *this; } -RTDCmptTraits& RTDCmptTraits::Clear() { +CmptTraits& CmptTraits::Clear() { names.clear(); trivials.clear(); sizeofs.clear(); diff --git a/src/core/EntityMngr.cpp b/src/core/EntityMngr.cpp index 89dc675..919b348 100644 --- a/src/core/EntityMngr.cpp +++ b/src/core/EntityMngr.cpp @@ -302,9 +302,9 @@ void EntityMngr::Destroy(Entity e) { RecycleEntityEntry(e); } -Ubpa::small_vector EntityMngr::LocateSingletons(const SingletonLocator& locator) const { +Ubpa::small_vector EntityMngr::LocateSingletons(const SingletonLocator& locator) const { std::size_t numSingletons = 0; - small_vector rst; + small_vector rst; rst.reserve(locator.SingletonTypes().size()); for (const auto& t : locator.SingletonTypes()) { auto ptr = GetSingleton(t);