@auto_js/utility 0.0.9 → 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.9",
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",
@@ -1,60 +1,62 @@
1
+ module;
2
+ #include <version>
1
3
  export module util:platform.format;
2
4
  import std;
3
5
 
4
6
  namespace util {
5
7
 
6
- #if defined(__GNUC__) && !defined(__clang__)
8
+ #if __GLIBCXX__
7
9
 
8
10
  // Claude-generated `std::format` fill to avoid gcc 16.2.0 libstdc++ requirement.
9
11
 
10
12
  template <class Type>
11
13
  struct printf_arg {
12
- static_assert(false, "type is not formattable by the `util::format` polyfill");
14
+ static_assert(false, "type is not formattable by the `util::format` polyfill");
13
15
  };
14
16
 
15
17
  template <>
16
18
  struct printf_arg<bool> {
17
- constexpr static auto spec = std::string_view{"%s"};
18
- constexpr static auto pass(bool value) { return std::tuple{value ? "true" : "false"}; }
19
+ constexpr static auto spec = std::string_view{"%s"};
20
+ constexpr static auto pass(bool value) { return std::tuple{value ? "true" : "false"}; }
19
21
  };
20
22
 
21
23
  template <>
22
24
  struct printf_arg<char> {
23
- constexpr static auto spec = std::string_view{"%c"};
24
- constexpr static auto pass(char value) { return std::tuple{value}; }
25
+ constexpr static auto spec = std::string_view{"%c"};
26
+ constexpr static auto pass(char value) { return std::tuple{value}; }
25
27
  };
26
28
 
27
29
  template <class Type>
28
30
  requires std::signed_integral<Type>
29
31
  struct printf_arg<Type> {
30
- constexpr static auto spec = std::string_view{"%lld"};
31
- constexpr static auto pass(Type value) { return std::tuple{static_cast<long long>(value)}; }
32
+ constexpr static auto spec = std::string_view{"%lld"};
33
+ constexpr static auto pass(Type value) { return std::tuple{static_cast<long long>(value)}; }
32
34
  };
33
35
 
34
36
  template <class Type>
35
37
  requires std::unsigned_integral<Type>
36
38
  struct printf_arg<Type> {
37
- constexpr static auto spec = std::string_view{"%llu"};
38
- constexpr static auto pass(Type value) { return std::tuple{static_cast<unsigned long long>(value)}; }
39
+ constexpr static auto spec = std::string_view{"%llu"};
40
+ constexpr static auto pass(Type value) { return std::tuple{static_cast<unsigned long long>(value)}; }
39
41
  };
40
42
 
41
43
  template <class Type>
42
- requires (std::same_as<Type, float> || std::same_as<Type, double>)
44
+ requires(std::same_as<Type, float> || std::same_as<Type, double>)
43
45
  struct printf_arg<Type> {
44
- constexpr static auto spec = std::string_view{"%g"};
45
- constexpr static auto pass(Type value) { return std::tuple{static_cast<double>(value)}; }
46
+ constexpr static auto spec = std::string_view{"%g"};
47
+ constexpr static auto pass(Type value) { return std::tuple{static_cast<double>(value)}; }
46
48
  };
47
49
 
48
50
  template <>
49
51
  struct printf_arg<long double> {
50
- constexpr static auto spec = std::string_view{"%Lg"};
51
- constexpr static auto pass(long double value) { return std::tuple{value}; }
52
+ constexpr static auto spec = std::string_view{"%Lg"};
53
+ constexpr static auto pass(long double value) { return std::tuple{value}; }
52
54
  };
53
55
 
54
56
  template <>
55
57
  struct printf_arg<const char*> {
56
- constexpr static auto spec = std::string_view{"%s"};
57
- constexpr static auto pass(const char* value) { return std::tuple{value}; }
58
+ constexpr static auto spec = std::string_view{"%s"};
59
+ constexpr static auto pass(const char* value) { return std::tuple{value}; }
58
60
  };
59
61
 
60
62
  template <>
@@ -62,10 +64,10 @@ struct printf_arg<char*> : printf_arg<const char*> {};
62
64
 
63
65
  template <>
64
66
  struct printf_arg<std::string_view> {
65
- constexpr static auto spec = std::string_view{"%.*s"};
66
- constexpr static auto pass(std::string_view value) {
67
- return std::tuple{static_cast<int>(value.size()), value.data()};
68
- }
67
+ constexpr static auto spec = std::string_view{"%.*s"};
68
+ constexpr static auto pass(std::string_view value) {
69
+ return std::tuple{static_cast<int>(value.size()), value.data()};
70
+ }
69
71
  };
70
72
 
71
73
  template <>
@@ -73,8 +75,8 @@ struct printf_arg<std::string> : printf_arg<std::string_view> {};
73
75
 
74
76
  template <>
75
77
  struct printf_arg<const void*> {
76
- constexpr static auto spec = std::string_view{"%p"};
77
- constexpr static auto pass(const void* value) { return std::tuple{value}; }
78
+ constexpr static auto spec = std::string_view{"%p"};
79
+ constexpr static auto pass(const void* value) { return std::tuple{value}; }
78
80
  };
79
81
 
80
82
  template <>
@@ -82,8 +84,8 @@ struct printf_arg<void*> : printf_arg<const void*> {};
82
84
 
83
85
  template <>
84
86
  struct printf_arg<std::nullptr_t> {
85
- constexpr static auto spec = std::string_view{"%p"};
86
- constexpr static auto pass(std::nullptr_t /*value*/) { return std::tuple{static_cast<const void*>(nullptr)}; }
87
+ constexpr static auto spec = std::string_view{"%p"};
88
+ constexpr static auto pass(std::nullptr_t /*value*/) { return std::tuple{static_cast<const void*>(nullptr)}; }
87
89
  };
88
90
 
89
91
  // Checks the format string against the argument types and rewrites `{}` replacement fields into
@@ -160,7 +162,8 @@ export template <class... Args>
160
162
  std::snprintf(result.data(), result.size() + 1, format.get(), values...);
161
163
  return result;
162
164
  },
163
- std::tuple_cat(printf_arg<std::decay_t<Args>>::pass(args)...));
165
+ std::tuple_cat(printf_arg<std::decay_t<Args>>::pass(args)...)
166
+ );
164
167
  }
165
168
 
166
169
  #else
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{};