mirror of git://gcc.gnu.org/git/gcc.git
alloc_traits.h (allocator_traits::_S_allocate): Do not use varargs when argument could be non-POD.
* include/bits/alloc_traits.h (allocator_traits::_S_allocate): Do not use varargs when argument could be non-POD. (__alloctr_rebind_helper): Eliminate static const bool member by using true_type and false_type. (allocator_traits::__allocate_helper): Likewise. (allocator_traits::__construct_helper): Likewise. (allocator_traits::__destroy_helper): Likewise. (allocator_traits::__maxsize_helper): Likewise. (allocator_traits::__select_helper): Likewise. * include/bits/ptr_traits.h (__ptrtr_rebind_helper): Likewise. * include/bits/stl_tree.h (_Rb_tree::operator=(const _Rb_tree&)): Remove redundant condition. * include/bits/stl_vector.h (vector::operator=(const vector&)): Likewise. (_Vector_impl::_M_allocate, _Vector_impl::_M_deallocate): Use indirection through __alloc_traits. * include/ext/alloc_traits.h (__allocator_always_compares_equal): Eliminate static const bool members by using true_type and false_type. (__gnu_cxx::__alloc_traits::__is_custom_pointer): Optimize. * testsuite/util/testsuite_allocator.h (PointerBase): Define. * testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc: New. * testsuite/20_util/allocator_traits/requirements/typedefs2.cc: New. From-SVN: r207240
This commit is contained in:
parent
77574c3534
commit
200674232e
|
|
@ -1,3 +1,29 @@
|
||||||
|
2014-01-28 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
* include/bits/alloc_traits.h (allocator_traits::_S_allocate): Do
|
||||||
|
not use varargs when argument could be non-POD.
|
||||||
|
(__alloctr_rebind_helper): Eliminate static const bool member by
|
||||||
|
using true_type and false_type.
|
||||||
|
(allocator_traits::__allocate_helper): Likewise.
|
||||||
|
(allocator_traits::__construct_helper): Likewise.
|
||||||
|
(allocator_traits::__destroy_helper): Likewise.
|
||||||
|
(allocator_traits::__maxsize_helper): Likewise.
|
||||||
|
(allocator_traits::__select_helper): Likewise.
|
||||||
|
* include/bits/ptr_traits.h (__ptrtr_rebind_helper): Likewise.
|
||||||
|
* include/bits/stl_tree.h (_Rb_tree::operator=(const _Rb_tree&)):
|
||||||
|
Remove redundant condition.
|
||||||
|
* include/bits/stl_vector.h (vector::operator=(const vector&)):
|
||||||
|
Likewise.
|
||||||
|
(_Vector_impl::_M_allocate, _Vector_impl::_M_deallocate): Use
|
||||||
|
indirection through __alloc_traits.
|
||||||
|
* include/ext/alloc_traits.h (__allocator_always_compares_equal):
|
||||||
|
Eliminate static const bool members by using true_type and false_type.
|
||||||
|
(__gnu_cxx::__alloc_traits::__is_custom_pointer): Optimize.
|
||||||
|
* testsuite/util/testsuite_allocator.h (PointerBase): Define.
|
||||||
|
* testsuite/20_util/allocator_traits/members/allocate_hint_nonpod.cc:
|
||||||
|
New.
|
||||||
|
* testsuite/20_util/allocator_traits/requirements/typedefs2.cc: New.
|
||||||
|
|
||||||
2014-01-28 Jonathan Wakely <jwakely@redhat.com>
|
2014-01-28 Jonathan Wakely <jwakely@redhat.com>
|
||||||
Kyle Lippincott <spectral@google.com>
|
Kyle Lippincott <spectral@google.com>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,24 +44,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
class __alloctr_rebind_helper
|
class __alloctr_rebind_helper
|
||||||
{
|
{
|
||||||
template<typename _Alloc2, typename _Tp2>
|
template<typename _Alloc2, typename _Tp2>
|
||||||
static constexpr bool
|
static constexpr true_type
|
||||||
_S_chk(typename _Alloc2::template rebind<_Tp2>::other*)
|
_S_chk(typename _Alloc2::template rebind<_Tp2>::other*);
|
||||||
{ return true; }
|
|
||||||
|
|
||||||
template<typename, typename>
|
template<typename, typename>
|
||||||
static constexpr bool
|
static constexpr false_type
|
||||||
_S_chk(...)
|
_S_chk(...);
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const bool __value = _S_chk<_Alloc, _Tp>(nullptr);
|
using __type = decltype(_S_chk<_Alloc, _Tp>(nullptr));
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Alloc, typename _Tp>
|
|
||||||
const bool __alloctr_rebind_helper<_Alloc, _Tp>::__value;
|
|
||||||
|
|
||||||
template<typename _Alloc, typename _Tp,
|
template<typename _Alloc, typename _Tp,
|
||||||
bool = __alloctr_rebind_helper<_Alloc, _Tp>::__value>
|
bool = __alloctr_rebind_helper<_Alloc, _Tp>::__type::value>
|
||||||
struct __alloctr_rebind;
|
struct __alloctr_rebind;
|
||||||
|
|
||||||
template<typename _Alloc, typename _Tp>
|
template<typename _Alloc, typename _Tp>
|
||||||
|
|
@ -71,7 +66,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename, typename...> class _Alloc, typename _Tp,
|
template<template<typename, typename...> class _Alloc, typename _Tp,
|
||||||
typename _Up, typename... _Args>
|
typename _Up, typename... _Args>
|
||||||
struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp, false>
|
struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp, false>
|
||||||
{
|
{
|
||||||
typedef _Alloc<_Tp, _Args...> __type;
|
typedef _Alloc<_Tp, _Args...> __type;
|
||||||
|
|
@ -140,7 +135,7 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(const_void_pointer,
|
||||||
typedef __const_void_pointer const_void_pointer;
|
typedef __const_void_pointer const_void_pointer;
|
||||||
|
|
||||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type,
|
_GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type,
|
||||||
typename pointer_traits<pointer>::difference_type)
|
typename pointer_traits<pointer>::difference_type)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The allocator's difference type
|
* @brief The allocator's difference type
|
||||||
|
|
@ -151,7 +146,7 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type,
|
||||||
typedef __difference_type difference_type;
|
typedef __difference_type difference_type;
|
||||||
|
|
||||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type,
|
_GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type,
|
||||||
typename make_unsigned<difference_type>::type)
|
typename make_unsigned<difference_type>::type)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The allocator's size type
|
* @brief The allocator's size type
|
||||||
|
|
@ -162,7 +157,7 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type,
|
||||||
typedef __size_type size_type;
|
typedef __size_type size_type;
|
||||||
|
|
||||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment,
|
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment,
|
||||||
false_type)
|
false_type)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief How the allocator is propagated on copy assignment
|
* @brief How the allocator is propagated on copy assignment
|
||||||
|
|
@ -171,10 +166,10 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment,
|
||||||
* otherwise @c false_type
|
* otherwise @c false_type
|
||||||
*/
|
*/
|
||||||
typedef __propagate_on_container_copy_assignment
|
typedef __propagate_on_container_copy_assignment
|
||||||
propagate_on_container_copy_assignment;
|
propagate_on_container_copy_assignment;
|
||||||
|
|
||||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment,
|
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment,
|
||||||
false_type)
|
false_type)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief How the allocator is propagated on move assignment
|
* @brief How the allocator is propagated on move assignment
|
||||||
|
|
@ -183,10 +178,10 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment,
|
||||||
* otherwise @c false_type
|
* otherwise @c false_type
|
||||||
*/
|
*/
|
||||||
typedef __propagate_on_container_move_assignment
|
typedef __propagate_on_container_move_assignment
|
||||||
propagate_on_container_move_assignment;
|
propagate_on_container_move_assignment;
|
||||||
|
|
||||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||||
false_type)
|
false_type)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief How the allocator is propagated on swap
|
* @brief How the allocator is propagated on swap
|
||||||
|
|
@ -199,9 +194,9 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||||
#undef _GLIBCXX_ALLOC_TR_NESTED_TYPE
|
#undef _GLIBCXX_ALLOC_TR_NESTED_TYPE
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type;
|
using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type;
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
|
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename _Alloc2>
|
template<typename _Alloc2>
|
||||||
|
|
@ -216,20 +211,22 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||||
template<typename>
|
template<typename>
|
||||||
static false_type __test(...);
|
static false_type __test(...);
|
||||||
|
|
||||||
typedef decltype(__test<_Alloc>(0)) type;
|
using type = decltype(__test<_Alloc>(0));
|
||||||
static const bool value = type::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Alloc2>
|
template<typename _Alloc2>
|
||||||
static typename
|
using __has_allocate = typename __allocate_helper<_Alloc2>::type;
|
||||||
enable_if<__allocate_helper<_Alloc2>::value, pointer>::type
|
|
||||||
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint)
|
template<typename _Alloc2,
|
||||||
|
typename = _Require<__has_allocate<_Alloc2>>>
|
||||||
|
static pointer
|
||||||
|
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint)
|
||||||
{ return __a.allocate(__n, __hint); }
|
{ return __a.allocate(__n, __hint); }
|
||||||
|
|
||||||
template<typename _Alloc2>
|
template<typename _Alloc2, typename _UnusedHint,
|
||||||
static typename
|
typename = _Require<__not_<__has_allocate<_Alloc2>>>>
|
||||||
enable_if<!__allocate_helper<_Alloc2>::value, pointer>::type
|
static pointer
|
||||||
_S_allocate(_Alloc2& __a, size_type __n, ...)
|
_S_allocate(_Alloc2& __a, size_type __n, _UnusedHint)
|
||||||
{ return __a.allocate(__n); }
|
{ return __a.allocate(__n); }
|
||||||
|
|
||||||
template<typename _Tp, typename... _Args>
|
template<typename _Tp, typename... _Args>
|
||||||
|
|
@ -243,21 +240,23 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||||
template<typename>
|
template<typename>
|
||||||
static false_type __test(...);
|
static false_type __test(...);
|
||||||
|
|
||||||
typedef decltype(__test<_Alloc>(0)) type;
|
using type = decltype(__test<_Alloc>(0));
|
||||||
static const bool value = type::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Tp, typename... _Args>
|
template<typename _Tp, typename... _Args>
|
||||||
static typename
|
using __has_construct
|
||||||
enable_if<__construct_helper<_Tp, _Args...>::value, void>::type
|
= typename __construct_helper<_Tp, _Args...>::type;
|
||||||
_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
|
|
||||||
|
template<typename _Tp, typename... _Args>
|
||||||
|
static _Require<__has_construct<_Tp, _Args...>>
|
||||||
|
_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
|
||||||
{ __a.construct(__p, std::forward<_Args>(__args)...); }
|
{ __a.construct(__p, std::forward<_Args>(__args)...); }
|
||||||
|
|
||||||
template<typename _Tp, typename... _Args>
|
template<typename _Tp, typename... _Args>
|
||||||
static typename
|
static
|
||||||
enable_if<__and_<__not_<__construct_helper<_Tp, _Args...>>,
|
_Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
|
||||||
is_constructible<_Tp, _Args...>>::value, void>::type
|
is_constructible<_Tp, _Args...>>>
|
||||||
_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
|
_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
|
||||||
{ ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
|
{ ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
|
|
@ -271,18 +270,20 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||||
template<typename>
|
template<typename>
|
||||||
static false_type __test(...);
|
static false_type __test(...);
|
||||||
|
|
||||||
typedef decltype(__test<_Alloc>(0)) type;
|
using type = decltype(__test<_Alloc>(0));
|
||||||
static const bool value = type::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
static typename enable_if<__destroy_helper<_Tp>::value, void>::type
|
using __has_destroy = typename __destroy_helper<_Tp>::type;
|
||||||
_S_destroy(_Alloc& __a, _Tp* __p)
|
|
||||||
|
template<typename _Tp>
|
||||||
|
static _Require<__has_destroy<_Tp>>
|
||||||
|
_S_destroy(_Alloc& __a, _Tp* __p)
|
||||||
{ __a.destroy(__p); }
|
{ __a.destroy(__p); }
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
static typename enable_if<!__destroy_helper<_Tp>::value, void>::type
|
static _Require<__not_<__has_destroy<_Tp>>>
|
||||||
_S_destroy(_Alloc&, _Tp* __p)
|
_S_destroy(_Alloc&, _Tp* __p)
|
||||||
{ __p->~_Tp(); }
|
{ __p->~_Tp(); }
|
||||||
|
|
||||||
template<typename _Alloc2>
|
template<typename _Alloc2>
|
||||||
|
|
@ -295,20 +296,22 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||||
template<typename>
|
template<typename>
|
||||||
static false_type __test(...);
|
static false_type __test(...);
|
||||||
|
|
||||||
typedef decltype(__test<_Alloc2>(0)) type;
|
using type = decltype(__test<_Alloc2>(0));
|
||||||
static const bool value = type::value;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Alloc2>
|
template<typename _Alloc2>
|
||||||
static typename
|
using __has_max_size = typename __maxsize_helper<_Alloc2>::type;
|
||||||
enable_if<__maxsize_helper<_Alloc2>::value, size_type>::type
|
|
||||||
_S_max_size(_Alloc2& __a)
|
template<typename _Alloc2,
|
||||||
|
typename = _Require<__has_max_size<_Alloc2>>>
|
||||||
|
static size_type
|
||||||
|
_S_max_size(_Alloc2& __a, int)
|
||||||
{ return __a.max_size(); }
|
{ return __a.max_size(); }
|
||||||
|
|
||||||
template<typename _Alloc2>
|
template<typename _Alloc2,
|
||||||
static typename
|
typename = _Require<__not_<__has_max_size<_Alloc2>>>>
|
||||||
enable_if<!__maxsize_helper<_Alloc2>::value, size_type>::type
|
static size_type
|
||||||
_S_max_size(_Alloc2&)
|
_S_max_size(_Alloc2&, ...)
|
||||||
{ return __gnu_cxx::__numeric_traits<size_type>::__max; }
|
{ return __gnu_cxx::__numeric_traits<size_type>::__max; }
|
||||||
|
|
||||||
template<typename _Alloc2>
|
template<typename _Alloc2>
|
||||||
|
|
@ -322,19 +325,22 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||||
template<typename>
|
template<typename>
|
||||||
static false_type __test(...);
|
static false_type __test(...);
|
||||||
|
|
||||||
typedef decltype(__test<_Alloc2>(0)) type;
|
using type = decltype(__test<_Alloc2>(0));
|
||||||
static const bool value = type::value;
|
|
||||||
};
|
};
|
||||||
template<typename _Alloc2>
|
|
||||||
static typename
|
|
||||||
enable_if<__select_helper<_Alloc2>::value, _Alloc2>::type
|
|
||||||
_S_select(_Alloc2& __a)
|
|
||||||
{ return __a.select_on_container_copy_construction(); }
|
|
||||||
|
|
||||||
template<typename _Alloc2>
|
template<typename _Alloc2>
|
||||||
static typename
|
using __has_soccc = typename __select_helper<_Alloc2>::type;
|
||||||
enable_if<!__select_helper<_Alloc2>::value, _Alloc2>::type
|
|
||||||
_S_select(_Alloc2& __a)
|
template<typename _Alloc2,
|
||||||
|
typename = _Require<__has_soccc<_Alloc2>>>
|
||||||
|
static _Alloc2
|
||||||
|
_S_select(_Alloc2& __a, int)
|
||||||
|
{ return __a.select_on_container_copy_construction(); }
|
||||||
|
|
||||||
|
template<typename _Alloc2,
|
||||||
|
typename = _Require<__not_<__has_soccc<_Alloc2>>>>
|
||||||
|
static _Alloc2
|
||||||
|
_S_select(_Alloc2& __a, ...)
|
||||||
{ return __a; }
|
{ return __a; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -413,7 +419,7 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||||
* otherwise returns @c numeric_limits<size_type>::max()
|
* otherwise returns @c numeric_limits<size_type>::max()
|
||||||
*/
|
*/
|
||||||
static size_type max_size(const _Alloc& __a) noexcept
|
static size_type max_size(const _Alloc& __a) noexcept
|
||||||
{ return _S_max_size(__a); }
|
{ return _S_max_size(__a, 0); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Obtain an allocator to use when copying a container.
|
* @brief Obtain an allocator to use when copying a container.
|
||||||
|
|
@ -425,30 +431,9 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||||
*/
|
*/
|
||||||
static _Alloc
|
static _Alloc
|
||||||
select_on_container_copy_construction(const _Alloc& __rhs)
|
select_on_container_copy_construction(const _Alloc& __rhs)
|
||||||
{ return _S_select(__rhs); }
|
{ return _S_select(__rhs, 0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Alloc>
|
|
||||||
template<typename _Alloc2>
|
|
||||||
const bool allocator_traits<_Alloc>::__allocate_helper<_Alloc2>::value;
|
|
||||||
|
|
||||||
template<typename _Alloc>
|
|
||||||
template<typename _Tp, typename... _Args>
|
|
||||||
const bool
|
|
||||||
allocator_traits<_Alloc>::__construct_helper<_Tp, _Args...>::value;
|
|
||||||
|
|
||||||
template<typename _Alloc>
|
|
||||||
template<typename _Tp>
|
|
||||||
const bool allocator_traits<_Alloc>::__destroy_helper<_Tp>::value;
|
|
||||||
|
|
||||||
template<typename _Alloc>
|
|
||||||
template<typename _Alloc2>
|
|
||||||
const bool allocator_traits<_Alloc>::__maxsize_helper<_Alloc2>::value;
|
|
||||||
|
|
||||||
template<typename _Alloc>
|
|
||||||
template<typename _Alloc2>
|
|
||||||
const bool allocator_traits<_Alloc>::__select_helper<_Alloc2>::value;
|
|
||||||
|
|
||||||
template<typename _Alloc>
|
template<typename _Alloc>
|
||||||
inline void
|
inline void
|
||||||
__do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
|
__do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
|
||||||
|
|
|
||||||
|
|
@ -73,24 +73,19 @@ _GLIBCXX_HAS_NESTED_TYPE(difference_type)
|
||||||
class __ptrtr_rebind_helper
|
class __ptrtr_rebind_helper
|
||||||
{
|
{
|
||||||
template<typename _Ptr2, typename _Up2>
|
template<typename _Ptr2, typename _Up2>
|
||||||
static constexpr bool
|
static constexpr true_type
|
||||||
_S_chk(typename _Ptr2::template rebind<_Up2>*)
|
_S_chk(typename _Ptr2::template rebind<_Up2>*);
|
||||||
{ return true; }
|
|
||||||
|
|
||||||
template<typename, typename>
|
template<typename, typename>
|
||||||
static constexpr bool
|
static constexpr false_type
|
||||||
_S_chk(...)
|
_S_chk(...);
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const bool __value = _S_chk<_Ptr, _Up>(nullptr);
|
using __type = decltype(_S_chk<_Ptr, _Up>(nullptr));
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Ptr, typename _Up>
|
|
||||||
const bool __ptrtr_rebind_helper<_Ptr, _Up>::__value;
|
|
||||||
|
|
||||||
template<typename _Tp, typename _Up,
|
template<typename _Tp, typename _Up,
|
||||||
bool = __ptrtr_rebind_helper<_Tp, _Up>::__value>
|
bool = __ptrtr_rebind_helper<_Tp, _Up>::__type::value>
|
||||||
struct __ptrtr_rebind;
|
struct __ptrtr_rebind;
|
||||||
|
|
||||||
template<typename _Tp, typename _Up>
|
template<typename _Tp, typename _Up>
|
||||||
|
|
|
||||||
|
|
@ -1080,9 +1080,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
clear();
|
clear();
|
||||||
if (__x._M_root() != 0)
|
if (__x._M_root() != 0)
|
||||||
_M_move_data(__x, std::true_type());
|
_M_move_data(__x, std::true_type());
|
||||||
if (_Alloc_traits::_S_propagate_on_move_assign())
|
std::__alloc_on_move(_M_get_Node_allocator(),
|
||||||
std::__alloc_on_move(_M_get_Node_allocator(),
|
__x._M_get_Node_allocator());
|
||||||
__x._M_get_Node_allocator());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -165,13 +165,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
|
|
||||||
pointer
|
pointer
|
||||||
_M_allocate(size_t __n)
|
_M_allocate(size_t __n)
|
||||||
{ return __n != 0 ? _M_impl.allocate(__n) : 0; }
|
{
|
||||||
|
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
|
||||||
|
return __n != 0 ? _Tr::allocate(_M_impl, __n) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_M_deallocate(pointer __p, size_t __n)
|
_M_deallocate(pointer __p, size_t __n)
|
||||||
{
|
{
|
||||||
|
typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
|
||||||
if (__p)
|
if (__p)
|
||||||
_M_impl.deallocate(__p, __n);
|
_Tr::deallocate(_M_impl, __p, __n);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -1446,9 +1450,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||||
vector __tmp(get_allocator());
|
vector __tmp(get_allocator());
|
||||||
this->_M_impl._M_swap_data(__tmp._M_impl);
|
this->_M_impl._M_swap_data(__tmp._M_impl);
|
||||||
this->_M_impl._M_swap_data(__x._M_impl);
|
this->_M_impl._M_swap_data(__x._M_impl);
|
||||||
if (_Alloc_traits::_S_propagate_on_move_assign())
|
std::__alloc_on_move(_M_get_Tp_allocator(), __x._M_get_Tp_allocator());
|
||||||
std::__alloc_on_move(_M_get_Tp_allocator(),
|
|
||||||
__x._M_get_Tp_allocator());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do move assignment when it might not be possible to move source
|
// Do move assignment when it might not be possible to move source
|
||||||
|
|
|
||||||
|
|
@ -44,73 +44,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
template<typename _Alloc>
|
template<typename _Alloc>
|
||||||
struct __allocator_always_compares_equal
|
struct __allocator_always_compares_equal : std::false_type { };
|
||||||
{ static const bool value = false; };
|
|
||||||
|
|
||||||
template<typename _Alloc>
|
|
||||||
const bool __allocator_always_compares_equal<_Alloc>::value;
|
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct __allocator_always_compares_equal<std::allocator<_Tp>>
|
struct __allocator_always_compares_equal<std::allocator<_Tp>>
|
||||||
{ static const bool value = true; };
|
: std::true_type { };
|
||||||
|
|
||||||
template<typename _Tp>
|
|
||||||
const bool __allocator_always_compares_equal<std::allocator<_Tp>>::value;
|
|
||||||
|
|
||||||
template<typename, typename> struct array_allocator;
|
template<typename, typename> struct array_allocator;
|
||||||
|
|
||||||
template<typename _Tp, typename _Array>
|
template<typename _Tp, typename _Array>
|
||||||
struct __allocator_always_compares_equal<array_allocator<_Tp, _Array>>
|
struct __allocator_always_compares_equal<array_allocator<_Tp, _Array>>
|
||||||
{ static const bool value = true; };
|
: std::true_type { };
|
||||||
|
|
||||||
template<typename _Tp, typename _Array>
|
|
||||||
const bool
|
|
||||||
__allocator_always_compares_equal<array_allocator<_Tp, _Array>>::value;
|
|
||||||
|
|
||||||
template<typename> struct bitmap_allocator;
|
template<typename> struct bitmap_allocator;
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct __allocator_always_compares_equal<bitmap_allocator<_Tp>>
|
struct __allocator_always_compares_equal<bitmap_allocator<_Tp>>
|
||||||
{ static const bool value = true; };
|
: std::true_type { };
|
||||||
|
|
||||||
template<typename _Tp>
|
|
||||||
const bool __allocator_always_compares_equal<bitmap_allocator<_Tp>>::value;
|
|
||||||
|
|
||||||
template<typename> struct malloc_allocator;
|
template<typename> struct malloc_allocator;
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct __allocator_always_compares_equal<malloc_allocator<_Tp>>
|
struct __allocator_always_compares_equal<malloc_allocator<_Tp>>
|
||||||
{ static const bool value = true; };
|
: std::true_type { };
|
||||||
|
|
||||||
template<typename _Tp>
|
|
||||||
const bool __allocator_always_compares_equal<malloc_allocator<_Tp>>::value;
|
|
||||||
|
|
||||||
template<typename> struct mt_allocator;
|
template<typename> struct mt_allocator;
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct __allocator_always_compares_equal<mt_allocator<_Tp>>
|
struct __allocator_always_compares_equal<mt_allocator<_Tp>>
|
||||||
{ static const bool value = true; };
|
: std::true_type { };
|
||||||
|
|
||||||
template<typename _Tp>
|
|
||||||
const bool __allocator_always_compares_equal<mt_allocator<_Tp>>::value;
|
|
||||||
|
|
||||||
template<typename> struct new_allocator;
|
template<typename> struct new_allocator;
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct __allocator_always_compares_equal<new_allocator<_Tp>>
|
struct __allocator_always_compares_equal<new_allocator<_Tp>>
|
||||||
{ static const bool value = true; };
|
: std::true_type { };
|
||||||
|
|
||||||
template<typename _Tp>
|
|
||||||
const bool __allocator_always_compares_equal<new_allocator<_Tp>>::value;
|
|
||||||
|
|
||||||
template<typename> struct pool_allocator;
|
template<typename> struct pool_allocator;
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
struct __allocator_always_compares_equal<pool_allocator<_Tp>>
|
struct __allocator_always_compares_equal<pool_allocator<_Tp>>
|
||||||
{ static const bool value = true; };
|
: std::true_type { };
|
||||||
|
|
||||||
template<typename _Tp>
|
|
||||||
const bool __allocator_always_compares_equal<pool_allocator<_Tp>>::value;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -131,7 +105,7 @@ template<typename _Alloc>
|
||||||
typedef typename _Base_type::const_pointer const_pointer;
|
typedef typename _Base_type::const_pointer const_pointer;
|
||||||
typedef typename _Base_type::size_type size_type;
|
typedef typename _Base_type::size_type size_type;
|
||||||
typedef typename _Base_type::difference_type difference_type;
|
typedef typename _Base_type::difference_type difference_type;
|
||||||
// C++0x allocators do not define reference or const_reference
|
// C++11 allocators do not define reference or const_reference
|
||||||
typedef value_type& reference;
|
typedef value_type& reference;
|
||||||
typedef const value_type& const_reference;
|
typedef const value_type& const_reference;
|
||||||
using _Base_type::allocate;
|
using _Base_type::allocate;
|
||||||
|
|
@ -142,10 +116,9 @@ template<typename _Alloc>
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename _Ptr>
|
template<typename _Ptr>
|
||||||
struct __is_custom_pointer
|
using __is_custom_pointer
|
||||||
: std::integral_constant<bool, std::is_same<pointer, _Ptr>::value
|
= std::__and_<std::is_same<pointer, _Ptr>,
|
||||||
&& !std::is_pointer<_Ptr>::value>
|
std::__not_<std::is_pointer<_Ptr>>>;
|
||||||
{ };
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// overload construct for non-standard pointer types
|
// overload construct for non-standard pointer types
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
// { dg-options "-std=gnu++11" }
|
||||||
|
|
||||||
|
// Copyright (C) 2014 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
// User-defined pointer type with non-trivial destructor.
|
||||||
|
template<typename T>
|
||||||
|
struct Pointer : __gnu_test::PointerBase<Pointer<T>, T>
|
||||||
|
{
|
||||||
|
using __gnu_test::PointerBase<Pointer<T>, T>::PointerBase;
|
||||||
|
|
||||||
|
~Pointer() { /* non-trivial */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Minimal allocator with user-defined pointer type.
|
||||||
|
template<typename T>
|
||||||
|
struct Alloc
|
||||||
|
{
|
||||||
|
typedef T value_type;
|
||||||
|
typedef Pointer<T> pointer;
|
||||||
|
|
||||||
|
Alloc() = default;
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
Alloc(const Alloc<U>&) { }
|
||||||
|
|
||||||
|
pointer allocate(std::size_t n) // does not take a hint
|
||||||
|
{ return pointer(std::allocator<T>().allocate(n)); }
|
||||||
|
|
||||||
|
void deallocate(pointer p, std::size_t n)
|
||||||
|
{ std::allocator<T>().deallocate(p.value, n); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator==(Alloc<T> l, Alloc<T> r) { return true; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool operator!=(Alloc<T> l, Alloc<T> r) { return false; }
|
||||||
|
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
typedef std::allocator_traits<Alloc<int>> traits_type;
|
||||||
|
traits_type::allocator_type a;
|
||||||
|
traits_type::const_void_pointer v;
|
||||||
|
traits_type::pointer p = traits_type::allocate(a, 1, v);
|
||||||
|
traits_type::deallocate(a, p, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
// { dg-options "-std=gnu++11" }
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this library; see the file COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <testsuite_allocator.h>
|
||||||
|
|
||||||
|
// { dg-do compile }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ptr
|
||||||
|
{
|
||||||
|
ptr() = default;
|
||||||
|
template<typename U>
|
||||||
|
ptr(ptr<U> const& p) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
// This doesn't meet the allocator requirements, it's only to check
|
||||||
|
// that allocator_traits finds the right nested types.
|
||||||
|
template<typename T>
|
||||||
|
struct alloc
|
||||||
|
{
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
typedef ptr<T> pointer;
|
||||||
|
typedef ptr<const T> const_pointer;
|
||||||
|
typedef ptr<void> void_pointer;
|
||||||
|
typedef ptr<const void> const_void_pointer;
|
||||||
|
typedef int difference_type;
|
||||||
|
typedef int size_type;
|
||||||
|
|
||||||
|
typedef std::false_type propagate_on_container_copy_assignment;
|
||||||
|
typedef std::false_type propagate_on_container_move_assignment;
|
||||||
|
typedef std::false_type propagate_on_container_swap;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef alloc<int> alloc_type;
|
||||||
|
typedef std::allocator_traits<alloc_type> traits;
|
||||||
|
|
||||||
|
using std::is_same;
|
||||||
|
|
||||||
|
static_assert( is_same<traits::pointer, alloc_type::pointer>::value,
|
||||||
|
"pointer" );
|
||||||
|
|
||||||
|
static_assert( is_same<traits::const_pointer,
|
||||||
|
alloc_type::const_pointer>::value,
|
||||||
|
"const_pointer" );
|
||||||
|
|
||||||
|
static_assert( is_same<traits::void_pointer, alloc_type::void_pointer>::value,
|
||||||
|
"void_pointer" );
|
||||||
|
|
||||||
|
static_assert( is_same<traits::const_void_pointer,
|
||||||
|
alloc_type::const_void_pointer>::value,
|
||||||
|
"const_void_pointer");
|
||||||
|
|
||||||
|
static_assert( is_same<traits::difference_type,
|
||||||
|
alloc_type::difference_type>::value,
|
||||||
|
"difference_type" );
|
||||||
|
|
||||||
|
static_assert( is_same<traits::size_type, alloc_type::size_type>::value,
|
||||||
|
"size_type" );
|
||||||
|
|
||||||
|
static_assert( is_same<traits::size_type, alloc_type::size_type>::value,
|
||||||
|
"size_type" );
|
||||||
|
|
||||||
|
static_assert( is_same<traits::propagate_on_container_copy_assignment,
|
||||||
|
alloc_type::propagate_on_container_copy_assignment
|
||||||
|
>::value,
|
||||||
|
"propagate_on_container_copy_assignment" );
|
||||||
|
|
||||||
|
static_assert( is_same<traits::propagate_on_container_move_assignment,
|
||||||
|
alloc_type::propagate_on_container_move_assignment
|
||||||
|
>::value,
|
||||||
|
"propagate_on_container_move_assignment" );
|
||||||
|
|
||||||
|
static_assert( is_same<traits::propagate_on_container_swap,
|
||||||
|
alloc_type::propagate_on_container_swap>::value,
|
||||||
|
"propagate_on_container_swap" );
|
||||||
|
|
@ -517,6 +517,106 @@ namespace __gnu_test
|
||||||
void deallocate(pointer p, std::size_t n)
|
void deallocate(pointer p, std::size_t n)
|
||||||
{ std::allocator<Tp>::deallocate(std::addressof(*p), n); }
|
{ std::allocator<Tp>::deallocate(std::addressof(*p), n); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Utility for use as CRTP base class of custom pointer types
|
||||||
|
template<typename Derived, typename T>
|
||||||
|
struct PointerBase
|
||||||
|
{
|
||||||
|
typedef T element_type;
|
||||||
|
|
||||||
|
// typedefs for iterator_traits
|
||||||
|
typedef T value_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
|
typedef Derived pointer;
|
||||||
|
typedef T& reference;
|
||||||
|
|
||||||
|
T* value;
|
||||||
|
|
||||||
|
explicit PointerBase(T* p = nullptr) : value(p) { }
|
||||||
|
|
||||||
|
template<typename D, typename U,
|
||||||
|
typename = decltype(static_cast<T*>(std::declval<U*>()))>
|
||||||
|
PointerBase(const PointerBase<D, U>& p) : value(p.value) { }
|
||||||
|
|
||||||
|
T& operator*() const { return *value; }
|
||||||
|
T* operator->() const { return value; }
|
||||||
|
|
||||||
|
Derived& operator++() { ++value; return derived(); }
|
||||||
|
Derived operator++(int) { Derived tmp(derived()); ++value; return tmp; }
|
||||||
|
Derived& operator--() { --value; return derived(); }
|
||||||
|
Derived operator--(int) { Derived tmp(derived()); --value; return tmp; }
|
||||||
|
|
||||||
|
Derived& operator+=(difference_type n) { value += n; return derived(); }
|
||||||
|
Derived& operator-=(difference_type n) { value -= n; return derived(); }
|
||||||
|
|
||||||
|
explicit operator bool() const { return value != nullptr; }
|
||||||
|
|
||||||
|
Derived
|
||||||
|
operator+(difference_type n) const
|
||||||
|
{
|
||||||
|
Derived p(derived());
|
||||||
|
return p += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
Derived
|
||||||
|
operator-(difference_type n) const
|
||||||
|
{
|
||||||
|
Derived p(derived());
|
||||||
|
return p -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Derived& derived() { return static_cast<Derived&>(*this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename D, typename T>
|
||||||
|
std::ptrdiff_t operator-(PointerBase<D, T> l, PointerBase<D, T> r)
|
||||||
|
{ return l.value - r.value; }
|
||||||
|
|
||||||
|
template<typename D, typename T>
|
||||||
|
bool operator==(PointerBase<D, T> l, PointerBase<D, T> r)
|
||||||
|
{ return l.value == r.value; }
|
||||||
|
|
||||||
|
template<typename D, typename T>
|
||||||
|
bool operator!=(PointerBase<D, T> l, PointerBase<D, T> r)
|
||||||
|
{ return l.value != r.value; }
|
||||||
|
|
||||||
|
// implementation for void specializations
|
||||||
|
template<typename T>
|
||||||
|
struct PointerBase_void
|
||||||
|
{
|
||||||
|
typedef T element_type;
|
||||||
|
|
||||||
|
// typedefs for iterator_traits
|
||||||
|
typedef T value_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
|
|
||||||
|
T* value;
|
||||||
|
|
||||||
|
explicit PointerBase_void(T* p = nullptr) : value(p) { }
|
||||||
|
|
||||||
|
template<typename D, typename U,
|
||||||
|
typename = decltype(static_cast<T*>(std::declval<U*>()))>
|
||||||
|
PointerBase_void(const PointerBase<D, U>& p) : value(p.value) { }
|
||||||
|
|
||||||
|
explicit operator bool() const { return value != nullptr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct PointerBase<Derived, void> : PointerBase_void<void>
|
||||||
|
{
|
||||||
|
using PointerBase_void::PointerBase_void;
|
||||||
|
typedef Derived pointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
struct PointerBase<Derived, const void> : PointerBase_void<const void>
|
||||||
|
{
|
||||||
|
using PointerBase_void::PointerBase_void;
|
||||||
|
typedef Derived pointer;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace __gnu_test
|
} // namespace __gnu_test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue