Skip to content

Commit 722877a

Browse files
shuaimuclaude
andcommitted
Add RustyHash adapter and include try.hpp in parity runner
RustyHash<K> (include/rusty/hashmap.hpp): - Generic hash adapter for rusty::HashMap default hash parameter - Uses std::hash<K> when available (SFINAE specialization) - Falls back to K::hash() method (transpiled Rust #[derive(Hash)]) - Last resort: FNV hash of raw bytes - Fixes: std::hash<ArrayString<16>>::~hash() deleted error HashMap default hash changed from std::hash<K> to RustyHash<K>. This lets transpiled types with .hash() methods work as HashMap keys without requiring explicit std::hash specializations. Runner generation (transpiler/src/main.rs): - Added #include <rusty/try.hpp> for RUSTY_TRY/RUSTY_CO_TRY macros - Fixes: RUSTY_TRY not declared in scope error 716 transpiler tests + 19 C++ io tests, all passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 66d08ca commit 722877a

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

include/rusty/hashmap.hpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,39 @@
1010
#include "option.hpp"
1111
#include "vec.hpp"
1212

13+
// Generic hash adapter: uses std::hash<K> if available, otherwise falls back
14+
// to calling K::hash() method (as generated by Rust's #[derive(Hash)]).
15+
// This bridges transpiled Rust types (which have .hash() methods) with C++
16+
// hash containers that expect std::hash<K>.
17+
template<typename K, typename = void>
18+
struct RustyHash {
19+
// Fallback: call the type's .hash() method if it has one
20+
size_t operator()(const K& key) const {
21+
size_t state = 0;
22+
if constexpr (requires { key.hash(state); }) {
23+
key.hash(state);
24+
return state;
25+
} else {
26+
// Last resort: hash the raw bytes
27+
const auto* bytes = reinterpret_cast<const unsigned char*>(&key);
28+
size_t h = 14695981039346656037ULL;
29+
for (size_t i = 0; i < sizeof(K); ++i) {
30+
h ^= bytes[i];
31+
h *= 1099511628211ULL;
32+
}
33+
return h;
34+
}
35+
}
36+
};
37+
38+
// Specialization: if std::hash<K> is valid, use it
39+
template<typename K>
40+
struct RustyHash<K, std::void_t<decltype(std::hash<K>{}(std::declval<K>()))>> {
41+
size_t operator()(const K& key) const {
42+
return std::hash<K>{}(key);
43+
}
44+
};
45+
1346
// Swiss Table HashMap - High-performance hash table based on Google's SwissTable/Abseil
1447
// and Rust's HashMap implementation
1548
//
@@ -141,7 +174,7 @@ struct ProbeSeq {
141174
}
142175
};
143176

144-
template <typename K, typename V, typename Hash = std::hash<K>, typename KeyEqual = std::equal_to<K>>
177+
template <typename K, typename V, typename Hash = RustyHash<K>, typename KeyEqual = std::equal_to<K>>
145178
class HashMap {
146179
private:
147180
// Bucket structure

transpiler/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1314,7 +1314,7 @@ fn run_parity_test(args: &ParityTestArgs) -> Result<(), String> {
13141314
runner_src.push_str("#include <iostream>\n#include <cassert>\n#include <vector>\n");
13151315
runner_src.push_str("#include <functional>\n#include <span>\n");
13161316
runner_src.push_str("#include <rusty/rusty.hpp>\n");
1317-
runner_src.push_str("#include <rusty/io.hpp>\n#include <rusty/array.hpp>\n\n");
1317+
runner_src.push_str("#include <rusty/io.hpp>\n#include <rusty/array.hpp>\n#include <rusty/try.hpp>\n\n");
13181318
runner_src.push_str("// Overloaded visitor helper\n");
13191319
runner_src.push_str(
13201320
"template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };\n",

0 commit comments

Comments
 (0)