BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslh_hashvariant.h
Go to the documentation of this file.
1/// @file bslh_hashvariant.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslh_hashvariant.h -*-C++-*-
8#ifndef INCLUDED_BSLH_HASHVARIANT
9#define INCLUDED_BSLH_HASHVARIANT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslh_hashvariant bslh_hashvariant
15/// @brief Provide `hashAppend` for `std::variant`.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslh
19/// @{
20/// @addtogroup bslh_hashvariant
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslh_hashvariant-purpose"> Purpose</a>
25/// * <a href="#bslh_hashvariant-description"> Description </a>
26/// * <a href="#bslh_hashvariant-usage"> Usage </a>
27/// * <a href="#bslh_hashvariant-example-1-hashing-an-integer-or-floating-point-value"> Example 1: Hashing an integer or floating-point value </a>
28///
29/// # Purpose {#bslh_hashvariant-purpose}
30/// Provide `hashAppend` for `std::variant`.
31///
32/// # Description {#bslh_hashvariant-description}
33/// This component provides a free function template,
34/// `bslh::hashAppend`, overloaded for the `std::variant` class template.
35/// Including this function allows for `std::variant` types (and types that
36/// contain them) to be used as keys in BDE hashed containers.
37///
38/// Note that use of this component requires that the language standard be 2017
39/// or later, as that is when `std::variant` first appears.
40///
41/// ## Usage {#bslh_hashvariant-usage}
42///
43///
44/// This section illustrates intended usage of this component.
45///
46/// ### Example 1: Hashing an integer or floating-point value {#bslh_hashvariant-example-1-hashing-an-integer-or-floating-point-value}
47///
48///
49/// Suppose we want to maintain a value as either an integer or a floating-point
50/// number, and have it fit within the BDE hash framework. We can use
51/// `std::variant<int, double>` for this, and demonstrate that such a value can
52/// be correctly hashed.
53///
54/// First, we set up a pair of such optional values to represent the two
55/// potential states we wish to represent.
56/// @code
57/// typedef std::variant<int, double> id;
58/// id variantInt = 42;
59/// id variantDouble = 3.475;
60/// @endcode
61/// Then, we create a hashing object.
62/// @code
63/// bslh::Hash<> hasher;
64/// @endcode
65/// Next, we hash each of our values.
66/// @code
67/// size_t variantIntHash = hasher(variantInt);
68/// size_t variantDoubleHash = hasher(variantDouble);
69/// @endcode
70/// Then we hash the underlying values. A variant hashes as a pair of values,
71/// first the `size_t` index of the held type, then the contained value, so we
72/// need to accumulate the hashes.
73/// @code
74/// bslh::Hash<>::HashAlgorithm haInt;
75/// hashAppend(haInt, size_t(0));
76/// hashAppend(haInt, 42);
77/// size_t expectedIntHash = size_t(haInt.computeHash());
78///
79/// bslh::Hash<>::HashAlgorithm haDouble;
80/// hashAppend(haDouble, size_t(1));
81/// hashAppend(haDouble, 3.475);
82/// size_t expectedDoubleHash = size_t(haDouble.computeHash());
83/// @endcode
84/// Finally, we verify that the `std::variant` hasher produces the same results
85/// as the underlying hashers.
86/// @code
87/// assert(expectedIntHash == variantIntHash);
88/// assert(expectedDoubleHash == variantDoubleHash);
89/// @endcode
90/// @}
91/** @} */
92/** @} */
93
94/** @addtogroup bsl
95 * @{
96 */
97/** @addtogroup bslh
98 * @{
99 */
100/** @addtogroup bslh_hashvariant
101 * @{
102 */
103
104#include <bslscm_version.h>
105
106#include <bslh_hash.h>
107
109#include <bsls_libraryfeatures.h>
110#include <bsls_platform.h>
111
112#include <stddef.h> // for 'size_t'
113
114#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
115
116#include <variant>
117
118#define BSLH_HASHVARIANT_DEFINE_HASH_MONOSTATE 1
119
120
121namespace bslh {
122
123// FREE FUNCTIONS
124
125/// Pass the special value corresponding to the `std::monostate` object to
126/// the specified `algorithm`. This function integrates with the `bslh`
127/// modular hashing system and effectively provides a `bsl::hash`
128/// specialization for `std::monostate`.
129template <class HASH_ALGORITHM>
130inline
131void
132hashAppend(HASH_ALGORITHM& algorithm, const std::monostate&)
133{
134 hashAppend(algorithm, -7777);
135}
136
137/// Pass the index of the active variant of the specified `input` to the
138/// specified `algorithm`, followed by the active value itself, to be
139/// combined into the internal state of the algorithm that is used to
140/// produce the resulting hash value.
141template <class HASH_ALGORITHM, class ... TYPE>
142inline
143void
144hashAppend(HASH_ALGORITHM& algorithm, const std::variant<TYPE ...> &input)
145{
146 hashAppend(algorithm, input.index());
147 std::visit([&](const auto& x) { hashAppend(algorithm, x); }, input);
148}
149
150} // close package namespace
151
152
153#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
154
155#endif
156
157// ----------------------------------------------------------------------------
158// Copyright 2020 Bloomberg Finance L.P.
159//
160// Licensed under the Apache License, Version 2.0 (the "License");
161// you may not use this file except in compliance with the License.
162// You may obtain a copy of the License at
163//
164// http://www.apache.org/licenses/LICENSE-2.0
165//
166// Unless required by applicable law or agreed to in writing, software
167// distributed under the License is distributed on an "AS IS" BASIS,
168// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
169// See the License for the specific language governing permissions and
170// limitations under the License.
171// ----------------------------- END-OF-FILE ----------------------------------
172
173/** @} */
174/** @} */
175/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslh_defaulthashalgorithm.h:339
bsl::enable_if<(bsl::is_integral< TYPE >::value||bsl::is_pointer< TYPE >::value||bsl::is_enum< TYPE >::value)&&!bsl::is_same< TYPE, bool >::value >::type hashAppend(HASH_ALGORITHM &hashAlg, TYPE input)
Definition bslh_hash.h:638