26 #ifndef LSST_UTILS_TESTS_H
27 #define LSST_UTILS_TESTS_H
32 #include <type_traits>
40 template <
typename,
typename =
void>
41 constexpr
bool HAS_STREAM_OUTPUT =
false;
43 constexpr
bool HAS_STREAM_OUTPUT<
44 T, std::enable_if_t<true, decltype((void)(std::declval<std::ostream&>() << std::declval<T&>()),
48 template <
typename T,
class Hash>
49 std::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));
54 template <
typename T,
class Hash>
55 std::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");
82 static_assert(
is_same<
typename Hash::argument_type, remove_cv_t<T>>::value,
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");
101 template <
typename T>
105 printIfHashEqual(obj1, obj2, Hash());