26#ifndef LSST_CPPUTILS_TESTS_H
27#define LSST_CPPUTILS_TESTS_H
40template <
typename,
typename =
void>
41constexpr bool HAS_STREAM_OUTPUT =
false;
43constexpr bool HAS_STREAM_OUTPUT<
44 T, std::enable_if_t<true, decltype((void)(std::declval<std::ostream&>() << std::declval<T&>()),
48template <
typename T,
class Hash>
49std::enable_if_t<HAS_STREAM_OUTPUT<T>> printIfHashEqual(T obj1, T obj2, Hash hash) {
50 BOOST_TEST_REQUIRE(obj1 == obj2);
51 BOOST_TEST(hash(obj1) == hash(obj2),
52 obj1 <<
" == " << obj2 <<
", but " << hash(obj1) <<
" != " << hash(obj2));
54template <
typename T,
class Hash>
55std::enable_if_t<!HAS_STREAM_OUTPUT<T>> printIfHashEqual(T obj1, T obj2, Hash hash) {
56 if (!(obj1 == obj2)) {
57 BOOST_FAIL(
"Unequal objects need not have equal hashes.");
59 BOOST_TEST(hash(obj1) == hash(obj2));
77 "std::hash specializations must be default-constructible");
83 "std::hash must have an argument_type member until C++20");
85 "std::hash must have a result_type member until C++20");
87 static_assert(
is_same<result_of_t<Hash(T)>,
size_t>::value,
88 "std::hash specializations must be callable and return a size_t");
105 printIfHashEqual(obj1, obj2, Hash());
109namespace utils = cpputils;
void assertHashesEqual(T obj1, T obj2)
Test that equal objects have equal hashes.
constexpr void assertValidHash()
Compile-time test of whether a specialization of std::hash conforms to the general spec.