]>
Commit | Line | Data |
---|---|---|
7adcbafe | 1 | // Copyright (C) 2021-2022 Free Software Foundation, Inc. |
d2b1a684 FD |
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 | // { dg-do run { target c++20 } } | |
19 | ||
20 | #include <unordered_set> | |
f78f25f4 JW |
21 | |
22 | #ifndef __cpp_lib_generic_unordered_lookup | |
23 | # error "Feature-test macro for generic lookup missing in <unordered_set>" | |
24 | #elif __cpp_lib_generic_unordered_lookup < 201811L | |
25 | # error "Feature-test macro for generic lookup has wrong value in <unordered_set>" | |
26 | #endif | |
27 | ||
d2b1a684 FD |
28 | #include <testsuite_hooks.h> |
29 | ||
30 | struct Equal | |
31 | { | |
32 | typedef void is_transparent; | |
33 | ||
34 | bool operator()(int i, long l) const { return i == l; } | |
35 | bool operator()(long l, int i) const { return l == i; } | |
36 | bool operator()(int i, int j) const { ++count; return i == j; } | |
37 | ||
38 | static int count; | |
39 | }; | |
40 | ||
41 | int Equal::count = 0; | |
42 | ||
43 | struct Hash | |
44 | { | |
45 | typedef void is_transparent; | |
46 | ||
47 | std::size_t operator()(int i) const { ++count; return i; } | |
48 | std::size_t operator()(long l) const { return l; } | |
49 | ||
50 | static int count; | |
51 | }; | |
52 | ||
53 | int Hash::count = 0; | |
54 | ||
55 | using test_type = std::unordered_set<int, Hash, Equal>; | |
56 | ||
57 | test_type x{ 1, 3, 5 }; | |
58 | const test_type& cx = x; | |
59 | ||
60 | void | |
61 | test01() | |
62 | { | |
63 | Hash::count = 0; | |
64 | Equal::count = 0; | |
65 | ||
66 | VERIFY( x.contains(1L) ); | |
67 | ||
68 | auto it = x.find(1L); | |
69 | VERIFY( it != x.end() && *it == 1 ); | |
70 | it = x.find(2L); | |
71 | VERIFY( it == x.end() ); | |
72 | ||
73 | auto cit = cx.find(3L); | |
74 | VERIFY( cit != cx.end() && *cit == 3 ); | |
75 | cit = cx.find(2L); | |
76 | VERIFY( cit == cx.end() ); | |
77 | ||
78 | VERIFY( Hash::count == 0 ); | |
79 | VERIFY( Equal::count == 0 ); | |
80 | ||
81 | static_assert(std::is_same<decltype(it), test_type::iterator>::value, | |
82 | "find returns iterator"); | |
83 | static_assert(std::is_same<decltype(cit), test_type::const_iterator>::value, | |
84 | "const find returns const_iterator"); | |
85 | } | |
86 | ||
87 | void | |
88 | test02() | |
89 | { | |
90 | Hash::count = 0; | |
91 | Equal::count = 0; | |
92 | ||
93 | auto n = x.count(1L); | |
94 | VERIFY( n == 1 ); | |
95 | n = x.count(2L); | |
96 | VERIFY( n == 0 ); | |
97 | ||
98 | auto cn = cx.count(3L); | |
99 | VERIFY( cn == 1 ); | |
100 | cn = cx.count(2L); | |
101 | VERIFY( cn == 0 ); | |
102 | ||
103 | VERIFY( Hash::count == 0 ); | |
104 | VERIFY( Equal::count == 0 ); | |
105 | } | |
106 | ||
107 | void | |
108 | test03() | |
109 | { | |
110 | Hash::count = 0; | |
111 | Equal::count = 0; | |
112 | ||
113 | auto it = x.equal_range(1L); | |
114 | VERIFY( it.first != it.second && *it.first == 1 ); | |
115 | it = x.equal_range(2L); | |
116 | VERIFY( it.first == it.second && it.first == x.end() ); | |
117 | ||
118 | auto cit = cx.equal_range(1L); | |
119 | VERIFY( cit.first != cit.second && *cit.first == 1 ); | |
120 | cit = cx.equal_range(2L); | |
121 | VERIFY( cit.first == cit.second && cit.first == cx.end() ); | |
122 | ||
123 | VERIFY( Hash::count == 0 ); | |
124 | VERIFY( Equal::count == 0 ); | |
125 | ||
126 | using pair = std::pair<test_type::iterator, test_type::iterator>; | |
127 | static_assert(std::is_same<decltype(it), pair>::value, | |
128 | "equal_range returns pair<iterator, iterator>"); | |
129 | using cpair = std::pair<test_type::const_iterator, test_type::const_iterator>; | |
130 | static_assert(std::is_same<decltype(cit), cpair>::value, | |
131 | "const equal_range returns pair<const_iterator, const_iterator>"); | |
132 | } | |
133 | ||
134 | void | |
135 | test04() | |
136 | { | |
137 | // https://gcc.gnu.org/ml/libstdc++/2015-01/msg00176.html | |
138 | // Verify the new function template overloads do not cause problems | |
139 | // when the comparison function is not transparent. | |
140 | struct I | |
141 | { | |
142 | int i; | |
143 | operator int() const { return i; } | |
144 | }; | |
145 | ||
146 | std::unordered_set<int> s; | |
147 | I i = { }; | |
148 | s.find(i); | |
149 | } | |
150 | ||
151 | void | |
152 | test05() | |
153 | { | |
154 | struct E | |
155 | { | |
156 | bool operator()(int l, int r) const { return l == r; } | |
157 | ||
158 | struct Partition { }; | |
159 | ||
160 | bool operator()(int l, Partition) const { return l < 6; } | |
161 | bool operator()(Partition, int r) const { return r > 3; } | |
162 | ||
163 | using is_transparent = void; | |
164 | }; | |
165 | ||
166 | struct H | |
167 | { | |
168 | size_t | |
169 | operator()(int x) const | |
170 | { return (size_t)(x / 10); } | |
171 | ||
172 | size_t | |
173 | operator()(E::Partition) const | |
174 | { return 0; } | |
175 | ||
176 | using is_transparent = void; | |
177 | }; | |
178 | ||
179 | std::unordered_set<int, H, E> s{ 1, 2, 3, 4, 5 }; | |
180 | ||
181 | auto n = s.count(E::Partition{}); | |
182 | VERIFY( n == 2 ); | |
183 | } | |
184 | ||
185 | int | |
186 | main() | |
187 | { | |
188 | test01(); | |
189 | test02(); | |
190 | test03(); | |
191 | test04(); | |
192 | test05(); | |
193 | } |