Add index_pool_config

This commit is contained in:
2025-05-28 00:47:52 +02:00
parent 8f59f113e8
commit 30237bb78f
3 changed files with 138 additions and 0 deletions

View 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",
],
)

View 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

View 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)
{
}