LCOV - code coverage report
Current view: top level - include/pairinteraction/utils - hash.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 11 11 100.0 %
Date: 2026-08-14 15:36:24 Functions: 10 10 100.0 %

          Line data    Source code
       1             : // SPDX-FileCopyrightText: 2024 PairInteraction Developers
       2             : // SPDX-License-Identifier: LGPL-3.0-or-later
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <array>
       7             : #include <complex>
       8             : #include <functional>
       9             : #include <vector>
      10             : 
      11             : namespace pairinteraction::utils {
      12             : 
      13             : /**
      14             :  * @struct hash
      15             :  *
      16             :  * @brief Hash function
      17             :  *
      18             :  * The `std::hash` template allows specialization but only for types that are
      19             :  * not in the standard library. This means that we cannot specialize
      20             :  * `std::hash` for, e.g. `std::array`. To this end we define a struct `hash`
      21             :  * which just inherits from `std::hash` by default.
      22             :  *
      23             :  * @tparam T type to be hashed
      24             :  */
      25             : 
      26             : template <typename T>
      27             : struct hash;
      28             : 
      29             : /**
      30             :  * @function hash_combine
      31             :  *
      32             :  * @brief Combine hashes
      33             :  *
      34             :  * The implementation of `hash_combine` is copied from Boost but simplified.
      35             :  *
      36             :  * @param seed  start hash
      37             :  * @param v  value whose hash is to be added to \p seed
      38             :  *
      39             :  * @tparam T type to be hashed
      40             :  */
      41             : 
      42             : template <typename T>
      43    34928844 : inline void hash_combine(std::size_t &seed, T const &v) {
      44             :     hash<T> hasher;
      45    34928844 :     seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
      46    34964296 : }
      47             : 
      48             : /**
      49             :  * @function hash_range
      50             :  *
      51             :  * @brief Combine hashes of values in a range
      52             :  *
      53             :  * @param first forward iterator
      54             :  * @param last forward iterator
      55             :  *
      56             :  * @return combined hash
      57             :  *
      58             :  * @tparam It forward iterator
      59             :  */
      60             : 
      61             : template <typename It>
      62    17683541 : inline std::size_t hash_range(It first, It last) {
      63    17683541 :     std::size_t seed = 0;
      64    52335894 :     for (; first != last; ++first) {
      65    34058727 :         hash_combine(seed, *first);
      66             :     }
      67    18170885 :     return seed;
      68             : }
      69             : 
      70             : // By default use std::hash
      71             : template <typename T>
      72             : struct hash : std::hash<T> {};
      73             : 
      74             : // Specializations for other types
      75             : template <typename T, std::size_t N>
      76             : struct hash<std::array<T, N>> {
      77       65348 :     std::size_t operator()(std::array<T, N> const &a) const {
      78       65348 :         return hash_range(a.begin(), a.end());
      79             :     }
      80             : };
      81             : 
      82             : template <typename T>
      83             : struct hash<std::vector<T>> {
      84    17631959 :     std::size_t operator()(std::vector<T> const &v) const { return hash_range(v.begin(), v.end()); }
      85             : };
      86             : 
      87             : template <typename T>
      88             : struct hash<std::complex<T>> {
      89             :     std::size_t operator()(std::complex<T> const &c) const {
      90             :         std::size_t seed = 0;
      91             :         hash_combine(seed, c.real());
      92             :         hash_combine(seed, c.imag());
      93             :         return seed;
      94             :     }
      95             : };
      96             : 
      97             : enum class Parity : int;
      98             : 
      99             : template <>
     100             : struct hash<Parity> {
     101             :     std::size_t operator()(const Parity &parity) const {
     102             :         return std::hash<char>{}(static_cast<char>(parity));
     103             :     }
     104             : };
     105             : 
     106             : } // namespace pairinteraction::utils

Generated by: LCOV version 1.16