1// Copyright (C) 2012-2015 Free Software Foundation, Inc.
2//
3// This file is part of the GNU ISO C++ Library.  This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8//
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3.  If not see
16// <http://www.gnu.org/licenses/>.
17//
18
19// { dg-options "-std=gnu++11" }
20
21#include <set>
22#include <unordered_map>
23#include <testsuite_hooks.h>
24
25bool test __attribute__((unused)) = true;
26
27struct A
28{
29  int x;
30  static std::set<const A*> destroyed;
31
32  A()
33  { destroyed.erase(this); }
34
35  A(const A& a)
36    : x(a.x)
37  { destroyed.erase(this); }
38
39  ~A()
40  { destroyed.insert(this); }
41
42  bool
43  operator==(const A& other) const
44  {
45    VERIFY( destroyed.find(this) == destroyed.end() );
46    VERIFY( destroyed.find(&other) == destroyed.end() );
47    return x == other.x;
48  }
49};
50
51std::set<const A*> A::destroyed;
52
53struct hasher
54{
55  std::size_t operator()(const A& a) const
56  {
57    VERIFY( A::destroyed.find(&a) == A::destroyed.end() );
58    return a.x / 10;
59  }
60};
61
62void test01()
63{
64  typedef std::unordered_map<A, A, hasher> UMap;
65  UMap map;
66
67  A::destroyed.clear();
68  A a;
69  a.x = 0;
70  map.insert({a, a});
71  a.x = 1;
72  map.insert({a, a});
73  VERIFY( map.size() == 2 );
74  std::size_t bkt = map.bucket(a);
75  VERIFY( map.bucket_size(bkt) == 2 );
76
77  VERIFY( map.erase( map.begin(bkt)->first ) == 1 );
78}
79
80void test02()
81{
82  typedef std::unordered_map<A, A, hasher> UMap;
83  UMap map;
84
85  A::destroyed.clear();
86  A a;
87  a.x = 0;
88  map.insert({a, a});
89  a.x = 1;
90  map.insert({a, a});
91  VERIFY( map.size() == 2 );
92  std::size_t bkt = map.bucket(a);
93  VERIFY( map.bucket_size(bkt) == 2 );
94
95  VERIFY( map.erase( map.begin(bkt)->second ) == 1 );
96}
97
98int main()
99{
100  test01();
101  test02();
102  return 0;
103}
104