re PR libstdc++/57263 (std::set with user-defined allocator - compile error)

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.

From-SVN: r200136
This commit is contained in:
Jonathan Wakely 2013-06-16 17:13:34 +00:00 committed by Jonathan Wakely
parent 8d2cddc125
commit f038f5824b
7 changed files with 200 additions and 7 deletions

View File

@ -1,3 +1,14 @@
2013-06-16 Jonathan Wakely <jwakely.gcc@gmail.com>
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 <jwakely.gcc@gmail.com>
* include/std/shared_mutex: Implement N3659.

View File

@ -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<typename... _Args>
_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);

View File

@ -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<typename _Key, typename _Value,
@ -835,7 +838,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_Bucket_alloc_type __alloc(_M_node_allocator());
__bucket_type* __p = _Bucket_alloc_traits::allocate(__alloc, __n);
auto __ptr = _Bucket_alloc_traits::allocate(__alloc, __n);
__bucket_type* __p = std::__addressof(*__ptr);
__builtin_memset(__p, 0, __n * sizeof(__bucket_type));
return __p;
}
@ -849,8 +853,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
_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<typename _Key, typename _Value,

View File

@ -0,0 +1,46 @@
// 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/>.
// { dg-options "-std=gnu++11" }
#include <forward_list>
#include <memory>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
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<T, CustomPointerAlloc<T>>;
void test01()
{
bool test __attribute__((unused)) = true;
typedef CustomPointerAlloc<T> alloc_type;
typedef std::forward_list<T, alloc_type> test_type;
test_type v;
v.push_front(T());
VERIFY( ++v.begin() == v.end() );
}
int main()
{
test01();
}

View File

@ -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
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <unordered_set>
#include <memory>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
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<T> { };
using __gnu_test::CustomPointerAlloc;
template class std::unordered_set<T, H, E, CustomPointerAlloc<T>>;
void test01()
{
bool test __attribute__((unused)) = true;
typedef CustomPointerAlloc<T> alloc_type;
typedef std::unordered_set<T, H, E, alloc_type> test_type;
test_type v;
v.insert(T());
VERIFY( ++v.begin() == v.end() );
}
int main()
{
test01();
}

View File

@ -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
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11" }
#include <vector>
#include <memory>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
struct T { int i; };
using __gnu_test::CustomPointerAlloc;
template class std::vector<T, CustomPointerAlloc<T>>;
void test01()
{
bool test __attribute__((unused)) = true;
typedef CustomPointerAlloc<T> alloc_type;
typedef std::vector<T, alloc_type> test_type;
test_type v;
v.push_back(T());
VERIFY( ++v.begin() == v.end() );
}
int main()
{
test01();
}

View File

@ -28,6 +28,7 @@
#include <tr1/unordered_map>
#include <bits/move.h>
#include <ext/pointer.h>
#include <testsuite_hooks.h>
namespace __gnu_test
@ -488,6 +489,36 @@ namespace __gnu_test
{ typedef ExplicitConsAlloc<Up> other; };
};
#if __cplusplus >= 201103L
template<typename Tp>
class CustomPointerAlloc : public std::allocator<Tp>
{
template<typename Up, typename Sp = __gnu_cxx::_Std_pointer_impl<Up>>
using Ptr = __gnu_cxx::_Pointer_adapter<Sp>;
public:
CustomPointerAlloc() = default;
template<typename Up>
CustomPointerAlloc(const CustomPointerAlloc<Up>&) { }
template<typename Up>
struct rebind
{ typedef CustomPointerAlloc<Up> other; };
typedef Ptr<Tp> pointer;
typedef Ptr<const Tp> const_pointer;
typedef Ptr<void> void_pointer;
typedef Ptr<const void> const_void_pointer;
pointer allocate(std::size_t n, pointer = {})
{ return pointer(std::allocator<Tp>::allocate(n)); }
void deallocate(pointer p, std::size_t n)
{ std::allocator<Tp>::deallocate(std::addressof(*p), n); }
};
#endif
} // namespace __gnu_test
#endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H