Skip to content

Commit dc15d25

Browse files
authored
Document C++ hash functions (#1443)
Resolves: #1431 Signed-off-by: Daniel Kamkha <daniel.kamkha@here.com>
1 parent 7c12304 commit dc15d25

File tree

1 file changed

+54
-12
lines changed

1 file changed

+54
-12
lines changed

docs/hashes.md

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,57 @@
11
Hash functions in C++
22
=====================
33

4-
TODO: #1431
5-
6-
For types marked as `Equatable` Gluecodium will also generate a hash function. It appears most
7-
convenient to generate `hash` for custom types in `std` namespace. Sadly STL does not provide
8-
`hash` for containers used by Gluecodium, i.e. `vector`, `unordered_map` and `unordered_set`. In order to
9-
not conflict with any library providing these, Gluecodium should not provide hash functionality for these
10-
in `std` namespace. Gluecodium also distinguishes between `Equatable` and `PointerEquatable` for classes,
11-
which should result in different hashing for `shared_ptr` of the classes. This would conflict with
12-
STL which already defines hash for `shared_ptr` thus might lead to conflicts in generated code. All
13-
in all it is much more consistent if Gluecodium uses `hash` in internal namespace which is implemented
14-
in a way to fallback to `std::hash` if no specialization is available, reusing hash for primitive
15-
types.
4+
For types marked as `Equatable`, Gluecodium will generate a C++ hash function in addition to any equality operators. It
5+
may seem most convenient to generate the `hash` function for custom types in the `std` namespace. Unfortunately, C++
6+
standard library (STL) does not provide `std::hash` for container types: `vector`, `unordered_map` and `unordered_set`.
7+
To avoid conflict with any third-party library providing these container hashes, the decision was made to provide such
8+
Gluecodium hashes in a custom namespace instead. The custom hash falls through to `std::hash` for types, where it is
9+
available.
10+
11+
Main hash function
12+
------------------
13+
14+
`gluecodium::hash` function, generated in a custom namespace, provides the hashing functionality for
15+
Gluecodium-generated code. The main function itself is a template with no logic of its own. The logic is provided either
16+
by a generated specialization, or by the fall-though template selector:
17+
* `gluecodium::hash` specialization is used, if available. Otherwise,
18+
* for enumerations, the trivial `EnumHash` is used, returning the enumerator value as the hash value;
19+
* for shared pointer, a specialization of `EqualityHash` template is used, if available (see below);
20+
* `std::hash` is used, if available.
21+
* if none of the above works, compilation fails (normally, this never happens).
22+
23+
Manual implementation
24+
---------------------
25+
26+
When a `class` or `interface` is marked with `@Equatable` in LIME IDL definitions, a `gluecodium::hash` specialization
27+
has to be implemented manually (next to the rest of the manual "logic" code). When this specialization is implemented,
28+
the main `gluecodium::hash` template uses it through the custom "shared pointer hash" template (see below).
29+
30+
Shared pointer hash
31+
-------------------
32+
33+
The standard `std::hash` does exist for `std::shared_ptr`. It computes the hash value based on the raw pointer value.
34+
However, for `@Equatable` classes the working assumption is: if an instance of this is somehow "equatable" based on its
35+
internal state, it also would be "hashable" based on the same state. Therefore, for such classes `gluecodium::hash` main
36+
template falls through to `EqualityHash` custom shared pointer hash. `EqualityHash`, in turn, uses the manually
37+
implemented specialization `gluecodium::hash` (see above), that is expected to perform this "internal state hashing".
38+
39+
Container hashes
40+
----------------
41+
42+
The `gluecodium::hash` template has specializations for several container types: `std::vector`, `std::unordered_set`,
43+
and `std::unordered_map`. For vector and set types, the hash value is calculated based on hash values of individual
44+
elements in the container. For the map type, the hash value is calculated based on both the keys and the values in the
45+
map.
46+
47+
Struct hash
48+
-----------
49+
50+
`@Equatable` structs have a generated specialization of the `gluecodium::hash` template. The hash value is calculated
51+
based on hash values of individual struct fields.
52+
53+
Other custom hashes
54+
-------------------
55+
56+
The `gluecodium::hash` template also has specializations for `std::chrono::duration` and `std::chrono::time_point`. The
57+
custom Gluecodium type `Locale` has a dedicated hash specialization too.

0 commit comments

Comments
 (0)