diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-05-28 00:47:52 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-05-28 00:47:52 +0200 |
commit | 048ab0903b8749717f4461a6abcfa023ceef0dd6 (patch) | |
tree | 480ff91c9190ca7823d335df0eb31b34c8229422 | |
parent | b8a87223bb70fccc47ba0f9c96b3f58de6e1e5bd (diff) |
WIPhandle_pool
-rw-r--r-- | asl/base/meta.hpp | 26 | ||||
-rw-r--r-- | asl/base/meta_tests.cpp | 36 | ||||
-rw-r--r-- | asl/handle_pool/BUILD.bazel | 33 | ||||
-rw-r--r-- | asl/handle_pool/index_pool.hpp | 88 | ||||
-rw-r--r-- | asl/handle_pool/index_pool_tests.cpp | 10 |
5 files changed, 189 insertions, 4 deletions
diff --git a/asl/base/meta.hpp b/asl/base/meta.hpp index b17d761..9f67e13 100644 --- a/asl/base/meta.hpp +++ b/asl/base/meta.hpp @@ -317,15 +317,33 @@ template<typename T> concept is_integer = is_signed_integer<T> || is_unsigned_in template<is_integer T> using as_unsigned_integer = _integer_traits<T>::as_unsigned; template<is_integer T> using as_signed_integer = _integer_traits<T>::as_signed; +template<int N> +struct smallest_unsigned_integer_type_for_width_helper { using type = void; }; + +template<int N> requires (N >= 1 and N <= 8) +struct smallest_unsigned_integer_type_for_width_helper<N> { using type = uint8_t; }; + +template<int N> requires (N >= 9 and N <= 16) +struct smallest_unsigned_integer_type_for_width_helper<N> { using type = uint16_t; }; + +template<int N> requires (N >= 17 and N <= 32) +struct smallest_unsigned_integer_type_for_width_helper<N> { using type = uint32_t; }; + +template<int N> requires (N >= 33 and N <= 64) +struct smallest_unsigned_integer_type_for_width_helper<N> { using type = uint64_t; }; + +template<int N> using smallest_unsigned_integer_type_for_width + = smallest_unsigned_integer_type_for_width_helper<N>::type; + template<typename T> concept is_enum = __is_enum(T); template<is_enum T> using underlying_t = __underlying_type(T); -template<typename T> struct is_uniquely_represented : false_type {}; -template<is_integer T> struct is_uniquely_represented<T> : true_type {}; -template<is_enum T> struct is_uniquely_represented<T> : true_type {}; +template<typename T> struct is_uniquely_represented : false_type {}; +template<is_integer T> struct is_uniquely_represented<T> : true_type {}; +template<is_enum T> struct is_uniquely_represented<T> : true_type {}; template<> struct is_uniquely_represented<uint128_t> : true_type {}; -template<> struct is_uniquely_represented<byte> : true_type {}; +template<> struct is_uniquely_represented<byte> : true_type {}; template<typename T> concept uniquely_represented = is_uniquely_represented<un_cv_t<T>>::value; diff --git a/asl/base/meta_tests.cpp b/asl/base/meta_tests.cpp index 36b0429..fbbec15 100644 --- a/asl/base/meta_tests.cpp +++ b/asl/base/meta_tests.cpp @@ -389,3 +389,39 @@ enum EnumI64 : int64_t {}; static_assert(asl::same_as<asl::underlying_t<EnumU8>, uint8_t>); static_assert(asl::same_as<asl::underlying_t<EnumI64>, int64_t>); +static_assert(!asl::is_integer<EnumU8>); +static_assert(!asl::is_integer<EnumI64>); + +static_assert(asl::same_as<asl::as_unsigned_integer<uint8_t>, uint8_t>); +static_assert(asl::same_as<asl::as_unsigned_integer<uint16_t>, uint16_t>); +static_assert(asl::same_as<asl::as_unsigned_integer<uint32_t>, uint32_t>); +static_assert(asl::same_as<asl::as_unsigned_integer<uint64_t>, uint64_t>); + +static_assert(asl::same_as<asl::as_unsigned_integer<int8_t>, uint8_t>); +static_assert(asl::same_as<asl::as_unsigned_integer<int16_t>, uint16_t>); +static_assert(asl::same_as<asl::as_unsigned_integer<int32_t>, uint32_t>); +static_assert(asl::same_as<asl::as_unsigned_integer<int64_t>, uint64_t>); + +static_assert(asl::same_as<asl::as_signed_integer<uint8_t>, int8_t>); +static_assert(asl::same_as<asl::as_signed_integer<uint16_t>, int16_t>); +static_assert(asl::same_as<asl::as_signed_integer<uint32_t>, int32_t>); +static_assert(asl::same_as<asl::as_signed_integer<uint64_t>, int64_t>); + +static_assert(asl::same_as<asl::as_signed_integer<int8_t>, int8_t>); +static_assert(asl::same_as<asl::as_signed_integer<int16_t>, int16_t>); +static_assert(asl::same_as<asl::as_signed_integer<int32_t>, int32_t>); +static_assert(asl::same_as<asl::as_signed_integer<int64_t>, int64_t>); + +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<1>, uint8_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<2>, uint8_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<4>, uint8_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<8>, uint8_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<12>, uint16_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<16>, uint16_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<20>, uint32_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<30>, uint32_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<31>, uint32_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<32>, uint32_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<50>, uint64_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<63>, uint64_t>); +static_assert(asl::same_as<asl::smallest_unsigned_integer_type_for_width<64>, uint64_t>); 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..377f6f4 --- /dev/null +++ b/asl/handle_pool/index_pool.hpp @@ -0,0 +1,88 @@ +// 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 +{ + +template< + int kIndexSize_, + int kGenSize_, + int kUserSize_ = 0 +> +requires ( + kUserSize_ >= 0 + && kGenSize_ > 0 + && kIndexSize_ > 0 + && (kUserSize_ + kGenSize_ + kIndexSize_ <= 63) +) +struct index_pool_config +{ + static constexpr int kUserSize = kUserSize_; + static constexpr int kGenSize = kGenSize_; + static constexpr int kIndexSize = kIndexSize_; + + static constexpr bool kHasUser = kUserSize > 0; + + using handle_type = smallest_unsigned_integer_type_for_width<kGenSize + kIndexSize + kUserSize>; + using user_type = select_t<kHasUser, smallest_unsigned_integer_type_for_width<kUserSize>, empty>; +}; + + +template< + int kIndexSize_, + int kGenSize_, + typename UserType = empty, + int kUserSize_ = 0 +> +requires ( + same_as<UserType, empty> || (kUserSize_ <= size_of<UserType> * 8 && trivially_copy_constructible<UserType>) +) +class index_pool_handle_base +{ + static constexpr int kUserSizeComputed = + same_as<UserType, empty> ? 0 : (kUserSize_ == 0 ? size_of<UserType> * 8 : kUserSize_); // NOLINT + +public: + using config = index_pool_config<kIndexSize_, kGenSize_, kUserSizeComputed>; + +private: + using handle_type = config::handle_type; + using user_type = config::user_type; + using user_type_external = UserType; + + static constexpr handle_type kHasValueMask = ~(~handle_type{0} >> 1); + + static constexpr handle_type kIndexMask = (handle_type{1} << config::kIndexSize) - 1; + + static constexpr int kGenShift = config::kIndexSize; + static constexpr handle_type kGenMask = ((handle_type{1} << config::kGenSize) - 1) << kGenShift; + + static constexpr int kUserShift = config::kIndexSize + config::kGenSize; + static constexpr handle_type kUserMask = ((handle_type{1} << config::kUserSize) - 1) << kUserShift; + + handle_type m_handle{}; + +public: + [[nodiscard]] constexpr bool has_value() const { return m_handle & kHasValueMask; } + + [[nodiscard]] constexpr user_type_external user() const + requires config::kHasUser + { + return bit_cast<user_type_external>( + static_cast<user_type>((m_handle & kUserMask) >> kUserShift) + ); + } +}; + +class IndexPool +{ +}; + +} // 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..1dd2816 --- /dev/null +++ b/asl/handle_pool/index_pool_tests.cpp @@ -0,0 +1,10 @@ +// Copyright 2025 Steven Le Rouzic +// +// SPDX-License-Identifier: BSD-3-Clause + +#include "asl/testing/testing.hpp" + +ASL_TEST(test) +{ +} + |