// Copyright 2018 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef ABSL_HASH_INTERNAL_SPY_HASH_STATE_H_ #define ABSL_HASH_INTERNAL_SPY_HASH_STATE_H_ #include <algorithm> #include <ostream> #include <string> #include <vector> #include "absl/hash/hash.h" #include "absl/strings/match.h" #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" namespace absl { ABSL_NAMESPACE_BEGIN namespace hash_internal { // SpyHashState is an implementation of the HashState API that simply // accumulates all input bytes in an internal buffer. This makes it useful // for testing AbslHashValue overloads (so long as they are templated on the // HashState parameter), since it can report the exact hash representation // that the AbslHashValue overload produces. // // Sample usage: // EXPECT_EQ(SpyHashState::combine(SpyHashState(), foo), // SpyHashState::combine(SpyHashState(), bar)); template <typename T> class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> { … }; template <typename T> bool SpyHashStateImpl<T>::direct_absl_hash_value_error_; template <bool& B> struct OdrUse { … }; template <void (*)()> struct RunOnStartup { … }; template <void (*f)()> bool RunOnStartup<f>::run = …; template < typename T, typename U, // Only trigger for when (T != U), typename = absl::enable_if_t<!std::is_same<T, U>::value>, // This statement works in two ways: // - First, it instantiates RunOnStartup and forces the initialization of // `run`, which set the global variable. // - Second, it triggers a SFINAE error disabling the overload to prevent // compile time errors. If we didn't disable the overload we would get // ambiguous overload errors, which we don't want. int = RunOnStartup<SpyHashStateImpl<T>::SetDirectAbslHashValueError>::run> void AbslHashValue(SpyHashStateImpl<T>, const U&); SpyHashState; } // namespace hash_internal ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_INTERNAL_SPY_HASH_STATE_H_