From a6135b896a99613d340fccfce5b75c3ee877b951 Mon Sep 17 00:00:00 2001 From: redi Date: Sun, 16 Jun 2013 17:13:34 +0000 Subject: [PATCH] PR libstdc++/57263 * include/bits/forward_list.h (_Fwd_list_base): Convert to/from allocator's pointer type. * include/bits/hashtable.h (_Hashtable): Likewise. * testsuite/util/testsuite_allocator.h (CustomPointerAlloc): Add. * testsuite/23_containers/forward_list/allocator/ext_ptr.cc: New. * testsuite/23_containers/unordered_set/allocator/ext_ptr.cc: New. * testsuite/23_containers/vector/allocator/ext_ptr.cc: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200136 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 11 +++++ libstdc++-v3/include/bits/forward_list.h | 11 ++++- libstdc++-v3/include/bits/hashtable.h | 16 +++++--- .../forward_list/allocator/ext_ptr.cc | 46 +++++++++++++++++++++ .../unordered_set/allocator/ext_ptr.cc | 48 ++++++++++++++++++++++ .../23_containers/vector/allocator/ext_ptr.cc | 44 ++++++++++++++++++++ libstdc++-v3/testsuite/util/testsuite_allocator.h | 31 ++++++++++++++ 7 files changed, 200 insertions(+), 7 deletions(-) create mode 100644 libstdc++-v3/testsuite/23_containers/forward_list/allocator/ext_ptr.cc create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_set/allocator/ext_ptr.cc create mode 100644 libstdc++-v3/testsuite/23_containers/vector/allocator/ext_ptr.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9f288bd6a1d..7501675df35 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,16 @@ 2013-06-16 Jonathan Wakely + PR libstdc++/57263 + * include/bits/forward_list.h (_Fwd_list_base): Convert to/from + allocator's pointer type. + * include/bits/hashtable.h (_Hashtable): Likewise. + * testsuite/util/testsuite_allocator.h (CustomPointerAlloc): Add. + * testsuite/23_containers/forward_list/allocator/ext_ptr.cc: New. + * testsuite/23_containers/unordered_set/allocator/ext_ptr.cc: New. + * testsuite/23_containers/vector/allocator/ext_ptr.cc: New. + +2013-06-16 Jonathan Wakely + * include/std/shared_mutex: Implement N3659. * include/bits/c++14_warning.h: New. * include/Makefile.am: Add new headers. diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index e7c4bdd816e..c3cee971399 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -338,7 +338,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _Node* _M_get_node() - { return _Node_alloc_traits::allocate(_M_get_Node_allocator(), 1); } + { + auto __ptr = _Node_alloc_traits::allocate(_M_get_Node_allocator(), 1); + return std::__addressof(*__ptr); + } template _Node* @@ -367,7 +370,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void _M_put_node(_Node* __p) - { _Node_alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); } + { + typedef typename _Node_alloc_traits::pointer _Ptr; + auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__p); + _Node_alloc_traits::deallocate(_M_get_Node_allocator(), __ptr, 1); + } _Fwd_list_node_base* _M_erase_after(_Fwd_list_node_base* __pos); diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index 0ff6e132a83..8ce264ed72e 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -775,7 +775,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_allocate_node(_Args&&... __args) { - __node_type* __n = _Node_alloc_traits::allocate(_M_node_allocator(), 1); + auto __nptr = _Node_alloc_traits::allocate(_M_node_allocator(), 1); + __node_type* __n = std::__addressof(*__nptr); __try { _Value_alloc_type __a(_M_node_allocator()); @@ -786,7 +787,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } __catch(...) { - _Node_alloc_traits::deallocate(_M_node_allocator(), __n, 1); + _Node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1); __throw_exception_again; } } @@ -800,10 +801,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_deallocate_node(__node_type* __n) { + typedef typename _Node_alloc_traits::pointer _Ptr; + auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n); _Value_alloc_type __a(_M_node_allocator()); _Value_alloc_traits::destroy(__a, __n->_M_valptr()); __n->~__node_type(); - _Node_alloc_traits::deallocate(_M_node_allocator(), __n, 1); + _Node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1); } template:: _M_deallocate_buckets(__bucket_type* __bkts, size_type __n) { + typedef typename _Bucket_alloc_traits::pointer _Ptr; + auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__bkts); _Bucket_alloc_type __alloc(_M_node_allocator()); - _Bucket_alloc_traits::deallocate(__alloc, __bkts, __n); + _Bucket_alloc_traits::deallocate(__alloc, __ptr, __n); } template. + +// { dg-options "-std=gnu++11" } + +#include +#include +#include +#include + +struct T { int i; }; +bool operator==(const T& l, const T& r) { return l.i == r.i; } +bool operator<(const T& l, const T& r) { return l.i < r.i; } + +using __gnu_test::CustomPointerAlloc; + +template class std::forward_list>; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef CustomPointerAlloc alloc_type; + typedef std::forward_list test_type; + test_type v; + v.push_front(T()); + VERIFY( ++v.begin() == v.end() ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/ext_ptr.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/ext_ptr.cc new file mode 100644 index 00000000000..55d9af3a5cb --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/ext_ptr.cc @@ -0,0 +1,48 @@ +// 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include +#include + +struct T { int i; }; +bool operator==(const T& l, const T& r) { return l.i == r.i; } +struct H { std::size_t operator()(const T& t) const noexcept { return t.i; } +}; +struct E : std::equal_to { }; + +using __gnu_test::CustomPointerAlloc; + +template class std::unordered_set>; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef CustomPointerAlloc alloc_type; + typedef std::unordered_set test_type; + test_type v; + v.insert(T()); + VERIFY( ++v.begin() == v.end() ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/allocator/ext_ptr.cc b/libstdc++-v3/testsuite/23_containers/vector/allocator/ext_ptr.cc new file mode 100644 index 00000000000..b94a47a939b --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/allocator/ext_ptr.cc @@ -0,0 +1,44 @@ +// 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 +// . + +// { dg-options "-std=gnu++11" } + +#include +#include +#include +#include + +struct T { int i; }; + +using __gnu_test::CustomPointerAlloc; + +template class std::vector>; + +void test01() +{ + bool test __attribute__((unused)) = true; + typedef CustomPointerAlloc alloc_type; + typedef std::vector test_type; + test_type v; + v.push_back(T()); + VERIFY( ++v.begin() == v.end() ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h index 2360274289e..d569eb0712d 100644 --- a/libstdc++-v3/testsuite/util/testsuite_allocator.h +++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h @@ -28,6 +28,7 @@ #include #include +#include #include namespace __gnu_test @@ -488,6 +489,36 @@ namespace __gnu_test { typedef ExplicitConsAlloc other; }; }; +#if __cplusplus >= 201103L + template + class CustomPointerAlloc : public std::allocator + { + template> + using Ptr = __gnu_cxx::_Pointer_adapter; + + public: + CustomPointerAlloc() = default; + + template + CustomPointerAlloc(const CustomPointerAlloc&) { } + + template + struct rebind + { typedef CustomPointerAlloc other; }; + + typedef Ptr pointer; + typedef Ptr const_pointer; + typedef Ptr void_pointer; + typedef Ptr const_void_pointer; + + pointer allocate(std::size_t n, pointer = {}) + { return pointer(std::allocator::allocate(n)); } + + void deallocate(pointer p, std::size_t n) + { std::allocator::deallocate(std::addressof(*p), n); } + }; +#endif + } // namespace __gnu_test #endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H -- 2.11.4.GIT