Add index_pool_config
This commit is contained in:
33
asl/handle_pool/BUILD.bazel
Normal file
33
asl/handle_pool/BUILD.bazel
Normal file
@ -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",
|
||||||
|
],
|
||||||
|
)
|
56
asl/handle_pool/index_pool.hpp
Normal file
56
asl/handle_pool/index_pool.hpp
Normal file
@ -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<UserType_, empty>;
|
||||||
|
|
||||||
|
using UserType = UserType_;
|
||||||
|
using PrimitiveUserType = smallest_unsigned_integer_type_for_width<size_of<UserType> * 8>;
|
||||||
|
|
||||||
|
static_assert(trivially_copy_constructible<UserType>);
|
||||||
|
static_assert(size_of<UserType> == size_of<PrimitiveUserType>, "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<UserType> * 8 : kUserBits_;
|
||||||
|
}();
|
||||||
|
|
||||||
|
static_assert(kUserBits <= size_of<UserType> * 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<kIndexBits + kGenBits + kUserBits + 1>;
|
||||||
|
|
||||||
|
static constexpr int kGenShift = kIndexBits;
|
||||||
|
static constexpr int kUserShift = kIndexBits + kGenBits;
|
||||||
|
|
||||||
|
static constexpr HandleType kValidMask = HandleType{1} << (size_of<HandleType> * 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
|
||||||
|
|
49
asl/handle_pool/index_pool_tests.cpp
Normal file
49
asl/handle_pool/index_pool_tests.cpp
Normal file
@ -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<Cfg1::HandleType, uint8_t>);
|
||||||
|
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<Cfg2::PrimitiveUserType, uint8_t>);
|
||||||
|
static_assert(asl::same_as<Cfg2::HandleType, uint32_t>);
|
||||||
|
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<Cfg3::PrimitiveUserType, uint8_t>);
|
||||||
|
static_assert(asl::same_as<Cfg3::HandleType, uint16_t>);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
Reference in New Issue
Block a user