core: reintroduce to_address (it's not available everywhere yet, I need to find a solution to inject it when needed)

This commit is contained in:
skypjack
2025-12-19 10:03:25 +01:00
parent b69d856ee3
commit c2d68e242a
4 changed files with 30 additions and 7 deletions

View File

@@ -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_.<br/>
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_.<br/>
I will not describe them here in detail. Instead, I recommend reading the inline
documentation to those interested in the subject.

View File

@@ -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<typename Type>
[[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
return ptr;
} else {
return to_address(std::forward<Type>(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<typename allocator_type::value_type>) {
using alloc_traits = std::allocator_traits<Allocator>;
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>(args)...);
alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
}
ENTT_CATCH {
alloc_traits::deallocate(alloc, ptr, 1u);

View File

@@ -265,7 +265,7 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
const auto it = base_type::try_emplace(entt, force_back);
ENTT_TRY {
auto *elem = std::to_address(assure_at_least(static_cast<size_type>(it.index())));
auto *elem = to_address(assure_at_least(static_cast<size_type>(it.index())));
entt::uninitialized_construct_using_allocator(elem, get_allocator(), std::forward<Args>(args)...);
}
ENTT_CATCH {
@@ -306,7 +306,7 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
void move_to(const std::size_t lhs, const std::size_t rhs) {
auto &elem = element_at(lhs);
allocator_type allocator{get_allocator()};
entt::uninitialized_construct_using_allocator(std::to_address(assure_at_least(rhs)), allocator, std::move(elem));
entt::uninitialized_construct_using_allocator(to_address(assure_at_least(rhs)), allocator, std::move(elem));
alloc_traits::destroy(allocator, std::addressof(elem));
}

View File

@@ -13,6 +13,14 @@
#include "../../common/throwing_type.hpp"
#include "../../common/tracked_memory_resource.hpp"
TEST(ToAddress, Functionalities) {
const std::shared_ptr<int> shared = std::make_shared<int>();
auto *plain = &*shared;
ASSERT_EQ(entt::to_address(shared), plain);
ASSERT_EQ(entt::to_address(plain), plain);
}
TEST(PoccaPocmaAndPocs, Functionalities) {
test::basic_test_allocator<int> lhs;
test::basic_test_allocator<int> rhs;