15 #ifndef ABSL_HASH_HASH_TESTING_H_ 16 #define ABSL_HASH_HASH_TESTING_H_ 18 #include <initializer_list> 20 #include <type_traits> 23 #include "gmock/gmock.h" 24 #include "gtest/gtest.h" 142 template <
int&... ExplicitBarrier,
typename Container>
146 template <
int&... ExplicitBarrier,
typename Container,
typename Eq>
150 template <
int&...,
typename T>
154 template <
int&...,
typename T,
typename Eq>
159 namespace hash_internal {
163 template <
typename T>
165 return absl::StrCat(
"#", index,
"(", testing::PrintToString(*value),
")");
169 template <
typename Eq>
172 template <
typename T,
typename U>
179 template <
typename T>
185 template <
typename Container,
typename Eq>
193 std::string ToString()
const {
199 using EqClass = std::vector<Info>;
200 std::vector<EqClass> classes;
204 for (
const auto&
value : values) {
205 EqClass* c =
nullptr;
206 for (
auto& eqclass : classes) {
213 classes.emplace_back();
216 c->push_back({
value, i});
220 if (
auto error = c->back().expand().error()) {
221 return testing::AssertionFailure() << *error;
225 if (classes.size() < 2) {
226 return testing::AssertionFailure()
227 <<
"At least two equivalence classes are expected.";
233 for (
const auto& c : classes) {
237 for (
const Info&
v : c) {
238 if (
v.expand() !=
v.expand()) {
239 return testing::AssertionFailure()
240 <<
"Hash expansion for " <<
v.ToString()
241 <<
" is non-deterministic.";
243 if (
v.expand() != expected) {
244 return testing::AssertionFailure()
245 <<
"Values " << c[0].ToString() <<
" and " <<
v.ToString()
246 <<
" evaluate as equal but have an unequal hash expansion.";
251 for (
const auto&
c2 : classes) {
252 if (&c == &
c2)
continue;
256 return testing::AssertionFailure()
257 <<
"Values " << c[0].ToString() <<
" and " <<
c2[0].ToString()
258 <<
" evaluate as unequal but have an equal hash expansion.";
260 return testing::AssertionFailure()
261 <<
"Hash expansion of " <<
c2[0].ToString()
262 <<
" is a suffix of the hash expansion of " << c[0].ToString()
265 return testing::AssertionFailure()
266 <<
"Hash expansion of " << c[0].ToString()
267 <<
" is a suffix of the hash expansion of " <<
c2[0].ToString()
274 return testing::AssertionSuccess();
277 template <
typename... T>
279 template <
typename U,
bool = disjunction<std::is_same<T, U>...>::value>
283 template <
typename U>
288 template <
template <
typename...>
class C>
292 template <
typename... T>
294 template <
typename T,
typename... Ts>
297 template <
typename... T>
299 const typename std::decay<T>::type*...>::template apply<absl::variant>;
301 template <
typename Container>
304 using Out = std::vector<V>;
306 static Out Do(
const Container& values) {
308 for (
const auto&
v : values) out.push_back(&
v);
313 template <
typename... T>
315 using V = VariantForTypes<T...>;
316 using Out = std::vector<V>;
318 template <
size_t... I>
320 return Out{&std::get<I>(tuple)...};
323 static Out Do(
const std::tuple<T...>& values) {
330 static std::vector<VariantForTypes<int>>
Do(std::tuple<>) {
return {}; }
334 template <
typename T,
typename U>
342 template <
int&...,
typename Container>
350 template <
int&...,
typename Container,
typename Eq>
357 template <
int&...,
typename T>
365 template <
int&...,
typename T,
typename Eq>
376 #endif // ABSL_HASH_HASH_TESTING_H_
VariantForTypes< T... > V
ABSL_MUST_USE_RESULT testing::AssertionResult VerifyTypeImplementsAbslHashCorrectly(const Container &values, Eq equals)
std::string operator()(const T *value) const
SpyHashState operator()(const T *value) const
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
static Out DoImpl(const std::tuple< T... > &tuple, absl::index_sequence< I... >)
static SpyHashStateImpl combine(SpyHashStateImpl s, const A &a, const Args &...args)
SpyHashStateImpl< void > SpyHashState
static std::vector< VariantForTypes< int > > Do(std::tuple<>)
bool operator()(const T *t, const U *u) const
typename MakeTypeSet< const typename std::decay< T >::type *... >::template apply< absl::variant > VariantForTypes
#define ABSL_MUST_USE_RESULT
static Out Do(const std::tuple< T... > &values)
ABSL_MUST_USE_RESULT testing::AssertionResult VerifyTypeImplementsAbslHashCorrectly(const Container &values)
make_index_sequence< sizeof...(Ts)> index_sequence_for
static Out Do(const Container &values)
variant_internal::VisitResult< Visitor, Variants... > visit(Visitor &&vis, Variants &&...vars)
hash_default_eq< typename T::first_type > eq
static CompareResult Compare(const SpyHashStateImpl &a, const SpyHashStateImpl &b)
bool operator()(const T &t, const U &u) const