* [committed] libstdc++: Specialize allocator_traits<pmr::polymorphic_allocator<T>>
@ 2021-08-03 15:34 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2021-08-03 15:34 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1162 bytes --]
This adds a partial specialization of allocator_traits, similar to what
was already done for std::allocator. This means that most uses of
polymorphic_allocator via the traits can avoid the metaprogramming
overhead needed to deduce the properties from polymorphic_allocator.
In addition, I'm changing polymorphic_allocator::delete_object to invoke
the destructor (or pseudo-destructor) directly, rather than calling
allocator_traits::destroy, which calls polymorphic_allocator::destroy
(which is deprecated). This is observable if a user has specialized
allocator_traits<polymorphic_allocator<Foo>> and expects to see its
destroy member function called. I consider explicit specializations of
allocator_traits to be wrong-headed, and this use case seems unnecessary
to support. So delete_object just invokes the destructor directly.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* include/std/memory_resource (polymorphic_allocator::delete_object):
Call destructor directly instead of using destroy.
(allocator_traits<polymorphic_allocator<T>>): Define partial
specialization.
Tested powerpc64le-linux. Committed to trunk.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 6280 bytes --]
commit 13a1ac9f6f700f4e214fcc83b122a4a405c6b13d
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Tue Aug 3 14:00:47 2021
libstdc++: Specialize allocator_traits<pmr::polymorphic_allocator<T>>
This adds a partial specialization of allocator_traits, similar to what
was already done for std::allocator. This means that most uses of
polymorphic_allocator via the traits can avoid the metaprogramming
overhead needed to deduce the properties from polymorphic_allocator.
In addition, I'm changing polymorphic_allocator::delete_object to invoke
the destructor (or pseudo-destructor) directly, rather than calling
allocator_traits::destroy, which calls polymorphic_allocator::destroy
(which is deprecated). This is observable if a user has specialized
allocator_traits<polymorphic_allocator<Foo>> and expects to see its
destroy member function called. I consider explicit specializations of
allocator_traits to be wrong-headed, and this use case seems unnecessary
to support. So delete_object just invokes the destructor directly.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* include/std/memory_resource (polymorphic_allocator::delete_object):
Call destructor directly instead of using destroy.
(allocator_traits<polymorphic_allocator<T>>): Define partial
specialization.
diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource
index cdc5e5d98b1..6bca0afa018 100644
--- a/libstdc++-v3/include/std/memory_resource
+++ b/libstdc++-v3/include/std/memory_resource
@@ -232,7 +232,7 @@ namespace pmr
void
delete_object(_Up* __p)
{
- destroy(__p);
+ __p->~_Up();
deallocate_object(__p);
}
#endif // C++2a
@@ -381,6 +381,136 @@ namespace pmr
{ return !(__a == __b); }
#endif
+} // namespace pmr
+
+ /// Partial specialization for std::pmr::polymorphic_allocator
+ template<typename _Tp>
+ struct allocator_traits<pmr::polymorphic_allocator<_Tp>>
+ {
+ /// The allocator type
+ using allocator_type = pmr::polymorphic_allocator<_Tp>;
+
+ /// The allocated type
+ using value_type = _Tp;
+
+ /// The allocator's pointer type.
+ using pointer = _Tp*;
+
+ /// The allocator's const pointer type.
+ using const_pointer = const _Tp*;
+
+ /// The allocator's void pointer type.
+ using void_pointer = void*;
+
+ /// The allocator's const void pointer type.
+ using const_void_pointer = const void*;
+
+ /// The allocator's difference type
+ using difference_type = std::ptrdiff_t;
+
+ /// The allocator's size type
+ using size_type = std::size_t;
+
+ /** @{
+ * A `polymorphic_allocator` does not propagate when a
+ * container is copied, moved, or swapped.
+ */
+ using propagate_on_container_copy_assignment = false_type;
+ using propagate_on_container_move_assignment = false_type;
+ using propagate_on_container_swap = false_type;
+
+ static allocator_type
+ select_on_container_copy_construction(const allocator_type&) noexcept
+ { return allocator_type(); }
+ /// @}
+
+ /// Whether all instances of the allocator type compare equal.
+ using is_always_equal = false_type;
+
+ template<typename _Up>
+ using rebind_alloc = pmr::polymorphic_allocator<_Up>;
+
+ template<typename _Up>
+ using rebind_traits = allocator_traits<pmr::polymorphic_allocator<_Up>>;
+
+ /**
+ * @brief Allocate memory.
+ * @param __a An allocator.
+ * @param __n The number of objects to allocate space for.
+ *
+ * Calls `a.allocate(n)`.
+ */
+ [[nodiscard]] static pointer
+ allocate(allocator_type& __a, size_type __n)
+ { return __a.allocate(__n); }
+
+ /**
+ * @brief Allocate memory.
+ * @param __a An allocator.
+ * @param __n The number of objects to allocate space for.
+ * @return Memory of suitable size and alignment for `n` objects
+ * of type `value_type`.
+ *
+ * The third parameter is ignored..
+ *
+ * Returns `a.allocate(n)`.
+ */
+ [[nodiscard]] static pointer
+ allocate(allocator_type& __a, size_type __n, const_void_pointer)
+ { return __a.allocate(__n); }
+
+ /**
+ * @brief Deallocate memory.
+ * @param __a An allocator.
+ * @param __p Pointer to the memory to deallocate.
+ * @param __n The number of objects space was allocated for.
+ *
+ * Calls `a.deallocate(p, n)`.
+ */
+ static void
+ deallocate(allocator_type& __a, pointer __p, size_type __n)
+ { __a.deallocate(__p, __n); }
+
+ /**
+ * @brief Construct an object of type `_Up`
+ * @param __a An allocator.
+ * @param __p Pointer to memory of suitable size and alignment for
+ * an object of type `_Up`.
+ * @param __args Constructor arguments.
+ *
+ * Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
+ * in C++11, C++14 and C++17. Changed in C++20 to call
+ * `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
+ */
+ template<typename _Up, typename... _Args>
+ static void
+ construct(allocator_type& __a, _Up* __p, _Args&&... __args)
+ { __a.construct(__p, std::forward<_Args>(__args)...); }
+
+ /**
+ * @brief Destroy an object of type `_Up`
+ * @param __a An allocator.
+ * @param __p Pointer to the object to destroy
+ *
+ * Calls `p->_Up()`.
+ */
+ template<typename _Up>
+ static _GLIBCXX20_CONSTEXPR void
+ destroy(allocator_type&, _Up* __p)
+ noexcept(is_nothrow_destructible<_Up>::value)
+ { __p->~_Up(); }
+
+ /**
+ * @brief The maximum supported allocation size
+ * @return `numeric_limits<size_t>::max() / sizeof(value_type)`
+ */
+ static _GLIBCXX20_CONSTEXPR size_type
+ max_size(const allocator_type&) noexcept
+ { return size_t(-1) / sizeof(value_type); }
+ };
+
+namespace pmr
+{
/// Parameters for tuning a pool resource's behaviour.
struct pool_options
{
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-08-03 15:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-03 15:34 [committed] libstdc++: Specialize allocator_traits<pmr::polymorphic_allocator<T>> Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).