This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git
The following commit(s) were added to refs/heads/main by this push:
new 7752c01dd fix(c++): std::unordered_map cannot be used in struct.
(#3727) (#3728)
7752c01dd is described below
commit 7752c01dd47c1504f5434f6bdfd3cf5d4e9c18de
Author: MikuSoft <[email protected]>
AuthorDate: Thu Jun 4 17:24:21 2026 +0800
fix(c++): std::unordered_map cannot be used in struct. (#3727) (#3728)
## Why?
Cannot compile when there is a std::unordered_map in struct.
## What does this PR do?
Fix that .
## Related issues
Issue #3727 .
## AI Contribution Checklist
- [ ] Substantial AI assistance was used in this PR: `yes` / `no`
- [ ] If `yes`, I included a completed [AI Contribution
Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs)
in this PR description and the required `AI Usage Disclosure`.
- [ ] If `yes`, my PR description includes the required `ai_review`
summary and screenshot evidence of the final clean AI review results
from both fresh reviewers on the current PR diff or current HEAD after
the latest code changes.
## Does this PR introduce any user-facing change?
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
---
cpp/fory/serialization/map_serializer.h | 13 ++-------
cpp/fory/serialization/map_serializer_test.cc | 40 +++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 10 deletions(-)
diff --git a/cpp/fory/serialization/map_serializer.h
b/cpp/fory/serialization/map_serializer.h
index 878da85e6..855462735 100644
--- a/cpp/fory/serialization/map_serializer.h
+++ b/cpp/fory/serialization/map_serializer.h
@@ -1080,22 +1080,15 @@ struct Serializer<std::unordered_map<K, V, Args...>> {
using MapType = std::unordered_map<K, V, Args...>;
static inline void write(const MapType &map, WriteContext &ctx,
- RefMode ref_mode, bool write_type) {
+ RefMode ref_mode, bool write_type,
+ bool has_generics = false) {
write_not_null_ref_flag(ctx, ref_mode);
if (write_type) {
ctx.write_uint8(static_cast<uint8_t>(type_id));
}
- constexpr bool is_fast_path =
- !is_polymorphic_v<K> && !is_polymorphic_v<V> && !is_shared_ref_v<K> &&
- !is_shared_ref_v<V> && !is_nullable_v<K> && !is_nullable_v<V>;
-
- if constexpr (is_fast_path) {
- write_map_data_fast<K, V>(map, ctx, false);
- } else {
- write_map_data_slow<K, V>(map, ctx, true);
- }
+ write_data_generic(map, ctx, has_generics);
}
static inline void write_data(const MapType &map, WriteContext &ctx) {
diff --git a/cpp/fory/serialization/map_serializer_test.cc
b/cpp/fory/serialization/map_serializer_test.cc
index 4478aef29..2d16697f8 100644
--- a/cpp/fory/serialization/map_serializer_test.cc
+++ b/cpp/fory/serialization/map_serializer_test.cc
@@ -97,6 +97,46 @@ TEST(MapSerializerTest, NestedMapRoundtrip) {
test_map_roundtrip(nested);
}
+struct MapsInStruct {
+ std::map<int, std::string> map{};
+ std::unordered_map<std::string, std::string> unordered_map{};
+
+ auto operator==(const MapsInStruct &rhs) const -> bool {
+ return map == rhs.map && unordered_map == rhs.unordered_map;
+ }
+
+ FORY_STRUCT(MapsInStruct, map, unordered_map);
+};
+
+TEST(MapSerializerTest, UnorderedMapInStruct) {
+ MapsInStruct original{};
+ original.map[1] = "1";
+ original.map[2] = "2";
+ original.unordered_map["1"] = "2";
+ original.unordered_map["2"] = "2";
+
+ // Create Fory instance with default config
+ auto fory = Fory::builder().xlang(true).compatible(true).build();
+
+ fory.register_struct<MapsInStruct>(0);
+
+ // Serialize
+ auto serialize_result = fory.serialize(original);
+ ASSERT_TRUE(serialize_result.ok())
+ << "Serialization failed: " << serialize_result.error().message();
+ auto bytes = serialize_result.value();
+
+ // Deserialize
+ auto deserialize_result =
+ fory.deserialize<MapsInStruct>(bytes.data(), bytes.size());
+ ASSERT_TRUE(deserialize_result.ok())
+ << "Deserialization failed: " << deserialize_result.error().message();
+ auto deserialized = deserialize_result.value();
+
+ // Compare
+ EXPECT_EQ(original, deserialized);
+}
+
// ============================================================================
// Map with Optional Values (Polymorphic-like behavior)
// ============================================================================
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]