Search before asking
Version
Latest Fory
Component(s)
C++
Minimal reproduce step
Consider this FDL:
package repro.temporal_key;
message Holder {
map<duration, string> values = 1;
}
What did you expect to see?
The generated code should compile.
What did you see instead?
The generated code fails to compile.
Anything Else?
Root Cause
This bug is introduced by PR #3745. In this PR, we generate unordered_map for IDL's map type to match the behaviors of other languages.
But in C++, the key type of an unordered_map must be hashable.
Fory documents duration and timestamp as valid IDL map key types. Currently, Fory maps duration to fory::serialization::Duration and timestamp to fory::serialization::Timestamp. But these two types are just aliases for standard library types:
|
// ============================================================================ |
|
// Temporal Type Aliases |
|
// ============================================================================ |
|
|
|
/// Duration: absolute length of time as nanoseconds |
|
using Duration = std::chrono::nanoseconds; |
|
|
|
/// Timestamp: point in time as nanoseconds since Unix epoch (Jan 1, 1970 UTC) |
|
using Timestamp = std::chrono::time_point<std::chrono::system_clock, |
|
std::chrono::nanoseconds>; |
In C++17, these standard library types do not provide usable std::hash specializations, so std::unordered_map<fory::serialization::Duration, ...> and std::unordered_map<fory::serialization::Timestamp, ...> fail to compile.
date does not hit the same problem because Fory maps it to a Fory-owned Date type instead of a standard library alias. date can also hit the same problem.
Proposed Fix
Replace fory::serialization::Duration and fory::serialization::Timestamp from standard-library aliases with Fory-owned wrapper types.
Duration should store a normalized seconds/nanoseconds representation or total nanoseconds, and Timestamp should store seconds/nanoseconds since the Unix epoch.
These wrapper types should provide equality, ordering, and hash methods, so they can be used directly as unordered_map keys.
The serializers can keep the existing wire format unchanged by reading from and writing to the wrapper fields using the same seconds/nanoseconds encoding.
Are you willing to submit a PR?
Search before asking
Version
Latest Fory
Component(s)
C++
Minimal reproduce step
Consider this FDL:
What did you expect to see?
The generated code should compile.
What did you see instead?
The generated code fails to compile.
Anything Else?
Root Cause
This bug is introduced by PR #3745. In this PR, we generate
unordered_mapfor IDL'smaptype to match the behaviors of other languages.But in C++, the key type of an
unordered_mapmust be hashable.Fory documents
durationandtimestampas valid IDLmapkey types. Currently, Fory mapsdurationtofory::serialization::Durationand timestamp tofory::serialization::Timestamp. But these two types are just aliases for standard library types:fory/cpp/fory/serialization/temporal_serializers.h
Lines 29 to 38 in 6c6ba3f
In C++17, these standard library types do not provide usable
std::hashspecializations, sostd::unordered_map<fory::serialization::Duration, ...>andstd::unordered_map<fory::serialization::Timestamp, ...>fail to compile.datedoes not hit the same problem because Fory maps it to a Fory-ownedDatetype instead of a standard library alias.datecan also hit the same problem.Proposed Fix
Replace
fory::serialization::Durationandfory::serialization::Timestampfrom standard-library aliases with Fory-owned wrapper types.Duration should store a normalized seconds/nanoseconds representation or total nanoseconds, and Timestamp should store seconds/nanoseconds since the Unix epoch.
These wrapper types should provide equality, ordering, and hash methods, so they can be used directly as
unordered_mapkeys.The serializers can keep the existing wire format unchanged by reading from and writing to the wrapper fields using the same seconds/nanoseconds encoding.
Are you willing to submit a PR?