diff mbox

[v3] Implement LWG 2466 (allocator_traits::max_size() is stoopid)

Message ID 20150513122130.GE30202@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely May 13, 2015, 12:21 p.m. UTC
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2466

We agreed to move this to Ready in Lenexa.

I'd like to see max_size() deprecated, it's useless, but if we can't
do that it might as well not give an impossible answer.

Tested powerpc64le-linux, committed to trunk.
diff mbox

Patch

commit 00f00caad92cbbc3d8893d5004df1ea2700d67af
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sun May 10 19:50:14 2015 +0100

    	* include/bits/alloc_traits.h (_S_max_size): Implement LWG 2466.
    	* testsuite/20_util/allocator_traits/members/max_size.cc: Adjust.
    	* testsuite/23_containers/forward_list/allocator/minimal.cc:
    	Likewise.
    	* testsuite/23_containers/map/allocator/minimal.cc: Likewise.
    	* testsuite/23_containers/multimap/allocator/minimal.cc: Likewise.
    	* testsuite/23_containers/multiset/allocator/minimal.cc: Likewise.
    	* testsuite/23_containers/set/allocator/minimal.cc: Likewise.
    	* testsuite/23_containers/unordered_map/allocator/minimal.cc:
    	Likewise.
    	* testsuite/23_containers/unordered_multimap/allocator/minimal.cc:
    	Likewise.
    	* testsuite/23_containers/unordered_multiset/allocator/minimal.cc:
    	Likewise.
    	* testsuite/23_containers/unordered_set/allocator/minimal.cc:
    	Likewise.
    	* testsuite/util/testsuite_allocator.h: Remove unused parameter.

diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index 12c6c12..e434261 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -315,7 +315,12 @@  _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
 	       typename = _Require<__not_<__has_max_size<_Alloc2>>>>
 	static size_type
 	_S_max_size(_Alloc2&, ...)
-	{ return __gnu_cxx::__numeric_traits<size_type>::__max; }
+	{
+	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+	  // 2466. allocator_traits::max_size() default behavior is incorrect
+	  return __gnu_cxx::__numeric_traits<size_type>::__max
+	    / sizeof(value_type);
+	}
 
       template<typename _Alloc2>
 	struct __select_helper
diff --git a/libstdc++-v3/testsuite/20_util/allocator_traits/members/max_size.cc b/libstdc++-v3/testsuite/20_util/allocator_traits/members/max_size.cc
index 2678646..862ff4a 100644
--- a/libstdc++-v3/testsuite/20_util/allocator_traits/members/max_size.cc
+++ b/libstdc++-v3/testsuite/20_util/allocator_traits/members/max_size.cc
@@ -57,11 +57,22 @@  void test02()
   typedef std::allocator_traits<unsized_allocator<X>> traits_type;
   traits_type::allocator_type a;
   auto size = std::numeric_limits<traits_type::size_type>::max();
-  VERIFY( traits_type::max_size(a) == size );
+  VERIFY( traits_type::max_size(a) == size / sizeof(X) );
+}
+
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::allocator_traits<unsized_allocator<int>> traits_type;
+  traits_type::allocator_type a;
+  auto size = std::numeric_limits<traits_type::size_type>::max();
+  VERIFY( traits_type::max_size(a) == size / sizeof(int) );
 }
 
 int main()
 {
   test01();
   test02();
+  test03();
 }
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/minimal.cc
index 514489b..a6b3ce2 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/minimal.cc
@@ -38,7 +38,7 @@  void test01()
   typedef std::forward_list<T, alloc_type> test_type;
   test_type v(alloc_type{});
   v.push_front(T());
-  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc
index bde6256..3351f70 100644
--- a/libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc
@@ -42,7 +42,7 @@  void test01()
   typedef std::map<T, U, Cmp, alloc_type> test_type;
   test_type v(alloc_type{});
   v = { test_type::value_type{} };
-  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc
index 433bcec..1ac1213 100644
--- a/libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc
@@ -42,7 +42,7 @@  void test01()
   typedef std::multimap<T, U, Cmp, alloc_type> test_type;
   test_type v(alloc_type{});
   v = { test_type::value_type{} };
-  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc
index 8d1b0ad..b8ccb64 100644
--- a/libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc
@@ -40,7 +40,7 @@  void test01()
   typedef std::multiset<T, Cmp, alloc_type> test_type;
   test_type v(alloc_type{});
   v = { test_type::value_type{} };
-  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc
index 369fc78..4364130 100644
--- a/libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc
@@ -40,7 +40,7 @@  void test01()
   typedef std::set<T, Cmp, alloc_type> test_type;
   test_type v(alloc_type{});
   v = { test_type::value_type{} };
-  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/minimal.cc
index c267a3f..918cc8f 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/minimal.cc
@@ -53,7 +53,7 @@  void test01()
   test_type v(alloc_type{});
   v.emplace(std::piecewise_construct,
 	    std::make_tuple(T()), std::make_tuple(T()));
-  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/minimal.cc
index 3a66069..4e5bbc7 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/minimal.cc
@@ -54,7 +54,7 @@  void test01()
   test_type v(alloc_type{});
   v.emplace(std::piecewise_construct,
 	    std::make_tuple(T()), std::make_tuple(T()));
-  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/minimal.cc
index 2820b92..5264168 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/minimal.cc
@@ -52,7 +52,7 @@  void test01()
   typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
   test_type v(alloc_type{});
   v.insert(T());
-  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/minimal.cc
index 8e950b5..666c3ef 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/minimal.cc
@@ -52,7 +52,7 @@  void test01()
   typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
   test_type v(alloc_type{});
   v.insert(T());
-  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+  VERIFY( v.max_size() < traits_type::max_size(v.get_allocator()) );
 }
 
 int main()
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index 642cef4..090e591 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -491,7 +491,7 @@  namespace __gnu_test
       SimpleAllocator() noexcept { }
 
       template <class T>
-        SimpleAllocator(const SimpleAllocator<T>& other) { }
+        SimpleAllocator(const SimpleAllocator<T>&) { }
 
       Tp *allocate(std::size_t n)
       { return std::allocator<Tp>().allocate(n); }