/* * libfud * Copyright 2025 Dominick Allen * * 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 * * http://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 FUD_HASH_HPP #define FUD_HASH_HPP #include "fud_string.hpp" #include "fud_string_view.hpp" #include "fud_utf8.hpp" #include /* namespace fud { template concept Hashable = requires(Key key) { { sink.drain(source) } -> std::same_as; }; } // namespace fud */ namespace fud::detail { constexpr uint64_t roundToNearest2(uint64_t inputValue) noexcept { if (inputValue == 0) { return 1; } uint64_t outputValue = inputValue - 1; constexpr uint8_t max2PowerShift = 32; for (uint8_t shift = 1; shift <= max2PowerShift; shift *= 2) { outputValue |= outputValue >> shift; } outputValue++; return outputValue; } /** \brief The djb2 algorithm by Dan Bernstein. See http://www.cse.yorku.ca/~oz/hash.html * * If passed a null pointer for data, returns the initial hash value. */ size_t djb2(const utf8* data, size_t length); template struct DefaultHash { static_assert(std::is_integral_v || std::is_enum_v); size_t operator()(const T& value, size_t seed) const { static_cast(seed); return djb2(std::bit_cast(&value), sizeof(value)); } }; template <> struct DefaultHash { size_t operator()(const String& value, size_t seed) const; }; template <> struct DefaultHash { size_t operator()(const StringView& value, size_t seed) const; }; } // namespace fud::detail #endif