|
| 1 | + |
| 2 | +// Copyright David Browne 2020-2023. |
| 3 | +// Distributed under the Boost Software License, Version 1.0. |
| 4 | +// (See accompanying file LICENSE_1_0.txt or copy at |
| 5 | +// https://www.boost.org/LICENSE_1_0.txt) |
| 6 | + |
| 7 | +#include "dsga.hxx" |
| 8 | +#include <functional> |
| 9 | + |
| 10 | + |
| 11 | +// based on https://www.boost.org/doc/libs/1_83_0/libs/container_hash/doc/html/hash.html#notes_hash_combine |
| 12 | +template <typename T> |
| 13 | +constexpr std::size_t hash_combine(std::size_t seed, const T &t) noexcept |
| 14 | +{ |
| 15 | + std::size_t x = seed + 0x9e3779b9 + std::hash<T>{}(t); |
| 16 | + |
| 17 | + x ^= x >> 32; |
| 18 | + x *= 0xe9846af9b1a615d; |
| 19 | + x ^= x >> 32; |
| 20 | + x *= 0xe9846af9b1a615d; |
| 21 | + x ^= x >> 28; |
| 22 | + |
| 23 | + return x; |
| 24 | +} |
| 25 | + |
| 26 | +template <dsga::dimensional_scalar T, std::size_t S> |
| 27 | +struct std::hash<dsga::basic_vector<T, S>> |
| 28 | +{ |
| 29 | + std::size_t operator()(const dsga::basic_vector<T, S> &v) const noexcept |
| 30 | + { |
| 31 | + std::size_t seed = 0; |
| 32 | + |
| 33 | + [&] <std::size_t ...Js>(std::index_sequence<Js ...>) |
| 34 | + { |
| 35 | + ((seed = hash_combine(seed, v[Js])), ...); |
| 36 | + }(std::make_index_sequence<S>{}); |
| 37 | + |
| 38 | + return seed; |
| 39 | + } |
| 40 | +}; |
| 41 | + |
| 42 | +template <dsga::floating_point_scalar T, std::size_t C, std::size_t R> |
| 43 | +struct std::hash<dsga::basic_matrix<T, C, R>> |
| 44 | +{ |
| 45 | + std::size_t operator()(const dsga::basic_matrix<T, C, R> &m) const noexcept |
| 46 | + { |
| 47 | + std::size_t seed = 0; |
| 48 | + |
| 49 | + [&] <std::size_t ...Js>(std::index_sequence<Js ...>) |
| 50 | + { |
| 51 | + ((seed = hash_combine(seed, m[Js])), ...); |
| 52 | + }(std::make_index_sequence<C>{}); |
| 53 | + |
| 54 | + return seed; |
| 55 | + } |
| 56 | +}; |
0 commit comments