Compare commits

..

No commits in common. "dev/lhecker/til-hash" and "main" have entirely different histories.

5 changed files with 146 additions and 330 deletions

View file

@ -61,6 +61,27 @@ private:
// * ActionEventArgs holds a single IActionArgs. For events that don't need
// additional args, this can be nullptr.
template<>
constexpr size_t Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(const winrt::Microsoft::Terminal::Settings::Model::IActionArgs& args)
{
return gsl::narrow_cast<size_t>(args.Hash());
}
template<>
constexpr size_t Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(const winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs& args)
{
return gsl::narrow_cast<size_t>(args.Hash());
}
// Retrieves the hash value for an empty-constructed object.
template<typename T>
static size_t EmptyHash()
{
// cache the value of the empty hash
static const size_t cachedHash = winrt::make_self<T>()->Hash();
return cachedHash;
}
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
using namespace ::Microsoft::Terminal::Settings::Model;
@ -164,18 +185,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_ColorScheme = _ColorScheme;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Commandline())>{}(h, Commandline());
til::hash<decltype(StartingDirectory())>{}(h, StartingDirectory());
til::hash<decltype(TabTitle())>{}(h, TabTitle());
til::hash<decltype(TabColor())>{}(h, TabColor());
til::hash<decltype(ProfileIndex())>{}(h, ProfileIndex());
til::hash<decltype(Profile())>{}(h, Profile());
til::hash<decltype(SuppressApplicationTitle())>{}(h, SuppressApplicationTitle());
til::hash<decltype(ColorScheme())>{}(h, ColorScheme());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Commandline(), StartingDirectory(), TabTitle(), TabColor(), ProfileIndex(), Profile(), SuppressApplicationTitle(), ColorScheme());
}
};
@ -229,12 +241,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_CopyFormatting = _CopyFormatting;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(SingleLine())>{}(h, SingleLine());
til::hash<decltype(CopyFormatting())>{}(h, CopyFormatting());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SingleLine(), CopyFormatting());
}
};
@ -279,11 +288,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TerminalArgs = _TerminalArgs.Copy();
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(TerminalArgs())>{}(h, TerminalArgs());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TerminalArgs());
}
};
@ -332,11 +339,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TabIndex = _TabIndex;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(TabIndex())>{}(h, TabIndex());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TabIndex());
}
};
@ -385,11 +390,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TabIndex = _TabIndex;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(TabIndex())>{}(h, TabIndex());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TabIndex());
}
};
@ -443,11 +446,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_ResizeDirection = _ResizeDirection;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(ResizeDirection())>{}(h, ResizeDirection());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(ResizeDirection());
}
};
@ -504,11 +505,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_FocusDirection = _FocusDirection;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(FocusDirection())>{}(h, FocusDirection());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(FocusDirection());
}
};
@ -565,11 +564,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Direction = _Direction;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Direction())>{}(h, Direction());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Direction());
}
};
@ -616,11 +613,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Delta = _Delta;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Delta())>{}(h, Delta());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Delta());
}
};
@ -670,11 +665,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Input = _Input;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Input())>{}(h, Input());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Input());
}
};
@ -756,14 +749,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_SplitSize = _SplitSize;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(SplitDirection())>{}(h, SplitDirection());
til::hash<decltype(TerminalArgs())>{}(h, TerminalArgs());
til::hash<decltype(SplitMode())>{}(h, SplitMode());
til::hash<decltype(SplitSize())>{}(h, SplitSize());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SplitDirection(), TerminalArgs(), SplitMode(), SplitSize());
}
};
@ -812,11 +800,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Target = _Target;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Target())>{}(h, Target());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Target());
}
};
@ -869,11 +855,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_SchemeName = _SchemeName;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(SchemeName())>{}(h, SchemeName());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SchemeName());
}
};
@ -922,11 +906,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TabColor = _TabColor;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(TabColor())>{}(h, TabColor());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TabColor());
}
};
@ -973,11 +955,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Title = _Title;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Title())>{}(h, Title());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Title());
}
};
@ -1030,11 +1010,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Commandline = _Commandline;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Commandline())>{}(h, Commandline());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Commandline());
}
};
@ -1083,11 +1061,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Index = _Index;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Index())>{}(h, Index());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Index());
}
};
@ -1136,11 +1112,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Index = _Index;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Index())>{}(h, Index());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Index());
}
};
@ -1189,11 +1163,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Index = _Index;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Index())>{}(h, Index());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Index());
}
};
@ -1249,11 +1221,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Direction = _Direction;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Direction())>{}(h, Direction());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Direction());
}
};
@ -1300,11 +1270,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_RowsToScroll = _RowsToScroll;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(RowsToScroll())>{}(h, RowsToScroll());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(RowsToScroll());
}
};
@ -1351,11 +1319,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_RowsToScroll = _RowsToScroll;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(RowsToScroll())>{}(h, RowsToScroll());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(RowsToScroll());
}
};
@ -1404,11 +1370,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_LaunchMode = _LaunchMode;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(LaunchMode())>{}(h, LaunchMode());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(LaunchMode());
}
};
@ -1464,11 +1428,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Direction = _Direction;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Direction())>{}(h, Direction());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Direction());
}
};
@ -1513,11 +1475,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TerminalArgs = _TerminalArgs.Copy();
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(TerminalArgs())>{}(h, TerminalArgs());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TerminalArgs());
}
};
@ -1565,11 +1525,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_SwitcherMode = _SwitcherMode;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(SwitcherMode())>{}(h, SwitcherMode());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SwitcherMode());
}
};
@ -1617,11 +1575,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_SwitcherMode = _SwitcherMode;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(SwitcherMode())>{}(h, SwitcherMode());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SwitcherMode());
}
};
@ -1669,11 +1625,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Name = _Name;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Name())>{}(h, Name());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Name());
}
};
@ -1755,15 +1709,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
args->_DropdownDuration = 200;
return { *args, {} };
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Name())>{}(h, Name());
til::hash<decltype(Desktop())>{}(h, Desktop());
til::hash<decltype(Monitor())>{}(h, Monitor());
til::hash<decltype(DropdownDuration())>{}(h, DropdownDuration());
til::hash<decltype(ToggleVisibility())>{}(h, ToggleVisibility());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Name(), Desktop(), Monitor(), DropdownDuration(), ToggleVisibility());
}
};
@ -1811,11 +1759,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Id = _Id;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Id())>{}(h, Id());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Id);
}
};
@ -1863,11 +1809,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Clear = _Clear;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<decltype(Clear())>{}(h, Clear());
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Clear);
}
};
@ -1914,11 +1858,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Actions = _Actions;
return *copy;
}
size_t Hash(size_t hasherState) const
size_t Hash() const
{
til::hasher h{ hasherState };
til::hash<void*>{}(h, winrt::get_abi(_Actions));
return h.finalize();
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Actions);
}
};
}

View file

@ -10,7 +10,7 @@ namespace Microsoft.Terminal.Settings.Model
Boolean Equals(IActionArgs other);
String GenerateName();
IActionArgs Copy();
UInt64 Hash(UInt64 hasher);
UInt64 Hash();
};
interface IActionEventArgs
@ -128,7 +128,7 @@ namespace Microsoft.Terminal.Settings.Model
Boolean Equals(NewTerminalArgs other);
String GenerateName();
String ToCommandline();
UInt64 Hash(UInt64 hasher);
UInt64 Hash();
};
[default_interface] runtimeclass ActionEventArgs : IActionEventArgs

View file

@ -15,12 +15,13 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
static InternalActionID Hash(const Model::ActionAndArgs& actionAndArgs)
{
const auto action = actionAndArgs.Action();
til::hasher hasher;
size_t hashedAction{ HashUtils::HashProperty(actionAndArgs.Action()) };
if (const auto args = actionAndArgs.Args())
size_t hashedArgs{};
if (const auto& args{ actionAndArgs.Args() })
{
hasher = gsl::narrow_cast<size_t>(args.Hash(hasher.finalize()));
// Args are defined, so hash them
hashedArgs = gsl::narrow_cast<size_t>(args.Hash());
}
else
{
@ -28,24 +29,22 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// Check if the ShortcutAction supports args.
switch (actionAndArgs.Action())
{
#define ON_ALL_ACTIONS_WITH_ARGS(action) \
case ShortcutAction::action: \
{ \
/* If it does, hash the default values for the args. */ \
/* Since til::hasher hasn't been written to at this point, hasher.finalize() is a constexpr. */ \
static const size_t cachedHash = winrt::make_self<implementation::action##Args>()->Hash(hasher.finalize()); \
hasher = gsl::narrow_cast<size_t>(cachedHash); \
break; \
}
#define ON_ALL_ACTIONS_WITH_ARGS(action) \
case ShortcutAction::action: \
/* If it does, hash the default values for the args.*/ \
hashedArgs = EmptyHash<implementation::action##Args>(); \
break;
ALL_SHORTCUT_ACTIONS_WITH_ARGS
#undef ON_ALL_ACTIONS_WITH_ARGS
default:
break;
{
// Otherwise, hash nullptr.
std::hash<IActionArgs> argsHash;
hashedArgs = argsHash(nullptr);
}
}
}
hasher.write(action);
return hasher.finalize();
return hashedAction ^ hashedArgs;
}
// Method Description:

View file

@ -17,37 +17,54 @@ Revision History:
#pragma once
#include <til/hash.h>
namespace til
namespace Microsoft::Terminal::Settings::Model::HashUtils
{
// This is a helper template function for hashing multiple variables in conjunction to each other.
template<typename T>
struct hash<winrt::Windows::Foundation::IReference<T>>
constexpr size_t HashProperty(const T& val)
{
constexpr void operator()(hasher& h, const winrt::Windows::Foundation::IReference<T>& v) const noexcept
{
if (v)
{
til::hash<decltype(v.Value())>{}(h, v.Value());
}
}
};
std::hash<T> hashFunc;
return hashFunc(val);
}
template<typename T, typename... Args>
constexpr size_t HashProperty(const T& val, Args&&... more)
{
// Inspired by boost::hash_combine, which causes this effect...
// seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
// Source: https://www.boost.org/doc/libs/1_35_0/doc/html/boost/hash_combine_id241013.html
const auto seed{ HashProperty(val) };
return seed ^ (0x9e3779b9 + (seed << 6) + (seed >> 2) + HashProperty(std::forward<Args>(more)...));
}
template<>
struct hash<winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs>
constexpr size_t HashProperty(const til::color& val)
{
void operator()(hasher& h, const winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs& value) const noexcept
{
til::hash<void*>{}(h, winrt::get_abi(value));
}
};
return HashProperty(val.a, val.r, val.g, val.b);
}
template<>
struct hash<winrt::hstring>
#ifdef WINRT_Windows_Foundation_H
template<typename T>
constexpr size_t HashProperty(const winrt::Windows::Foundation::IReference<T>& val)
{
void operator()(hasher& h, const winrt::hstring& value) const noexcept
{
h.write(reinterpret_cast<const uint8_t*>(value.data()), value.size() * sizeof(wchar_t));
}
};
}
return val ? HashProperty(val.Value()) : 0;
}
#endif
#ifdef WINRT_Windows_UI_H
template<>
constexpr size_t HashProperty(const winrt::Windows::UI::Color& val)
{
return HashProperty(til::color{ val });
}
#endif
#ifdef WINRT_Microsoft_Terminal_Core_H
template<>
constexpr size_t HashProperty(const winrt::Microsoft::Terminal::Core::Color& val)
{
return HashProperty(til::color{ val });
}
#endif
};

View file

@ -1,142 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include <utility>
namespace til
{
template<typename T>
struct integral_hash
{
constexpr size_t operator()(T v) const noexcept
{
auto h = static_cast<size_t>(v);
if constexpr (sizeof(size_t) == 4)
{
h ^= h >> 16;
h *= UINT32_C(0x85ebca6b);
h ^= h >> 13;
h *= UINT32_C(0xc2b2ae35);
h ^= h >> 16;
}
else
{
std::_Hash_array_representation
h ^= h >> 33;
h *= UINT64_C(0xff51afd7ed558ccd);
h ^= h >> 33;
h *= UINT64_C(0xc4ceb9fe1a85ec53);
h ^= h >> 33;
}
return h;
}
};
template<typename T>
struct hash;
struct hasher
{
constexpr hasher(size_t state = FNV_offset_basis) noexcept : _hash{state} {}
template<typename T, typename = std::enable_if_t<std::has_unique_object_representations_v<T>>>
constexpr void write(const T& v) noexcept
{
write(reinterpret_cast<const uint8_t*>(&v), sizeof(T));
}
template<typename T, typename = std::enable_if_t<std::has_unique_object_representations_v<T>>>
constexpr void write(const T* data, size_t count) noexcept
{
write(reinterpret_cast<const uint8_t*>(data), sizeof(T) * count);
}
constexpr void write(const uint8_t* data, size_t count) noexcept
{
for (size_t i = 0; i < count; ++i)
{
_hash ^= static_cast<size_t>(data[i]);
_hash *= FNV_prime;
}
}
constexpr size_t finalize() const noexcept
{
return _hash;
}
private:
#if defined(_WIN64)
static constexpr size_t FNV_offset_basis = 14695981039346656037ULL;
static constexpr size_t FNV_prime = 1099511628211ULL;
#else
static constexpr size_t FNV_offset_basis = 2166136261U;
static constexpr size_t FNV_prime = 16777619U;
#endif
size_t _hash = FNV_offset_basis;
};
namespace details
{
template<typename T, bool enable>
struct conditionally_enabled_hash
{
constexpr void operator()(hasher& h, const T& v) const noexcept
{
h.write(reinterpret_cast<const uint8_t*>(&v), sizeof(T));
}
};
template<typename T>
struct conditionally_enabled_hash<T, false>
{
conditionally_enabled_hash() = delete;
conditionally_enabled_hash(const conditionally_enabled_hash&) = delete;
conditionally_enabled_hash(conditionally_enabled_hash&&) = delete;
conditionally_enabled_hash& operator=(const conditionally_enabled_hash&) = delete;
conditionally_enabled_hash& operator=(conditionally_enabled_hash&&) = delete;
};
}
template<typename T>
struct hash : details::conditionally_enabled_hash<T, std::has_unique_object_representations_v<T>>
{
};
template<>
struct hash<float>
{
constexpr void operator()(hasher& h, float v) const noexcept
{
v = v == 0.0f ? 0.0f : v; // map -0 to 0
h.write(reinterpret_cast<const uint8_t*>(&v), sizeof(v));
}
};
template<>
struct hash<double>
{
constexpr void operator()(hasher& h, double v) const noexcept
{
v = v == 0.0 ? 0.0 : v; // map -0 to 0
h.write(reinterpret_cast<const uint8_t*>(&v), sizeof(v));
}
};
template <typename T, typename CharTraits, typename Allocator>
struct hash<std::basic_string<T, CharTraits, Allocator>> {
constexpr void operator()(const std::basic_string<T, CharTraits, Allocator>& v) const noexcept {
h.write(reinterpret_cast<const uint8_t*>(v.data()), sizeof(T) * v.size());
}
};
template <typename T, typename CharTraits>
struct hash<std::basic_string_view<T, CharTraits>> {
constexpr void operator()(const std::basic_string_view<T, CharTraits>& v) const noexcept {
h.write(reinterpret_cast<const uint8_t*>(v.data()), sizeof(T) * v.size());
}
};
}