@auto_js/utility 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auto_js/utility",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "author": "https://github.com/laverdet/",
5
5
  "homepage": "https://github.com/laverdet/isolated-vm/tree/experimental/packages/utility",
6
6
  "license": "ISC",
package/utility/hash.cc CHANGED
@@ -1,32 +1,76 @@
1
1
  export module util:utility.hash;
2
+ import :utility.string;
2
3
  import std;
3
4
 
4
5
  namespace util {
5
6
 
6
- // `constexpr` hash for property lookup
7
- export template <class Char>
8
- constexpr auto fnv1a_hash(std::basic_string_view<Char> view) -> std::uint32_t {
9
- constexpr std::uint32_t prime = 0x100'0193;
10
- std::uint32_t hash = 0x811c'9dc5;
11
- for (auto character : view) {
12
- auto bytes = std::bit_cast<std::array<std::uint8_t, sizeof(Char)>>(character);
13
- for (auto byte : bytes) {
14
- hash = hash ^ byte;
15
- hash *= prime;
7
+ // Dead simple `constexpr` hash for arbitrary data.
8
+ template <class Result>
9
+ struct fnv1a_hash_of {
10
+ static_assert(std::is_integral_v<Result>);
11
+ static_assert(std::is_unsigned_v<Result>);
12
+
13
+ template <class Type>
14
+ constexpr auto operator()(std::span<const Type> data) const -> Result {
15
+ constexpr auto xx = []() -> std::tuple<Result, Result> {
16
+ if constexpr (sizeof(Result) == 4) {
17
+ return {0x811c'9dc5, 0x100'0193};
18
+ } else {
19
+ static_assert(sizeof(Result) == 8);
20
+ return {0xcbf2'9ce4'8422'2325, 0x100'0000'01b3};
21
+ }
22
+ }();
23
+ constexpr auto offset_basis = std::get<0>(xx);
24
+ constexpr auto prime = std::get<1>(xx);
25
+ auto hash = offset_basis;
26
+ for (const auto& value : data) {
27
+ auto bytes = std::bit_cast<std::array<std::uint8_t, sizeof(Type)>>(value);
28
+ for (auto byte : bytes) {
29
+ hash = hash ^ byte;
30
+ hash *= prime;
31
+ }
32
+ }
33
+ return hash;
16
34
  }
17
- }
18
- return hash;
19
- }
35
+
36
+ template <class Char>
37
+ constexpr auto operator()(std::basic_string_view<Char> view) const -> Result {
38
+ return (*this)(std::span<const Char>{view.data(), view.size()});
39
+ }
40
+ };
41
+
42
+ export auto fnv1a_hash32 = fnv1a_hash_of<std::uint32_t>{};
43
+ export auto fnv1a_hash64 = fnv1a_hash_of<std::uint64_t>{};
20
44
 
21
45
  // constexpr `typeid(Type).hash_code()` replacement
22
- template <class Type>
23
- consteval auto make_type_hash() -> std::uint32_t {
24
- // "std::uint32_t make_type_hash() [Type = int]"
25
- constexpr auto name = std::source_location::current().function_name();
26
- return fnv1a_hash(std::string_view{name});
46
+ export template <class Result, class Type>
47
+ consteval auto type_hash_of() -> Result {
48
+ #if __clang__
49
+ constexpr auto name = std::string_view{std::source_location::current().function_name()};
50
+ // auto util::type_hash_of() [Result = unsigned int, Type = int]
51
+ // auto util::type_hash_of() [Result = unsigned int, Type = (lambda at /workspace/playground/sandbox.cc:15:12)]
52
+ if (name.contains("lambda at ")) {
53
+ throw std::logic_error{"cannot hash a lambda type"};
54
+ }
55
+ #elif __GNUC__
56
+ constexpr auto name = std::string_view{__PRETTY_FUNCTION__};
57
+ // consteval auto util::type_hash_of@util() [with Result = unsigned int; Type = int]
58
+ // consteval auto util::type_hash_of@util() [with Result = unsigned int; Type = main()::<lambda()>]
59
+ if (name.contains("lambda(")) {
60
+ throw std::logic_error{"cannot hash a lambda type"};
61
+ }
62
+ #else
63
+ #error "Unsupported compiler"
64
+ #endif
65
+ return fnv1a_hash_of<Result>{}(name);
27
66
  }
28
67
 
29
68
  export template <class Type>
30
- constexpr auto type_hash = make_type_hash<Type>();
69
+ constexpr auto type_hash32 = type_hash_of<std::uint32_t, Type>();
70
+
71
+ export template <class Type>
72
+ constexpr auto type_hash64 = type_hash_of<std::uint64_t, Type>();
73
+
74
+ static_assert(type_hash32<int> != type_hash32<unsigned>);
31
75
 
32
76
  } // namespace util
@@ -17,7 +17,7 @@ constexpr auto sequence_cw = [] consteval -> auto {
17
17
  // Return a sequence of constexpr indices
18
18
  export template <std::size_t Size>
19
19
  constexpr auto sequence = [] consteval -> auto {
20
- #if defined(__clang__)
20
+ #if defined(__clang__) && __clang_major__ < 23
21
21
  return sequence_cw<Size>;
22
22
  #else
23
23
  constexpr_array<std::size_t, Size> result{};