commit e2405ae375e28ca1c73c2f3fd138e63ffabf610d
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Mon Jan 11 14:29:07 2016 +0000
allocator_traits<allocator<T>> partial specialization
PR libstdc++/60976
* include/bits/alloc_traits.h (allocator_traits<allocator<_Tp>>):
Define partial specialization.
* testsuite/20_util/shared_ptr/cons/58659.cc: Add construct and
destroy members to std::allocator explicit specialization.
@@ -331,7 +331,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Calls @c __a.destroy(__p) if that expression is well-formed,
* otherwise calls @c __p->~_Tp()
*/
- template <class _Tp>
+ template<typename _Tp>
static void destroy(_Alloc& __a, _Tp* __p)
{ _S_destroy(__a, __p, 0); }
@@ -359,6 +359,133 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return _S_select(__rhs, 0); }
};
+ /// Partial specialization for std::allocator.
+ template<typename _Tp>
+ struct allocator_traits<allocator<_Tp>>
+ {
+ /// The allocator type
+ using allocator_type = 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;
+
+ /// How the allocator is propagated on copy assignment
+ using propagate_on_container_copy_assignment = false_type;
+
+ /// How the allocator is propagated on move assignment
+ using propagate_on_container_move_assignment = true_type;
+
+ /// How the allocator is propagated on swap
+ using propagate_on_container_swap = false_type;
+
+ /// Whether all instances of the allocator type compare equal.
+ using is_always_equal = true_type;
+
+ template<typename _Up>
+ using rebind_alloc = allocator<_Up>;
+
+ template<typename _Up>
+ using rebind_traits = allocator_traits<allocator<_Up>>;
+
+ /**
+ * @brief Allocate memory.
+ * @param __a An allocator.
+ * @param __n The number of objects to allocate space for.
+ *
+ * Calls @c a.allocate(n)
+ */
+ 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.
+ * @param __hint Aid to locality.
+ * @return Memory of suitable size and alignment for @a n objects
+ * of type @c value_type
+ *
+ * Returns <tt> a.allocate(n, hint) </tt>
+ */
+ static pointer
+ allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
+ { return __a.allocate(__n, __hint); }
+
+ /**
+ * @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 <tt> a.deallocate(p, n) </tt>
+ */
+ static void
+ deallocate(allocator_type& __a, pointer __p, size_type __n)
+ { __a.deallocate(__p, __n); }
+
+ /**
+ * @brief Construct an object of type @a _Up
+ * @param __a An allocator.
+ * @param __p Pointer to memory of suitable size and alignment for Tp
+ * @param __args Constructor arguments.
+ *
+ * Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
+ */
+ 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 @a _Up
+ * @param __a An allocator.
+ * @param __p Pointer to the object to destroy
+ *
+ * Calls @c __a.destroy(__p).
+ */
+ template<typename _Up>
+ static void
+ destroy(allocator_type& __a, _Up* __p)
+ { __a.destroy(__p); }
+
+ /**
+ * @brief The maximum supported allocation size
+ * @param __a An allocator.
+ * @return @c __a.max_size()
+ */
+ static size_type
+ max_size(const allocator_type& __a) noexcept
+ { return __a.max_size(); }
+
+ /**
+ * @brief Obtain an allocator to use when copying a container.
+ * @param __rhs An allocator.
+ * @return @c __rhs
+ */
+ static allocator_type
+ select_on_container_copy_construction(const allocator_type& __rhs)
+ { return __rhs; }
+ };
+
+
template<typename _Alloc>
inline void
__do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
@@ -51,6 +51,14 @@ namespace std
allocated = false;
}
+ template<typename _Up, typename... _Args>
+ void construct(_Up* __p, _Args&&... __args)
+ { ::new(__p) _Up(std::forward<_Args>(__args)...); }
+
+ template<typename _Up>
+ void destroy(_Up* __p)
+ { __p->~_Up(); }
+
static char storage[sizeof(spcd)];
static bool allocated;
};