File indexing completed on 2026-05-27 07:24:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/definitions/indexing.hpp"
0011
0012 #include "detray/utils/concepts.hpp"
0013
0014
0015 #include <gtest/gtest.h>
0016
0017
0018 #include <iostream>
0019 #include <limits>
0020
0021 using namespace detray;
0022
0023 namespace {
0024
0025
0026 enum class mask_id : std::uint8_t {
0027 e_unmasked = 0u,
0028 };
0029
0030 std::ostream& operator<<(std::ostream& os, mask_id ) {
0031 os << "e_unmasked";
0032 return os;
0033 }
0034
0035 }
0036
0037
0038 GTEST_TEST(detray_core, index_range) {
0039 using index_t = detail::index_range<unsigned int>;
0040 constexpr auto inv_idx{std::numeric_limits<std::uint32_t>::max()};
0041
0042 static_assert(concepts::interval<index_t>);
0043
0044
0045 auto ir = index_t{};
0046 EXPECT_EQ(ir.lower(), inv_idx);
0047 EXPECT_EQ(ir.upper(), inv_idx);
0048 EXPECT_TRUE(ir.is_invalid());
0049
0050
0051 ir.set_lower(5u).set_upper(42u);
0052
0053 EXPECT_EQ(ir.lower(), 5u);
0054 EXPECT_EQ(ir.upper(), 42u);
0055 EXPECT_EQ(detail::get<0>(ir), 5u);
0056 EXPECT_EQ(detail::get<1>(ir), 42u);
0057 EXPECT_EQ(ir.size(), 37u);
0058
0059
0060 EXPECT_FALSE(ir.is_invalid());
0061 ir.set_lower(inv_idx);
0062 EXPECT_TRUE(ir.is_invalid());
0063 ir.set_lower(10u);
0064 EXPECT_FALSE(ir.is_invalid());
0065
0066 ir.set_upper(inv_idx);
0067 EXPECT_TRUE(ir.is_invalid());
0068 ir.set_upper(20u);
0069 EXPECT_FALSE(ir.is_invalid());
0070
0071 EXPECT_EQ(ir.lower(), 10u);
0072 EXPECT_EQ(ir.upper(), 20u);
0073 EXPECT_EQ(detail::get<0>(ir), 10u);
0074 EXPECT_EQ(detail::get<1>(ir), 20u);
0075 EXPECT_EQ(ir.upper(), 20u);
0076 EXPECT_EQ(ir.size(), 10u);
0077
0078
0079 EXPECT_TRUE(ir == ir);
0080 index_t other = ir;
0081 EXPECT_TRUE(ir == other);
0082 ir.set_lower(13u);
0083 EXPECT_FALSE(ir == other);
0084
0085
0086 std::clog << ir << std::endl;
0087
0088
0089 index_t ir2 = ir + index_t{3u, 5u};
0090
0091 EXPECT_EQ(ir2.lower(), 3u);
0092 EXPECT_EQ(ir2.upper(), 20u);
0093 EXPECT_EQ(ir2.size(), 17u);
0094 ir2 = ir2 + 25u;
0095 EXPECT_EQ(ir2.lower(), 3u);
0096 EXPECT_EQ(ir2.upper(), 45u);
0097 EXPECT_EQ(ir2.size(), 42u);
0098
0099 index_t ir3 = ir - index_t{3u, 15u};
0100
0101 EXPECT_EQ(ir3.lower(), 13u);
0102 EXPECT_EQ(ir3.upper(), 15u);
0103 EXPECT_EQ(ir3.size(), 2u);
0104 ir3 = ir3 + 2u;
0105 EXPECT_EQ(ir3.lower(), 13u);
0106 EXPECT_EQ(ir3.upper(), 17u);
0107 EXPECT_EQ(ir3.size(), 4u);
0108
0109
0110 EXPECT_TRUE(ir3 < ir2);
0111 EXPECT_TRUE(ir3 != ir2);
0112 EXPECT_TRUE(ir2 > ir3);
0113
0114 EXPECT_FALSE(ir3 > ir2);
0115 EXPECT_FALSE(ir3 == ir2);
0116 EXPECT_FALSE(ir2 < ir3);
0117 }
0118
0119
0120 GTEST_TEST(detray_core, sized_index_range) {
0121
0122 using index_t = detail::index_range<unsigned int, detail::sized_index_range>;
0123 constexpr auto inv_idx{std::numeric_limits<std::uint32_t>::max()};
0124
0125 static_assert(concepts::interval<index_t>);
0126
0127
0128 auto ir = index_t{};
0129 EXPECT_EQ(ir.lower(), inv_idx);
0130 EXPECT_EQ(ir.upper(), 2u * inv_idx);
0131 EXPECT_TRUE(ir.is_invalid());
0132
0133
0134 ir.set_lower(5u).set_upper(42u);
0135
0136 EXPECT_EQ(ir.lower(), 5u);
0137 EXPECT_EQ(ir.upper(), 42u);
0138 EXPECT_EQ(detail::get<0>(ir), 5u);
0139 EXPECT_EQ(detail::get<1>(ir), 42u);
0140 EXPECT_EQ(ir.size(), 37u);
0141
0142
0143 EXPECT_FALSE(ir.is_invalid());
0144 ir.set_lower(inv_idx);
0145 EXPECT_TRUE(ir.is_invalid());
0146 ir.set_lower(10u);
0147 EXPECT_FALSE(ir.is_invalid());
0148
0149 ir.set_upper(inv_idx);
0150 EXPECT_TRUE(ir.is_invalid());
0151 ir.set_upper(20u);
0152 EXPECT_FALSE(ir.is_invalid());
0153
0154 EXPECT_EQ(ir.lower(), 10u);
0155 EXPECT_EQ(ir.upper(), 20u);
0156 EXPECT_EQ(detail::get<0>(ir), 10u);
0157 EXPECT_EQ(detail::get<1>(ir), 20u);
0158 EXPECT_EQ(ir.size(), 10u);
0159
0160
0161 EXPECT_TRUE(ir == ir);
0162 index_t other = ir;
0163 EXPECT_TRUE(ir == other);
0164 ir.set_lower(13u);
0165 EXPECT_FALSE(ir == other);
0166
0167
0168 std::clog << ir << std::endl;
0169
0170
0171 index_t ir2 = ir + index_t{3u, 5u};
0172
0173 EXPECT_EQ(ir2.lower(), 3u);
0174 EXPECT_EQ(ir2.upper(), 23);
0175 EXPECT_EQ(ir2.size(), 20u);
0176 ir2 = ir2 + 25u;
0177 EXPECT_EQ(ir2.lower(), 3u);
0178 EXPECT_EQ(ir2.upper(), 48u);
0179 EXPECT_EQ(ir2.size(), 45u);
0180
0181 index_t ir3 = ir - index_t{3u, 15u};
0182
0183 EXPECT_EQ(ir3.lower(), 13u);
0184 EXPECT_EQ(ir3.upper(), 18u);
0185 EXPECT_EQ(ir3.size(), 5u);
0186 ir3 = ir3 + 2u;
0187 EXPECT_EQ(ir3.lower(), 13u);
0188 EXPECT_EQ(ir3.upper(), 20u);
0189 EXPECT_EQ(ir3.size(), 7u);
0190
0191
0192 EXPECT_TRUE(ir3 < ir2);
0193 EXPECT_TRUE(ir3 != ir2);
0194 EXPECT_TRUE(ir2 > ir3);
0195
0196 EXPECT_FALSE(ir3 > ir2);
0197 EXPECT_FALSE(ir3 == ir2);
0198 EXPECT_FALSE(ir2 < ir3);
0199 }
0200
0201
0202 GTEST_TEST(detray_core, multi_index) {
0203
0204 using index_t = dmulti_index<unsigned int, 3>;
0205 constexpr auto inv_idx{detail::invalid_value<unsigned int>()};
0206
0207
0208 auto mi = index_t{};
0209 EXPECT_EQ(mi[0], inv_idx);
0210 EXPECT_EQ(mi[1], inv_idx);
0211 EXPECT_EQ(mi[2], inv_idx);
0212 EXPECT_EQ(mi.size(), 3u);
0213 EXPECT_EQ(index_t::size(), 3u);
0214 EXPECT_TRUE(mi.is_invalid());
0215
0216
0217 mi[0] = 21u;
0218 mi[1] = 42u;
0219 mi[2] = 84u;
0220
0221 EXPECT_EQ(mi[0], 21u);
0222 EXPECT_EQ(mi[1], 42u);
0223 EXPECT_EQ(mi[2], 84u);
0224 EXPECT_EQ(detail::get<0>(mi), 21u);
0225 EXPECT_EQ(detail::get<1>(mi), 42u);
0226 EXPECT_EQ(detail::get<2>(mi), 84u);
0227
0228
0229 EXPECT_FALSE(mi.is_invalid());
0230 mi[1] = inv_idx;
0231 EXPECT_TRUE(mi.is_invalid());
0232
0233
0234 EXPECT_TRUE(mi == mi);
0235 index_t other = mi;
0236 EXPECT_TRUE(mi == other);
0237 mi[1] = 13u;
0238 EXPECT_FALSE(mi == other);
0239
0240
0241 std::clog << mi << std::endl;
0242 }
0243
0244
0245 GTEST_TEST(detray_core, typed_index) {
0246 using index_t = dtyped_index<mask_id, unsigned int>;
0247
0248
0249 auto ti = index_t{};
0250 EXPECT_EQ(ti.id(), static_cast<mask_id>((1u << 4) - 1u));
0251 EXPECT_EQ(ti.index(), static_cast<unsigned int>((1u << 28) - 1u));
0252 EXPECT_TRUE(ti.is_invalid());
0253
0254
0255 ti.set_id(mask_id::e_unmasked).set_index(42u);
0256
0257 EXPECT_EQ(ti.id(), mask_id::e_unmasked);
0258 EXPECT_EQ(ti.index(), 42u);
0259
0260
0261 EXPECT_FALSE(ti.is_invalid());
0262 ti.set_id(static_cast<index_t::id_type>((1u << 4) - 1u));
0263 EXPECT_TRUE(ti.is_invalid());
0264 ti.set_id(mask_id::e_unmasked);
0265 EXPECT_FALSE(ti.is_invalid());
0266 ti.set_index((1u << 28) - 1u);
0267 EXPECT_TRUE(ti.is_invalid());
0268 ti.set_index(21u);
0269 EXPECT_FALSE(ti.is_invalid());
0270
0271
0272 EXPECT_TRUE(ti == ti);
0273 index_t other = ti;
0274 EXPECT_TRUE(ti == other);
0275 ti.set_index(13u);
0276 EXPECT_FALSE(ti == other);
0277
0278
0279 std::clog << ti << std::endl;
0280
0281
0282 ti += 5u;
0283
0284 EXPECT_EQ(ti.id(), mask_id::e_unmasked);
0285 EXPECT_EQ(ti.index(), 18u);
0286
0287 ti -= 6u;
0288 EXPECT_EQ(ti.index(), 12u);
0289
0290 index_t ti2 = ti + index_t{mask_id::e_unmasked, 6u};
0291 EXPECT_EQ(ti2.id(), mask_id::e_unmasked);
0292 EXPECT_EQ(ti2.index(), 18u);
0293 ++ti2;
0294 EXPECT_EQ(ti2.index(), 19u);
0295
0296 ti2 += ti;
0297 EXPECT_EQ(ti2.id(), mask_id::e_unmasked);
0298 EXPECT_EQ(ti2.index(), 31u);
0299
0300
0301 EXPECT_TRUE(ti < ti2);
0302 EXPECT_TRUE(ti != ti2);
0303 EXPECT_TRUE(ti2 > ti);
0304
0305 EXPECT_FALSE(ti > ti2);
0306 EXPECT_FALSE(ti == ti2);
0307 EXPECT_FALSE(ti2 < ti);
0308 }
0309
0310
0311 GTEST_TEST(detray_core, typed_index_range) {
0312 using ranged_index_t =
0313 detail::index_range<unsigned int, detail::sized_index_range,
0314 std::uint_least32_t, 0x0fffff00, 0x000000ff>;
0315 using index_t = dtyped_index<mask_id, ranged_index_t>;
0316
0317
0318 auto tri = index_t{};
0319 EXPECT_EQ(tri.id(), static_cast<mask_id>((1u << 4) - 1u));
0320 EXPECT_EQ(tri.index(), ranged_index_t{});
0321 EXPECT_TRUE(tri.is_invalid());
0322
0323
0324 constexpr ranged_index_t test_range{10u, 42u};
0325 tri.set_id(mask_id::e_unmasked).set_index(test_range);
0326
0327 EXPECT_EQ(tri.id(), mask_id::e_unmasked);
0328 EXPECT_EQ(tri.index(), test_range);
0329
0330
0331 EXPECT_FALSE(tri.is_invalid());
0332 tri.set_id(static_cast<index_t::id_type>((1u << 4) - 1u));
0333 EXPECT_TRUE(tri.is_invalid());
0334 tri.set_id(mask_id::e_unmasked);
0335 EXPECT_FALSE(tri.is_invalid());
0336 tri.set_index(ranged_index_t{});
0337 EXPECT_TRUE(tri.is_invalid());
0338 tri.set_index(ranged_index_t{5u, 42u});
0339 EXPECT_FALSE(tri.is_invalid());
0340
0341
0342 EXPECT_TRUE(tri == tri);
0343 index_t other = tri;
0344 EXPECT_TRUE(tri == other);
0345 tri.set_index(ranged_index_t{4u, 13u});
0346 EXPECT_FALSE(tri == other);
0347
0348
0349 std::clog << tri << std::endl;
0350
0351
0352 tri += 5u;
0353
0354 EXPECT_EQ(tri.id(), mask_id::e_unmasked);
0355 ranged_index_t test_range2{4u, 18u};
0356 EXPECT_EQ(tri.index(), test_range2);
0357
0358 tri -= 6u;
0359 ranged_index_t test_range3{4u, 12u};
0360 EXPECT_EQ(tri.index(), test_range3);
0361
0362 index_t tri2 = tri + index_t{mask_id::e_unmasked, ranged_index_t{0u, 6u}};
0363 ranged_index_t test_range4{0u, 16u};
0364 EXPECT_EQ(tri2.id(), mask_id::e_unmasked);
0365 EXPECT_EQ(tri2.index(), test_range4);
0366 ++tri2;
0367 test_range4 = test_range4 + 1u;
0368 EXPECT_EQ(tri2.index(), test_range4);
0369
0370 tri2 += tri;
0371 EXPECT_EQ(tri2.id(), mask_id::e_unmasked);
0372 EXPECT_EQ(tri2.index(), test_range4);
0373
0374
0375 EXPECT_TRUE(tri < tri2);
0376 EXPECT_TRUE(tri != tri2);
0377 EXPECT_TRUE(tri2 > tri);
0378
0379 EXPECT_FALSE(tri > tri2);
0380 EXPECT_FALSE(tri == tri2);
0381 EXPECT_FALSE(tri2 < tri);
0382 }