From c2d68e242a9f4c69d61368c3b6ff08444eb0fb9f Mon Sep 17 00:00:00 2001 From: skypjack Date: Fri, 19 Dec 2025 10:03:25 +0100 Subject: [PATCH] core: reintroduce to_address (it's not available everywhere yet, I need to find a solution to inject it when needed) --- docs/md/core.md | 6 +++--- src/entt/core/memory.hpp | 19 +++++++++++++++++-- src/entt/entity/storage.hpp | 4 ++-- test/entt/core/memory.cpp | 8 ++++++++ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/docs/md/core.md b/docs/md/core.md index 1baf9962f..0f7b48310 100644 --- a/docs/md/core.md +++ b/docs/md/core.md @@ -445,9 +445,9 @@ Some are geared towards simplifying the implementation of (internal or external) allocator aware containers. Others are designed to help the developer with everyday problems. -The former are very specific and for niche problems. For example, there are -tools designed to help forget the meaning of acronyms like _POCCA_, _POCMA_ or -_POCS_.
+The former are very specific and for niche problems. These are tools designed to +unwrap fancy or plain pointers (`to_address`) or to help forget the meaning of +acronyms like _POCCA_, _POCMA_ or _POCS_.
I will not describe them here in detail. Instead, I recommend reading the inline documentation to those interested in the subject. diff --git a/src/entt/core/memory.hpp b/src/entt/core/memory.hpp index bf19333af..85ae8ee8b 100644 --- a/src/entt/core/memory.hpp +++ b/src/entt/core/memory.hpp @@ -10,6 +10,21 @@ namespace entt { +/** + * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20). + * @tparam Type Pointer type. + * @param ptr Fancy or raw pointer. + * @return A raw pointer that represents the address of the original pointer. + */ +template +[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept { + if constexpr(std::is_pointer_v>) { + return ptr; + } else { + return to_address(std::forward(ptr).operator->()); + } +} + /** * @brief Utility function to design allocation-aware containers. * @tparam Allocator Type of allocator. @@ -76,7 +91,7 @@ struct allocation_deleter: private Allocator { */ constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v) { using alloc_traits = std::allocator_traits; - alloc_traits::destroy(*this, std::to_address(ptr)); + alloc_traits::destroy(*this, to_address(ptr)); alloc_traits::deallocate(*this, ptr, 1u); } }; @@ -101,7 +116,7 @@ constexpr auto allocate_unique(Allocator &allocator, Args &&...args) { auto ptr = alloc_traits::allocate(alloc, 1u); ENTT_TRY { - alloc_traits::construct(alloc, std::to_address(ptr), std::forward(args)...); + alloc_traits::construct(alloc, to_address(ptr), std::forward(args)...); } ENTT_CATCH { alloc_traits::deallocate(alloc, ptr, 1u); diff --git a/src/entt/entity/storage.hpp b/src/entt/entity/storage.hpp index 2aec8262f..5f3647551 100644 --- a/src/entt/entity/storage.hpp +++ b/src/entt/entity/storage.hpp @@ -265,7 +265,7 @@ class basic_storage: public basic_sparse_set(it.index()))); + auto *elem = to_address(assure_at_least(static_cast(it.index()))); entt::uninitialized_construct_using_allocator(elem, get_allocator(), std::forward(args)...); } ENTT_CATCH { @@ -306,7 +306,7 @@ class basic_storage: public basic_sparse_set shared = std::make_shared(); + auto *plain = &*shared; + + ASSERT_EQ(entt::to_address(shared), plain); + ASSERT_EQ(entt::to_address(plain), plain); +} + TEST(PoccaPocmaAndPocs, Functionalities) { test::basic_test_allocator lhs; test::basic_test_allocator rhs;