diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-06-15 22:46:01 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-06-15 23:45:37 +0200 |
commit | 971418ecaa4e464e5093fc79675704fff0d35a31 (patch) | |
tree | d0759e356e673767084d2ee0bc26c53d95aeee55 /asl/handle_pool | |
parent | 484bbdea95c66bf6db23b8080d2cf7987939b03c (diff) |
Add index_pool_handle
Diffstat (limited to 'asl/handle_pool')
-rw-r--r-- | asl/handle_pool/index_pool.hpp | 64 | ||||
-rw-r--r-- | asl/handle_pool/index_pool_tests.cpp | 63 |
2 files changed, 126 insertions, 1 deletions
diff --git a/asl/handle_pool/index_pool.hpp b/asl/handle_pool/index_pool.hpp index f874386..1d359d5 100644 --- a/asl/handle_pool/index_pool.hpp +++ b/asl/handle_pool/index_pool.hpp @@ -52,5 +52,69 @@ struct index_pool_config static constexpr HandleType kUserMask = ((HandleType{1} << kUserBits) - 1) << kUserShift; }; +template< + int kIndexBits_, + int kGenBits_, + typename UserType_ = empty, + int kUserBits_ = 0 +> +class index_pool_handle +{ + // using config = index_pool_config<5, 5>; + using config = index_pool_config<kIndexBits_, kGenBits_, UserType_, kUserBits_>; + + config::HandleType m_handle{}; + +public: + constexpr index_pool_handle() = default; + + constexpr index_pool_handle(uint64_t index, uint64_t gen) + requires (!config::kHasUser) + : m_handle{static_cast<config::HandleType>( + config::kValidMask | + (index & config::kIndexMask) | + ((gen << config::kGenShift) & config::kGenMask))} + { + ASL_ASSERT((index & uint64_t{config::kIndexMask}) == index); + ASL_ASSERT((gen & (uint64_t{config::kGenMask} >> config::kGenShift)) == gen); + } + + constexpr index_pool_handle(uint64_t index, uint64_t gen, config::UserType user) + requires config::kHasUser + : m_handle{static_cast<config::HandleType>( + config::kValidMask | + (index & config::kIndexMask) | + ((gen << config::kGenShift) & config::kGenMask) | + ((static_cast<config::HandleType>(bit_cast<typename config::PrimitiveUserType>(user)) << config::kUserShift) & config::kUserMask))} + { + ASL_ASSERT((index & uint64_t{config::kIndexMask}) == index); + ASL_ASSERT((gen & (uint64_t{config::kGenMask} >> config::kGenShift)) == gen); + ASL_ASSERT((bit_cast<typename config::PrimitiveUserType>(user) & (uint64_t{config::kUserMask} >> config::kUserShift)) == bit_cast<typename config::PrimitiveUserType>(user)); + } + + constexpr bool is_valid(this index_pool_handle self) + { + return self.m_handle & config::kValidMask; + } + + constexpr uint64_t index(this index_pool_handle self) + { + return self.m_handle & config::kIndexMask; + } + + constexpr uint64_t gen(this index_pool_handle self) + { + return (self.m_handle & config::kGenMask) >> config::kGenShift; + } + + constexpr config::UserType user(this index_pool_handle self) + { + return bit_cast<typename config::UserType>(static_cast<config::PrimitiveUserType>( + ((self.m_handle & config::kUserMask) >> config::kUserShift))); + } + + constexpr bool operator==(this index_pool_handle self, index_pool_handle other) = default; +}; + } // namespace asl diff --git a/asl/handle_pool/index_pool_tests.cpp b/asl/handle_pool/index_pool_tests.cpp index b49d0b9..3156320 100644 --- a/asl/handle_pool/index_pool_tests.cpp +++ b/asl/handle_pool/index_pool_tests.cpp @@ -44,6 +44,67 @@ static_assert(Cfg3::kUserMask == uint16_t{0x7800}); static_assert(Cfg3::kGenShift == 5); static_assert(Cfg3::kUserShift == 11); -ASL_TEST(test) +static_assert(asl::default_constructible<asl::index_pool_handle<5, 5, uint8_t>>); +static_assert(asl::trivially_copy_constructible<asl::index_pool_handle<5, 5, uint8_t>>); +static_assert(asl::trivially_move_constructible<asl::index_pool_handle<5, 5, uint8_t>>); +static_assert(asl::trivially_copy_assignable<asl::index_pool_handle<5, 5, uint8_t>>); +static_assert(asl::trivially_move_assignable<asl::index_pool_handle<5, 5, uint8_t>>); +static_assert(asl::trivially_destructible<asl::index_pool_handle<5, 5, uint8_t>>); + +ASL_TEST(default_is_invalid) { + const asl::index_pool_handle<5, 5, uint8_t> idx; + ASL_TEST_EXPECT(!idx.is_valid()); +} + +ASL_TEST(construct) +{ + const asl::index_pool_handle<5, 5> idx(9, 11); + ASL_TEST_EXPECT(idx.is_valid()); + ASL_TEST_EXPECT(idx.index() == 9); + ASL_TEST_EXPECT(idx.gen() == 11); +} + +ASL_TEST(construct_user) +{ + const asl::index_pool_handle<5, 5, Flags, 4> idx(9, 11, kFlag2); + ASL_TEST_EXPECT(idx.is_valid()); + ASL_TEST_EXPECT(idx.index() == 9); + ASL_TEST_EXPECT(idx.gen() == 11); + ASL_TEST_EXPECT(idx.user() == kFlag2); + static_assert(asl::same_as<Flags, decltype(idx.user())>); +} + + +ASL_TEST(compare) // NOLINT +{ + const asl::index_pool_handle<5, 5, Flags, 4> idx_default; + const asl::index_pool_handle<5, 5, Flags, 4> idx0; + const asl::index_pool_handle<5, 5, Flags, 4> idx1(9, 11, kFlag2); + const asl::index_pool_handle<5, 5, Flags, 4> idx2(9, 11, kFlag1); + const asl::index_pool_handle<5, 5, Flags, 4> idx3(9, 11, kFlag1); + const asl::index_pool_handle<5, 5, Flags, 4> idx4(9, 10, kFlag2); + const asl::index_pool_handle<5, 5, Flags, 4> idx5(8, 11, kFlag2); + + ASL_TEST_EXPECT(idx0 == idx_default); + + ASL_TEST_EXPECT(idx0 != idx1); + ASL_TEST_EXPECT(idx0 != idx2); + ASL_TEST_EXPECT(idx0 != idx3); + ASL_TEST_EXPECT(idx0 != idx4); + ASL_TEST_EXPECT(idx0 != idx5); + + ASL_TEST_EXPECT(idx1 != idx2); + ASL_TEST_EXPECT(idx1 != idx3); + ASL_TEST_EXPECT(idx1 != idx4); + ASL_TEST_EXPECT(idx1 != idx5); + + ASL_TEST_EXPECT(idx2 == idx3); + ASL_TEST_EXPECT(idx2 != idx4); + ASL_TEST_EXPECT(idx2 != idx5); + + ASL_TEST_EXPECT(idx3 != idx4); + ASL_TEST_EXPECT(idx3 != idx5); + + ASL_TEST_EXPECT(idx4 != idx5); } |