Skip to content

Commit

Permalink
Update hash_append.adoc
Browse files Browse the repository at this point in the history
  • Loading branch information
pdimov committed Nov 19, 2024
1 parent 1268d5d commit 999d6c0
Showing 1 changed file with 54 additions and 6 deletions.
60 changes: 54 additions & 6 deletions doc/hash2/reference/hash_append.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,30 @@ constexpr void hash_append( Hash& h, Flavor const& f, T const& v );

Appends the representation of `v` to the message stored in `h`.

Effects: ::
* If `is_contiguously_hashable<T, Flavor::byte_order>::value` is `true`, calls `h.update(&v, sizeof(v))`;
* If `std::is_integral<T>::value` is `true`, obtains a byte representation of `v` in the byte order requested by `Flavor::byte_order`, then calls `h.update(p, n)` where `p` is the address of that representation and `n` is `sizeof(v)`;
* If `std::is_pointer<T>::value` is `true`, calls `hash_append(h, f, reinterpret_cast<std::uintptr_t>(v))`;
* If `std::is_floating_point<T>::value` is true, first replaces `v` with positive zero if it's negative zero, then calls `hash_append(h, f, std::bit_cast<U>(v))`, where `U` is an unsigned integer type with the same size as `T`;
* If `T` is `std::nullptr_t`, calls `hash_append(h, f, static_cast<void*>(v))`;
* If `T` is an array type `U[N]`, calls `hash_append_range(h, f, v + 0, v + N)`;
* If `tag_invoke(hash_append_tag(), h, f, v)` is a valid expression, calls `tag_invoke(hash_append_tag(), h, f, v)`;
* If `std::is_enum<T>::value` is `true`, calls `hash_append(h, f, w)`, where `w` is `v` converted to the underlying type of `T`;
* If `boost::container_hash::is_unordered_range<T>::value` is `true`, calls `hash_append_unordered_range(h, f, v.begin(), v.end())`;
* If `boost::container_hash::is_contiguous_range<T>::value` is `true` and
- `has_constant_size<T>::value` is `true`, calls `hash_append_range(h, f, v.data(), v.data() + v.size())`;
- `has_constant_size<T>::value` is `false`, calls `hash_append_sized_range(h, f, v.data(), v.data() + v.size())`;
* If `boost::container_hash::is_range<T>::value` is `true` and
- `has_constant_size<T>::value` is `true`, calls `hash_append_range(h, f, v.begin(), v.end())`;
- `has_constant_size<T>::value` is `false`, calls `hash_append_sized_range(h, f, v.begin(), v.end())`;
* If `boost::container_hash::is_tuple_like<T>::value` is `true`, calls `hash_append(h, f, w)` for each tuple element `w`;
* If `boost::container_hash::is_described_class<T>::value` is `true`, calls `hash_append(h, f, b)` for each base class subobject `b` of `v`, then `hash_append(h, f, m)` for each member subobject `m` of `v`;
* Otherwise, the result is a compile-time error.

Remarks: ::
In case the above description would result in no calls being made (e.g. for a range of constant size zero, or a described `struct` with no bases and members),
a call to `hash_append(h, f, '\x00')` is made to satisfy the requirement that `hash_append` always results in at least one call to `Hash::update`.

## hash_append_range

```
Expand All @@ -57,14 +81,11 @@ Requires: ::
`It` must be an _iterator_ type. `[first, last)` must be a valid _iterator range_.

Effects: ::
* If `It` is `T*` and `is_contiguously_hashable<T, Flavor::byte_order>::value` is `true`, calls `h.update( first, (last - first) * sizeof(T) );`.
* Otherwise, for each iterator `i` in `[first, last)`, calls `hash_append(h, f, v);`, where `v` is `*i`, implicitly converted to `std::iterator_traits<It>::value_type const&`.
* If `It` is `T*` and `is_contiguously_hashable<T, Flavor::byte_order>::value` is `true`, calls `h.update(first, (last - first) * sizeof(T));`.
* Otherwise, for each element `v` in the range denoted by `[first, last)`, calls `hash_append(h, f, v);`.

Remarks: ::
+
If `hash_append_range` is called in a constant expression, the contiguously hashable optimization is only applied for `unsigned char*` and `unsigned char const*`.
+
`*i` is converted to a reference to the iterator `value_type` to handle the case when its `reference` is a proxy type, for example, when the iterator is `std::vector<bool>::iterator`.
If `hash_append_range` is called in a constant expression, the contiguously hashable optimization is only applied for `unsigned char*` and `unsigned char const*`.

## hash_append_size

Expand All @@ -75,6 +96,12 @@ constexpr void hash_append_size( Hash& h, Flavor const& f, T const& v );

Appends the representation of `v`, converted to `Flavor::size_type`, to the message stored in `h`.

Requires: ::
`T` must be an integral type.

Effects: ::
Equivalent to `hash_append(h, f, static_cast<typename Flavor::size_type>(v));`

## hash_append_sized_range

```
Expand All @@ -84,6 +111,12 @@ constexpr void hash_append_sized_range( Hash& h, Flavor const& f, It first, It l

Appends the representations of the elements of the range `[first, last)`, followed by the size of the range, to the message stored in `h`.

Requires: ::
`It` must be an _iterator_ type. `[first, last)` must be a valid _iterator range_.

Effects: ::
Equivalent to `hash_append_range(h, f, first, last); hash_append(h, f, m);`, where `m` is `std::distance(first, last)`.

## hash_append_unordered_range

```
Expand All @@ -93,6 +126,21 @@ constexpr void hash_append_unordered_range( Hash& h, Flavor const& f, It first,

Constructs a value from the representations of the elements of the range `[first, last)`, in a way such that their order doesn't affect the result, then appends that value, followed by the size of the range, to the message stored in `h`.

Requires: ::
`It` must be an _iterator_ type. `[first, last)` must be a valid _iterator range_.

Effects: ::
+
For each element `v` in the range denoted by `[first, last)`, obtains a hash value `r` by doing
+
```
Hash h2(h);
hash_append(h2, f, v);
auto r = h2.result();
```
+
and then combines the so obtained `r` values in a way that is not sensitive to their order, producing a combined value `q`. Calls `hash_append(h, f, q)`, followed by `hash_append(h, f, m)`, where `m` is `std::distance(first, last)`.

## hash_append_tag

```
Expand Down

0 comments on commit 999d6c0

Please sign in to comment.