Skip to main content

ConceptModelRegistry.ixx File

Generic type-indexed registry for type-erased wrappers. More...

Included Headers

#include <cassert> #include <memory> #include <span> #include <vector> #include <cstddef>

Namespaces Index

namespacehelios
namespaceengine
namespacecore
namespacecontainer

Classes Index

classConceptModelRegistry<AnyT, IdProvider>

Generic type-indexed registry for type-erased wrapper instances. More...

Description

Generic type-indexed registry for type-erased wrappers.

File Listing

The file content with the documentation metadata removed is:

1
5module;
6
7#include <cassert>
8#include <memory>
9#include <span>
10#include <vector>
11#include <cstddef>
12
13
14export module helios.engine.core.container.ConceptModelRegistry;
15
16
17export namespace helios::engine::core::container {
18
50 template<typename AnyT, typename IdProvider>
52
56 mutable std::vector<AnyT> items_;
57
61 std::vector<void*> underlyingAnyT_;
62
66 std::vector<size_t> insertionOrder_;
67
71 mutable std::vector<AnyT*> itemView_;
72
76 mutable bool needsUpdate_ = false;
77
81 void update() const {
82
83 if (!needsUpdate_) {
84 return;
85 }
86
87 itemView_.clear();
88 itemView_.reserve(insertionOrder_.size());
89
90 for (const auto insertionIndex : insertionOrder_) {
91 itemView_.push_back(const_cast<AnyT*>(&items_[insertionIndex]));
92 }
93
94 needsUpdate_ = false;
95
96 }
97
98
99 public:
100
106 [[nodiscard]] std::span<AnyT* const> items() const noexcept {
107 update();
108 return itemView_;
109 }
110
116 [[nodiscard]] std::span<AnyT*> items() noexcept {
117 update();
118 return itemView_;
119 }
120
121
138 template<typename T, typename... Args>
139 T& add(Args&&... args) {
140
141 assert(!has<T>() && "AnyT already registered.");
142
143 AnyT wrapper{T{std::forward<Args>(args)...}};
144
145 const auto idx = IdProvider::template id<T>().value();
146
147 if (items_.size() <= idx) {
148 items_.resize(idx + 1);
149 }
150 if (underlyingAnyT_.size() <= idx) {
151 underlyingAnyT_.resize(idx + 1);
152 }
153
154 items_[idx] = std::move(wrapper);
155 void* rawUnderlying = items_[idx].underlying();
156 underlyingAnyT_[idx] = rawUnderlying;
157
158
159 insertionOrder_.push_back(idx);
160
161 needsUpdate_ = true;
162 return *static_cast<T*>(rawUnderlying);
163 }
164
184 template<typename T>
186 const auto idx = IdProvider::template id<T>().value();
187
188 if (items_.size() <= idx) {
189 items_.resize(idx + 1);
190 }
191 if (underlyingAnyT_.size() <= idx) {
192 underlyingAnyT_.resize(idx + 1);
193 }
194
195 items_[idx] = std::move(wrapper);
196
197 void* rawUnderlying = items_[idx].underlying();
198 underlyingAnyT_[idx] = rawUnderlying;
199
200 insertionOrder_.push_back(idx);
201 needsUpdate_ = true;
202
203 return *static_cast<T*>(rawUnderlying);
204 }
205
206
214 template<typename T>
215 [[nodiscard]] bool has() const {
216 return item<T>() != nullptr;
217 }
218
226 template<typename T>
227 [[nodiscard]] T* item() const {
228
229 const auto idx = IdProvider::template id<T>().value();
230 if (items_.size() <= idx || underlyingAnyT_.size() <= idx) {
231 return nullptr;
232 }
233
234 return underlyingAnyT_[idx] ? static_cast<T*>(underlyingAnyT_[idx]) : nullptr;
235 }
236
237 };
238
239
240}
241

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.