1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef TEST_TRANSPARENT_UNORDERED_H
10 #define TEST_TRANSPARENT_UNORDERED_H
12 #include "test_macros.h"
13 #include "is_transparent.h"
27 constexpr std::size_t operator()(SearchedType
<T
> const& t
) const {
28 return static_cast<std::size_t>(t
.get_value());
32 constexpr std::size_t operator()(StoredType
<T
> const& t
) const {
33 return static_cast<std::size_t>(t
.get_value());
37 struct non_transparent_hash
: hash_impl
{};
39 struct transparent_hash
: hash_impl
{
40 using is_transparent
= void;
43 struct transparent_hash_final final
: transparent_hash
{};
45 struct transparent_equal_final final
: std::equal_to
<> {};
49 explicit SearchedType(T value
, int *counter
) : value_(value
), conversions_(counter
) { }
51 // Whenever a conversion is performed, increment the counter to keep track
53 operator StoredType
<T
>() const {
55 return StoredType
<T
>{value_
};
58 int get_value() const {
69 StoredType() = default;
70 StoredType(T value
) : value_(value
) { }
72 friend bool operator==(StoredType
const& lhs
, StoredType
const& rhs
) {
73 return lhs
.value_
== rhs
.value_
;
76 // If we're being passed a SearchedType<T> object, avoid the conversion
77 // to T. This allows testing that the transparent operations are correctly
78 // forwarding the SearchedType all the way to this comparison by checking
79 // that we didn't have a conversion when we search for a SearchedType<T>
80 // in a container full of StoredType<T>.
81 friend bool operator==(StoredType
const& lhs
, SearchedType
<T
> const& rhs
) {
82 return lhs
.value_
== rhs
.get_value();
85 int get_value() const {
93 template<template<class...> class UnorderedSet
, class Hash
, class Equal
>
94 using unord_set_type
= UnorderedSet
<StoredType
<int>, Hash
, Equal
>;
96 template<template<class...> class UnorderedMap
, class Hash
, class Equal
>
97 using unord_map_type
= UnorderedMap
<StoredType
<int>, int, Hash
, Equal
>;
99 template<class Container
>
100 void test_transparent_find(Container c
) {
102 assert(c
.find(SearchedType
<int>(1, &conversions
)) != c
.end());
103 assert(c
.find(SearchedType
<int>(2, &conversions
)) != c
.end());
104 assert(c
.find(SearchedType
<int>(3, &conversions
)) == c
.end());
105 assert(conversions
== 0);
108 template<class Container
>
109 void test_non_transparent_find(Container c
) {
111 assert(c
.find(SearchedType
<int>(1, &conversions
)) != c
.end());
112 assert(conversions
== 1);
113 assert(c
.find(SearchedType
<int>(2, &conversions
)) != c
.end());
114 assert(conversions
== 2);
115 assert(c
.find(SearchedType
<int>(3, &conversions
)) == c
.end());
116 assert(conversions
== 3);
119 template<class Container
>
120 void test_transparent_count(Container c
) {
122 assert(c
.count(SearchedType
<int>(1, &conversions
)) > 0);
123 assert(c
.count(SearchedType
<int>(2, &conversions
)) > 0);
124 assert(c
.count(SearchedType
<int>(3, &conversions
)) == 0);
125 assert(conversions
== 0);
128 template<class Container
>
129 void test_non_transparent_count(Container c
) {
131 assert(c
.count(SearchedType
<int>(1, &conversions
)) > 0);
132 assert(conversions
== 1);
133 assert(c
.count(SearchedType
<int>(2, &conversions
)) > 0);
134 assert(conversions
== 2);
135 assert(c
.count(SearchedType
<int>(3, &conversions
)) == 0);
136 assert(conversions
== 3);
139 template<class Container
>
140 void test_transparent_contains(Container c
) {
142 assert(c
.contains(SearchedType
<int>(1, &conversions
)));
143 assert(c
.contains(SearchedType
<int>(2, &conversions
)));
144 assert(!c
.contains(SearchedType
<int>(3, &conversions
)));
145 assert(conversions
== 0);
148 template<class Container
>
149 void test_non_transparent_contains(Container c
) {
151 assert(c
.contains(SearchedType
<int>(1, &conversions
)));
152 assert(conversions
== 1);
153 assert(c
.contains(SearchedType
<int>(2, &conversions
)));
154 assert(conversions
== 2);
155 assert(!c
.contains(SearchedType
<int>(3, &conversions
)));
156 assert(conversions
== 3);
159 template<class Container
>
160 void test_transparent_equal_range(Container c
) {
162 auto iters
= c
.equal_range(SearchedType
<int>(1, &conversions
));
163 assert(std::distance(iters
.first
, iters
.second
) > 0);
164 iters
= c
.equal_range(SearchedType
<int>(2, &conversions
));
165 assert(std::distance(iters
.first
, iters
.second
) > 0);
166 iters
= c
.equal_range(SearchedType
<int>(3, &conversions
));
167 assert(std::distance(iters
.first
, iters
.second
) == 0);
168 assert(conversions
== 0);
171 template<class Container
>
172 void test_non_transparent_equal_range(Container c
) {
174 auto iters
= c
.equal_range(SearchedType
<int>(1, &conversions
));
175 assert(std::distance(iters
.first
, iters
.second
) > 0);
176 assert(conversions
== 1);
177 iters
= c
.equal_range(SearchedType
<int>(2, &conversions
));
178 assert(std::distance(iters
.first
, iters
.second
) > 0);
179 assert(conversions
== 2);
180 iters
= c
.equal_range(SearchedType
<int>(3, &conversions
));
181 assert(std::distance(iters
.first
, iters
.second
) == 0);
182 assert(conversions
== 3);
185 #endif // TEST_STD_VER > 17
187 #endif // TEST_TRANSPARENT_UNORDERED_H