@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 +1 -1
- package/platform/format.cc +29 -26
- package/utility/hash.cc +63 -19
- package/utility/sequence.cc +1 -1
package/package.json
CHANGED
package/platform/format.cc
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
|
|
31
|
-
|
|
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
|
-
|
|
38
|
-
|
|
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
|
|
44
|
+
requires(std::same_as<Type, float> || std::same_as<Type, double>)
|
|
43
45
|
struct printf_arg<Type> {
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
51
|
-
|
|
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
|
-
|
|
57
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
77
|
-
|
|
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
|
-
|
|
86
|
-
|
|
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
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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
|
|
24
|
-
|
|
25
|
-
constexpr auto name = std::source_location::current().function_name();
|
|
26
|
-
|
|
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
|
|
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
|
package/utility/sequence.cc
CHANGED
|
@@ -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{};
|