GCC Code Coverage Report


libs/base/src/base/
File: hash.string.h
Date: 2025-03-19 20:55:25
Lines:
25/25
100.0%
Functions:
21/21
100.0%
Branches:
6/10
60.0%

Line Branch Exec Source
1 #pragma once
2
3 #include "base/ints.h"
4
5 #include <string_view>
6 #include <string>
7 #include <unordered_map>
8
9 // 1 = include text in hash, 0=don't
10 // todo(Gustav): move to a config instead
11 #define USE_HASH_TEXT 1
12
13 namespace eu
14 {
15
16 /// fnv-1a hash.
17 /// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
18 100 constexpr u64 hash64(const std::string_view str, u64 hash = 0xcbf29ce484222325)
19
2/2
✓ Branch 0 (3 → 4) taken 19 times.
✓ Branch 1 (3 → 5) taken 81 times.
100 { return str.empty() ? hash : hash64(str.substr(1), (hash ^ str[0]) * 0x100000001b3); }
20
21 /// Hash of a non-owning string.
22 /// It will be (pretty) printed as the original string if that is enabled.
23 /// Treat it as a regular `std::string_view` but without the string functionality.
24 /// @see \ref hash64
25 /// @see \ref HshO
26 struct Hsh
27 {
28 /// The actual hash.
29 /// Prefer to use operators on \ref Hsh instead of accessing this directly.
30 u64 hash;
31
32 #if USE_HASH_TEXT == 1
33 /// Non-owning storage of the printable string, if enabled.
34 /// Please ignore if possible and just print as normal.
35 std::string_view text;
36 #endif
37
38 /// Creates a new hash object and computes the hash at compile time if possible.
39 2 constexpr Hsh(const std::string_view s)
40 2 : hash( hash64(s) )
41 #if USE_HASH_TEXT == 1
42 2 , text(s)
43 #endif
44 2 { }
45 };
46
47 /// Hash of an owning string.
48 /// It will be (pretty) printed as the original string if that is enabled.
49 /// Treat it as a regular `std::string` but without the string functionality.
50 /// @see \ref hash64
51 /// @see \ref Hsh
52 struct HshO
53 {
54 /// The actual hash.
55 /// Prefer to use operators on \ref HshO instead of accessing this directly.
56 u64 hash;
57
58 #if USE_HASH_TEXT == 1
59 /// Owning storage of the printable string, if enabled.
60 /// Please ignore if possible and just print as normal.
61 std::string text;
62 #endif
63
64 /// Creates a new hash object and computes the hash at compile time if possible.
65 1 constexpr HshO(const std::string& s)
66 1 : hash(hash64(s))
67 #if USE_HASH_TEXT == 1
68 1 , text(s)
69 #endif
70 1 { }
71
72 /// Creates a new hash object and computes the hash at compile time if possible.
73 13 constexpr HshO(const std::string_view& s)
74 13 : hash(hash64(s))
75 #if USE_HASH_TEXT == 1
76
1/2
✓ Branch 0 (5 → 6) taken 13 times.
✗ Branch 1 (5 → 8) not taken.
26 , text(s)
77 #endif
78 13 { }
79
80 /// Copy data from a non-owning hash.
81 33 constexpr HshO(const Hsh& o)
82 33 : hash(o.hash)
83 #if USE_HASH_TEXT == 1
84
1/2
✓ Branch 0 (4 → 5) taken 33 times.
✗ Branch 1 (4 → 7) not taken.
66 , text(o.text)
85 #endif
86 33 { }
87 };
88
89 #define OP(op) \
90 constexpr bool operator op(const Hsh& lhs, const Hsh& rhs)\
91 { return lhs.hash op rhs.hash; }\
92 constexpr bool operator op(const HshO& lhs, const Hsh& rhs)\
93 { return lhs.hash op rhs.hash; }\
94 constexpr bool operator op(const Hsh& lhs, const HshO& rhs)\
95 { return lhs.hash op rhs.hash; }\
96 constexpr bool operator op(const HshO& lhs, const HshO& rhs)\
97 { return lhs.hash op rhs.hash; }
98 78 OP(==) OP(!=) OP(<) OP(>) OP(<=) OP(>=)
99 #undef OP
100
101
102 std::string string_from(const Hsh h);
103 std::string string_from(const HshO& h);
104
105
106 ADD_CATCH_FORMATTER_DEF(Hsh)
107 ADD_CATCH_FORMATTER_DEF(HshO)
108 }
109
110
1/2
✓ Branch 0 (2 → 3) taken 1 times.
✗ Branch 1 (2 → 17) not taken.
2 ADD_DEFAULT_FORMATTER(eu::Hsh, std::string, eu::string_from);
111
1/2
✓ Branch 0 (2 → 3) taken 1 times.
✗ Branch 1 (2 → 17) not taken.
2 ADD_DEFAULT_FORMATTER(eu::HshO, std::string, eu::string_from);
112
113
114 namespace std
115 {
116
117 /// \private
118 template <> struct hash<eu::Hsh>
119 {
120 4 std::size_t operator()(const eu::Hsh& x) const
121 4 { return x.hash; }
122 };
123
124 /// \private
125 template <> struct hash<eu::HshO>
126 {
127 20 std::size_t operator()(const eu::HshO& x) const
128 20 { return x.hash; }
129 };
130
131 }
132