@@ -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);
@@ -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,
new file mode 100644
@@ -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();
+}
new file mode 100644
@@ -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();
+}
new file mode 100644
@@ -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();
+}
@@ -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