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