[libcxx-commits] [libcxx] [libc++] Specialize allocator_traits for std::allocator (PR #160278)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 29 02:52:44 PST 2026
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/160278
>From 56028a850ca60a39786800df09680bbcb5b2e56c Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 23 Sep 2025 13:17:41 +0200
Subject: [PATCH] [libc++] Specialize allocator_traits for std::allocator
---
libcxx/include/__memory/allocator_traits.h | 62 +++++++++++++++++++++-
1 file changed, 61 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index b38d7293a3fd3..eebddcfbbfbf5 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -11,6 +11,7 @@
#define _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H
#include <__config>
+#include <__cstddef/ptrdiff_t.h>
#include <__cstddef/size_t.h>
#include <__fwd/memory.h>
#include <__memory/construct_at.h>
@@ -223,8 +224,13 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(allocation_result);
#endif // _LIBCPP_STD_VER
+template <class>
+struct allocator_traits;
+
+// We have a base class that can be specialized for different allocators, since the metaprogramming to get the aliases
+// is quite expensive and the definition of these aliases is usually quite trivial in the end.
template <class _Alloc>
-struct allocator_traits {
+struct __allocator_traits_base {
using allocator_type = _Alloc;
using value_type = typename allocator_type::value_type;
using pointer = __pointer<value_type, allocator_type>;
@@ -253,6 +259,60 @@ struct allocator_traits {
using other = allocator_traits<typename rebind_alloc<_Tp>::other>;
};
#endif // _LIBCPP_CXX03_LANG
+};
+
+template <class _Tp>
+struct __allocator_traits_base<allocator<_Tp> > {
+ using allocator_type = allocator<_Tp>;
+ using value_type = _Tp;
+ using pointer = _Tp*;
+ using const_pointer = const _Tp*;
+ using void_pointer = void*;
+ using const_void_pointer = const void*;
+ using difference_type = ptrdiff_t;
+ using size_type = size_t;
+ using propagate_on_container_copy_assignment = false_type;
+ using propagate_on_container_move_assignment = true_type;
+ using propagate_on_container_swap = false_type;
+ using is_always_equal = true_type;
+
+#ifndef _LIBCPP_CXX03_LANG
+ template <class _Up>
+ using rebind_alloc = allocator<_Up>;
+ template <class _Up>
+ using rebind_traits = allocator_traits<allocator<_Up> >;
+#else
+ template <class _Up>
+ struct rebind_alloc {
+ using other = allocator<_Up>;
+ };
+ template <class _Up>
+ struct rebind_traits {
+ using other = allocator_traits<allocator<_Up> >;
+ };
+#endif
+};
+
+template <class _Alloc>
+struct allocator_traits : __allocator_traits_base<_Alloc> {
+ using __base = __allocator_traits_base<_Alloc>;
+
+ using allocator_type = typename __base::allocator_type;
+ using value_type = typename __base::value_type;
+ using pointer = typename __base::pointer;
+ using const_pointer = typename __base::const_pointer;
+ using void_pointer = typename __base::void_pointer;
+ using const_void_pointer = typename __base::const_void_pointer;
+ using difference_type = typename __base::difference_type;
+ using size_type = typename __base::size_type;
+ using propagate_on_container_copy_assignment = typename __base::propagate_on_container_copy_assignment;
+ using propagate_on_container_move_assignment = typename __base::propagate_on_container_move_assignment;
+ using is_always_equal = typename __base::is_always_equal;
+
+ template <class _Tp>
+ using rebind_alloc = typename __base::template rebind_alloc<_Tp>;
+ template <class _Tp>
+ using rebind_traits = typename __base::template rebind_traits<_Tp>;
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
allocate(allocator_type& __a, size_type __n) {
More information about the libcxx-commits
mailing list