1*9356374aSAndroid Build Coastguard Worker // Copyright 2018 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker //
15*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
16*9356374aSAndroid Build Coastguard Worker // File: hash.h
17*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
18*9356374aSAndroid Build Coastguard Worker //
19*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_HASH_INTERNAL_HASH_H_
20*9356374aSAndroid Build Coastguard Worker #define ABSL_HASH_INTERNAL_HASH_H_
21*9356374aSAndroid Build Coastguard Worker
22*9356374aSAndroid Build Coastguard Worker #ifdef __APPLE__
23*9356374aSAndroid Build Coastguard Worker #include <Availability.h>
24*9356374aSAndroid Build Coastguard Worker #include <TargetConditionals.h>
25*9356374aSAndroid Build Coastguard Worker #endif
26*9356374aSAndroid Build Coastguard Worker
27*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
28*9356374aSAndroid Build Coastguard Worker
29*9356374aSAndroid Build Coastguard Worker // For feature testing and determining which headers can be included.
30*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
31*9356374aSAndroid Build Coastguard Worker #include <version>
32*9356374aSAndroid Build Coastguard Worker #else
33*9356374aSAndroid Build Coastguard Worker #include <ciso646>
34*9356374aSAndroid Build Coastguard Worker #endif
35*9356374aSAndroid Build Coastguard Worker
36*9356374aSAndroid Build Coastguard Worker #include <algorithm>
37*9356374aSAndroid Build Coastguard Worker #include <array>
38*9356374aSAndroid Build Coastguard Worker #include <bitset>
39*9356374aSAndroid Build Coastguard Worker #include <cmath>
40*9356374aSAndroid Build Coastguard Worker #include <cstddef>
41*9356374aSAndroid Build Coastguard Worker #include <cstring>
42*9356374aSAndroid Build Coastguard Worker #include <deque>
43*9356374aSAndroid Build Coastguard Worker #include <forward_list>
44*9356374aSAndroid Build Coastguard Worker #include <functional>
45*9356374aSAndroid Build Coastguard Worker #include <iterator>
46*9356374aSAndroid Build Coastguard Worker #include <limits>
47*9356374aSAndroid Build Coastguard Worker #include <list>
48*9356374aSAndroid Build Coastguard Worker #include <map>
49*9356374aSAndroid Build Coastguard Worker #include <memory>
50*9356374aSAndroid Build Coastguard Worker #include <set>
51*9356374aSAndroid Build Coastguard Worker #include <string>
52*9356374aSAndroid Build Coastguard Worker #include <tuple>
53*9356374aSAndroid Build Coastguard Worker #include <type_traits>
54*9356374aSAndroid Build Coastguard Worker #include <unordered_map>
55*9356374aSAndroid Build Coastguard Worker #include <unordered_set>
56*9356374aSAndroid Build Coastguard Worker #include <utility>
57*9356374aSAndroid Build Coastguard Worker #include <vector>
58*9356374aSAndroid Build Coastguard Worker
59*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/unaligned_access.h"
60*9356374aSAndroid Build Coastguard Worker #include "absl/base/port.h"
61*9356374aSAndroid Build Coastguard Worker #include "absl/container/fixed_array.h"
62*9356374aSAndroid Build Coastguard Worker #include "absl/hash/internal/city.h"
63*9356374aSAndroid Build Coastguard Worker #include "absl/hash/internal/low_level_hash.h"
64*9356374aSAndroid Build Coastguard Worker #include "absl/meta/type_traits.h"
65*9356374aSAndroid Build Coastguard Worker #include "absl/numeric/bits.h"
66*9356374aSAndroid Build Coastguard Worker #include "absl/numeric/int128.h"
67*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
68*9356374aSAndroid Build Coastguard Worker #include "absl/types/optional.h"
69*9356374aSAndroid Build Coastguard Worker #include "absl/types/variant.h"
70*9356374aSAndroid Build Coastguard Worker #include "absl/utility/utility.h"
71*9356374aSAndroid Build Coastguard Worker
72*9356374aSAndroid Build Coastguard Worker #if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L && \
73*9356374aSAndroid Build Coastguard Worker !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
74*9356374aSAndroid Build Coastguard Worker #include <filesystem> // NOLINT
75*9356374aSAndroid Build Coastguard Worker #endif
76*9356374aSAndroid Build Coastguard Worker
77*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_STD_STRING_VIEW
78*9356374aSAndroid Build Coastguard Worker #include <string_view>
79*9356374aSAndroid Build Coastguard Worker #endif
80*9356374aSAndroid Build Coastguard Worker
81*9356374aSAndroid Build Coastguard Worker namespace absl {
82*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
83*9356374aSAndroid Build Coastguard Worker
84*9356374aSAndroid Build Coastguard Worker class HashState;
85*9356374aSAndroid Build Coastguard Worker
86*9356374aSAndroid Build Coastguard Worker namespace hash_internal {
87*9356374aSAndroid Build Coastguard Worker
88*9356374aSAndroid Build Coastguard Worker // Internal detail: Large buffers are hashed in smaller chunks. This function
89*9356374aSAndroid Build Coastguard Worker // returns the size of these chunks.
PiecewiseChunkSize()90*9356374aSAndroid Build Coastguard Worker constexpr size_t PiecewiseChunkSize() { return 1024; }
91*9356374aSAndroid Build Coastguard Worker
92*9356374aSAndroid Build Coastguard Worker // PiecewiseCombiner
93*9356374aSAndroid Build Coastguard Worker //
94*9356374aSAndroid Build Coastguard Worker // PiecewiseCombiner is an internal-only helper class for hashing a piecewise
95*9356374aSAndroid Build Coastguard Worker // buffer of `char` or `unsigned char` as though it were contiguous. This class
96*9356374aSAndroid Build Coastguard Worker // provides two methods:
97*9356374aSAndroid Build Coastguard Worker //
98*9356374aSAndroid Build Coastguard Worker // H add_buffer(state, data, size)
99*9356374aSAndroid Build Coastguard Worker // H finalize(state)
100*9356374aSAndroid Build Coastguard Worker //
101*9356374aSAndroid Build Coastguard Worker // `add_buffer` can be called zero or more times, followed by a single call to
102*9356374aSAndroid Build Coastguard Worker // `finalize`. This will produce the same hash expansion as concatenating each
103*9356374aSAndroid Build Coastguard Worker // buffer piece into a single contiguous buffer, and passing this to
104*9356374aSAndroid Build Coastguard Worker // `H::combine_contiguous`.
105*9356374aSAndroid Build Coastguard Worker //
106*9356374aSAndroid Build Coastguard Worker // Example usage:
107*9356374aSAndroid Build Coastguard Worker // PiecewiseCombiner combiner;
108*9356374aSAndroid Build Coastguard Worker // for (const auto& piece : pieces) {
109*9356374aSAndroid Build Coastguard Worker // state = combiner.add_buffer(std::move(state), piece.data, piece.size);
110*9356374aSAndroid Build Coastguard Worker // }
111*9356374aSAndroid Build Coastguard Worker // return combiner.finalize(std::move(state));
112*9356374aSAndroid Build Coastguard Worker class PiecewiseCombiner {
113*9356374aSAndroid Build Coastguard Worker public:
PiecewiseCombiner()114*9356374aSAndroid Build Coastguard Worker PiecewiseCombiner() : position_(0) {}
115*9356374aSAndroid Build Coastguard Worker PiecewiseCombiner(const PiecewiseCombiner&) = delete;
116*9356374aSAndroid Build Coastguard Worker PiecewiseCombiner& operator=(const PiecewiseCombiner&) = delete;
117*9356374aSAndroid Build Coastguard Worker
118*9356374aSAndroid Build Coastguard Worker // PiecewiseCombiner::add_buffer()
119*9356374aSAndroid Build Coastguard Worker //
120*9356374aSAndroid Build Coastguard Worker // Appends the given range of bytes to the sequence to be hashed, which may
121*9356374aSAndroid Build Coastguard Worker // modify the provided hash state.
122*9356374aSAndroid Build Coastguard Worker template <typename H>
123*9356374aSAndroid Build Coastguard Worker H add_buffer(H state, const unsigned char* data, size_t size);
124*9356374aSAndroid Build Coastguard Worker template <typename H>
add_buffer(H state,const char * data,size_t size)125*9356374aSAndroid Build Coastguard Worker H add_buffer(H state, const char* data, size_t size) {
126*9356374aSAndroid Build Coastguard Worker return add_buffer(std::move(state),
127*9356374aSAndroid Build Coastguard Worker reinterpret_cast<const unsigned char*>(data), size);
128*9356374aSAndroid Build Coastguard Worker }
129*9356374aSAndroid Build Coastguard Worker
130*9356374aSAndroid Build Coastguard Worker // PiecewiseCombiner::finalize()
131*9356374aSAndroid Build Coastguard Worker //
132*9356374aSAndroid Build Coastguard Worker // Finishes combining the hash sequence, which may may modify the provided
133*9356374aSAndroid Build Coastguard Worker // hash state.
134*9356374aSAndroid Build Coastguard Worker //
135*9356374aSAndroid Build Coastguard Worker // Once finalize() is called, add_buffer() may no longer be called. The
136*9356374aSAndroid Build Coastguard Worker // resulting hash state will be the same as if the pieces passed to
137*9356374aSAndroid Build Coastguard Worker // add_buffer() were concatenated into a single flat buffer, and then provided
138*9356374aSAndroid Build Coastguard Worker // to H::combine_contiguous().
139*9356374aSAndroid Build Coastguard Worker template <typename H>
140*9356374aSAndroid Build Coastguard Worker H finalize(H state);
141*9356374aSAndroid Build Coastguard Worker
142*9356374aSAndroid Build Coastguard Worker private:
143*9356374aSAndroid Build Coastguard Worker unsigned char buf_[PiecewiseChunkSize()];
144*9356374aSAndroid Build Coastguard Worker size_t position_;
145*9356374aSAndroid Build Coastguard Worker };
146*9356374aSAndroid Build Coastguard Worker
147*9356374aSAndroid Build Coastguard Worker // is_hashable()
148*9356374aSAndroid Build Coastguard Worker //
149*9356374aSAndroid Build Coastguard Worker // Trait class which returns true if T is hashable by the absl::Hash framework.
150*9356374aSAndroid Build Coastguard Worker // Used for the AbslHashValue implementations for composite types below.
151*9356374aSAndroid Build Coastguard Worker template <typename T>
152*9356374aSAndroid Build Coastguard Worker struct is_hashable;
153*9356374aSAndroid Build Coastguard Worker
154*9356374aSAndroid Build Coastguard Worker // HashStateBase
155*9356374aSAndroid Build Coastguard Worker //
156*9356374aSAndroid Build Coastguard Worker // An internal implementation detail that contains common implementation details
157*9356374aSAndroid Build Coastguard Worker // for all of the "hash state objects" objects generated by Abseil. This is not
158*9356374aSAndroid Build Coastguard Worker // a public API; users should not create classes that inherit from this.
159*9356374aSAndroid Build Coastguard Worker //
160*9356374aSAndroid Build Coastguard Worker // A hash state object is the template argument `H` passed to `AbslHashValue`.
161*9356374aSAndroid Build Coastguard Worker // It represents an intermediate state in the computation of an unspecified hash
162*9356374aSAndroid Build Coastguard Worker // algorithm. `HashStateBase` provides a CRTP style base class for hash state
163*9356374aSAndroid Build Coastguard Worker // implementations. Developers adding type support for `absl::Hash` should not
164*9356374aSAndroid Build Coastguard Worker // rely on any parts of the state object other than the following member
165*9356374aSAndroid Build Coastguard Worker // functions:
166*9356374aSAndroid Build Coastguard Worker //
167*9356374aSAndroid Build Coastguard Worker // * HashStateBase::combine()
168*9356374aSAndroid Build Coastguard Worker // * HashStateBase::combine_contiguous()
169*9356374aSAndroid Build Coastguard Worker // * HashStateBase::combine_unordered()
170*9356374aSAndroid Build Coastguard Worker //
171*9356374aSAndroid Build Coastguard Worker // A derived hash state class of type `H` must provide a public member function
172*9356374aSAndroid Build Coastguard Worker // with a signature similar to the following:
173*9356374aSAndroid Build Coastguard Worker //
174*9356374aSAndroid Build Coastguard Worker // `static H combine_contiguous(H state, const unsigned char*, size_t)`.
175*9356374aSAndroid Build Coastguard Worker //
176*9356374aSAndroid Build Coastguard Worker // It must also provide a private template method named RunCombineUnordered.
177*9356374aSAndroid Build Coastguard Worker //
178*9356374aSAndroid Build Coastguard Worker // A "consumer" is a 1-arg functor returning void. Its argument is a reference
179*9356374aSAndroid Build Coastguard Worker // to an inner hash state object, and it may be called multiple times. When
180*9356374aSAndroid Build Coastguard Worker // called, the functor consumes the entropy from the provided state object,
181*9356374aSAndroid Build Coastguard Worker // and resets that object to its empty state.
182*9356374aSAndroid Build Coastguard Worker //
183*9356374aSAndroid Build Coastguard Worker // A "combiner" is a stateless 2-arg functor returning void. Its arguments are
184*9356374aSAndroid Build Coastguard Worker // an inner hash state object and an ElementStateConsumer functor. A combiner
185*9356374aSAndroid Build Coastguard Worker // uses the provided inner hash state object to hash each element of the
186*9356374aSAndroid Build Coastguard Worker // container, passing the inner hash state object to the consumer after hashing
187*9356374aSAndroid Build Coastguard Worker // each element.
188*9356374aSAndroid Build Coastguard Worker //
189*9356374aSAndroid Build Coastguard Worker // Given these definitions, a derived hash state class of type H
190*9356374aSAndroid Build Coastguard Worker // must provide a private template method with a signature similar to the
191*9356374aSAndroid Build Coastguard Worker // following:
192*9356374aSAndroid Build Coastguard Worker //
193*9356374aSAndroid Build Coastguard Worker // `template <typename CombinerT>`
194*9356374aSAndroid Build Coastguard Worker // `static H RunCombineUnordered(H outer_state, CombinerT combiner)`
195*9356374aSAndroid Build Coastguard Worker //
196*9356374aSAndroid Build Coastguard Worker // This function is responsible for constructing the inner state object and
197*9356374aSAndroid Build Coastguard Worker // providing a consumer to the combiner. It uses side effects of the consumer
198*9356374aSAndroid Build Coastguard Worker // and combiner to mix the state of each element in an order-independent manner,
199*9356374aSAndroid Build Coastguard Worker // and uses this to return an updated value of `outer_state`.
200*9356374aSAndroid Build Coastguard Worker //
201*9356374aSAndroid Build Coastguard Worker // This inside-out approach generates efficient object code in the normal case,
202*9356374aSAndroid Build Coastguard Worker // but allows us to use stack storage to implement the absl::HashState type
203*9356374aSAndroid Build Coastguard Worker // erasure mechanism (avoiding heap allocations while hashing).
204*9356374aSAndroid Build Coastguard Worker //
205*9356374aSAndroid Build Coastguard Worker // `HashStateBase` will provide a complete implementation for a hash state
206*9356374aSAndroid Build Coastguard Worker // object in terms of these two methods.
207*9356374aSAndroid Build Coastguard Worker //
208*9356374aSAndroid Build Coastguard Worker // Example:
209*9356374aSAndroid Build Coastguard Worker //
210*9356374aSAndroid Build Coastguard Worker // // Use CRTP to define your derived class.
211*9356374aSAndroid Build Coastguard Worker // struct MyHashState : HashStateBase<MyHashState> {
212*9356374aSAndroid Build Coastguard Worker // static H combine_contiguous(H state, const unsigned char*, size_t);
213*9356374aSAndroid Build Coastguard Worker // using MyHashState::HashStateBase::combine;
214*9356374aSAndroid Build Coastguard Worker // using MyHashState::HashStateBase::combine_contiguous;
215*9356374aSAndroid Build Coastguard Worker // using MyHashState::HashStateBase::combine_unordered;
216*9356374aSAndroid Build Coastguard Worker // private:
217*9356374aSAndroid Build Coastguard Worker // template <typename CombinerT>
218*9356374aSAndroid Build Coastguard Worker // static H RunCombineUnordered(H state, CombinerT combiner);
219*9356374aSAndroid Build Coastguard Worker // };
220*9356374aSAndroid Build Coastguard Worker template <typename H>
221*9356374aSAndroid Build Coastguard Worker class HashStateBase {
222*9356374aSAndroid Build Coastguard Worker public:
223*9356374aSAndroid Build Coastguard Worker // HashStateBase::combine()
224*9356374aSAndroid Build Coastguard Worker //
225*9356374aSAndroid Build Coastguard Worker // Combines an arbitrary number of values into a hash state, returning the
226*9356374aSAndroid Build Coastguard Worker // updated state.
227*9356374aSAndroid Build Coastguard Worker //
228*9356374aSAndroid Build Coastguard Worker // Each of the value types `T` must be separately hashable by the Abseil
229*9356374aSAndroid Build Coastguard Worker // hashing framework.
230*9356374aSAndroid Build Coastguard Worker //
231*9356374aSAndroid Build Coastguard Worker // NOTE:
232*9356374aSAndroid Build Coastguard Worker //
233*9356374aSAndroid Build Coastguard Worker // state = H::combine(std::move(state), value1, value2, value3);
234*9356374aSAndroid Build Coastguard Worker //
235*9356374aSAndroid Build Coastguard Worker // is guaranteed to produce the same hash expansion as:
236*9356374aSAndroid Build Coastguard Worker //
237*9356374aSAndroid Build Coastguard Worker // state = H::combine(std::move(state), value1);
238*9356374aSAndroid Build Coastguard Worker // state = H::combine(std::move(state), value2);
239*9356374aSAndroid Build Coastguard Worker // state = H::combine(std::move(state), value3);
240*9356374aSAndroid Build Coastguard Worker template <typename T, typename... Ts>
241*9356374aSAndroid Build Coastguard Worker static H combine(H state, const T& value, const Ts&... values);
combine(H state)242*9356374aSAndroid Build Coastguard Worker static H combine(H state) { return state; }
243*9356374aSAndroid Build Coastguard Worker
244*9356374aSAndroid Build Coastguard Worker // HashStateBase::combine_contiguous()
245*9356374aSAndroid Build Coastguard Worker //
246*9356374aSAndroid Build Coastguard Worker // Combines a contiguous array of `size` elements into a hash state, returning
247*9356374aSAndroid Build Coastguard Worker // the updated state.
248*9356374aSAndroid Build Coastguard Worker //
249*9356374aSAndroid Build Coastguard Worker // NOTE:
250*9356374aSAndroid Build Coastguard Worker //
251*9356374aSAndroid Build Coastguard Worker // state = H::combine_contiguous(std::move(state), data, size);
252*9356374aSAndroid Build Coastguard Worker //
253*9356374aSAndroid Build Coastguard Worker // is NOT guaranteed to produce the same hash expansion as a for-loop (it may
254*9356374aSAndroid Build Coastguard Worker // perform internal optimizations). If you need this guarantee, use the
255*9356374aSAndroid Build Coastguard Worker // for-loop instead.
256*9356374aSAndroid Build Coastguard Worker template <typename T>
257*9356374aSAndroid Build Coastguard Worker static H combine_contiguous(H state, const T* data, size_t size);
258*9356374aSAndroid Build Coastguard Worker
259*9356374aSAndroid Build Coastguard Worker template <typename I>
260*9356374aSAndroid Build Coastguard Worker static H combine_unordered(H state, I begin, I end);
261*9356374aSAndroid Build Coastguard Worker
262*9356374aSAndroid Build Coastguard Worker using AbslInternalPiecewiseCombiner = PiecewiseCombiner;
263*9356374aSAndroid Build Coastguard Worker
264*9356374aSAndroid Build Coastguard Worker template <typename T>
265*9356374aSAndroid Build Coastguard Worker using is_hashable = absl::hash_internal::is_hashable<T>;
266*9356374aSAndroid Build Coastguard Worker
267*9356374aSAndroid Build Coastguard Worker private:
268*9356374aSAndroid Build Coastguard Worker // Common implementation of the iteration step of a "combiner", as described
269*9356374aSAndroid Build Coastguard Worker // above.
270*9356374aSAndroid Build Coastguard Worker template <typename I>
271*9356374aSAndroid Build Coastguard Worker struct CombineUnorderedCallback {
272*9356374aSAndroid Build Coastguard Worker I begin;
273*9356374aSAndroid Build Coastguard Worker I end;
274*9356374aSAndroid Build Coastguard Worker
275*9356374aSAndroid Build Coastguard Worker template <typename InnerH, typename ElementStateConsumer>
operatorCombineUnorderedCallback276*9356374aSAndroid Build Coastguard Worker void operator()(InnerH inner_state, ElementStateConsumer cb) {
277*9356374aSAndroid Build Coastguard Worker for (; begin != end; ++begin) {
278*9356374aSAndroid Build Coastguard Worker inner_state = H::combine(std::move(inner_state), *begin);
279*9356374aSAndroid Build Coastguard Worker cb(inner_state);
280*9356374aSAndroid Build Coastguard Worker }
281*9356374aSAndroid Build Coastguard Worker }
282*9356374aSAndroid Build Coastguard Worker };
283*9356374aSAndroid Build Coastguard Worker };
284*9356374aSAndroid Build Coastguard Worker
285*9356374aSAndroid Build Coastguard Worker // is_uniquely_represented
286*9356374aSAndroid Build Coastguard Worker //
287*9356374aSAndroid Build Coastguard Worker // `is_uniquely_represented<T>` is a trait class that indicates whether `T`
288*9356374aSAndroid Build Coastguard Worker // is uniquely represented.
289*9356374aSAndroid Build Coastguard Worker //
290*9356374aSAndroid Build Coastguard Worker // A type is "uniquely represented" if two equal values of that type are
291*9356374aSAndroid Build Coastguard Worker // guaranteed to have the same bytes in their underlying storage. In other
292*9356374aSAndroid Build Coastguard Worker // words, if `a == b`, then `memcmp(&a, &b, sizeof(T))` is guaranteed to be
293*9356374aSAndroid Build Coastguard Worker // zero. This property cannot be detected automatically, so this trait is false
294*9356374aSAndroid Build Coastguard Worker // by default, but can be specialized by types that wish to assert that they are
295*9356374aSAndroid Build Coastguard Worker // uniquely represented. This makes them eligible for certain optimizations.
296*9356374aSAndroid Build Coastguard Worker //
297*9356374aSAndroid Build Coastguard Worker // If you have any doubt whatsoever, do not specialize this template.
298*9356374aSAndroid Build Coastguard Worker // The default is completely safe, and merely disables some optimizations
299*9356374aSAndroid Build Coastguard Worker // that will not matter for most types. Specializing this template,
300*9356374aSAndroid Build Coastguard Worker // on the other hand, can be very hazardous.
301*9356374aSAndroid Build Coastguard Worker //
302*9356374aSAndroid Build Coastguard Worker // To be uniquely represented, a type must not have multiple ways of
303*9356374aSAndroid Build Coastguard Worker // representing the same value; for example, float and double are not
304*9356374aSAndroid Build Coastguard Worker // uniquely represented, because they have distinct representations for
305*9356374aSAndroid Build Coastguard Worker // +0 and -0. Furthermore, the type's byte representation must consist
306*9356374aSAndroid Build Coastguard Worker // solely of user-controlled data, with no padding bits and no compiler-
307*9356374aSAndroid Build Coastguard Worker // controlled data such as vptrs or sanitizer metadata. This is usually
308*9356374aSAndroid Build Coastguard Worker // very difficult to guarantee, because in most cases the compiler can
309*9356374aSAndroid Build Coastguard Worker // insert data and padding bits at its own discretion.
310*9356374aSAndroid Build Coastguard Worker //
311*9356374aSAndroid Build Coastguard Worker // If you specialize this template for a type `T`, you must do so in the file
312*9356374aSAndroid Build Coastguard Worker // that defines that type (or in this file). If you define that specialization
313*9356374aSAndroid Build Coastguard Worker // anywhere else, `is_uniquely_represented<T>` could have different meanings
314*9356374aSAndroid Build Coastguard Worker // in different places.
315*9356374aSAndroid Build Coastguard Worker //
316*9356374aSAndroid Build Coastguard Worker // The Enable parameter is meaningless; it is provided as a convenience,
317*9356374aSAndroid Build Coastguard Worker // to support certain SFINAE techniques when defining specializations.
318*9356374aSAndroid Build Coastguard Worker template <typename T, typename Enable = void>
319*9356374aSAndroid Build Coastguard Worker struct is_uniquely_represented : std::false_type {};
320*9356374aSAndroid Build Coastguard Worker
321*9356374aSAndroid Build Coastguard Worker // is_uniquely_represented<unsigned char>
322*9356374aSAndroid Build Coastguard Worker //
323*9356374aSAndroid Build Coastguard Worker // unsigned char is a synonym for "byte", so it is guaranteed to be
324*9356374aSAndroid Build Coastguard Worker // uniquely represented.
325*9356374aSAndroid Build Coastguard Worker template <>
326*9356374aSAndroid Build Coastguard Worker struct is_uniquely_represented<unsigned char> : std::true_type {};
327*9356374aSAndroid Build Coastguard Worker
328*9356374aSAndroid Build Coastguard Worker // is_uniquely_represented for non-standard integral types
329*9356374aSAndroid Build Coastguard Worker //
330*9356374aSAndroid Build Coastguard Worker // Integral types other than bool should be uniquely represented on any
331*9356374aSAndroid Build Coastguard Worker // platform that this will plausibly be ported to.
332*9356374aSAndroid Build Coastguard Worker template <typename Integral>
333*9356374aSAndroid Build Coastguard Worker struct is_uniquely_represented<
334*9356374aSAndroid Build Coastguard Worker Integral, typename std::enable_if<std::is_integral<Integral>::value>::type>
335*9356374aSAndroid Build Coastguard Worker : std::true_type {};
336*9356374aSAndroid Build Coastguard Worker
337*9356374aSAndroid Build Coastguard Worker // is_uniquely_represented<bool>
338*9356374aSAndroid Build Coastguard Worker //
339*9356374aSAndroid Build Coastguard Worker //
340*9356374aSAndroid Build Coastguard Worker template <>
341*9356374aSAndroid Build Coastguard Worker struct is_uniquely_represented<bool> : std::false_type {};
342*9356374aSAndroid Build Coastguard Worker
343*9356374aSAndroid Build Coastguard Worker // hash_bytes()
344*9356374aSAndroid Build Coastguard Worker //
345*9356374aSAndroid Build Coastguard Worker // Convenience function that combines `hash_state` with the byte representation
346*9356374aSAndroid Build Coastguard Worker // of `value`.
347*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
348*9356374aSAndroid Build Coastguard Worker H hash_bytes(H hash_state, const T& value) {
349*9356374aSAndroid Build Coastguard Worker const unsigned char* start = reinterpret_cast<const unsigned char*>(&value);
350*9356374aSAndroid Build Coastguard Worker return H::combine_contiguous(std::move(hash_state), start, sizeof(value));
351*9356374aSAndroid Build Coastguard Worker }
352*9356374aSAndroid Build Coastguard Worker
353*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
354*9356374aSAndroid Build Coastguard Worker // AbslHashValue for Basic Types
355*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
356*9356374aSAndroid Build Coastguard Worker
357*9356374aSAndroid Build Coastguard Worker // Note: Default `AbslHashValue` implementations live in `hash_internal`. This
358*9356374aSAndroid Build Coastguard Worker // allows us to block lexical scope lookup when doing an unqualified call to
359*9356374aSAndroid Build Coastguard Worker // `AbslHashValue` below. User-defined implementations of `AbslHashValue` can
360*9356374aSAndroid Build Coastguard Worker // only be found via ADL.
361*9356374aSAndroid Build Coastguard Worker
362*9356374aSAndroid Build Coastguard Worker // AbslHashValue() for hashing bool values
363*9356374aSAndroid Build Coastguard Worker //
364*9356374aSAndroid Build Coastguard Worker // We use SFINAE to ensure that this overload only accepts bool, not types that
365*9356374aSAndroid Build Coastguard Worker // are convertible to bool.
366*9356374aSAndroid Build Coastguard Worker template <typename H, typename B>
367*9356374aSAndroid Build Coastguard Worker typename std::enable_if<std::is_same<B, bool>::value, H>::type AbslHashValue(
368*9356374aSAndroid Build Coastguard Worker H hash_state, B value) {
369*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state),
370*9356374aSAndroid Build Coastguard Worker static_cast<unsigned char>(value ? 1 : 0));
371*9356374aSAndroid Build Coastguard Worker }
372*9356374aSAndroid Build Coastguard Worker
373*9356374aSAndroid Build Coastguard Worker // AbslHashValue() for hashing enum values
374*9356374aSAndroid Build Coastguard Worker template <typename H, typename Enum>
375*9356374aSAndroid Build Coastguard Worker typename std::enable_if<std::is_enum<Enum>::value, H>::type AbslHashValue(
376*9356374aSAndroid Build Coastguard Worker H hash_state, Enum e) {
377*9356374aSAndroid Build Coastguard Worker // In practice, we could almost certainly just invoke hash_bytes directly,
378*9356374aSAndroid Build Coastguard Worker // but it's possible that a sanitizer might one day want to
379*9356374aSAndroid Build Coastguard Worker // store data in the unused bits of an enum. To avoid that risk, we
380*9356374aSAndroid Build Coastguard Worker // convert to the underlying type before hashing. Hopefully this will get
381*9356374aSAndroid Build Coastguard Worker // optimized away; if not, we can reopen discussion with c-toolchain-team.
382*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state),
383*9356374aSAndroid Build Coastguard Worker static_cast<typename std::underlying_type<Enum>::type>(e));
384*9356374aSAndroid Build Coastguard Worker }
385*9356374aSAndroid Build Coastguard Worker // AbslHashValue() for hashing floating-point values
386*9356374aSAndroid Build Coastguard Worker template <typename H, typename Float>
387*9356374aSAndroid Build Coastguard Worker typename std::enable_if<std::is_same<Float, float>::value ||
388*9356374aSAndroid Build Coastguard Worker std::is_same<Float, double>::value,
389*9356374aSAndroid Build Coastguard Worker H>::type
390*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state, Float value) {
391*9356374aSAndroid Build Coastguard Worker return hash_internal::hash_bytes(std::move(hash_state),
392*9356374aSAndroid Build Coastguard Worker value == 0 ? 0 : value);
393*9356374aSAndroid Build Coastguard Worker }
394*9356374aSAndroid Build Coastguard Worker
395*9356374aSAndroid Build Coastguard Worker // Long double has the property that it might have extra unused bytes in it.
396*9356374aSAndroid Build Coastguard Worker // For example, in x86 sizeof(long double)==16 but it only really uses 80-bits
397*9356374aSAndroid Build Coastguard Worker // of it. This means we can't use hash_bytes on a long double and have to
398*9356374aSAndroid Build Coastguard Worker // convert it to something else first.
399*9356374aSAndroid Build Coastguard Worker template <typename H, typename LongDouble>
400*9356374aSAndroid Build Coastguard Worker typename std::enable_if<std::is_same<LongDouble, long double>::value, H>::type
401*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state, LongDouble value) {
402*9356374aSAndroid Build Coastguard Worker const int category = std::fpclassify(value);
403*9356374aSAndroid Build Coastguard Worker switch (category) {
404*9356374aSAndroid Build Coastguard Worker case FP_INFINITE:
405*9356374aSAndroid Build Coastguard Worker // Add the sign bit to differentiate between +Inf and -Inf
406*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), std::signbit(value));
407*9356374aSAndroid Build Coastguard Worker break;
408*9356374aSAndroid Build Coastguard Worker
409*9356374aSAndroid Build Coastguard Worker case FP_NAN:
410*9356374aSAndroid Build Coastguard Worker case FP_ZERO:
411*9356374aSAndroid Build Coastguard Worker default:
412*9356374aSAndroid Build Coastguard Worker // Category is enough for these.
413*9356374aSAndroid Build Coastguard Worker break;
414*9356374aSAndroid Build Coastguard Worker
415*9356374aSAndroid Build Coastguard Worker case FP_NORMAL:
416*9356374aSAndroid Build Coastguard Worker case FP_SUBNORMAL:
417*9356374aSAndroid Build Coastguard Worker // We can't convert `value` directly to double because this would have
418*9356374aSAndroid Build Coastguard Worker // undefined behavior if the value is out of range.
419*9356374aSAndroid Build Coastguard Worker // std::frexp gives us a value in the range (-1, -.5] or [.5, 1) that is
420*9356374aSAndroid Build Coastguard Worker // guaranteed to be in range for `double`. The truncation is
421*9356374aSAndroid Build Coastguard Worker // implementation defined, but that works as long as it is deterministic.
422*9356374aSAndroid Build Coastguard Worker int exp;
423*9356374aSAndroid Build Coastguard Worker auto mantissa = static_cast<double>(std::frexp(value, &exp));
424*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), mantissa, exp);
425*9356374aSAndroid Build Coastguard Worker }
426*9356374aSAndroid Build Coastguard Worker
427*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), category);
428*9356374aSAndroid Build Coastguard Worker }
429*9356374aSAndroid Build Coastguard Worker
430*9356374aSAndroid Build Coastguard Worker // Without this overload, an array decays to a pointer and we hash that, which
431*9356374aSAndroid Build Coastguard Worker // is not likely to be what the caller intended.
432*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, size_t N>
433*9356374aSAndroid Build Coastguard Worker H AbslHashValue(H hash_state, T (&)[N]) {
434*9356374aSAndroid Build Coastguard Worker static_assert(
435*9356374aSAndroid Build Coastguard Worker sizeof(T) == -1,
436*9356374aSAndroid Build Coastguard Worker "Hashing C arrays is not allowed. For string literals, wrap the literal "
437*9356374aSAndroid Build Coastguard Worker "in absl::string_view(). To hash the array contents, use "
438*9356374aSAndroid Build Coastguard Worker "absl::MakeSpan() or make the array an std::array. To hash the array "
439*9356374aSAndroid Build Coastguard Worker "address, use &array[0].");
440*9356374aSAndroid Build Coastguard Worker return hash_state;
441*9356374aSAndroid Build Coastguard Worker }
442*9356374aSAndroid Build Coastguard Worker
443*9356374aSAndroid Build Coastguard Worker // AbslHashValue() for hashing pointers
444*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
445*9356374aSAndroid Build Coastguard Worker std::enable_if_t<std::is_pointer<T>::value, H> AbslHashValue(H hash_state,
446*9356374aSAndroid Build Coastguard Worker T ptr) {
447*9356374aSAndroid Build Coastguard Worker auto v = reinterpret_cast<uintptr_t>(ptr);
448*9356374aSAndroid Build Coastguard Worker // Due to alignment, pointers tend to have low bits as zero, and the next few
449*9356374aSAndroid Build Coastguard Worker // bits follow a pattern since they are also multiples of some base value.
450*9356374aSAndroid Build Coastguard Worker // Mixing the pointer twice helps prevent stuck low bits for certain alignment
451*9356374aSAndroid Build Coastguard Worker // values.
452*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), v, v);
453*9356374aSAndroid Build Coastguard Worker }
454*9356374aSAndroid Build Coastguard Worker
455*9356374aSAndroid Build Coastguard Worker // AbslHashValue() for hashing nullptr_t
456*9356374aSAndroid Build Coastguard Worker template <typename H>
457*9356374aSAndroid Build Coastguard Worker H AbslHashValue(H hash_state, std::nullptr_t) {
458*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), static_cast<void*>(nullptr));
459*9356374aSAndroid Build Coastguard Worker }
460*9356374aSAndroid Build Coastguard Worker
461*9356374aSAndroid Build Coastguard Worker // AbslHashValue() for hashing pointers-to-member
462*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, typename C>
463*9356374aSAndroid Build Coastguard Worker H AbslHashValue(H hash_state, T C::*ptr) {
464*9356374aSAndroid Build Coastguard Worker auto salient_ptm_size = [](std::size_t n) -> std::size_t {
465*9356374aSAndroid Build Coastguard Worker #if defined(_MSC_VER)
466*9356374aSAndroid Build Coastguard Worker // Pointers-to-member-function on MSVC consist of one pointer plus 0, 1, 2,
467*9356374aSAndroid Build Coastguard Worker // or 3 ints. In 64-bit mode, they are 8-byte aligned and thus can contain
468*9356374aSAndroid Build Coastguard Worker // padding (namely when they have 1 or 3 ints). The value below is a lower
469*9356374aSAndroid Build Coastguard Worker // bound on the number of salient, non-padding bytes that we use for
470*9356374aSAndroid Build Coastguard Worker // hashing.
471*9356374aSAndroid Build Coastguard Worker if (alignof(T C::*) == alignof(int)) {
472*9356374aSAndroid Build Coastguard Worker // No padding when all subobjects have the same size as the total
473*9356374aSAndroid Build Coastguard Worker // alignment. This happens in 32-bit mode.
474*9356374aSAndroid Build Coastguard Worker return n;
475*9356374aSAndroid Build Coastguard Worker } else {
476*9356374aSAndroid Build Coastguard Worker // Padding for 1 int (size 16) or 3 ints (size 24).
477*9356374aSAndroid Build Coastguard Worker // With 2 ints, the size is 16 with no padding, which we pessimize.
478*9356374aSAndroid Build Coastguard Worker return n == 24 ? 20 : n == 16 ? 12 : n;
479*9356374aSAndroid Build Coastguard Worker }
480*9356374aSAndroid Build Coastguard Worker #else
481*9356374aSAndroid Build Coastguard Worker // On other platforms, we assume that pointers-to-members do not have
482*9356374aSAndroid Build Coastguard Worker // padding.
483*9356374aSAndroid Build Coastguard Worker #ifdef __cpp_lib_has_unique_object_representations
484*9356374aSAndroid Build Coastguard Worker static_assert(std::has_unique_object_representations<T C::*>::value);
485*9356374aSAndroid Build Coastguard Worker #endif // __cpp_lib_has_unique_object_representations
486*9356374aSAndroid Build Coastguard Worker return n;
487*9356374aSAndroid Build Coastguard Worker #endif
488*9356374aSAndroid Build Coastguard Worker };
489*9356374aSAndroid Build Coastguard Worker return H::combine_contiguous(std::move(hash_state),
490*9356374aSAndroid Build Coastguard Worker reinterpret_cast<unsigned char*>(&ptr),
491*9356374aSAndroid Build Coastguard Worker salient_ptm_size(sizeof ptr));
492*9356374aSAndroid Build Coastguard Worker }
493*9356374aSAndroid Build Coastguard Worker
494*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
495*9356374aSAndroid Build Coastguard Worker // AbslHashValue for Composite Types
496*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
497*9356374aSAndroid Build Coastguard Worker
498*9356374aSAndroid Build Coastguard Worker // AbslHashValue() for hashing pairs
499*9356374aSAndroid Build Coastguard Worker template <typename H, typename T1, typename T2>
500*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T1>::value && is_hashable<T2>::value,
501*9356374aSAndroid Build Coastguard Worker H>::type
502*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state, const std::pair<T1, T2>& p) {
503*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), p.first, p.second);
504*9356374aSAndroid Build Coastguard Worker }
505*9356374aSAndroid Build Coastguard Worker
506*9356374aSAndroid Build Coastguard Worker // hash_tuple()
507*9356374aSAndroid Build Coastguard Worker //
508*9356374aSAndroid Build Coastguard Worker // Helper function for hashing a tuple. The third argument should
509*9356374aSAndroid Build Coastguard Worker // be an index_sequence running from 0 to tuple_size<Tuple> - 1.
510*9356374aSAndroid Build Coastguard Worker template <typename H, typename Tuple, size_t... Is>
511*9356374aSAndroid Build Coastguard Worker H hash_tuple(H hash_state, const Tuple& t, absl::index_sequence<Is...>) {
512*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), std::get<Is>(t)...);
513*9356374aSAndroid Build Coastguard Worker }
514*9356374aSAndroid Build Coastguard Worker
515*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing tuples
516*9356374aSAndroid Build Coastguard Worker template <typename H, typename... Ts>
517*9356374aSAndroid Build Coastguard Worker #if defined(_MSC_VER)
518*9356374aSAndroid Build Coastguard Worker // This SFINAE gets MSVC confused under some conditions. Let's just disable it
519*9356374aSAndroid Build Coastguard Worker // for now.
520*9356374aSAndroid Build Coastguard Worker H
521*9356374aSAndroid Build Coastguard Worker #else // _MSC_VER
522*9356374aSAndroid Build Coastguard Worker typename std::enable_if<absl::conjunction<is_hashable<Ts>...>::value, H>::type
523*9356374aSAndroid Build Coastguard Worker #endif // _MSC_VER
524*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state, const std::tuple<Ts...>& t) {
525*9356374aSAndroid Build Coastguard Worker return hash_internal::hash_tuple(std::move(hash_state), t,
526*9356374aSAndroid Build Coastguard Worker absl::make_index_sequence<sizeof...(Ts)>());
527*9356374aSAndroid Build Coastguard Worker }
528*9356374aSAndroid Build Coastguard Worker
529*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
530*9356374aSAndroid Build Coastguard Worker // AbslHashValue for Pointers
531*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
532*9356374aSAndroid Build Coastguard Worker
533*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing unique_ptr
534*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, typename D>
535*9356374aSAndroid Build Coastguard Worker H AbslHashValue(H hash_state, const std::unique_ptr<T, D>& ptr) {
536*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), ptr.get());
537*9356374aSAndroid Build Coastguard Worker }
538*9356374aSAndroid Build Coastguard Worker
539*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing shared_ptr
540*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
541*9356374aSAndroid Build Coastguard Worker H AbslHashValue(H hash_state, const std::shared_ptr<T>& ptr) {
542*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), ptr.get());
543*9356374aSAndroid Build Coastguard Worker }
544*9356374aSAndroid Build Coastguard Worker
545*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
546*9356374aSAndroid Build Coastguard Worker // AbslHashValue for String-Like Types
547*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
548*9356374aSAndroid Build Coastguard Worker
549*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing strings
550*9356374aSAndroid Build Coastguard Worker //
551*9356374aSAndroid Build Coastguard Worker // All the string-like types supported here provide the same hash expansion for
552*9356374aSAndroid Build Coastguard Worker // the same character sequence. These types are:
553*9356374aSAndroid Build Coastguard Worker //
554*9356374aSAndroid Build Coastguard Worker // - `absl::Cord`
555*9356374aSAndroid Build Coastguard Worker // - `std::string` (and std::basic_string<T, std::char_traits<T>, A> for
556*9356374aSAndroid Build Coastguard Worker // any allocator A and any T in {char, wchar_t, char16_t, char32_t})
557*9356374aSAndroid Build Coastguard Worker // - `absl::string_view`, `std::string_view`, `std::wstring_view`,
558*9356374aSAndroid Build Coastguard Worker // `std::u16string_view`, and `std::u32_string_view`.
559*9356374aSAndroid Build Coastguard Worker //
560*9356374aSAndroid Build Coastguard Worker // For simplicity, we currently support only strings built on `char`, `wchar_t`,
561*9356374aSAndroid Build Coastguard Worker // `char16_t`, or `char32_t`. This support may be broadened, if necessary, but
562*9356374aSAndroid Build Coastguard Worker // with some caution - this overload would misbehave in cases where the traits'
563*9356374aSAndroid Build Coastguard Worker // `eq()` member isn't equivalent to `==` on the underlying character type.
564*9356374aSAndroid Build Coastguard Worker template <typename H>
565*9356374aSAndroid Build Coastguard Worker H AbslHashValue(H hash_state, absl::string_view str) {
566*9356374aSAndroid Build Coastguard Worker return H::combine(
567*9356374aSAndroid Build Coastguard Worker H::combine_contiguous(std::move(hash_state), str.data(), str.size()),
568*9356374aSAndroid Build Coastguard Worker str.size());
569*9356374aSAndroid Build Coastguard Worker }
570*9356374aSAndroid Build Coastguard Worker
571*9356374aSAndroid Build Coastguard Worker // Support std::wstring, std::u16string and std::u32string.
572*9356374aSAndroid Build Coastguard Worker template <typename Char, typename Alloc, typename H,
573*9356374aSAndroid Build Coastguard Worker typename = absl::enable_if_t<std::is_same<Char, wchar_t>::value ||
574*9356374aSAndroid Build Coastguard Worker std::is_same<Char, char16_t>::value ||
575*9356374aSAndroid Build Coastguard Worker std::is_same<Char, char32_t>::value>>
576*9356374aSAndroid Build Coastguard Worker H AbslHashValue(
577*9356374aSAndroid Build Coastguard Worker H hash_state,
578*9356374aSAndroid Build Coastguard Worker const std::basic_string<Char, std::char_traits<Char>, Alloc>& str) {
579*9356374aSAndroid Build Coastguard Worker return H::combine(
580*9356374aSAndroid Build Coastguard Worker H::combine_contiguous(std::move(hash_state), str.data(), str.size()),
581*9356374aSAndroid Build Coastguard Worker str.size());
582*9356374aSAndroid Build Coastguard Worker }
583*9356374aSAndroid Build Coastguard Worker
584*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_STD_STRING_VIEW
585*9356374aSAndroid Build Coastguard Worker
586*9356374aSAndroid Build Coastguard Worker // Support std::wstring_view, std::u16string_view and std::u32string_view.
587*9356374aSAndroid Build Coastguard Worker template <typename Char, typename H,
588*9356374aSAndroid Build Coastguard Worker typename = absl::enable_if_t<std::is_same<Char, wchar_t>::value ||
589*9356374aSAndroid Build Coastguard Worker std::is_same<Char, char16_t>::value ||
590*9356374aSAndroid Build Coastguard Worker std::is_same<Char, char32_t>::value>>
591*9356374aSAndroid Build Coastguard Worker H AbslHashValue(H hash_state, std::basic_string_view<Char> str) {
592*9356374aSAndroid Build Coastguard Worker return H::combine(
593*9356374aSAndroid Build Coastguard Worker H::combine_contiguous(std::move(hash_state), str.data(), str.size()),
594*9356374aSAndroid Build Coastguard Worker str.size());
595*9356374aSAndroid Build Coastguard Worker }
596*9356374aSAndroid Build Coastguard Worker
597*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_STD_STRING_VIEW
598*9356374aSAndroid Build Coastguard Worker
599*9356374aSAndroid Build Coastguard Worker #if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L && \
600*9356374aSAndroid Build Coastguard Worker !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) && \
601*9356374aSAndroid Build Coastguard Worker (!defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || \
602*9356374aSAndroid Build Coastguard Worker __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 130000) && \
603*9356374aSAndroid Build Coastguard Worker (!defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \
604*9356374aSAndroid Build Coastguard Worker __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500)
605*9356374aSAndroid Build Coastguard Worker
606*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_STD_FILESYSTEM_PATH_HASH_AVAILABLE 1
607*9356374aSAndroid Build Coastguard Worker
608*9356374aSAndroid Build Coastguard Worker // Support std::filesystem::path. The SFINAE is required because some string
609*9356374aSAndroid Build Coastguard Worker // types are implicitly convertible to std::filesystem::path.
610*9356374aSAndroid Build Coastguard Worker template <typename Path, typename H,
611*9356374aSAndroid Build Coastguard Worker typename = absl::enable_if_t<
612*9356374aSAndroid Build Coastguard Worker std::is_same_v<Path, std::filesystem::path>>>
613*9356374aSAndroid Build Coastguard Worker H AbslHashValue(H hash_state, const Path& path) {
614*9356374aSAndroid Build Coastguard Worker // This is implemented by deferring to the standard library to compute the
615*9356374aSAndroid Build Coastguard Worker // hash. The standard library requires that for two paths, `p1 == p2`, then
616*9356374aSAndroid Build Coastguard Worker // `hash_value(p1) == hash_value(p2)`. `AbslHashValue` has the same
617*9356374aSAndroid Build Coastguard Worker // requirement. Since `operator==` does platform specific matching, deferring
618*9356374aSAndroid Build Coastguard Worker // to the standard library is the simplest approach.
619*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), std::filesystem::hash_value(path));
620*9356374aSAndroid Build Coastguard Worker }
621*9356374aSAndroid Build Coastguard Worker
622*9356374aSAndroid Build Coastguard Worker #endif // ABSL_INTERNAL_STD_FILESYSTEM_PATH_HASH_AVAILABLE
623*9356374aSAndroid Build Coastguard Worker
624*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
625*9356374aSAndroid Build Coastguard Worker // AbslHashValue for Sequence Containers
626*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
627*9356374aSAndroid Build Coastguard Worker
628*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::array
629*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, size_t N>
630*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue(
631*9356374aSAndroid Build Coastguard Worker H hash_state, const std::array<T, N>& array) {
632*9356374aSAndroid Build Coastguard Worker return H::combine_contiguous(std::move(hash_state), array.data(),
633*9356374aSAndroid Build Coastguard Worker array.size());
634*9356374aSAndroid Build Coastguard Worker }
635*9356374aSAndroid Build Coastguard Worker
636*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::deque
637*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, typename Allocator>
638*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue(
639*9356374aSAndroid Build Coastguard Worker H hash_state, const std::deque<T, Allocator>& deque) {
640*9356374aSAndroid Build Coastguard Worker // TODO(gromer): investigate a more efficient implementation taking
641*9356374aSAndroid Build Coastguard Worker // advantage of the chunk structure.
642*9356374aSAndroid Build Coastguard Worker for (const auto& t : deque) {
643*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), t);
644*9356374aSAndroid Build Coastguard Worker }
645*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), deque.size());
646*9356374aSAndroid Build Coastguard Worker }
647*9356374aSAndroid Build Coastguard Worker
648*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::forward_list
649*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, typename Allocator>
650*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue(
651*9356374aSAndroid Build Coastguard Worker H hash_state, const std::forward_list<T, Allocator>& list) {
652*9356374aSAndroid Build Coastguard Worker size_t size = 0;
653*9356374aSAndroid Build Coastguard Worker for (const T& t : list) {
654*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), t);
655*9356374aSAndroid Build Coastguard Worker ++size;
656*9356374aSAndroid Build Coastguard Worker }
657*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), size);
658*9356374aSAndroid Build Coastguard Worker }
659*9356374aSAndroid Build Coastguard Worker
660*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::list
661*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, typename Allocator>
662*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue(
663*9356374aSAndroid Build Coastguard Worker H hash_state, const std::list<T, Allocator>& list) {
664*9356374aSAndroid Build Coastguard Worker for (const auto& t : list) {
665*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), t);
666*9356374aSAndroid Build Coastguard Worker }
667*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), list.size());
668*9356374aSAndroid Build Coastguard Worker }
669*9356374aSAndroid Build Coastguard Worker
670*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::vector
671*9356374aSAndroid Build Coastguard Worker //
672*9356374aSAndroid Build Coastguard Worker // Do not use this for vector<bool> on platforms that have a working
673*9356374aSAndroid Build Coastguard Worker // implementation of std::hash. It does not have a .data(), and a fallback for
674*9356374aSAndroid Build Coastguard Worker // std::hash<> is most likely faster.
675*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, typename Allocator>
676*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T>::value && !std::is_same<T, bool>::value,
677*9356374aSAndroid Build Coastguard Worker H>::type
678*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
679*9356374aSAndroid Build Coastguard Worker return H::combine(H::combine_contiguous(std::move(hash_state), vector.data(),
680*9356374aSAndroid Build Coastguard Worker vector.size()),
681*9356374aSAndroid Build Coastguard Worker vector.size());
682*9356374aSAndroid Build Coastguard Worker }
683*9356374aSAndroid Build Coastguard Worker
684*9356374aSAndroid Build Coastguard Worker // AbslHashValue special cases for hashing std::vector<bool>
685*9356374aSAndroid Build Coastguard Worker
686*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_IS_BIG_ENDIAN) && \
687*9356374aSAndroid Build Coastguard Worker (defined(__GLIBCXX__) || defined(__GLIBCPP__))
688*9356374aSAndroid Build Coastguard Worker
689*9356374aSAndroid Build Coastguard Worker // std::hash in libstdc++ does not work correctly with vector<bool> on Big
690*9356374aSAndroid Build Coastguard Worker // Endian platforms therefore we need to implement a custom AbslHashValue for
691*9356374aSAndroid Build Coastguard Worker // it. More details on the bug:
692*9356374aSAndroid Build Coastguard Worker // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531
693*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, typename Allocator>
694*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T>::value && std::is_same<T, bool>::value,
695*9356374aSAndroid Build Coastguard Worker H>::type
696*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
697*9356374aSAndroid Build Coastguard Worker typename H::AbslInternalPiecewiseCombiner combiner;
698*9356374aSAndroid Build Coastguard Worker for (const auto& i : vector) {
699*9356374aSAndroid Build Coastguard Worker unsigned char c = static_cast<unsigned char>(i);
700*9356374aSAndroid Build Coastguard Worker hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c));
701*9356374aSAndroid Build Coastguard Worker }
702*9356374aSAndroid Build Coastguard Worker return H::combine(combiner.finalize(std::move(hash_state)), vector.size());
703*9356374aSAndroid Build Coastguard Worker }
704*9356374aSAndroid Build Coastguard Worker #else
705*9356374aSAndroid Build Coastguard Worker // When not working around the libstdc++ bug above, we still have to contend
706*9356374aSAndroid Build Coastguard Worker // with the fact that std::hash<vector<bool>> is often poor quality, hashing
707*9356374aSAndroid Build Coastguard Worker // directly on the internal words and on no other state. On these platforms,
708*9356374aSAndroid Build Coastguard Worker // vector<bool>{1, 1} and vector<bool>{1, 1, 0} hash to the same value.
709*9356374aSAndroid Build Coastguard Worker //
710*9356374aSAndroid Build Coastguard Worker // Mixing in the size (as we do in our other vector<> implementations) on top
711*9356374aSAndroid Build Coastguard Worker // of the library-provided hash implementation avoids this QOI issue.
712*9356374aSAndroid Build Coastguard Worker template <typename H, typename T, typename Allocator>
713*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T>::value && std::is_same<T, bool>::value,
714*9356374aSAndroid Build Coastguard Worker H>::type
715*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
716*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state),
717*9356374aSAndroid Build Coastguard Worker std::hash<std::vector<T, Allocator>>{}(vector),
718*9356374aSAndroid Build Coastguard Worker vector.size());
719*9356374aSAndroid Build Coastguard Worker }
720*9356374aSAndroid Build Coastguard Worker #endif
721*9356374aSAndroid Build Coastguard Worker
722*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
723*9356374aSAndroid Build Coastguard Worker // AbslHashValue for Ordered Associative Containers
724*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
725*9356374aSAndroid Build Coastguard Worker
726*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::map
727*9356374aSAndroid Build Coastguard Worker template <typename H, typename Key, typename T, typename Compare,
728*9356374aSAndroid Build Coastguard Worker typename Allocator>
729*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<Key>::value && is_hashable<T>::value,
730*9356374aSAndroid Build Coastguard Worker H>::type
731*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state, const std::map<Key, T, Compare, Allocator>& map) {
732*9356374aSAndroid Build Coastguard Worker for (const auto& t : map) {
733*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), t);
734*9356374aSAndroid Build Coastguard Worker }
735*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), map.size());
736*9356374aSAndroid Build Coastguard Worker }
737*9356374aSAndroid Build Coastguard Worker
738*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::multimap
739*9356374aSAndroid Build Coastguard Worker template <typename H, typename Key, typename T, typename Compare,
740*9356374aSAndroid Build Coastguard Worker typename Allocator>
741*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<Key>::value && is_hashable<T>::value,
742*9356374aSAndroid Build Coastguard Worker H>::type
743*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state,
744*9356374aSAndroid Build Coastguard Worker const std::multimap<Key, T, Compare, Allocator>& map) {
745*9356374aSAndroid Build Coastguard Worker for (const auto& t : map) {
746*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), t);
747*9356374aSAndroid Build Coastguard Worker }
748*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), map.size());
749*9356374aSAndroid Build Coastguard Worker }
750*9356374aSAndroid Build Coastguard Worker
751*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::set
752*9356374aSAndroid Build Coastguard Worker template <typename H, typename Key, typename Compare, typename Allocator>
753*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<Key>::value, H>::type AbslHashValue(
754*9356374aSAndroid Build Coastguard Worker H hash_state, const std::set<Key, Compare, Allocator>& set) {
755*9356374aSAndroid Build Coastguard Worker for (const auto& t : set) {
756*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), t);
757*9356374aSAndroid Build Coastguard Worker }
758*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), set.size());
759*9356374aSAndroid Build Coastguard Worker }
760*9356374aSAndroid Build Coastguard Worker
761*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::multiset
762*9356374aSAndroid Build Coastguard Worker template <typename H, typename Key, typename Compare, typename Allocator>
763*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<Key>::value, H>::type AbslHashValue(
764*9356374aSAndroid Build Coastguard Worker H hash_state, const std::multiset<Key, Compare, Allocator>& set) {
765*9356374aSAndroid Build Coastguard Worker for (const auto& t : set) {
766*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), t);
767*9356374aSAndroid Build Coastguard Worker }
768*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), set.size());
769*9356374aSAndroid Build Coastguard Worker }
770*9356374aSAndroid Build Coastguard Worker
771*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
772*9356374aSAndroid Build Coastguard Worker // AbslHashValue for Unordered Associative Containers
773*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
774*9356374aSAndroid Build Coastguard Worker
775*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::unordered_set
776*9356374aSAndroid Build Coastguard Worker template <typename H, typename Key, typename Hash, typename KeyEqual,
777*9356374aSAndroid Build Coastguard Worker typename Alloc>
778*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<Key>::value, H>::type AbslHashValue(
779*9356374aSAndroid Build Coastguard Worker H hash_state, const std::unordered_set<Key, Hash, KeyEqual, Alloc>& s) {
780*9356374aSAndroid Build Coastguard Worker return H::combine(
781*9356374aSAndroid Build Coastguard Worker H::combine_unordered(std::move(hash_state), s.begin(), s.end()),
782*9356374aSAndroid Build Coastguard Worker s.size());
783*9356374aSAndroid Build Coastguard Worker }
784*9356374aSAndroid Build Coastguard Worker
785*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::unordered_multiset
786*9356374aSAndroid Build Coastguard Worker template <typename H, typename Key, typename Hash, typename KeyEqual,
787*9356374aSAndroid Build Coastguard Worker typename Alloc>
788*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<Key>::value, H>::type AbslHashValue(
789*9356374aSAndroid Build Coastguard Worker H hash_state,
790*9356374aSAndroid Build Coastguard Worker const std::unordered_multiset<Key, Hash, KeyEqual, Alloc>& s) {
791*9356374aSAndroid Build Coastguard Worker return H::combine(
792*9356374aSAndroid Build Coastguard Worker H::combine_unordered(std::move(hash_state), s.begin(), s.end()),
793*9356374aSAndroid Build Coastguard Worker s.size());
794*9356374aSAndroid Build Coastguard Worker }
795*9356374aSAndroid Build Coastguard Worker
796*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::unordered_set
797*9356374aSAndroid Build Coastguard Worker template <typename H, typename Key, typename T, typename Hash,
798*9356374aSAndroid Build Coastguard Worker typename KeyEqual, typename Alloc>
799*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<Key>::value && is_hashable<T>::value,
800*9356374aSAndroid Build Coastguard Worker H>::type
801*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state,
802*9356374aSAndroid Build Coastguard Worker const std::unordered_map<Key, T, Hash, KeyEqual, Alloc>& s) {
803*9356374aSAndroid Build Coastguard Worker return H::combine(
804*9356374aSAndroid Build Coastguard Worker H::combine_unordered(std::move(hash_state), s.begin(), s.end()),
805*9356374aSAndroid Build Coastguard Worker s.size());
806*9356374aSAndroid Build Coastguard Worker }
807*9356374aSAndroid Build Coastguard Worker
808*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::unordered_multiset
809*9356374aSAndroid Build Coastguard Worker template <typename H, typename Key, typename T, typename Hash,
810*9356374aSAndroid Build Coastguard Worker typename KeyEqual, typename Alloc>
811*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<Key>::value && is_hashable<T>::value,
812*9356374aSAndroid Build Coastguard Worker H>::type
813*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state,
814*9356374aSAndroid Build Coastguard Worker const std::unordered_multimap<Key, T, Hash, KeyEqual, Alloc>& s) {
815*9356374aSAndroid Build Coastguard Worker return H::combine(
816*9356374aSAndroid Build Coastguard Worker H::combine_unordered(std::move(hash_state), s.begin(), s.end()),
817*9356374aSAndroid Build Coastguard Worker s.size());
818*9356374aSAndroid Build Coastguard Worker }
819*9356374aSAndroid Build Coastguard Worker
820*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
821*9356374aSAndroid Build Coastguard Worker // AbslHashValue for Wrapper Types
822*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
823*9356374aSAndroid Build Coastguard Worker
824*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::reference_wrapper
825*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
826*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue(
827*9356374aSAndroid Build Coastguard Worker H hash_state, std::reference_wrapper<T> opt) {
828*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), opt.get());
829*9356374aSAndroid Build Coastguard Worker }
830*9356374aSAndroid Build Coastguard Worker
831*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing absl::optional
832*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
833*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue(
834*9356374aSAndroid Build Coastguard Worker H hash_state, const absl::optional<T>& opt) {
835*9356374aSAndroid Build Coastguard Worker if (opt) hash_state = H::combine(std::move(hash_state), *opt);
836*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), opt.has_value());
837*9356374aSAndroid Build Coastguard Worker }
838*9356374aSAndroid Build Coastguard Worker
839*9356374aSAndroid Build Coastguard Worker // VariantVisitor
840*9356374aSAndroid Build Coastguard Worker template <typename H>
841*9356374aSAndroid Build Coastguard Worker struct VariantVisitor {
842*9356374aSAndroid Build Coastguard Worker H&& hash_state;
843*9356374aSAndroid Build Coastguard Worker template <typename T>
844*9356374aSAndroid Build Coastguard Worker H operator()(const T& t) const {
845*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), t);
846*9356374aSAndroid Build Coastguard Worker }
847*9356374aSAndroid Build Coastguard Worker };
848*9356374aSAndroid Build Coastguard Worker
849*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing absl::variant
850*9356374aSAndroid Build Coastguard Worker template <typename H, typename... T>
851*9356374aSAndroid Build Coastguard Worker typename std::enable_if<conjunction<is_hashable<T>...>::value, H>::type
852*9356374aSAndroid Build Coastguard Worker AbslHashValue(H hash_state, const absl::variant<T...>& v) {
853*9356374aSAndroid Build Coastguard Worker if (!v.valueless_by_exception()) {
854*9356374aSAndroid Build Coastguard Worker hash_state = absl::visit(VariantVisitor<H>{std::move(hash_state)}, v);
855*9356374aSAndroid Build Coastguard Worker }
856*9356374aSAndroid Build Coastguard Worker return H::combine(std::move(hash_state), v.index());
857*9356374aSAndroid Build Coastguard Worker }
858*9356374aSAndroid Build Coastguard Worker
859*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
860*9356374aSAndroid Build Coastguard Worker // AbslHashValue for Other Types
861*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
862*9356374aSAndroid Build Coastguard Worker
863*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::bitset is not defined on Little Endian
864*9356374aSAndroid Build Coastguard Worker // platforms, for the same reason as for vector<bool> (see std::vector above):
865*9356374aSAndroid Build Coastguard Worker // It does not expose the raw bytes, and a fallback to std::hash<> is most
866*9356374aSAndroid Build Coastguard Worker // likely faster.
867*9356374aSAndroid Build Coastguard Worker
868*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_IS_BIG_ENDIAN) && \
869*9356374aSAndroid Build Coastguard Worker (defined(__GLIBCXX__) || defined(__GLIBCPP__))
870*9356374aSAndroid Build Coastguard Worker // AbslHashValue for hashing std::bitset
871*9356374aSAndroid Build Coastguard Worker //
872*9356374aSAndroid Build Coastguard Worker // std::hash in libstdc++ does not work correctly with std::bitset on Big Endian
873*9356374aSAndroid Build Coastguard Worker // platforms therefore we need to implement a custom AbslHashValue for it. More
874*9356374aSAndroid Build Coastguard Worker // details on the bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102531
875*9356374aSAndroid Build Coastguard Worker template <typename H, size_t N>
876*9356374aSAndroid Build Coastguard Worker H AbslHashValue(H hash_state, const std::bitset<N>& set) {
877*9356374aSAndroid Build Coastguard Worker typename H::AbslInternalPiecewiseCombiner combiner;
878*9356374aSAndroid Build Coastguard Worker for (size_t i = 0; i < N; i++) {
879*9356374aSAndroid Build Coastguard Worker unsigned char c = static_cast<unsigned char>(set[i]);
880*9356374aSAndroid Build Coastguard Worker hash_state = combiner.add_buffer(std::move(hash_state), &c, sizeof(c));
881*9356374aSAndroid Build Coastguard Worker }
882*9356374aSAndroid Build Coastguard Worker return H::combine(combiner.finalize(std::move(hash_state)), N);
883*9356374aSAndroid Build Coastguard Worker }
884*9356374aSAndroid Build Coastguard Worker #endif
885*9356374aSAndroid Build Coastguard Worker
886*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
887*9356374aSAndroid Build Coastguard Worker
888*9356374aSAndroid Build Coastguard Worker // hash_range_or_bytes()
889*9356374aSAndroid Build Coastguard Worker //
890*9356374aSAndroid Build Coastguard Worker // Mixes all values in the range [data, data+size) into the hash state.
891*9356374aSAndroid Build Coastguard Worker // This overload accepts only uniquely-represented types, and hashes them by
892*9356374aSAndroid Build Coastguard Worker // hashing the entire range of bytes.
893*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
894*9356374aSAndroid Build Coastguard Worker typename std::enable_if<is_uniquely_represented<T>::value, H>::type
895*9356374aSAndroid Build Coastguard Worker hash_range_or_bytes(H hash_state, const T* data, size_t size) {
896*9356374aSAndroid Build Coastguard Worker const auto* bytes = reinterpret_cast<const unsigned char*>(data);
897*9356374aSAndroid Build Coastguard Worker return H::combine_contiguous(std::move(hash_state), bytes, sizeof(T) * size);
898*9356374aSAndroid Build Coastguard Worker }
899*9356374aSAndroid Build Coastguard Worker
900*9356374aSAndroid Build Coastguard Worker // hash_range_or_bytes()
901*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
902*9356374aSAndroid Build Coastguard Worker typename std::enable_if<!is_uniquely_represented<T>::value, H>::type
903*9356374aSAndroid Build Coastguard Worker hash_range_or_bytes(H hash_state, const T* data, size_t size) {
904*9356374aSAndroid Build Coastguard Worker for (const auto end = data + size; data < end; ++data) {
905*9356374aSAndroid Build Coastguard Worker hash_state = H::combine(std::move(hash_state), *data);
906*9356374aSAndroid Build Coastguard Worker }
907*9356374aSAndroid Build Coastguard Worker return hash_state;
908*9356374aSAndroid Build Coastguard Worker }
909*9356374aSAndroid Build Coastguard Worker
910*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE) && \
911*9356374aSAndroid Build Coastguard Worker ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
912*9356374aSAndroid Build Coastguard Worker #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 1
913*9356374aSAndroid Build Coastguard Worker #else
914*9356374aSAndroid Build Coastguard Worker #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 0
915*9356374aSAndroid Build Coastguard Worker #endif
916*9356374aSAndroid Build Coastguard Worker
917*9356374aSAndroid Build Coastguard Worker // HashSelect
918*9356374aSAndroid Build Coastguard Worker //
919*9356374aSAndroid Build Coastguard Worker // Type trait to select the appropriate hash implementation to use.
920*9356374aSAndroid Build Coastguard Worker // HashSelect::type<T> will give the proper hash implementation, to be invoked
921*9356374aSAndroid Build Coastguard Worker // as:
922*9356374aSAndroid Build Coastguard Worker // HashSelect::type<T>::Invoke(state, value)
923*9356374aSAndroid Build Coastguard Worker // Also, HashSelect::type<T>::value is a boolean equal to `true` if there is a
924*9356374aSAndroid Build Coastguard Worker // valid `Invoke` function. Types that are not hashable will have a ::value of
925*9356374aSAndroid Build Coastguard Worker // `false`.
926*9356374aSAndroid Build Coastguard Worker struct HashSelect {
927*9356374aSAndroid Build Coastguard Worker private:
928*9356374aSAndroid Build Coastguard Worker struct State : HashStateBase<State> {
929*9356374aSAndroid Build Coastguard Worker static State combine_contiguous(State hash_state, const unsigned char*,
930*9356374aSAndroid Build Coastguard Worker size_t);
931*9356374aSAndroid Build Coastguard Worker using State::HashStateBase::combine_contiguous;
932*9356374aSAndroid Build Coastguard Worker };
933*9356374aSAndroid Build Coastguard Worker
934*9356374aSAndroid Build Coastguard Worker struct UniquelyRepresentedProbe {
935*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
936*9356374aSAndroid Build Coastguard Worker static auto Invoke(H state, const T& value)
937*9356374aSAndroid Build Coastguard Worker -> absl::enable_if_t<is_uniquely_represented<T>::value, H> {
938*9356374aSAndroid Build Coastguard Worker return hash_internal::hash_bytes(std::move(state), value);
939*9356374aSAndroid Build Coastguard Worker }
940*9356374aSAndroid Build Coastguard Worker };
941*9356374aSAndroid Build Coastguard Worker
942*9356374aSAndroid Build Coastguard Worker struct HashValueProbe {
943*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
944*9356374aSAndroid Build Coastguard Worker static auto Invoke(H state, const T& value) -> absl::enable_if_t<
945*9356374aSAndroid Build Coastguard Worker std::is_same<H,
946*9356374aSAndroid Build Coastguard Worker decltype(AbslHashValue(std::move(state), value))>::value,
947*9356374aSAndroid Build Coastguard Worker H> {
948*9356374aSAndroid Build Coastguard Worker return AbslHashValue(std::move(state), value);
949*9356374aSAndroid Build Coastguard Worker }
950*9356374aSAndroid Build Coastguard Worker };
951*9356374aSAndroid Build Coastguard Worker
952*9356374aSAndroid Build Coastguard Worker struct LegacyHashProbe {
953*9356374aSAndroid Build Coastguard Worker #if ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_
954*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
955*9356374aSAndroid Build Coastguard Worker static auto Invoke(H state, const T& value) -> absl::enable_if_t<
956*9356374aSAndroid Build Coastguard Worker std::is_convertible<
957*9356374aSAndroid Build Coastguard Worker decltype(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE::hash<T>()(value)),
958*9356374aSAndroid Build Coastguard Worker size_t>::value,
959*9356374aSAndroid Build Coastguard Worker H> {
960*9356374aSAndroid Build Coastguard Worker return hash_internal::hash_bytes(
961*9356374aSAndroid Build Coastguard Worker std::move(state),
962*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_LEGACY_HASH_NAMESPACE::hash<T>{}(value));
963*9356374aSAndroid Build Coastguard Worker }
964*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_
965*9356374aSAndroid Build Coastguard Worker };
966*9356374aSAndroid Build Coastguard Worker
967*9356374aSAndroid Build Coastguard Worker struct StdHashProbe {
968*9356374aSAndroid Build Coastguard Worker template <typename H, typename T>
969*9356374aSAndroid Build Coastguard Worker static auto Invoke(H state, const T& value)
970*9356374aSAndroid Build Coastguard Worker -> absl::enable_if_t<type_traits_internal::IsHashable<T>::value, H> {
971*9356374aSAndroid Build Coastguard Worker return hash_internal::hash_bytes(std::move(state), std::hash<T>{}(value));
972*9356374aSAndroid Build Coastguard Worker }
973*9356374aSAndroid Build Coastguard Worker };
974*9356374aSAndroid Build Coastguard Worker
975*9356374aSAndroid Build Coastguard Worker template <typename Hash, typename T>
976*9356374aSAndroid Build Coastguard Worker struct Probe : Hash {
977*9356374aSAndroid Build Coastguard Worker private:
978*9356374aSAndroid Build Coastguard Worker template <typename H, typename = decltype(H::Invoke(
979*9356374aSAndroid Build Coastguard Worker std::declval<State>(), std::declval<const T&>()))>
980*9356374aSAndroid Build Coastguard Worker static std::true_type Test(int);
981*9356374aSAndroid Build Coastguard Worker template <typename U>
982*9356374aSAndroid Build Coastguard Worker static std::false_type Test(char);
983*9356374aSAndroid Build Coastguard Worker
984*9356374aSAndroid Build Coastguard Worker public:
985*9356374aSAndroid Build Coastguard Worker static constexpr bool value = decltype(Test<Hash>(0))::value;
986*9356374aSAndroid Build Coastguard Worker };
987*9356374aSAndroid Build Coastguard Worker
988*9356374aSAndroid Build Coastguard Worker public:
989*9356374aSAndroid Build Coastguard Worker // Probe each implementation in order.
990*9356374aSAndroid Build Coastguard Worker // disjunction provides short circuiting wrt instantiation.
991*9356374aSAndroid Build Coastguard Worker template <typename T>
992*9356374aSAndroid Build Coastguard Worker using Apply = absl::disjunction< //
993*9356374aSAndroid Build Coastguard Worker Probe<UniquelyRepresentedProbe, T>, //
994*9356374aSAndroid Build Coastguard Worker Probe<HashValueProbe, T>, //
995*9356374aSAndroid Build Coastguard Worker Probe<LegacyHashProbe, T>, //
996*9356374aSAndroid Build Coastguard Worker Probe<StdHashProbe, T>, //
997*9356374aSAndroid Build Coastguard Worker std::false_type>;
998*9356374aSAndroid Build Coastguard Worker };
999*9356374aSAndroid Build Coastguard Worker
1000*9356374aSAndroid Build Coastguard Worker template <typename T>
1001*9356374aSAndroid Build Coastguard Worker struct is_hashable
1002*9356374aSAndroid Build Coastguard Worker : std::integral_constant<bool, HashSelect::template Apply<T>::value> {};
1003*9356374aSAndroid Build Coastguard Worker
1004*9356374aSAndroid Build Coastguard Worker // MixingHashState
1005*9356374aSAndroid Build Coastguard Worker class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> {
1006*9356374aSAndroid Build Coastguard Worker // absl::uint128 is not an alias or a thin wrapper around the intrinsic.
1007*9356374aSAndroid Build Coastguard Worker // We use the intrinsic when available to improve performance.
1008*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
1009*9356374aSAndroid Build Coastguard Worker using uint128 = __uint128_t;
1010*9356374aSAndroid Build Coastguard Worker #else // ABSL_HAVE_INTRINSIC_INT128
1011*9356374aSAndroid Build Coastguard Worker using uint128 = absl::uint128;
1012*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HAVE_INTRINSIC_INT128
1013*9356374aSAndroid Build Coastguard Worker
1014*9356374aSAndroid Build Coastguard Worker static constexpr uint64_t kMul =
1015*9356374aSAndroid Build Coastguard Worker sizeof(size_t) == 4 ? uint64_t{0xcc9e2d51}
1016*9356374aSAndroid Build Coastguard Worker : uint64_t{0x9ddfea08eb382d69};
1017*9356374aSAndroid Build Coastguard Worker
1018*9356374aSAndroid Build Coastguard Worker template <typename T>
1019*9356374aSAndroid Build Coastguard Worker using IntegralFastPath =
1020*9356374aSAndroid Build Coastguard Worker conjunction<std::is_integral<T>, is_uniquely_represented<T>>;
1021*9356374aSAndroid Build Coastguard Worker
1022*9356374aSAndroid Build Coastguard Worker public:
1023*9356374aSAndroid Build Coastguard Worker // Move only
1024*9356374aSAndroid Build Coastguard Worker MixingHashState(MixingHashState&&) = default;
1025*9356374aSAndroid Build Coastguard Worker MixingHashState& operator=(MixingHashState&&) = default;
1026*9356374aSAndroid Build Coastguard Worker
1027*9356374aSAndroid Build Coastguard Worker // MixingHashState::combine_contiguous()
1028*9356374aSAndroid Build Coastguard Worker //
1029*9356374aSAndroid Build Coastguard Worker // Fundamental base case for hash recursion: mixes the given range of bytes
1030*9356374aSAndroid Build Coastguard Worker // into the hash state.
1031*9356374aSAndroid Build Coastguard Worker static MixingHashState combine_contiguous(MixingHashState hash_state,
1032*9356374aSAndroid Build Coastguard Worker const unsigned char* first,
1033*9356374aSAndroid Build Coastguard Worker size_t size) {
1034*9356374aSAndroid Build Coastguard Worker return MixingHashState(
1035*9356374aSAndroid Build Coastguard Worker CombineContiguousImpl(hash_state.state_, first, size,
1036*9356374aSAndroid Build Coastguard Worker std::integral_constant<int, sizeof(size_t)>{}));
1037*9356374aSAndroid Build Coastguard Worker }
1038*9356374aSAndroid Build Coastguard Worker using MixingHashState::HashStateBase::combine_contiguous;
1039*9356374aSAndroid Build Coastguard Worker
1040*9356374aSAndroid Build Coastguard Worker // MixingHashState::hash()
1041*9356374aSAndroid Build Coastguard Worker //
1042*9356374aSAndroid Build Coastguard Worker // For performance reasons in non-opt mode, we specialize this for
1043*9356374aSAndroid Build Coastguard Worker // integral types.
1044*9356374aSAndroid Build Coastguard Worker // Otherwise we would be instantiating and calling dozens of functions for
1045*9356374aSAndroid Build Coastguard Worker // something that is just one multiplication and a couple xor's.
1046*9356374aSAndroid Build Coastguard Worker // The result should be the same as running the whole algorithm, but faster.
1047*9356374aSAndroid Build Coastguard Worker template <typename T, absl::enable_if_t<IntegralFastPath<T>::value, int> = 0>
1048*9356374aSAndroid Build Coastguard Worker static size_t hash(T value) {
1049*9356374aSAndroid Build Coastguard Worker return static_cast<size_t>(
1050*9356374aSAndroid Build Coastguard Worker Mix(Seed(), static_cast<std::make_unsigned_t<T>>(value)));
1051*9356374aSAndroid Build Coastguard Worker }
1052*9356374aSAndroid Build Coastguard Worker
1053*9356374aSAndroid Build Coastguard Worker // Overload of MixingHashState::hash()
1054*9356374aSAndroid Build Coastguard Worker template <typename T, absl::enable_if_t<!IntegralFastPath<T>::value, int> = 0>
1055*9356374aSAndroid Build Coastguard Worker static size_t hash(const T& value) {
1056*9356374aSAndroid Build Coastguard Worker return static_cast<size_t>(combine(MixingHashState{}, value).state_);
1057*9356374aSAndroid Build Coastguard Worker }
1058*9356374aSAndroid Build Coastguard Worker
1059*9356374aSAndroid Build Coastguard Worker private:
1060*9356374aSAndroid Build Coastguard Worker // Invoked only once for a given argument; that plus the fact that this is
1061*9356374aSAndroid Build Coastguard Worker // move-only ensures that there is only one non-moved-from object.
1062*9356374aSAndroid Build Coastguard Worker MixingHashState() : state_(Seed()) {}
1063*9356374aSAndroid Build Coastguard Worker
1064*9356374aSAndroid Build Coastguard Worker friend class MixingHashState::HashStateBase;
1065*9356374aSAndroid Build Coastguard Worker
1066*9356374aSAndroid Build Coastguard Worker template <typename CombinerT>
1067*9356374aSAndroid Build Coastguard Worker static MixingHashState RunCombineUnordered(MixingHashState state,
1068*9356374aSAndroid Build Coastguard Worker CombinerT combiner) {
1069*9356374aSAndroid Build Coastguard Worker uint64_t unordered_state = 0;
1070*9356374aSAndroid Build Coastguard Worker combiner(MixingHashState{}, [&](MixingHashState& inner_state) {
1071*9356374aSAndroid Build Coastguard Worker // Add the hash state of the element to the running total, but mix the
1072*9356374aSAndroid Build Coastguard Worker // carry bit back into the low bit. This in intended to avoid losing
1073*9356374aSAndroid Build Coastguard Worker // entropy to overflow, especially when unordered_multisets contain
1074*9356374aSAndroid Build Coastguard Worker // multiple copies of the same value.
1075*9356374aSAndroid Build Coastguard Worker auto element_state = inner_state.state_;
1076*9356374aSAndroid Build Coastguard Worker unordered_state += element_state;
1077*9356374aSAndroid Build Coastguard Worker if (unordered_state < element_state) {
1078*9356374aSAndroid Build Coastguard Worker ++unordered_state;
1079*9356374aSAndroid Build Coastguard Worker }
1080*9356374aSAndroid Build Coastguard Worker inner_state = MixingHashState{};
1081*9356374aSAndroid Build Coastguard Worker });
1082*9356374aSAndroid Build Coastguard Worker return MixingHashState::combine(std::move(state), unordered_state);
1083*9356374aSAndroid Build Coastguard Worker }
1084*9356374aSAndroid Build Coastguard Worker
1085*9356374aSAndroid Build Coastguard Worker // Allow the HashState type-erasure implementation to invoke
1086*9356374aSAndroid Build Coastguard Worker // RunCombinedUnordered() directly.
1087*9356374aSAndroid Build Coastguard Worker friend class absl::HashState;
1088*9356374aSAndroid Build Coastguard Worker
1089*9356374aSAndroid Build Coastguard Worker // Workaround for MSVC bug.
1090*9356374aSAndroid Build Coastguard Worker // We make the type copyable to fix the calling convention, even though we
1091*9356374aSAndroid Build Coastguard Worker // never actually copy it. Keep it private to not affect the public API of the
1092*9356374aSAndroid Build Coastguard Worker // type.
1093*9356374aSAndroid Build Coastguard Worker MixingHashState(const MixingHashState&) = default;
1094*9356374aSAndroid Build Coastguard Worker
1095*9356374aSAndroid Build Coastguard Worker explicit MixingHashState(uint64_t state) : state_(state) {}
1096*9356374aSAndroid Build Coastguard Worker
1097*9356374aSAndroid Build Coastguard Worker // Implementation of the base case for combine_contiguous where we actually
1098*9356374aSAndroid Build Coastguard Worker // mix the bytes into the state.
1099*9356374aSAndroid Build Coastguard Worker // Dispatch to different implementations of the combine_contiguous depending
1100*9356374aSAndroid Build Coastguard Worker // on the value of `sizeof(size_t)`.
1101*9356374aSAndroid Build Coastguard Worker static uint64_t CombineContiguousImpl(uint64_t state,
1102*9356374aSAndroid Build Coastguard Worker const unsigned char* first, size_t len,
1103*9356374aSAndroid Build Coastguard Worker std::integral_constant<int, 4>
1104*9356374aSAndroid Build Coastguard Worker /* sizeof_size_t */);
1105*9356374aSAndroid Build Coastguard Worker static uint64_t CombineContiguousImpl(uint64_t state,
1106*9356374aSAndroid Build Coastguard Worker const unsigned char* first, size_t len,
1107*9356374aSAndroid Build Coastguard Worker std::integral_constant<int, 8>
1108*9356374aSAndroid Build Coastguard Worker /* sizeof_size_t */);
1109*9356374aSAndroid Build Coastguard Worker
1110*9356374aSAndroid Build Coastguard Worker // Slow dispatch path for calls to CombineContiguousImpl with a size argument
1111*9356374aSAndroid Build Coastguard Worker // larger than PiecewiseChunkSize(). Has the same effect as calling
1112*9356374aSAndroid Build Coastguard Worker // CombineContiguousImpl() repeatedly with the chunk stride size.
1113*9356374aSAndroid Build Coastguard Worker static uint64_t CombineLargeContiguousImpl32(uint64_t state,
1114*9356374aSAndroid Build Coastguard Worker const unsigned char* first,
1115*9356374aSAndroid Build Coastguard Worker size_t len);
1116*9356374aSAndroid Build Coastguard Worker static uint64_t CombineLargeContiguousImpl64(uint64_t state,
1117*9356374aSAndroid Build Coastguard Worker const unsigned char* first,
1118*9356374aSAndroid Build Coastguard Worker size_t len);
1119*9356374aSAndroid Build Coastguard Worker
1120*9356374aSAndroid Build Coastguard Worker // Reads 9 to 16 bytes from p.
1121*9356374aSAndroid Build Coastguard Worker // The least significant 8 bytes are in .first, the rest (zero padded) bytes
1122*9356374aSAndroid Build Coastguard Worker // are in .second.
1123*9356374aSAndroid Build Coastguard Worker static std::pair<uint64_t, uint64_t> Read9To16(const unsigned char* p,
1124*9356374aSAndroid Build Coastguard Worker size_t len) {
1125*9356374aSAndroid Build Coastguard Worker uint64_t low_mem = absl::base_internal::UnalignedLoad64(p);
1126*9356374aSAndroid Build Coastguard Worker uint64_t high_mem = absl::base_internal::UnalignedLoad64(p + len - 8);
1127*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_IS_LITTLE_ENDIAN
1128*9356374aSAndroid Build Coastguard Worker uint64_t most_significant = high_mem;
1129*9356374aSAndroid Build Coastguard Worker uint64_t least_significant = low_mem;
1130*9356374aSAndroid Build Coastguard Worker #else
1131*9356374aSAndroid Build Coastguard Worker uint64_t most_significant = low_mem;
1132*9356374aSAndroid Build Coastguard Worker uint64_t least_significant = high_mem;
1133*9356374aSAndroid Build Coastguard Worker #endif
1134*9356374aSAndroid Build Coastguard Worker return {least_significant, most_significant};
1135*9356374aSAndroid Build Coastguard Worker }
1136*9356374aSAndroid Build Coastguard Worker
1137*9356374aSAndroid Build Coastguard Worker // Reads 4 to 8 bytes from p. Zero pads to fill uint64_t.
1138*9356374aSAndroid Build Coastguard Worker static uint64_t Read4To8(const unsigned char* p, size_t len) {
1139*9356374aSAndroid Build Coastguard Worker uint32_t low_mem = absl::base_internal::UnalignedLoad32(p);
1140*9356374aSAndroid Build Coastguard Worker uint32_t high_mem = absl::base_internal::UnalignedLoad32(p + len - 4);
1141*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_IS_LITTLE_ENDIAN
1142*9356374aSAndroid Build Coastguard Worker uint32_t most_significant = high_mem;
1143*9356374aSAndroid Build Coastguard Worker uint32_t least_significant = low_mem;
1144*9356374aSAndroid Build Coastguard Worker #else
1145*9356374aSAndroid Build Coastguard Worker uint32_t most_significant = low_mem;
1146*9356374aSAndroid Build Coastguard Worker uint32_t least_significant = high_mem;
1147*9356374aSAndroid Build Coastguard Worker #endif
1148*9356374aSAndroid Build Coastguard Worker return (static_cast<uint64_t>(most_significant) << (len - 4) * 8) |
1149*9356374aSAndroid Build Coastguard Worker least_significant;
1150*9356374aSAndroid Build Coastguard Worker }
1151*9356374aSAndroid Build Coastguard Worker
1152*9356374aSAndroid Build Coastguard Worker // Reads 1 to 3 bytes from p. Zero pads to fill uint32_t.
1153*9356374aSAndroid Build Coastguard Worker static uint32_t Read1To3(const unsigned char* p, size_t len) {
1154*9356374aSAndroid Build Coastguard Worker // The trick used by this implementation is to avoid branches if possible.
1155*9356374aSAndroid Build Coastguard Worker unsigned char mem0 = p[0];
1156*9356374aSAndroid Build Coastguard Worker unsigned char mem1 = p[len / 2];
1157*9356374aSAndroid Build Coastguard Worker unsigned char mem2 = p[len - 1];
1158*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_IS_LITTLE_ENDIAN
1159*9356374aSAndroid Build Coastguard Worker unsigned char significant2 = mem2;
1160*9356374aSAndroid Build Coastguard Worker unsigned char significant1 = mem1;
1161*9356374aSAndroid Build Coastguard Worker unsigned char significant0 = mem0;
1162*9356374aSAndroid Build Coastguard Worker #else
1163*9356374aSAndroid Build Coastguard Worker unsigned char significant2 = mem0;
1164*9356374aSAndroid Build Coastguard Worker unsigned char significant1 = len == 2 ? mem0 : mem1;
1165*9356374aSAndroid Build Coastguard Worker unsigned char significant0 = mem2;
1166*9356374aSAndroid Build Coastguard Worker #endif
1167*9356374aSAndroid Build Coastguard Worker return static_cast<uint32_t>(significant0 | //
1168*9356374aSAndroid Build Coastguard Worker (significant1 << (len / 2 * 8)) | //
1169*9356374aSAndroid Build Coastguard Worker (significant2 << ((len - 1) * 8)));
1170*9356374aSAndroid Build Coastguard Worker }
1171*9356374aSAndroid Build Coastguard Worker
1172*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) {
1173*9356374aSAndroid Build Coastguard Worker // Though the 128-bit product on AArch64 needs two instructions, it is
1174*9356374aSAndroid Build Coastguard Worker // still a good balance between speed and hash quality.
1175*9356374aSAndroid Build Coastguard Worker using MultType =
1176*9356374aSAndroid Build Coastguard Worker absl::conditional_t<sizeof(size_t) == 4, uint64_t, uint128>;
1177*9356374aSAndroid Build Coastguard Worker // We do the addition in 64-bit space to make sure the 128-bit
1178*9356374aSAndroid Build Coastguard Worker // multiplication is fast. If we were to do it as MultType the compiler has
1179*9356374aSAndroid Build Coastguard Worker // to assume that the high word is non-zero and needs to perform 2
1180*9356374aSAndroid Build Coastguard Worker // multiplications instead of one.
1181*9356374aSAndroid Build Coastguard Worker MultType m = state + v;
1182*9356374aSAndroid Build Coastguard Worker m *= kMul;
1183*9356374aSAndroid Build Coastguard Worker return static_cast<uint64_t>(m ^ (m >> (sizeof(m) * 8 / 2)));
1184*9356374aSAndroid Build Coastguard Worker }
1185*9356374aSAndroid Build Coastguard Worker
1186*9356374aSAndroid Build Coastguard Worker // An extern to avoid bloat on a direct call to LowLevelHash() with fixed
1187*9356374aSAndroid Build Coastguard Worker // values for both the seed and salt parameters.
1188*9356374aSAndroid Build Coastguard Worker static uint64_t LowLevelHashImpl(const unsigned char* data, size_t len);
1189*9356374aSAndroid Build Coastguard Worker
1190*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Hash64(const unsigned char* data,
1191*9356374aSAndroid Build Coastguard Worker size_t len) {
1192*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_INTRINSIC_INT128
1193*9356374aSAndroid Build Coastguard Worker return LowLevelHashImpl(data, len);
1194*9356374aSAndroid Build Coastguard Worker #else
1195*9356374aSAndroid Build Coastguard Worker return hash_internal::CityHash64(reinterpret_cast<const char*>(data), len);
1196*9356374aSAndroid Build Coastguard Worker #endif
1197*9356374aSAndroid Build Coastguard Worker }
1198*9356374aSAndroid Build Coastguard Worker
1199*9356374aSAndroid Build Coastguard Worker // Seed()
1200*9356374aSAndroid Build Coastguard Worker //
1201*9356374aSAndroid Build Coastguard Worker // A non-deterministic seed.
1202*9356374aSAndroid Build Coastguard Worker //
1203*9356374aSAndroid Build Coastguard Worker // The current purpose of this seed is to generate non-deterministic results
1204*9356374aSAndroid Build Coastguard Worker // and prevent having users depend on the particular hash values.
1205*9356374aSAndroid Build Coastguard Worker // It is not meant as a security feature right now, but it leaves the door
1206*9356374aSAndroid Build Coastguard Worker // open to upgrade it to a true per-process random seed. A true random seed
1207*9356374aSAndroid Build Coastguard Worker // costs more and we don't need to pay for that right now.
1208*9356374aSAndroid Build Coastguard Worker //
1209*9356374aSAndroid Build Coastguard Worker // On platforms with ASLR, we take advantage of it to make a per-process
1210*9356374aSAndroid Build Coastguard Worker // random value.
1211*9356374aSAndroid Build Coastguard Worker // See https://en.wikipedia.org/wiki/Address_space_layout_randomization
1212*9356374aSAndroid Build Coastguard Worker //
1213*9356374aSAndroid Build Coastguard Worker // On other platforms this is still going to be non-deterministic but most
1214*9356374aSAndroid Build Coastguard Worker // probably per-build and not per-process.
1215*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Seed() {
1216*9356374aSAndroid Build Coastguard Worker #if (!defined(__clang__) || __clang_major__ > 11) && \
1217*9356374aSAndroid Build Coastguard Worker (!defined(__apple_build_version__) || \
1218*9356374aSAndroid Build Coastguard Worker __apple_build_version__ >= 19558921) // Xcode 12
1219*9356374aSAndroid Build Coastguard Worker return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&kSeed));
1220*9356374aSAndroid Build Coastguard Worker #else
1221*9356374aSAndroid Build Coastguard Worker // Workaround the absence of
1222*9356374aSAndroid Build Coastguard Worker // https://github.com/llvm/llvm-project/commit/bc15bf66dcca76cc06fe71fca35b74dc4d521021.
1223*9356374aSAndroid Build Coastguard Worker return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(kSeed));
1224*9356374aSAndroid Build Coastguard Worker #endif
1225*9356374aSAndroid Build Coastguard Worker }
1226*9356374aSAndroid Build Coastguard Worker static const void* const kSeed;
1227*9356374aSAndroid Build Coastguard Worker
1228*9356374aSAndroid Build Coastguard Worker uint64_t state_;
1229*9356374aSAndroid Build Coastguard Worker };
1230*9356374aSAndroid Build Coastguard Worker
1231*9356374aSAndroid Build Coastguard Worker // MixingHashState::CombineContiguousImpl()
1232*9356374aSAndroid Build Coastguard Worker inline uint64_t MixingHashState::CombineContiguousImpl(
1233*9356374aSAndroid Build Coastguard Worker uint64_t state, const unsigned char* first, size_t len,
1234*9356374aSAndroid Build Coastguard Worker std::integral_constant<int, 4> /* sizeof_size_t */) {
1235*9356374aSAndroid Build Coastguard Worker // For large values we use CityHash, for small ones we just use a
1236*9356374aSAndroid Build Coastguard Worker // multiplicative hash.
1237*9356374aSAndroid Build Coastguard Worker uint64_t v;
1238*9356374aSAndroid Build Coastguard Worker if (len > 8) {
1239*9356374aSAndroid Build Coastguard Worker if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) {
1240*9356374aSAndroid Build Coastguard Worker return CombineLargeContiguousImpl32(state, first, len);
1241*9356374aSAndroid Build Coastguard Worker }
1242*9356374aSAndroid Build Coastguard Worker v = hash_internal::CityHash32(reinterpret_cast<const char*>(first), len);
1243*9356374aSAndroid Build Coastguard Worker } else if (len >= 4) {
1244*9356374aSAndroid Build Coastguard Worker v = Read4To8(first, len);
1245*9356374aSAndroid Build Coastguard Worker } else if (len > 0) {
1246*9356374aSAndroid Build Coastguard Worker v = Read1To3(first, len);
1247*9356374aSAndroid Build Coastguard Worker } else {
1248*9356374aSAndroid Build Coastguard Worker // Empty ranges have no effect.
1249*9356374aSAndroid Build Coastguard Worker return state;
1250*9356374aSAndroid Build Coastguard Worker }
1251*9356374aSAndroid Build Coastguard Worker return Mix(state, v);
1252*9356374aSAndroid Build Coastguard Worker }
1253*9356374aSAndroid Build Coastguard Worker
1254*9356374aSAndroid Build Coastguard Worker // Overload of MixingHashState::CombineContiguousImpl()
1255*9356374aSAndroid Build Coastguard Worker inline uint64_t MixingHashState::CombineContiguousImpl(
1256*9356374aSAndroid Build Coastguard Worker uint64_t state, const unsigned char* first, size_t len,
1257*9356374aSAndroid Build Coastguard Worker std::integral_constant<int, 8> /* sizeof_size_t */) {
1258*9356374aSAndroid Build Coastguard Worker // For large values we use LowLevelHash or CityHash depending on the platform,
1259*9356374aSAndroid Build Coastguard Worker // for small ones we just use a multiplicative hash.
1260*9356374aSAndroid Build Coastguard Worker uint64_t v;
1261*9356374aSAndroid Build Coastguard Worker if (len > 16) {
1262*9356374aSAndroid Build Coastguard Worker if (ABSL_PREDICT_FALSE(len > PiecewiseChunkSize())) {
1263*9356374aSAndroid Build Coastguard Worker return CombineLargeContiguousImpl64(state, first, len);
1264*9356374aSAndroid Build Coastguard Worker }
1265*9356374aSAndroid Build Coastguard Worker v = Hash64(first, len);
1266*9356374aSAndroid Build Coastguard Worker } else if (len > 8) {
1267*9356374aSAndroid Build Coastguard Worker // This hash function was constructed by the ML-driven algorithm discovery
1268*9356374aSAndroid Build Coastguard Worker // using reinforcement learning. We fed the agent lots of inputs from
1269*9356374aSAndroid Build Coastguard Worker // microbenchmarks, SMHasher, low hamming distance from generated inputs and
1270*9356374aSAndroid Build Coastguard Worker // picked up the one that was good on micro and macrobenchmarks.
1271*9356374aSAndroid Build Coastguard Worker auto p = Read9To16(first, len);
1272*9356374aSAndroid Build Coastguard Worker uint64_t lo = p.first;
1273*9356374aSAndroid Build Coastguard Worker uint64_t hi = p.second;
1274*9356374aSAndroid Build Coastguard Worker // Rotation by 53 was found to be most often useful when discovering these
1275*9356374aSAndroid Build Coastguard Worker // hashing algorithms with ML techniques.
1276*9356374aSAndroid Build Coastguard Worker lo = absl::rotr(lo, 53);
1277*9356374aSAndroid Build Coastguard Worker state += kMul;
1278*9356374aSAndroid Build Coastguard Worker lo += state;
1279*9356374aSAndroid Build Coastguard Worker state ^= hi;
1280*9356374aSAndroid Build Coastguard Worker uint128 m = state;
1281*9356374aSAndroid Build Coastguard Worker m *= lo;
1282*9356374aSAndroid Build Coastguard Worker return static_cast<uint64_t>(m ^ (m >> 64));
1283*9356374aSAndroid Build Coastguard Worker } else if (len >= 4) {
1284*9356374aSAndroid Build Coastguard Worker v = Read4To8(first, len);
1285*9356374aSAndroid Build Coastguard Worker } else if (len > 0) {
1286*9356374aSAndroid Build Coastguard Worker v = Read1To3(first, len);
1287*9356374aSAndroid Build Coastguard Worker } else {
1288*9356374aSAndroid Build Coastguard Worker // Empty ranges have no effect.
1289*9356374aSAndroid Build Coastguard Worker return state;
1290*9356374aSAndroid Build Coastguard Worker }
1291*9356374aSAndroid Build Coastguard Worker return Mix(state, v);
1292*9356374aSAndroid Build Coastguard Worker }
1293*9356374aSAndroid Build Coastguard Worker
1294*9356374aSAndroid Build Coastguard Worker struct AggregateBarrier {};
1295*9356374aSAndroid Build Coastguard Worker
1296*9356374aSAndroid Build Coastguard Worker // HashImpl
1297*9356374aSAndroid Build Coastguard Worker
1298*9356374aSAndroid Build Coastguard Worker // Add a private base class to make sure this type is not an aggregate.
1299*9356374aSAndroid Build Coastguard Worker // Aggregates can be aggregate initialized even if the default constructor is
1300*9356374aSAndroid Build Coastguard Worker // deleted.
1301*9356374aSAndroid Build Coastguard Worker struct PoisonedHash : private AggregateBarrier {
1302*9356374aSAndroid Build Coastguard Worker PoisonedHash() = delete;
1303*9356374aSAndroid Build Coastguard Worker PoisonedHash(const PoisonedHash&) = delete;
1304*9356374aSAndroid Build Coastguard Worker PoisonedHash& operator=(const PoisonedHash&) = delete;
1305*9356374aSAndroid Build Coastguard Worker };
1306*9356374aSAndroid Build Coastguard Worker
1307*9356374aSAndroid Build Coastguard Worker template <typename T>
1308*9356374aSAndroid Build Coastguard Worker struct HashImpl {
1309*9356374aSAndroid Build Coastguard Worker size_t operator()(const T& value) const {
1310*9356374aSAndroid Build Coastguard Worker return MixingHashState::hash(value);
1311*9356374aSAndroid Build Coastguard Worker }
1312*9356374aSAndroid Build Coastguard Worker };
1313*9356374aSAndroid Build Coastguard Worker
1314*9356374aSAndroid Build Coastguard Worker template <typename T>
1315*9356374aSAndroid Build Coastguard Worker struct Hash
1316*9356374aSAndroid Build Coastguard Worker : absl::conditional_t<is_hashable<T>::value, HashImpl<T>, PoisonedHash> {};
1317*9356374aSAndroid Build Coastguard Worker
1318*9356374aSAndroid Build Coastguard Worker template <typename H>
1319*9356374aSAndroid Build Coastguard Worker template <typename T, typename... Ts>
1320*9356374aSAndroid Build Coastguard Worker H HashStateBase<H>::combine(H state, const T& value, const Ts&... values) {
1321*9356374aSAndroid Build Coastguard Worker return H::combine(hash_internal::HashSelect::template Apply<T>::Invoke(
1322*9356374aSAndroid Build Coastguard Worker std::move(state), value),
1323*9356374aSAndroid Build Coastguard Worker values...);
1324*9356374aSAndroid Build Coastguard Worker }
1325*9356374aSAndroid Build Coastguard Worker
1326*9356374aSAndroid Build Coastguard Worker // HashStateBase::combine_contiguous()
1327*9356374aSAndroid Build Coastguard Worker template <typename H>
1328*9356374aSAndroid Build Coastguard Worker template <typename T>
1329*9356374aSAndroid Build Coastguard Worker H HashStateBase<H>::combine_contiguous(H state, const T* data, size_t size) {
1330*9356374aSAndroid Build Coastguard Worker return hash_internal::hash_range_or_bytes(std::move(state), data, size);
1331*9356374aSAndroid Build Coastguard Worker }
1332*9356374aSAndroid Build Coastguard Worker
1333*9356374aSAndroid Build Coastguard Worker // HashStateBase::combine_unordered()
1334*9356374aSAndroid Build Coastguard Worker template <typename H>
1335*9356374aSAndroid Build Coastguard Worker template <typename I>
1336*9356374aSAndroid Build Coastguard Worker H HashStateBase<H>::combine_unordered(H state, I begin, I end) {
1337*9356374aSAndroid Build Coastguard Worker return H::RunCombineUnordered(std::move(state),
1338*9356374aSAndroid Build Coastguard Worker CombineUnorderedCallback<I>{begin, end});
1339*9356374aSAndroid Build Coastguard Worker }
1340*9356374aSAndroid Build Coastguard Worker
1341*9356374aSAndroid Build Coastguard Worker // HashStateBase::PiecewiseCombiner::add_buffer()
1342*9356374aSAndroid Build Coastguard Worker template <typename H>
1343*9356374aSAndroid Build Coastguard Worker H PiecewiseCombiner::add_buffer(H state, const unsigned char* data,
1344*9356374aSAndroid Build Coastguard Worker size_t size) {
1345*9356374aSAndroid Build Coastguard Worker if (position_ + size < PiecewiseChunkSize()) {
1346*9356374aSAndroid Build Coastguard Worker // This partial chunk does not fill our existing buffer
1347*9356374aSAndroid Build Coastguard Worker memcpy(buf_ + position_, data, size);
1348*9356374aSAndroid Build Coastguard Worker position_ += size;
1349*9356374aSAndroid Build Coastguard Worker return state;
1350*9356374aSAndroid Build Coastguard Worker }
1351*9356374aSAndroid Build Coastguard Worker
1352*9356374aSAndroid Build Coastguard Worker // If the buffer is partially filled we need to complete the buffer
1353*9356374aSAndroid Build Coastguard Worker // and hash it.
1354*9356374aSAndroid Build Coastguard Worker if (position_ != 0) {
1355*9356374aSAndroid Build Coastguard Worker const size_t bytes_needed = PiecewiseChunkSize() - position_;
1356*9356374aSAndroid Build Coastguard Worker memcpy(buf_ + position_, data, bytes_needed);
1357*9356374aSAndroid Build Coastguard Worker state = H::combine_contiguous(std::move(state), buf_, PiecewiseChunkSize());
1358*9356374aSAndroid Build Coastguard Worker data += bytes_needed;
1359*9356374aSAndroid Build Coastguard Worker size -= bytes_needed;
1360*9356374aSAndroid Build Coastguard Worker }
1361*9356374aSAndroid Build Coastguard Worker
1362*9356374aSAndroid Build Coastguard Worker // Hash whatever chunks we can without copying
1363*9356374aSAndroid Build Coastguard Worker while (size >= PiecewiseChunkSize()) {
1364*9356374aSAndroid Build Coastguard Worker state = H::combine_contiguous(std::move(state), data, PiecewiseChunkSize());
1365*9356374aSAndroid Build Coastguard Worker data += PiecewiseChunkSize();
1366*9356374aSAndroid Build Coastguard Worker size -= PiecewiseChunkSize();
1367*9356374aSAndroid Build Coastguard Worker }
1368*9356374aSAndroid Build Coastguard Worker // Fill the buffer with the remainder
1369*9356374aSAndroid Build Coastguard Worker memcpy(buf_, data, size);
1370*9356374aSAndroid Build Coastguard Worker position_ = size;
1371*9356374aSAndroid Build Coastguard Worker return state;
1372*9356374aSAndroid Build Coastguard Worker }
1373*9356374aSAndroid Build Coastguard Worker
1374*9356374aSAndroid Build Coastguard Worker // HashStateBase::PiecewiseCombiner::finalize()
1375*9356374aSAndroid Build Coastguard Worker template <typename H>
1376*9356374aSAndroid Build Coastguard Worker H PiecewiseCombiner::finalize(H state) {
1377*9356374aSAndroid Build Coastguard Worker // Hash the remainder left in the buffer, which may be empty
1378*9356374aSAndroid Build Coastguard Worker return H::combine_contiguous(std::move(state), buf_, position_);
1379*9356374aSAndroid Build Coastguard Worker }
1380*9356374aSAndroid Build Coastguard Worker
1381*9356374aSAndroid Build Coastguard Worker } // namespace hash_internal
1382*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
1383*9356374aSAndroid Build Coastguard Worker } // namespace absl
1384*9356374aSAndroid Build Coastguard Worker
1385*9356374aSAndroid Build Coastguard Worker #endif // ABSL_HASH_INTERNAL_HASH_H_
1386