File indexing completed on 2026-05-27 07:24:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/utils/ranges.hpp"
0011
0012 #include "detray/definitions/containers.hpp"
0013
0014
0015 #include "vecmem/containers/device_vector.hpp"
0016 #include "vecmem/containers/jagged_device_vector.hpp"
0017 #include "vecmem/containers/jagged_vector.hpp"
0018
0019
0020 #include <gtest/gtest.h>
0021
0022
0023 #include <forward_list>
0024 #include <list>
0025 #include <type_traits>
0026
0027 using namespace detray;
0028
0029
0030 GTEST_TEST(detray_utils, ranges) {
0031
0032
0033
0034
0035 static_assert(detray::ranges::range<dvector<float>>);
0036 static_assert(!detray::ranges::view<dvector<float>>);
0037 static_assert(detray::ranges::random_access_range<dvector<float>>);
0038 static_assert(detray::ranges::common_range<dvector<float>>);
0039
0040
0041 static_assert(detray::ranges::range<darray<float, 1>>);
0042 static_assert(!detray::ranges::view<darray<float, 1>>);
0043 static_assert(detray::ranges::random_access_range<darray<float, 1>>);
0044 static_assert(detray::ranges::common_range<darray<float, 1>>);
0045
0046
0047 static_assert(detray::ranges::range<dmap<int, float>>);
0048 static_assert(!detray::ranges::view<dmap<int, float>>);
0049 static_assert(detray::ranges::bidirectional_range<dmap<int, float>>);
0050 static_assert(!detray::ranges::random_access_range<dmap<int, float>>);
0051 static_assert(detray::ranges::common_range<dmap<int, float>>);
0052
0053
0054 static_assert(!detray::ranges::range<dtuple<int, float>>);
0055 static_assert(!detray::ranges::view<dtuple<int, float>>);
0056
0057
0058
0059
0060
0061
0062 static_assert(detray::ranges::range<vecmem::device_vector<float>>);
0063 static_assert(!detray::ranges::view<vecmem::device_vector<float>>);
0064 static_assert(
0065 detray::ranges::random_access_range<vecmem::device_vector<float>>);
0066 static_assert(detray::ranges::common_range<vecmem::device_vector<float>>);
0067
0068
0069 static_assert(detray::ranges::range<djagged_vector<float>>);
0070 static_assert(!detray::ranges::view<djagged_vector<float>>);
0071 static_assert(detray::ranges::bidirectional_range<djagged_vector<float>>);
0072 static_assert(detray::ranges::common_range<djagged_vector<float>>);
0073
0074
0075 static_assert(detray::ranges::range<vecmem::jagged_device_vector<float>>);
0076 static_assert(!detray::ranges::view<vecmem::jagged_device_vector<float>>);
0077 static_assert(
0078 detray::ranges::bidirectional_range<vecmem::jagged_device_vector<float>>);
0079 static_assert(
0080 detray::ranges::common_range<vecmem::jagged_device_vector<float>>);
0081
0082
0083
0084
0085
0086
0087 static_assert(detray::ranges::range<std::forward_list<float>>);
0088 static_assert(!detray::ranges::view<std::forward_list<float>>);
0089 static_assert(detray::ranges::forward_range<std::forward_list<float>>);
0090 static_assert(!detray::ranges::bidirectional_range<std::forward_list<float>>);
0091 static_assert(detray::ranges::common_range<std::forward_list<float>>);
0092
0093
0094 static_assert(detray::ranges::range<std::list<float>>);
0095 static_assert(!detray::ranges::view<std::list<float>>);
0096 static_assert(detray::ranges::bidirectional_range<std::list<float>>);
0097 static_assert(!detray::ranges::random_access_range<std::list<float>>);
0098 static_assert(detray::ranges::common_range<std::list<float>>);
0099 }
0100
0101
0102 GTEST_TEST(detray_utils, ranges_empty) {
0103 auto ev = detray::views::empty<float>();
0104
0105
0106 static_assert(std::is_copy_assignable_v<decltype(ev)>);
0107 static_assert(detray::ranges::range<decltype(ev)>);
0108 static_assert(detray::ranges::view<decltype(ev)>);
0109 static_assert(detray::ranges::random_access_range<decltype(ev)>);
0110
0111
0112 static_assert(
0113 std::is_copy_constructible_v<typename decltype(ev)::iterator_t>);
0114 static_assert(std::is_copy_assignable_v<typename decltype(ev)::iterator_t>);
0115 static_assert(std::is_destructible_v<typename decltype(ev)::iterator_t>);
0116
0117
0118 ASSERT_EQ(ev.size(), 0u);
0119
0120 for (const auto i : ev) {
0121 ASSERT_TRUE(i != i);
0122 }
0123 }
0124
0125
0126 GTEST_TEST(detray_utils, ranges_single) {
0127 const dindex value{251u};
0128
0129 auto sngl = detray::views::single(value);
0130
0131
0132 static_assert(std::is_copy_assignable_v<decltype(sngl)>);
0133 static_assert(detray::ranges::range<decltype(sngl)>);
0134 static_assert(detray::ranges::view<decltype(sngl)>);
0135 static_assert(detray::ranges::random_access_range<decltype(sngl)>);
0136
0137
0138 static_assert(
0139 std::is_copy_constructible_v<typename decltype(sngl)::iterator_t>);
0140 static_assert(std::is_copy_assignable_v<typename decltype(sngl)::iterator_t>);
0141 static_assert(std::is_destructible_v<typename decltype(sngl)::iterator_t>);
0142
0143
0144 ASSERT_EQ(sngl[0], value);
0145 ASSERT_EQ(sngl.size(), 1u);
0146 ASSERT_EQ(sngl.front(), 251u);
0147 ASSERT_EQ(sngl.back(), 251u);
0148
0149 for (auto i : sngl) {
0150 ASSERT_EQ(251u, i);
0151 }
0152 }
0153
0154
0155 GTEST_TEST(detray_utils, ranges_pointer) {
0156 const dindex value{251u};
0157
0158 auto ptr = detray::views::pointer(value);
0159
0160
0161 static_assert(std::is_copy_assignable_v<decltype(ptr)>);
0162 static_assert(detray::ranges::range<decltype(ptr)>);
0163 static_assert(detray::ranges::view<decltype(ptr)>);
0164 static_assert(detray::ranges::random_access_range<decltype(ptr)>);
0165
0166
0167 static_assert(
0168 std::is_copy_constructible_v<typename decltype(ptr)::iterator_t>);
0169 static_assert(std::is_copy_assignable_v<typename decltype(ptr)::iterator_t>);
0170 static_assert(std::is_destructible_v<typename decltype(ptr)::iterator_t>);
0171
0172
0173 ASSERT_EQ(ptr[0], value);
0174 ASSERT_EQ(ptr.size(), 1u);
0175 ASSERT_EQ(ptr.front(), 251u);
0176 ASSERT_EQ(ptr.back(), 251u);
0177
0178 for (auto i : ptr) {
0179 ASSERT_EQ(251u, i);
0180 }
0181 }
0182
0183
0184 GTEST_TEST(detray_utils, ranges_iota_single) {
0185 dindex check{0u};
0186 dindex single{7u};
0187
0188 auto seq = detray::views::iota(single);
0189
0190
0191 static_assert(std::is_copy_assignable_v<decltype(seq)>);
0192 static_assert(detray::ranges::range<decltype(seq)>);
0193 static_assert(detray::ranges::view<decltype(seq)>);
0194 static_assert(detray::ranges::forward_range<decltype(seq)>);
0195 static_assert(detray::ranges::bidirectional_range<decltype(seq)>);
0196 static_assert(detray::ranges::random_access_range<decltype(seq)>);
0197
0198
0199 static_assert(
0200 std::is_copy_constructible_v<typename decltype(seq)::iterator_t>);
0201 static_assert(std::is_copy_assignable_v<typename decltype(seq)::iterator_t>);
0202 static_assert(std::is_destructible_v<typename decltype(seq)::iterator_t>);
0203
0204
0205 ASSERT_EQ(seq.size(), 1u);
0206
0207 for (auto i : seq) {
0208 check += i;
0209 }
0210 ASSERT_EQ(check, single);
0211 }
0212
0213
0214 GTEST_TEST(detray_utils, ranges_iota_interval) {
0215 darray<dindex, 2> interval = {2u, 7u};
0216
0217 auto seq = detray::views::iota(interval);
0218
0219
0220 static_assert(detray::ranges::range<decltype(seq)>);
0221 static_assert(detray::ranges::view<decltype(seq)>);
0222 static_assert(std::is_copy_assignable_v<decltype(seq)>);
0223 static_assert(detray::ranges::forward_range<decltype(seq)>);
0224 static_assert(detray::ranges::bidirectional_range<decltype(seq)>);
0225 static_assert(detray::ranges::random_access_range<decltype(seq)>);
0226
0227
0228 static_assert(
0229 std::is_copy_constructible_v<typename decltype(seq)::iterator_t>);
0230 static_assert(std::is_copy_assignable_v<typename decltype(seq)::iterator_t>);
0231 static_assert(std::is_destructible_v<typename decltype(seq)::iterator_t>);
0232
0233
0234 ASSERT_EQ(seq.size(), 5u);
0235
0236 std::vector<dindex> reference = {2u, 3u, 4u, 5u, 6u};
0237 std::vector<dindex> check = {};
0238 for (auto i : seq) {
0239 check.push_back(i);
0240 }
0241 ASSERT_EQ(check.size(), reference.size());
0242 ASSERT_EQ(check, reference);
0243 }
0244
0245
0246 GTEST_TEST(detray_utils, ranges_cartesian_product_trivial) {
0247 auto seq1 = detray::views::iota(dindex_range{1u, 2u});
0248 auto seq2 = detray::views::iota(dindex_range{2u, 3u});
0249 auto seq3 = detray::views::iota(dindex_range{3u, 4u});
0250
0251 detray::views::cartesian_product cp{seq1, seq2, seq3};
0252
0253
0254 static_assert(detray::ranges::range<decltype(cp)>);
0255 static_assert(detray::ranges::view<decltype(cp)>);
0256 static_assert(std::is_copy_assignable_v<decltype(cp)>);
0257 static_assert(detray::ranges::input_range<decltype(cp)>);
0258 static_assert(detray::ranges::forward_range<decltype(cp)>);
0259 static_assert(detray::ranges::bidirectional_range<decltype(cp)>);
0260 static_assert(!detray::ranges::random_access_range<decltype(cp)>);
0261
0262
0263 static_assert(
0264 std::is_copy_constructible_v<typename decltype(cp)::iterator_t>);
0265 static_assert(std::is_copy_assignable_v<typename decltype(cp)::iterator_t>);
0266 static_assert(std::is_destructible_v<typename decltype(cp)::iterator_t>);
0267
0268
0269 ASSERT_EQ(cp.size(), 1u);
0270
0271 std::size_t r{0u};
0272 for (const auto [i, j, k] : cp) {
0273 ++r;
0274 ASSERT_EQ(i, 1u);
0275 ASSERT_EQ(j, 2u);
0276 ASSERT_EQ(k, 3u);
0277 }
0278
0279 ASSERT_EQ(r, 1u);
0280 }
0281
0282 GTEST_TEST(detray_utils, ranges_cartesian_product) {
0283 const dindex_range range1{2u, 7u};
0284 const dindex_range range2{1u, 10u};
0285 const dindex_range range3{3u, 4u};
0286
0287 auto seq1 = detray::views::iota(range1);
0288 auto seq2 = detray::views::iota(range2);
0289 auto seq3 = detray::views::iota(range3);
0290
0291 const std::size_t size{seq1.size() * seq2.size() * seq3.size()};
0292
0293 detray::views::cartesian_product cp{seq1, seq2, seq3};
0294
0295
0296 static_assert(detray::ranges::range<decltype(cp)>);
0297 static_assert(detray::ranges::view<decltype(cp)>);
0298 static_assert(std::is_copy_assignable_v<decltype(cp)>);
0299 static_assert(detray::ranges::input_range<decltype(cp)>);
0300 static_assert(detray::ranges::forward_range<decltype(cp)>);
0301 static_assert(detray::ranges::bidirectional_range<decltype(cp)>);
0302 static_assert(!detray::ranges::random_access_range<decltype(cp)>);
0303
0304
0305 static_assert(
0306 std::is_copy_constructible_v<typename decltype(cp)::iterator_t>);
0307 static_assert(std::is_copy_assignable_v<typename decltype(cp)::iterator_t>);
0308 static_assert(std::is_destructible_v<typename decltype(cp)::iterator_t>);
0309
0310
0311 ASSERT_EQ(cp.size(), size);
0312
0313
0314 std::vector<std::tuple<dindex, dindex, dindex>> result;
0315 for (auto i : detray::views::iota(range1)) {
0316 for (auto j : detray::views::iota(range2)) {
0317 for (auto k : detray::views::iota(range3)) {
0318 result.emplace_back(i, j, k);
0319 }
0320 }
0321 }
0322
0323 std::size_t r{0u};
0324 for (const auto [i, j, k] : cp) {
0325 const auto [l, m, n] = result[r];
0326 ++r;
0327 ASSERT_EQ(i, l);
0328 ASSERT_EQ(j, m);
0329 ASSERT_EQ(k, n);
0330 }
0331 }
0332
0333
0334 GTEST_TEST(detray_utils, ranges_enumerate) {
0335 struct uint_holder {
0336 unsigned int ui{0u};
0337 };
0338
0339 dvector<uint_holder> seq = {{0u}, {1u}, {2u}, {3u}, {4u}, {5u}};
0340
0341 auto enumerator = detray::views::enumerate(seq);
0342
0343
0344 static_assert(detray::ranges::range<decltype(enumerator)>);
0345 static_assert(detray::ranges::view<decltype(enumerator)>);
0346 static_assert(std::is_copy_assignable_v<decltype(enumerator)>);
0347 static_assert(detray::ranges::random_access_range<decltype(enumerator)>);
0348
0349
0350 static_assert(
0351 std::is_copy_constructible_v<typename decltype(enumerator)::iterator_t>);
0352 static_assert(
0353 std::is_copy_assignable_v<typename decltype(enumerator)::iterator_t>);
0354 static_assert(
0355 std::is_destructible_v<typename decltype(enumerator)::iterator_t>);
0356
0357
0358 const auto [i, v] = enumerator[2];
0359 ASSERT_EQ(i, 2u);
0360 ASSERT_EQ(v.ui, 2u);
0361 ASSERT_EQ(enumerator.size(), 6u);
0362 const auto [i_front, v_front] = enumerator.front();
0363 ASSERT_EQ(i_front, 0u);
0364 ASSERT_EQ(v_front.ui, 0u);
0365 const auto [i_back, v_back] = enumerator.back();
0366 ASSERT_EQ(i_back, 5u);
0367 ASSERT_EQ(v_back.ui, 5u);
0368
0369 for (auto [j, w] : enumerator) {
0370 ASSERT_TRUE(j == w.ui);
0371 ASSERT_EQ(j, w.ui);
0372 }
0373 }
0374
0375
0376 GTEST_TEST(detray_utils, ranges_pick) {
0377
0378 std::vector<dindex> indices = {2u, 3u, 7u, 8u};
0379 std::vector<dindex> check = {};
0380
0381 struct uint_holder {
0382 unsigned int ui{0u};
0383 };
0384
0385 dvector<uint_holder> seq = {{0u}, {1u}, {2u}, {3u}, {4u},
0386 {5u}, {6u}, {7u}, {8u}};
0387
0388 auto selected = detray::views::pick(seq, indices);
0389
0390
0391 static_assert(detray::ranges::range<decltype(selected)>);
0392 static_assert(detray::ranges::view<decltype(selected)>);
0393 static_assert(std::is_copy_assignable_v<decltype(selected)>);
0394 static_assert(detray::ranges::random_access_range<decltype(selected)>);
0395
0396
0397 static_assert(
0398 std::is_copy_constructible_v<typename decltype(selected)::iterator_t>);
0399 static_assert(
0400 std::is_copy_assignable_v<typename decltype(selected)::iterator_t>);
0401 static_assert(
0402 std::is_destructible_v<typename decltype(selected)::iterator_t>);
0403
0404
0405 const auto [i, v] = selected[2];
0406 ASSERT_EQ(i, 7u);
0407 ASSERT_EQ(v.ui, 7u);
0408 ASSERT_EQ(selected.size(), 4u);
0409 const auto [i_front, v_front] = selected.front();
0410 ASSERT_EQ(i_front, 2u);
0411 ASSERT_EQ(v_front.ui, 2u);
0412 const auto [i_back, v_back] = selected.back();
0413 ASSERT_EQ(i_back, 8u);
0414 ASSERT_EQ(v_back.ui, 8u);
0415
0416 for (auto [j, w] : selected) {
0417 ASSERT_EQ(j, w.ui);
0418 check.push_back(w.ui);
0419 }
0420 ASSERT_EQ(check.size(), indices.size());
0421 ASSERT_EQ(check, indices);
0422 }
0423
0424
0425 GTEST_TEST(detray_utils, ranges_join) {
0426 dvector<dindex> interval_0 = {};
0427 dvector<dindex> interval_1 = {2u, 3u, 4u};
0428 dvector<dindex> interval_2 = {7u, 8u, 9u};
0429 dvector<dindex> interval_3 = {10u, 11u, 12u, 13u};
0430 dvector<dvector<dindex>> intervals{interval_0, interval_0, interval_1,
0431 interval_2, interval_0, interval_3,
0432 interval_0};
0433
0434 std::vector<dindex> reference = {2u, 3u, 4u, 7u, 8u, 9u, 10u, 11u, 12u, 13u};
0435 std::vector<dindex> check = {};
0436
0437 auto joined = detray::views::join(intervals);
0438
0439
0440 static_assert(detray::ranges::range<decltype(joined)>);
0441 static_assert(detray::ranges::view<decltype(joined)>);
0442 static_assert(std::is_copy_assignable_v<decltype(joined)>);
0443 static_assert(detray::ranges::random_access_range<decltype(joined)>);
0444
0445
0446 static_assert(
0447 std::is_copy_constructible_v<typename decltype(joined)::iterator_t>);
0448 static_assert(
0449 std::is_copy_assignable_v<typename decltype(joined)::iterator_t>);
0450 static_assert(std::is_destructible_v<typename decltype(joined)::iterator_t>);
0451
0452
0453 ASSERT_EQ(joined[1], 3u);
0454 ASSERT_EQ(joined[4], 8u);
0455 ASSERT_EQ(joined[7], 11u);
0456 ASSERT_EQ(joined.size(), 10u);
0457 ASSERT_EQ(joined.front(), 2u);
0458 ASSERT_EQ(joined.back(), 13u);
0459
0460 for (auto j : joined) {
0461 static_assert(!std::is_const_v<decltype(j)>, "Non-const element in join");
0462 check.push_back(j);
0463 }
0464 ASSERT_EQ(check.size(), reference.size());
0465 ASSERT_EQ(check, reference);
0466
0467 auto joined_comp = intervals | detray::views::join();
0468
0469 check.clear();
0470 for (auto j : joined_comp) {
0471 static_assert(!std::is_const_v<decltype(j)>, "Non-const element in join");
0472 check.push_back(j);
0473 }
0474 ASSERT_EQ(check.size(), reference.size());
0475 ASSERT_EQ(check, reference);
0476 }
0477
0478
0479 GTEST_TEST(detray_utils, ranges_static_join) {
0480 dvector<dindex> interval_1 = {2u, 3u, 4u};
0481 dvector<dindex> interval_2 = {7u, 8u, 9u};
0482
0483 std::vector<dindex> reference = {2u, 3u, 4u, 7u, 8u, 9u};
0484 std::vector<dindex> check = {};
0485
0486 auto joined = detray::views::static_join(interval_1, interval_2);
0487
0488
0489 static_assert(detray::ranges::range<decltype(joined)>);
0490 static_assert(detray::ranges::view<decltype(joined)>);
0491 static_assert(std::is_copy_assignable_v<decltype(joined)>);
0492 static_assert(detray::ranges::random_access_range<decltype(joined)>);
0493
0494
0495 static_assert(
0496 std::is_copy_constructible_v<typename decltype(joined)::iterator_t>);
0497 static_assert(
0498 std::is_copy_assignable_v<typename decltype(joined)::iterator_t>);
0499 static_assert(std::is_destructible_v<typename decltype(joined)::iterator_t>);
0500
0501
0502 ASSERT_EQ(joined[1], 3u);
0503 ASSERT_EQ(joined[4], 8u);
0504 ASSERT_EQ(joined.size(), 6u);
0505 ASSERT_EQ(joined.front(), 2u);
0506 ASSERT_EQ(joined.back(), 9u);
0507
0508 for (const auto j : joined) {
0509 check.push_back(j);
0510 }
0511 ASSERT_EQ(check.size(), reference.size());
0512 ASSERT_EQ(check, reference);
0513 }
0514
0515
0516 GTEST_TEST(detray_utils, ranges_subrange) {
0517 std::size_t begin{1u};
0518 std::size_t end{4u};
0519 std::array<std::size_t, 2> interval{begin, end};
0520
0521 dvector<int> seq = {0, 1, 2, 3, 4, 5};
0522
0523 auto sr = detray::ranges::subrange(seq, interval);
0524
0525
0526 static_assert(detray::ranges::range<decltype(sr)>);
0527 static_assert(detray::ranges::view<decltype(sr)>);
0528 static_assert(std::is_copy_assignable_v<decltype(sr)>);
0529 static_assert(detray::ranges::random_access_range<decltype(sr)>);
0530
0531
0532 static_assert(
0533 std::is_copy_constructible_v<typename decltype(sr)::iterator_t>);
0534 static_assert(std::is_copy_assignable_v<typename decltype(sr)::iterator_t>);
0535 static_assert(std::is_destructible_v<typename decltype(sr)::iterator_t>);
0536
0537 ASSERT_EQ(sr[1], seq[begin + 1u]);
0538 ASSERT_EQ(sr.size(), 3u);
0539 ASSERT_EQ(sr.front(), 1u);
0540 ASSERT_EQ(sr.back(), 3u);
0541
0542
0543 std::size_t i{1u};
0544 for (const auto& v : sr) {
0545 ASSERT_NE(v, 0u);
0546 ASSERT_NE(v, 4u);
0547 ASSERT_EQ(v, seq[i++]);
0548 }
0549
0550
0551 const dvector<int> seq_c(seq);
0552 i = 1u;
0553 for (const auto& v : detray::ranges::subrange(seq_c, interval)) {
0554 ASSERT_EQ(v, seq[i++]);
0555 }
0556
0557
0558 interval[0] = 0u;
0559 interval[1] = 0u;
0560 for (const auto& v : detray::ranges::subrange(seq_c, interval)) {
0561 (void)v;
0562 ASSERT_TRUE(false);
0563 }
0564 }