-// { dg-options "-std=gnu++0x" }
+// { dg-do run { target c++11 } }
-// Copyright (C) 2011 Free Software Foundation, Inc.
+// Copyright (C) 2011-2023 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
#include <ext/throw_allocator.h>
#include <testsuite_hooks.h>
-void test01()
-{
- bool test __attribute__((unused)) = true;
+template<template<typename _Value, typename _Hash,
+ typename _Pred, typename _Alloc>
+ typename _USet>
+ void test()
+ {
+ typedef std::numeric_limits<std::size_t> nl_size_t;
+ _USet<int, std::hash<int>, std::equal_to<int>,
+ __gnu_cxx::throw_allocator_limit<int> > us;
+ int val = 0;
+ for (; val != 100; ++val)
+ {
+ VERIFY( us.insert(val).second );
+ VERIFY( us.load_factor() <= us.max_load_factor() );
+ }
- typedef std::numeric_limits<std::size_t> nl_size_t;
- std::unordered_set<int, std::hash<int>, std::equal_to<int>,
- __gnu_cxx::throw_allocator_limit<int> > us;
- int val = 0;
- for (; val != 100; ++val)
- {
- VERIFY( us.insert(val).second) ;
- VERIFY( us.load_factor() <= us.max_load_factor() );
- }
+ float cur_max_load_factor = us.max_load_factor();
+ int counter = 0;
+ std::size_t thrown_exceptions = 0;
- float cur_max_load_factor = us.max_load_factor();
- int counter = 0;
- std::size_t thrown_exceptions = 0;
- while (true)
- {
- __gnu_cxx::limit_condition::set_limit(counter++);
- bool do_break = false;
- try
- {
- us.max_load_factor(.5f);
- do_break = true;
- }
- catch (const __gnu_cxx::forced_error&)
- {
- VERIFY( us.max_load_factor() == cur_max_load_factor );
- ++thrown_exceptions;
- }
- // Lets check that unordered_set will still be correctly resized
- // when needed
- __gnu_cxx::limit_condition::set_limit(nl_size_t::max());
- for (;;)
- {
- VERIFY( us.load_factor() <= us.max_load_factor() );
- size_t nbkts = us.bucket_count();
- VERIFY( us.insert(val++).second );
- if (us.bucket_count() != nbkts)
- break;
- }
- if (do_break)
- break;
- }
- VERIFY( thrown_exceptions > 0 );
-}
+ // Reduce max load factor.
+ us.max_load_factor(us.max_load_factor() / 4);
+
+ // At this point load factor is higher than max_load_factor because we can't
+ // rehash in max_load_factor call.
+ VERIFY( us.load_factor() > us.max_load_factor() );
+
+ while (true)
+ {
+ __gnu_cxx::limit_condition::limit_adjustor adjustor(counter++);
+ bool do_break = false;
+ try
+ {
+ size_t nbkts = us.bucket_count();
+ // Check that unordered_set will still be correctly resized when
+ // needed.
+ VERIFY( us.insert(val++).second );
+ VERIFY( us.bucket_count() != nbkts );
+ VERIFY( us.load_factor() <= us.max_load_factor() );
+ do_break = true;
+ }
+ catch (const __gnu_cxx::forced_error&)
+ {
+ // max load factor doesn't change.
+ VERIFY( us.max_load_factor() == .25f );
+ ++thrown_exceptions;
+ }
+
+ if (do_break)
+ break;
+ }
+
+ VERIFY( thrown_exceptions > 0 );
+ }
+
+
+template<typename _Value, typename _Hash,
+ typename _Pred, typename _Alloc>
+ using unordered_set_power2_rehash =
+ std::_Hashtable<_Value, _Value, _Alloc,
+ std::__detail::_Identity,
+ _Pred,
+ _Hash,
+ std::__detail::_Mask_range_hashing,
+ std::__detail::_Default_ranged_hash,
+ std::__detail::_Power2_rehash_policy,
+ std::__detail::_Hashtable_traits<false, true, true>>;
int main()
{
- test01();
+ test<std::unordered_set>();
+ test<unordered_set_power2_rehash>();
return 0;
}