File indexing completed on 2026-05-27 07:24:04
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/core/detail/container_views.hpp"
0013 #include "detray/definitions/detail/qualifiers.hpp"
0014 #include "detray/definitions/indexing.hpp"
0015 #include "detray/utils/invalid_values.hpp"
0016 #include "detray/utils/ranges.hpp"
0017
0018
0019 #include <algorithm>
0020
0021 namespace detray::bins {
0022
0023
0024 template <typename entry_t>
0025 class single : public detray::ranges::single_view<entry_t> {
0026 using base_type = detray::ranges::single_view<entry_t>;
0027
0028 public:
0029 using entry_type = entry_t;
0030 using base_type::base_type;
0031 using base_type::operator=;
0032
0033
0034 DETRAY_HOST_DEVICE constexpr single()
0035 : base_type{detail::invalid_value<entry_t>()} {}
0036
0037
0038 DETRAY_HOST_DEVICE
0039 constexpr dindex capacity() noexcept { return 1u; }
0040
0041
0042 template <typename E = entry_t>
0043 DETRAY_HOST_DEVICE constexpr void push_back(E&& entry) noexcept {
0044 (*this).ref() = std::forward<E>(entry);
0045 }
0046
0047
0048 DETRAY_HOST_DEVICE
0049 constexpr auto init(entry_t entry = detail::invalid_value<entry_t>())
0050 -> single& {
0051 (*this).ref() = entry;
0052 return *this;
0053 }
0054
0055
0056
0057
0058
0059
0060 DETRAY_HOST_DEVICE
0061 constexpr bool operator==(const single& rhs) const {
0062 return (*this).value() == rhs.value();
0063 }
0064 };
0065
0066
0067
0068
0069
0070 template <typename entry_t, std::size_t N>
0071 class static_array
0072 : public detray::ranges::view_interface<static_array<entry_t, N>> {
0073 using bin_view_t = detray::ranges::subrange<darray<entry_t, N>>;
0074 using const_bin_view_t = detray::ranges::subrange<const darray<entry_t, N>>;
0075 using bin_iterator_t = typename detray::ranges::iterator_t<bin_view_t>;
0076 using const_bin_iterator_t =
0077 typename detray::ranges::const_iterator_t<const_bin_view_t>;
0078
0079 public:
0080 using entry_type = entry_t;
0081
0082
0083 DETRAY_HOST_DEVICE constexpr static_array() { init(); };
0084 constexpr static_array(const static_array& other) = default;
0085 constexpr static_array(static_array&& other) noexcept = default;
0086 static_array& operator=(const static_array& other) noexcept = default;
0087
0088
0089
0090 DETRAY_HOST_DEVICE bin_iterator_t begin() {
0091 bin_view_t bv{view()};
0092 return detray::ranges::begin(bv);
0093 }
0094 DETRAY_HOST_DEVICE bin_iterator_t end() {
0095 bin_view_t bv{view()};
0096 return detray::ranges::end(bv);
0097 }
0098 DETRAY_HOST_DEVICE
0099 const_bin_iterator_t begin() const { return detray::ranges::cbegin(view()); }
0100 DETRAY_HOST_DEVICE
0101 const_bin_iterator_t end() const { return detray::ranges::cend(view()); }
0102
0103
0104
0105 DETRAY_HOST_DEVICE
0106 constexpr dindex size() const { return m_size; }
0107
0108
0109 DETRAY_HOST_DEVICE
0110 constexpr dindex capacity() const noexcept {
0111 return static_cast<dindex>(m_content.size());
0112 }
0113
0114
0115 template <typename E = entry_t>
0116 DETRAY_HOST_DEVICE constexpr void push_back(E&& entry) noexcept {
0117 m_content[m_size] = std::forward<E>(entry);
0118 ++m_size;
0119 }
0120
0121
0122
0123
0124 DETRAY_HOST_DEVICE
0125 constexpr auto init(entry_t entry = detail::invalid_value<entry_t>())
0126 -> static_array& {
0127
0128 for (auto& e : m_content) {
0129 e = detail::invalid_value<entry_t>();
0130 }
0131
0132 if (entry == detail::invalid_value<entry_t>()) {
0133 m_size = 0u;
0134 return *this;
0135 }
0136
0137
0138 m_content[0] = entry;
0139 m_size = 1u;
0140
0141 return *this;
0142 }
0143
0144
0145
0146
0147 DETRAY_HOST_DEVICE
0148 constexpr auto init(darray<entry_t, N> content) -> static_array& {
0149 m_content = content;
0150 m_size = 0u;
0151 for (const auto& entry : m_content) {
0152 if (entry != detail::invalid_value<entry_t>()) {
0153 ++m_size;
0154 }
0155 }
0156
0157 return *this;
0158 }
0159
0160
0161
0162
0163
0164
0165 DETRAY_HOST_DEVICE
0166 constexpr bool operator==(const static_array& rhs) const {
0167 return m_content == rhs.m_content;
0168 }
0169
0170 private:
0171
0172 DETRAY_HOST_DEVICE constexpr auto view() const {
0173 return const_bin_view_t{m_content, dindex_range{0u, m_size}};
0174 }
0175
0176
0177 DETRAY_HOST_DEVICE constexpr auto view() {
0178 return bin_view_t{m_content, dindex_range{0u, m_size}};
0179 }
0180
0181
0182 dindex m_size{0u};
0183
0184 darray<entry_t, N> m_content{};
0185 };
0186
0187
0188
0189
0190 template <typename entry_t>
0191 class dynamic_array
0192 : public detray::ranges::view_interface<dynamic_array<entry_t>> {
0193 using container_t = device_container_types::template vector_type<entry_t>;
0194 using bin_view_t = detray::ranges::subrange<container_t>;
0195 using const_bin_view_t = detray::ranges::subrange<const container_t>;
0196
0197 public:
0198 struct data {
0199 dindex offset{0u};
0200 dindex size{0u};
0201 dindex capacity{0u};
0202
0203 constexpr bool operator==(const data& rhs) const = default;
0204
0205 DETRAY_HOST_DEVICE
0206 constexpr void update_offset(std::size_t shift) {
0207 offset += static_cast<dindex>(shift);
0208 }
0209 };
0210
0211 using entry_type = entry_t;
0212 using entry_ptr_t = const entry_type*;
0213 using data_ptr_t = const data*;
0214
0215
0216 DETRAY_HOST_DEVICE constexpr dynamic_array() { init(); };
0217
0218
0219
0220
0221 DETRAY_HOST_DEVICE
0222 dynamic_array(entry_type* bin_storage, data& bin_data)
0223 : m_data{&bin_data}, m_capacity{bin_data.capacity} {
0224
0225 if (bin_storage) {
0226 m_global_storage = bin_storage + bin_data.offset;
0227 }
0228 }
0229
0230
0231
0232
0233 DETRAY_HOST_DEVICE
0234 dynamic_array(const entry_type* bin_storage, const data& bin_data)
0235 : m_data{&bin_data}, m_capacity{bin_data.capacity} {
0236
0237 if (bin_storage) {
0238 m_global_storage = bin_storage + bin_data.offset;
0239 }
0240 }
0241
0242
0243
0244 DETRAY_HOST_DEVICE auto begin() {
0245 bin_view_t bv{view()};
0246 return detray::ranges::begin(bv);
0247 }
0248 DETRAY_HOST_DEVICE auto end() {
0249 bin_view_t bv{view()};
0250 return detray::ranges::end(bv);
0251 }
0252 DETRAY_HOST_DEVICE
0253 auto begin() const { return detray::ranges::cbegin(view()); }
0254 DETRAY_HOST_DEVICE auto end() const { return detray::ranges::cend(view()); }
0255
0256
0257
0258 DETRAY_HOST_DEVICE
0259 constexpr dindex size() const { return m_data->size; }
0260
0261
0262 DETRAY_HOST_DEVICE
0263 constexpr dindex capacity() const noexcept { return m_capacity; }
0264
0265
0266
0267 template <typename E = entry_type>
0268 DETRAY_HOST_DEVICE constexpr void push_back(E&& entry) {
0269 assert(m_capacity > 0);
0270 assert(m_data->size < m_capacity);
0271 assert(m_global_storage);
0272
0273 if (m_data->size < m_capacity) {
0274 *(const_cast<entry_type*>(m_global_storage) + m_data->size) =
0275 std::forward<E>(entry);
0276 ++(const_cast<data*>(m_data)->size);
0277 }
0278 }
0279
0280
0281
0282
0283 DETRAY_HOST_DEVICE
0284 constexpr auto init(entry_type entry = detail::invalid_value<entry_type>())
0285 -> dynamic_array& {
0286 if (capacity() == 0u) {
0287 return *this;
0288 }
0289
0290
0291 std::ranges::fill(this, detail::invalid_value<entry_type>());
0292
0293 if (entry == detail::invalid_value<entry_type>()) {
0294 const_cast<data*>(m_data)->size = 0u;
0295 return *this;
0296 }
0297
0298
0299 this->front() = entry;
0300 const_cast<data*>(m_data)->size = 1u;
0301
0302 return *this;
0303 }
0304
0305
0306
0307
0308 template <typename storage_t>
0309 DETRAY_HOST_DEVICE constexpr auto init(const storage_t& content)
0310 -> dynamic_array& {
0311 const_cast<data*>(m_data)->size = 0u;
0312 for (dindex i{0u}; i < m_capacity; ++i) {
0313 if (content[i] != detail::invalid_value<entry_type>()) {
0314 const_cast<entry_type*>(m_global_storage)[i] = content[i];
0315 ++(const_cast<data*>(m_data)->size);
0316 }
0317 }
0318 return *this;
0319 }
0320
0321
0322
0323
0324
0325
0326 DETRAY_HOST_DEVICE
0327 constexpr bool operator==(const dynamic_array& rhs) const {
0328
0329 if (m_data == rhs.m_data || *m_data == *rhs.m_data) {
0330 return true;
0331 }
0332 if (m_data->size != rhs.m_data->size) {
0333 return false;
0334 }
0335
0336
0337 auto this_view = view();
0338 auto rhs_view = rhs.view();
0339
0340 for (dindex i{0u}; i < m_data->size; ++i) {
0341 if (this_view[i] != rhs_view[i]) {
0342 return false;
0343 }
0344 }
0345 return true;
0346 }
0347
0348 private:
0349
0350 DETRAY_HOST_DEVICE auto view() const {
0351 return const_bin_view_t{m_global_storage, m_global_storage + m_data->size};
0352 }
0353
0354
0355 DETRAY_HOST_DEVICE auto view() {
0356 return bin_view_t{const_cast<entry_type*>(m_global_storage),
0357 const_cast<entry_type*>(m_global_storage) + m_data->size};
0358 }
0359
0360
0361
0362 entry_ptr_t m_global_storage{nullptr};
0363
0364 data_ptr_t m_data{nullptr};
0365
0366 dindex m_capacity{0u};
0367 };
0368
0369 template <typename entry_t, typename data_t>
0370 dynamic_array(entry_t* bin_storage, data_t& bin_data) -> dynamic_array<entry_t>;
0371
0372 template <typename entry_t, typename data_t>
0373 dynamic_array(const entry_t* bin_storage, const data_t& bin_data)
0374 -> dynamic_array<entry_t>;
0375
0376
0377 }