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.

From-SVN: r232232
This commit is contained in:
Jonathan Wakely 2016-01-11 16:47:58 +00:00 committed by Jonathan Wakely
parent 8c18c836db
commit 1517bc3008
3 changed files with 144 additions and 1 deletions

View File

@ -1,3 +1,11 @@
2016-01-11 Jonathan Wakely <jwakely@redhat.com>
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.
2016-01-08 Jonathan Wakely <jwakely@redhat.com>
* testsuite/26_numerics/headers/cmath/

View File

@ -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)

View File

@ -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;
};