[libcxx-commits] [libcxx] [libc++] Specialize allocator_traits for std::allocator (PR #160278)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Sep 23 04:20:11 PDT 2025
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/160278
This reduces the time to instantiate `allocator_traits<allocator<T>>` from ~0.7ms to ~0.07ms, or reduces the time to instantiate `vector<T>` by ~28%.
>From 47c2e350bac2d8e6cb26a2b4b990394924535635 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 | 74 ++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index 46c247f7040e0..f02e4ddf3c9a6 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -336,6 +336,80 @@ struct allocator_traits {
}
};
+template <class _Tp>
+struct allocator_traits<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
+
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer allocate(allocator_type& __alloc, size_type __n) {
+ return __alloc.allocate(__n);
+ }
+
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
+ allocate(allocator_type& __alloc, size_type __n, const_void_pointer) {
+ return __alloc.allocate(__n);
+ }
+
+#if _LIBCPP_STD_VER >= 23
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr allocation_result<pointer, size_type>
+ allocate_at_least(allocator_type& __alloc, size_type __n) {
+ return {__alloc.allocate(__n), __n};
+ }
+#endif
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void
+ deallocate(allocator_type& __alloc, pointer __ptr, size_type __n) _NOEXCEPT {
+ __alloc.deallocate(__ptr, __n);
+ }
+
+ template <class _Up, class... _Args>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void
+ construct(allocator_type&, _Up* __ptr, _Args&&... __args) {
+ std::__construct_at(__ptr, std::forward<_Args>(__args)...);
+ }
+
+ template <class _Up>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void destroy(allocator_type&, _Up* __ptr) {
+ std::__destroy_at(__ptr);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static size_type max_size(const allocator_type&) _NOEXCEPT {
+ return numeric_limits<size_type>::max() / sizeof(value_type);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static allocator_type
+ select_on_container_copy_construction(const allocator_type&) _NOEXCEPT {
+ return allocator_type();
+ }
+};
+
#ifndef _LIBCPP_CXX03_LANG
template <class _Traits, class _Tp>
using __rebind_alloc _LIBCPP_NODEBUG = typename _Traits::template rebind_alloc<_Tp>;
More information about the libcxx-commits
mailing list