From 30237bb78f00a2aeb277bc8f011d285908fa8b41 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Wed, 28 May 2025 00:47:52 +0200 Subject: Add index_pool_config --- asl/handle_pool/BUILD.bazel | 33 +++++++++++++++++++++ asl/handle_pool/index_pool.hpp | 56 ++++++++++++++++++++++++++++++++++++ asl/handle_pool/index_pool_tests.cpp | 49 +++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 asl/handle_pool/BUILD.bazel create mode 100644 asl/handle_pool/index_pool.hpp create mode 100644 asl/handle_pool/index_pool_tests.cpp diff --git a/asl/handle_pool/BUILD.bazel b/asl/handle_pool/BUILD.bazel new file mode 100644 index 0000000..e5048d3 --- /dev/null +++ b/asl/handle_pool/BUILD.bazel @@ -0,0 +1,33 @@ +# Copyright 2025 Steven Le Rouzic +# +# SPDX-License-Identifier: BSD-3-Clause + +package( + default_applicable_licenses = ["//:license"], +) + +cc_library( + name = "index_pool", + hdrs = [ + "index_pool.hpp", + ], + deps = [ + "//asl/memory", + "//asl/memory:allocator", + "//asl/base", + "//asl/containers:chunked_buffer", + ], + visibility = ["//visibility:public"], +) + +cc_test( + name = "index_pool_tests", + srcs = [ + "index_pool_tests.cpp", + ], + deps = [ + ":index_pool", + "//asl/tests:utils", + "//asl/testing", + ], +) diff --git a/asl/handle_pool/index_pool.hpp b/asl/handle_pool/index_pool.hpp new file mode 100644 index 0000000..f874386 --- /dev/null +++ b/asl/handle_pool/index_pool.hpp @@ -0,0 +1,56 @@ +// Copyright 2025 Steven Le Rouzic +// +// SPDX-License-Identifier: BSD-3-Clause + +#include "asl/base/integers.hpp" +#include "asl/base/meta.hpp" +#include "asl/containers/chunked_buffer.hpp" +#include "asl/memory/allocator.hpp" + +namespace asl +{ + +// @Todo Uniquely represented for the handle? + +template< + int kIndexBits_, + int kGenBits_, + typename UserType_ = empty, + int kUserBits_ = 0 +> +requires (kIndexBits_ > 0 && kGenBits_ > 0 && kUserBits_ >= 0) +struct index_pool_config +{ + static constexpr bool kHasUser = !same_as; + + using UserType = UserType_; + using PrimitiveUserType = smallest_unsigned_integer_type_for_width * 8>; + + static_assert(trivially_copy_constructible); + static_assert(size_of == size_of, "UserType should be of size 1, 2 or 4"); + + static constexpr int kUserBits = []() static -> int { + if constexpr (!kHasUser) { return 0; }; + return kUserBits_ == 0 ? size_of * 8 : kUserBits_; + }(); + + static_assert(kUserBits <= size_of * 8); + + static constexpr int kIndexBits = kIndexBits_; + static constexpr int kGenBits = kGenBits_; + + static_assert(kIndexBits + kGenBits + kUserBits <= 63); + + using HandleType = smallest_unsigned_integer_type_for_width; + + static constexpr int kGenShift = kIndexBits; + static constexpr int kUserShift = kIndexBits + kGenBits; + + static constexpr HandleType kValidMask = HandleType{1} << (size_of * 8 - 1); + static constexpr HandleType kIndexMask = (HandleType{1} << kIndexBits) - 1; + static constexpr HandleType kGenMask = ((HandleType{1} << kGenBits) - 1) << kGenShift; + static constexpr HandleType kUserMask = ((HandleType{1} << kUserBits) - 1) << kUserShift; +}; + +} // namespace asl + diff --git a/asl/handle_pool/index_pool_tests.cpp b/asl/handle_pool/index_pool_tests.cpp new file mode 100644 index 0000000..b49d0b9 --- /dev/null +++ b/asl/handle_pool/index_pool_tests.cpp @@ -0,0 +1,49 @@ +// Copyright 2025 Steven Le Rouzic +// +// SPDX-License-Identifier: BSD-3-Clause + +#include "asl/testing/testing.hpp" +#include "asl/handle_pool/index_pool.hpp" + +enum Flags: uint8_t { + kFlag0 = 0, + kFlag1 = 1, + kFlag2 = 2, +}; + +using Cfg1 = asl::index_pool_config<4, 3>; +static_assert(!Cfg1::kHasUser); +static_assert(Cfg1::kUserBits == 0); +static_assert(asl::same_as); +static_assert(Cfg1::kValidMask == uint8_t{0x80}); +static_assert(Cfg1::kIndexMask == uint8_t{0x0f}); +static_assert(Cfg1::kGenMask == uint8_t{0x70}); +static_assert(Cfg1::kGenShift == 4); + +using Cfg2 = asl::index_pool_config<5, 5, Flags>; +static_assert(Cfg2::kHasUser); +static_assert(Cfg2::kUserBits == 8); +static_assert(asl::same_as); +static_assert(asl::same_as); +static_assert(Cfg2::kValidMask == uint32_t{0x8000'0000}); +static_assert(Cfg2::kIndexMask == uint32_t{0x0000'001f}); +static_assert(Cfg2::kGenMask == uint32_t{0x0000'03e0}); +static_assert(Cfg2::kUserMask == uint32_t{0x0003'fc00}); +static_assert(Cfg2::kGenShift == 5); +static_assert(Cfg2::kUserShift == 10); + +using Cfg3 = asl::index_pool_config<5, 6, Flags, 4>; +static_assert(Cfg3::kHasUser); +static_assert(Cfg3::kUserBits == 4); +static_assert(asl::same_as); +static_assert(asl::same_as); +static_assert(Cfg3::kValidMask == uint16_t{0x8000}); +static_assert(Cfg3::kIndexMask == uint16_t{0x001f}); +static_assert(Cfg3::kGenMask == uint16_t{0x07e0}); +static_assert(Cfg3::kUserMask == uint16_t{0x7800}); +static_assert(Cfg3::kGenShift == 5); +static_assert(Cfg3::kUserShift == 11); + +ASL_TEST(test) +{ +} -- cgit