vkmEngine 1.0.0
A C++ game engine · vkmengine.com
Loading...
Searching...
No Matches
type_registry.h
1#pragma once
2
3#include <cstddef>
4#include <memory>
5#include <utility>
6#include <vector>
7
8#include "core/memory/types.h"
9
10namespace Vkm::Engine {
11
20template <typename Base>
21class TypeRegistry {
22 public:
23 TypeRegistry() = default;
24 ~TypeRegistry() = default;
25
26 TypeRegistry(const TypeRegistry& other) = delete;
27 TypeRegistry& operator=(const TypeRegistry& other) = delete;
28
29 // Exchanged through swap(), never moved.
30 TypeRegistry(TypeRegistry && other) = delete;
31 TypeRegistry& operator=(TypeRegistry && other) = delete;
32
33 public:
42 template <typename T, typename Make>
43 Base& ensure(Make&& make) {
44 std::unique_ptr<Base>& held = slot<T>();
45 if (!held) held = make();
46 return *held;
47 }
48
55 template <typename T>
56 Base* find() {
57 const TypeId id = typeId<T>();
58 return id < m_slots.size() ? m_slots[id].get() : nullptr;
59 }
60
62 template <typename T>
63 const Base* find() const {
64 const TypeId id = typeId<T>();
65 return id < m_slots.size() ? m_slots[id].get() : nullptr;
66 }
67
76 template <typename T>
77 std::unique_ptr<Base>& slot() {
78 const TypeId id = typeId<T>();
79 if (id >= m_slots.size()) m_slots.resize(id + 1);
80 return m_slots[id];
81 }
82
84 void clear() { m_slots.clear(); }
85
95 template <typename Pred>
96 void removeIf(Pred&& pred) {
97 for (auto& held : m_slots) {
98 if (held && pred(static_cast<const Base&>(*held))) held.reset();
99 }
100 }
101
107 void swap(TypeRegistry& other) noexcept { m_slots.swap(other.m_slots); }
108
116 std::size_t count() const {
117 std::size_t n = 0;
118 for (const auto& held : m_slots) {
119 if (held) ++n;
120 }
121 return n;
122 }
123
130 template <typename Fn>
131 void forEach(Fn&& fn) {
132 for (auto& held : m_slots) {
133 if (held) fn(*held);
134 }
135 }
136
138 template <typename Fn>
139 void forEach(Fn&& fn) const {
140 for (const auto& held : m_slots) {
141 if (held) fn(*held);
142 }
143 }
144
145 private:
146 std::vector<std::unique_ptr<Base>> m_slots;
147};
148
149} // namespace Vkm::Engine
Base * find()
The slot for T without creating one.
Definition type_registry.h:56
Base & ensure(Make &&make)
The slot for T, created by make the first time it is asked for.
Definition type_registry.h:43
void forEach(Fn &&fn) const
Invoke fn(Base&) for every filled slot, in type-id order.
Definition type_registry.h:139
const Base * find() const
The slot for T without creating one.
Definition type_registry.h:63
std::size_t count() const
How many types actually have a slot.
Definition type_registry.h:116
std::unique_ptr< Base > & slot()
The owning pointer for T's slot, grown into existence but left empty.
Definition type_registry.h:77
void clear()
Drop every slot. Types are re-registered lazily on the next ask.
Definition type_registry.h:84
void forEach(Fn &&fn)
Invoke fn(Base&) for every filled slot, in type-id order.
Definition type_registry.h:131
void removeIf(Pred &&pred)
Empty every slot pred accepts, keeping the rest where they are.
Definition type_registry.h:96
void swap(TypeRegistry &other) noexcept
Exchange every slot with another registry.
Definition type_registry.h:107