https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97773
--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Reduced:
using size_t = decltype(sizeof(0));
template<typename T> struct remove_reference { using type = T; };
template<typename T> struct remove_reference<T&> { using type = T; };
template<typename T> struct remove_reference<T&&> { using type = T; };
template<typename T> using remove_reference_t = typename
remove_reference<T>::type;
struct seconds
{
long count() const;
};
template <typename T>
struct hash
{
};
template <>
struct hash<seconds>
{
auto operator()(seconds const cp) const noexcept
{
return (size_t)cp.count();
}
};
template <typename ...T>
size_t hash_combine(T&& ...v) noexcept(noexcept(
((hash<remove_reference_t<T>>()(v)), ...)))
{
auto seed{672807365};
(
(
seed ^= hash<remove_reference_t<T>>()(v) +
0x9e3779b9 + (seed << 6) + (seed >> 2)
),
...
);
return seed;
}
template<typename T>
struct tuple_node
{
T t;
};
template<typename... T>
struct tuple : tuple_node<T>...
{
};
template<typename F, typename... T>
auto
apply(F& f, tuple<T...> t)
{
f(static_cast<tuple_node<T>&>(t).t...);
}
template <typename ...T>
struct hash<tuple<T...>>
{
auto operator()(tuple<T...>& t) const
{
return apply(hash_combine<T&...>, t);
}
};
int main()
{
using T = tuple<seconds>;
hash<T> h;
T t;
h(t);
}