diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2015-07-01 13:24:09 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2015-07-01 13:24:09 +0100 |
commit | 7946683835932333aafd231f140b1e8812137bfb (patch) | |
tree | c9a4fa80f7b0e895d8e2fdc59cfd42a9bddc9bbc | |
parent | 4f44c5556fc384b57ea0c8c6908701bb5f1c4ed4 (diff) | |
download | gcc-7946683835932333aafd231f140b1e8812137bfb.zip gcc-7946683835932333aafd231f140b1e8812137bfb.tar.gz gcc-7946683835932333aafd231f140b1e8812137bfb.tar.bz2 |
alloc_traits.h (__alloctr_rebind): Remove.
* include/bits/alloc_traits.h (__alloctr_rebind): Remove.
(__allocator_traits_base): New base class.
(__alloc_rebind): Reimplement in terms of detection idiom.
(allocator_traits): Derive from __allocator_traits_base. Reimplement
nested types in terms of detection idiom. Simplify SFINAE constraints
on overloaded static member functions.
* include/bits/hashtable.h (_Hashtable): Use __alloc_rebind instead
of __alloctr_rebind.
* testsuite/20_util/scoped_allocator/propagation.cc: Define rebind.
* testsuite/23_containers/unordered_set/instantiation_neg.cc: Adjust
dg-error line number.
From-SVN: r225244
-rw-r--r-- | libstdc++-v3/ChangeLog | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/alloc_traits.h | 260 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/hashtable.h | 9 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/scoped_allocator/propagation.cc | 4 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc | 2 |
5 files changed, 103 insertions, 184 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f7ea928..e87c303 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,17 @@ 2015-07-01 Jonathan Wakely <jwakely@redhat.com> + * include/bits/alloc_traits.h (__alloctr_rebind): Remove. + (__allocator_traits_base): New base class. + (__alloc_rebind): Reimplement in terms of detection idiom. + (allocator_traits): Derive from __allocator_traits_base. Reimplement + nested types in terms of detection idiom. Simplify SFINAE constraints + on overloaded static member functions. + * include/bits/hashtable.h (_Hashtable): Use __alloc_rebind instead + of __alloctr_rebind. + * testsuite/20_util/scoped_allocator/propagation.cc: Define rebind. + * testsuite/23_containers/unordered_set/instantiation_neg.cc: Adjust + dg-error line number. + * include/bits/ptr_traits.h (__ptrtr_elt_type, __ptrtr_diff_type, __ptrtr_rebind, __ptrtr_not_void): Remove (__get_first_arg, __replace_first_arg, __make_not_void): Define new diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h index bb98c1d..e5ed92b 100644 --- a/libstdc++-v3/include/bits/alloc_traits.h +++ b/libstdc++-v3/include/bits/alloc_traits.h @@ -40,72 +40,57 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - template<typename _Alloc, typename _Tp> - class __alloctr_rebind_helper - { - template<typename _Alloc2, typename _Tp2> - static constexpr true_type - _S_chk(typename _Alloc2::template rebind<_Tp2>::other*); - - template<typename, typename> - static constexpr false_type - _S_chk(...); - - public: - using __type = decltype(_S_chk<_Alloc, _Tp>(nullptr)); - }; - - template<typename _Alloc, typename _Tp, - bool = __alloctr_rebind_helper<_Alloc, _Tp>::__type::value> - struct __alloctr_rebind; - - template<typename _Alloc, typename _Tp> - struct __alloctr_rebind<_Alloc, _Tp, true> - { - typedef typename _Alloc::template rebind<_Tp>::other __type; - }; - - template<template<typename, typename...> class _Alloc, typename _Tp, - typename _Up, typename... _Args> - struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp, false> - { - typedef _Alloc<_Tp, _Args...> __type; - }; - - template<typename _Alloc, typename _Tp> - using __alloc_rebind = typename __alloctr_rebind<_Alloc, _Tp>::__type; + struct __allocator_traits_base + { + template<typename _Alloc, typename _Up> + using __rebind = typename _Alloc::template rebind<_Up>::other; + + protected: + template<typename _Tp> + using __pointer = typename _Tp::pointer; + template<typename _Tp> + using __c_pointer = typename _Tp::const_pointer; + template<typename _Tp> + using __v_pointer = typename _Tp::void_pointer; + template<typename _Tp> + using __cv_pointer = typename _Tp::const_void_pointer; + template<typename _Tp> + using __diff_type = typename _Tp::difference_type; + template<typename _Tp> + using __size_type = typename _Tp::size_type; + template<typename _Tp> + using __pocca = typename _Tp::propagate_on_container_copy_assignment; + template<typename _Tp> + using __pocma = typename _Tp::propagate_on_container_move_assignment; + template<typename _Tp> + using __pocs = typename _Tp::propagate_on_container_swap; + template<typename _Tp> + using __equal = typename _Tp::is_always_equal; + }; + + template<typename _Alloc, typename _Up> + using __alloc_rebind = __detected_or_t_<__replace_first_arg_t, + __allocator_traits_base::__rebind, + _Alloc, _Up>; /** * @brief Uniform interface to all allocator types. * @ingroup allocators */ template<typename _Alloc> - struct allocator_traits + struct allocator_traits : __allocator_traits_base { /// The allocator type typedef _Alloc allocator_type; /// The allocated type typedef typename _Alloc::value_type value_type; -#define _GLIBCXX_ALLOC_TR_NESTED_TYPE(_NTYPE, _ALT) \ - private: \ - template<typename _Tp> \ - static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \ - static _ALT _S_##_NTYPE##_helper(...); \ - typedef decltype(_S_##_NTYPE##_helper((_Alloc*)0)) __##_NTYPE; \ - public: - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(pointer, value_type*) - /** * @brief The allocator's pointer type. * * @c Alloc::pointer if that type exists, otherwise @c value_type* */ - typedef __pointer pointer; - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_pointer, - typename pointer_traits<pointer>::template rebind<const value_type>) + using pointer = __detected_or_t<value_type*, __pointer, _Alloc>; /** * @brief The allocator's const pointer type. @@ -113,10 +98,9 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(const_pointer, * @c Alloc::const_pointer if that type exists, otherwise * <tt> pointer_traits<pointer>::rebind<const value_type> </tt> */ - typedef __const_pointer const_pointer; - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(void_pointer, - typename pointer_traits<pointer>::template rebind<void>) + using const_pointer + = __detected_or_t<__ptr_rebind<pointer, const value_type>, + __c_pointer, _Alloc>; /** * @brief The allocator's void pointer type. @@ -124,10 +108,8 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(void_pointer, * @c Alloc::void_pointer if that type exists, otherwise * <tt> pointer_traits<pointer>::rebind<void> </tt> */ - typedef __void_pointer void_pointer; - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_void_pointer, - typename pointer_traits<pointer>::template rebind<const void>) + using void_pointer + = __detected_or_t<__ptr_rebind<pointer, void>, __v_pointer, _Alloc>; /** * @brief The allocator's const void pointer type. @@ -135,10 +117,9 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(const_void_pointer, * @c Alloc::const_void_pointer if that type exists, otherwise * <tt> pointer_traits<pointer>::rebind<const void> </tt> */ - typedef __const_void_pointer const_void_pointer; - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type, - typename pointer_traits<pointer>::difference_type) + using const_void_pointer + = __detected_or_t<__ptr_rebind<pointer, const void>, __cv_pointer, + _Alloc>; /** * @brief The allocator's difference type @@ -146,10 +127,9 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type, * @c Alloc::difference_type if that type exists, otherwise * <tt> pointer_traits<pointer>::difference_type </tt> */ - typedef __difference_type difference_type; - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type, - typename make_unsigned<difference_type>::type) + using difference_type + = __detected_or_t<typename pointer_traits<pointer>::difference_type, + __diff_type, _Alloc>; /** * @brief The allocator's size type @@ -157,10 +137,9 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type, * @c Alloc::size_type if that type exists, otherwise * <tt> make_unsigned<difference_type>::type </tt> */ - typedef __size_type size_type; - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment, - false_type) + using size_type + = __detected_or_t<typename make_unsigned<difference_type>::type, + __size_type, _Alloc>; /** * @brief How the allocator is propagated on copy assignment @@ -168,11 +147,8 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment, * @c Alloc::propagate_on_container_copy_assignment if that type exists, * otherwise @c false_type */ - typedef __propagate_on_container_copy_assignment - propagate_on_container_copy_assignment; - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment, - false_type) + using propagate_on_container_copy_assignment + = __detected_or_t<false_type, __pocca, _Alloc>; /** * @brief How the allocator is propagated on move assignment @@ -180,11 +156,8 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment, * @c Alloc::propagate_on_container_move_assignment if that type exists, * otherwise @c false_type */ - typedef __propagate_on_container_move_assignment - propagate_on_container_move_assignment; - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, - false_type) + using propagate_on_container_move_assignment + = __detected_or_t<false_type, __pocma, _Alloc>; /** * @brief How the allocator is propagated on swap @@ -192,10 +165,8 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, * @c Alloc::propagate_on_container_swap if that type exists, * otherwise @c false_type */ - typedef __propagate_on_container_swap propagate_on_container_swap; - -_GLIBCXX_ALLOC_TR_NESTED_TYPE(is_always_equal, - typename is_empty<_Alloc>::type) + using propagate_on_container_swap + = __detected_or_t<false_type, __pocs, _Alloc>; /** * @brief Whether all instances of the allocator type compare equal. @@ -203,44 +174,27 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(is_always_equal, * @c Alloc::is_always_equal if that type exists, * otherwise @c is_empty<Alloc>::type */ - typedef __is_always_equal is_always_equal; - -#undef _GLIBCXX_ALLOC_TR_NESTED_TYPE + using is_always_equal + = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>; template<typename _Tp> - using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type; + using rebind_alloc = __alloc_rebind<_Alloc, _Tp>; template<typename _Tp> using rebind_traits = allocator_traits<rebind_alloc<_Tp>>; - private: - template<typename _Alloc2> - struct __allocate_helper - { - template<typename _Alloc3, - typename = decltype(std::declval<_Alloc3*>()->allocate( - std::declval<size_type>(), - std::declval<const_void_pointer>()))> - static true_type __test(int); - - template<typename> - static false_type __test(...); - - using type = decltype(__test<_Alloc>(0)); - }; + static_assert(!is_same<rebind_alloc<value_type>, __undefined>::value, + "allocator defines rebind or is like Alloc<T, Args>"); + private: template<typename _Alloc2> - using __has_allocate = typename __allocate_helper<_Alloc2>::type; - - template<typename _Alloc2, - typename = _Require<__has_allocate<_Alloc2>>> - static pointer - _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint) + static auto + _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int) + -> decltype(__a.allocate(__n, __hint)) { return __a.allocate(__n, __hint); } - template<typename _Alloc2, typename _UnusedHint, - typename = _Require<__not_<__has_allocate<_Alloc2>>>> + template<typename _Alloc2> static pointer - _S_allocate(_Alloc2& __a, size_type __n, _UnusedHint) + _S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...) { return __a.allocate(__n); } template<typename _Tp, typename... _Args> @@ -273,57 +227,24 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(is_always_equal, _S_construct(_Alloc&, _Tp* __p, _Args&&... __args) { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); } - template<typename _Tp> - struct __destroy_helper - { - template<typename _Alloc2, - typename = decltype(std::declval<_Alloc2*>()->destroy( - std::declval<_Tp*>()))> - static true_type __test(int); - - template<typename> - static false_type __test(...); - - using type = decltype(__test<_Alloc>(0)); - }; - - template<typename _Tp> - using __has_destroy = typename __destroy_helper<_Tp>::type; - - template<typename _Tp> - static _Require<__has_destroy<_Tp>> - _S_destroy(_Alloc& __a, _Tp* __p) + template<typename _Alloc2, typename _Tp> + static auto + _S_destroy(_Alloc2& __a, _Tp* __p, int) + -> decltype(__a.destroy(__p)) { __a.destroy(__p); } - template<typename _Tp> - static _Require<__not_<__has_destroy<_Tp>>> - _S_destroy(_Alloc&, _Tp* __p) + template<typename _Alloc2, typename _Tp> + static void + _S_destroy(_Alloc2&, _Tp* __p, ...) { __p->~_Tp(); } template<typename _Alloc2> - struct __maxsize_helper - { - template<typename _Alloc3, - typename = decltype(std::declval<_Alloc3*>()->max_size())> - static true_type __test(int); - - template<typename> - static false_type __test(...); - - using type = decltype(__test<_Alloc2>(0)); - }; - - template<typename _Alloc2> - using __has_max_size = typename __maxsize_helper<_Alloc2>::type; - - template<typename _Alloc2, - typename = _Require<__has_max_size<_Alloc2>>> - static size_type + static auto _S_max_size(_Alloc2& __a, int) + -> decltype(__a.max_size()) { return __a.max_size(); } - template<typename _Alloc2, - typename = _Require<__not_<__has_max_size<_Alloc2>>>> + template<typename _Alloc2> static size_type _S_max_size(_Alloc2&, ...) { @@ -334,30 +255,12 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(is_always_equal, } template<typename _Alloc2> - struct __select_helper - { - template<typename _Alloc3, typename - = decltype(std::declval<_Alloc3*>() - ->select_on_container_copy_construction())> - static true_type __test(int); - - template<typename> - static false_type __test(...); - - using type = decltype(__test<_Alloc2>(0)); - }; - - template<typename _Alloc2> - using __has_soccc = typename __select_helper<_Alloc2>::type; - - template<typename _Alloc2, - typename = _Require<__has_soccc<_Alloc2>>> - static _Alloc2 + static auto _S_select(_Alloc2& __a, int) + -> decltype(__a.select_on_container_copy_construction()) { return __a.select_on_container_copy_construction(); } - template<typename _Alloc2, - typename = _Require<__not_<__has_soccc<_Alloc2>>>> + template<typename _Alloc2> static _Alloc2 _S_select(_Alloc2& __a, ...) { return __a; } @@ -388,7 +291,7 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(is_always_equal, */ static pointer allocate(_Alloc& __a, size_type __n, const_void_pointer __hint) - { return _S_allocate(__a, __n, __hint); } + { return _S_allocate(__a, __n, __hint, 0); } /** * @brief Deallocate memory. @@ -398,7 +301,8 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(is_always_equal, * * Calls <tt> a.deallocate(p, n) </tt> */ - static void deallocate(_Alloc& __a, pointer __p, size_type __n) + static void + deallocate(_Alloc& __a, pointer __p, size_type __n) { __a.deallocate(__p, __n); } /** @@ -427,7 +331,7 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(is_always_equal, */ template <class _Tp> static void destroy(_Alloc& __a, _Tp* __p) - { _S_destroy(__a, __p); } + { _S_destroy(__a, __p, 0); } /** * @brief The maximum supported allocation size diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index 31d237e..4881004 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -179,15 +179,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public __detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>, private __detail::_Hashtable_alloc< - typename __alloctr_rebind<_Alloc, - __detail::_Hash_node<_Value, - _Traits::__hash_cached::value> >::__type> + __alloc_rebind<_Alloc, + __detail::_Hash_node<_Value, + _Traits::__hash_cached::value>>> { using __traits_type = _Traits; using __hash_cached = typename __traits_type::__hash_cached; using __node_type = __detail::_Hash_node<_Value, __hash_cached::value>; - using __node_alloc_type = - typename __alloctr_rebind<_Alloc, __node_type>::__type; + using __node_alloc_type = __alloc_rebind<_Alloc, __node_type>; using __hashtable_alloc = __detail::_Hashtable_alloc<__node_alloc_type>; diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/propagation.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/propagation.cc index e1e5946..a3da6c0 100644 --- a/libstdc++-v3/testsuite/20_util/scoped_allocator/propagation.cc +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/propagation.cc @@ -41,6 +41,10 @@ template<typename T> template<typename T, bool copy, bool move, bool swap> struct test_allocator : minimal_allocator<T> { + template<typename U> + struct rebind + { using other = test_allocator<U, copy, move, swap>; }; + struct propagate_on_container_copy_assignment : std::integral_constant<bool, copy> { }; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc index 61848de..ac19900 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc @@ -19,7 +19,7 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -// { dg-error "with noexcept" "" { target *-*-* } 266 } +// { dg-error "with noexcept" "" { target *-*-* } 265 } #include <unordered_set> |