18
18
#include < vecmem/memory/memory_resource.hpp>
19
19
20
20
// System include(s)
21
+ #include < iostream>
21
22
#include < type_traits>
22
23
23
24
namespace detray {
@@ -65,7 +66,9 @@ class single_store {
65
66
template <typename allocator_t = vecmem::memory_resource>
66
67
requires (std::derived_from<allocator_t , std::pmr::memory_resource>)
67
68
DETRAY_HOST explicit single_store (allocator_t &resource)
68
- : m_container(&resource) {}
69
+ : m_container(&resource) {
70
+ m_context_size = m_container.size ();
71
+ }
69
72
70
73
// / Copy Construct with a specific memory resource @param resource
71
74
// / (host-side only)
@@ -74,12 +77,16 @@ class single_store {
74
77
requires (std::is_same_v<C, std::vector<T>>
75
78
&&std::derived_from<allocator_t , std::pmr::memory_resource>)
76
79
DETRAY_HOST single_store (allocator_t &resource, const T &arg)
77
- : m_container(&resource, arg) {}
80
+ : m_container(&resource, arg) {
81
+ m_context_size = m_container.size ();
82
+ }
78
83
79
84
// / Construct from the container @param view . Mainly used device-side.
80
85
template <concepts::device_view container_view_t >
81
86
DETRAY_HOST_DEVICE explicit single_store (container_view_t &view)
82
- : m_container(view) {}
87
+ : m_container(view) {
88
+ m_context_size = m_container.size ();
89
+ }
83
90
84
91
// / @returns a pointer to the underlying container - const
85
92
DETRAY_HOST_DEVICE
@@ -95,26 +102,29 @@ class single_store {
95
102
DETRAY_HOST_DEVICE
96
103
constexpr auto size (const context_type & /* ctx*/ = {}) const noexcept
97
104
-> dindex {
98
- return static_cast <dindex>(m_container. size () );
105
+ return static_cast <dindex>(m_context_size );
99
106
}
100
107
101
108
// / @returns true if the underlying container is empty
102
109
DETRAY_HOST_DEVICE
103
- constexpr auto empty (const context_type & /* ctx*/ = {}) const noexcept
104
- -> bool {
105
- return m_container.empty ();
110
+ constexpr auto empty (const context_type &ctx = {}) const noexcept -> bool {
111
+ if (m_n_contexts == 0u ) {
112
+ return m_container.empty ();
113
+ } else {
114
+ return ctx.get () > m_n_contexts;
115
+ }
106
116
}
107
117
108
118
// / @returns the collections iterator at the start position
109
119
DETRAY_HOST_DEVICE
110
- constexpr auto begin (const context_type & /* ctx*/ = {}) const {
111
- return m_container.begin ();
120
+ constexpr auto begin (const context_type &ctx = {}) const {
121
+ return m_container.begin () + ctx. get () * m_context_size ;
112
122
}
113
123
114
124
// / @returns the collections iterator sentinel
115
125
DETRAY_HOST_DEVICE
116
- constexpr auto end (const context_type & /* ctx*/ = {}) const {
117
- return m_container.end () ;
126
+ constexpr auto end (const context_type &ctx = {}) const {
127
+ return m_container.begin () + (ctx. get () + 1 ) * m_context_size ;
118
128
}
119
129
120
130
// / @returns access to the underlying container - const
@@ -135,33 +145,34 @@ class single_store {
135
145
constexpr auto at (const dindex i,
136
146
const context_type &ctx = {}) const noexcept
137
147
-> const T & {
138
- [[maybe_unused]] context_type tmp_ctx{
139
- ctx}; // Temporary measure to avoid warnings
140
- return m_container.at (i);
148
+ return m_container.at (ctx.get () * m_context_size + i);
141
149
}
142
150
143
151
// / @returns context based access to an element (also range checked)
144
152
DETRAY_HOST_DEVICE
145
153
constexpr auto at (const dindex i, const context_type &ctx = {}) noexcept
146
154
-> T & {
147
- [[maybe_unused]] context_type tmp_ctx{
148
- ctx}; // Temporary measure to avoid warnings
149
- return m_container.at (i);
155
+ return m_container.at (ctx.get () * m_context_size + i);
150
156
}
151
157
152
158
// / Removes and destructs all elements in the container.
153
159
DETRAY_HOST void clear (const context_type & /* ctx*/ ) {
160
+ assert (m_n_contexts == 0u );
154
161
m_container.clear ();
162
+ m_context_size = 0 ;
155
163
}
156
164
157
165
// / Reserve memory of size @param n for a given geometry context
158
166
DETRAY_HOST void reserve (std::size_t n, const context_type & /* ctx*/ ) {
167
+ assert (m_n_contexts == 0u );
159
168
m_container.reserve (n);
160
169
}
161
170
162
171
// / Resize the underlying container to @param n for a given geometry context
163
172
DETRAY_HOST void resize (std::size_t n, const context_type & /* ctx*/ ) {
173
+ assert (m_n_contexts == 0u );
164
174
m_container.resize (n);
175
+ m_context_size = m_container.size ();
165
176
}
166
177
167
178
// / Add a new element to the collection - copy
@@ -175,7 +186,9 @@ class single_store {
175
186
DETRAY_HOST constexpr auto push_back (
176
187
const U &arg, const context_type & /* ctx*/ = {}) noexcept (false )
177
188
-> void {
189
+ assert (m_n_contexts == 0u );
178
190
m_container.push_back (arg);
191
+ m_context_size = m_container.size ();
179
192
}
180
193
181
194
// / Add a new element to the collection - move
@@ -188,7 +201,9 @@ class single_store {
188
201
template <typename U>
189
202
DETRAY_HOST constexpr auto push_back (
190
203
U &&arg, const context_type & /* ctx*/ = {}) noexcept (false ) -> void {
204
+ assert (m_n_contexts == 0u );
191
205
m_container.push_back (std::forward<U>(arg));
206
+ m_context_size = m_container.size ();
192
207
}
193
208
194
209
// / Add a new element to the collection in place
@@ -201,6 +216,8 @@ class single_store {
201
216
template <typename ... Args>
202
217
DETRAY_HOST constexpr decltype (auto ) emplace_back(
203
218
const context_type & /* ctx*/ = {}, Args &&... args) noexcept (false ) {
219
+ assert (m_n_contexts == 0u );
220
+ m_context_size++;
204
221
return m_container.emplace_back (std::forward<Args>(args)...);
205
222
}
206
223
@@ -215,8 +232,10 @@ class single_store {
215
232
DETRAY_HOST auto insert (container_t <U> &new_data,
216
233
const context_type & /* ctx*/ = {}) noexcept (false )
217
234
-> void {
235
+ assert (m_n_contexts == 0u );
218
236
m_container.reserve (m_container.size () + new_data.size ());
219
237
m_container.insert (m_container.end (), new_data.begin (), new_data.end ());
238
+ m_context_size = m_container.size ();
220
239
}
221
240
222
241
// / Insert another collection - move
@@ -230,30 +249,61 @@ class single_store {
230
249
DETRAY_HOST auto insert (container_t <U> &&new_data,
231
250
const context_type & /* ctx*/ = {}) noexcept (false )
232
251
-> void {
252
+ assert (m_n_contexts == 0u );
233
253
m_container.reserve (m_container.size () + new_data.size ());
234
254
m_container.insert (m_container.end (),
235
255
std::make_move_iterator (new_data.begin ()),
236
256
std::make_move_iterator (new_data.end ()));
257
+ m_context_size = m_container.size ();
258
+ }
259
+
260
+ template <typename U>
261
+ DETRAY_HOST auto add_context (container_t <U> &context_data) noexcept (false )
262
+ -> void {
263
+ // Cannot add context data to an empty store
264
+ if (m_context_size == 0u ) {
265
+ std::cout << " WARNING: Single Store. Cannot add a context to an "
266
+ " empty store " ;
267
+ return ;
268
+ }
269
+ // Wrong size of the context_data vector
270
+ if (context_data.size () % m_context_size != 0u ) {
271
+ std::cout << " WARNING: Single Store. Wrong size of the inserted "
272
+ " vector. Must be multiple of the context size" ;
273
+ return ;
274
+ }
275
+ // Drop previous contexts if any
276
+ if (m_container.size () > m_context_size)
277
+ m_container.resize (m_context_size);
278
+ // Add new contexts
279
+ m_n_contexts = context_data.size () / m_context_size;
280
+ m_container.reserve (m_container.size () + context_data.size ());
281
+ m_container.insert (m_container.end (), context_data.begin (),
282
+ context_data.end ());
237
283
}
238
284
239
285
// / Append another store to the current one
240
286
// /
241
287
// / @param other The other container
242
288
// /
243
289
// / @note in general can throw an exception
290
+ // / ? Remove the ctx argument ?
244
291
DETRAY_HOST void append (single_store &other,
245
292
const context_type &ctx = {}) noexcept (false ) {
246
293
insert (other.m_container , ctx);
294
+ m_context_size = m_container.size ();
247
295
}
248
296
249
297
// / Append another store to the current one - move
250
298
// /
251
299
// / @param other The other container
252
300
// /
253
301
// / @note in general can throw an exception
302
+ // / ? Remove the ctx argument ?
254
303
DETRAY_HOST void append (single_store &&other,
255
304
const context_type &ctx = {}) noexcept (false ) {
256
305
insert (std::move (other.m_container ), ctx);
306
+ m_context_size = m_container.size ();
257
307
}
258
308
259
309
// / @return the view on the underlying container - non-const
@@ -269,6 +319,8 @@ class single_store {
269
319
private:
270
320
// / The underlying container implementation
271
321
base_type m_container;
322
+ size_type m_context_size{0u };
323
+ size_type m_n_contexts{0u };
272
324
};
273
325
274
326
} // namespace detray
0 commit comments