Compare commits

...

1 Commits

Author SHA1 Message Date
Leonard Hecker a7ed60efc2 wip 2021-11-26 21:52:30 +01:00
5 changed files with 329 additions and 145 deletions

View File

@ -61,27 +61,6 @@ 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;
@ -185,9 +164,18 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_ColorScheme = _ColorScheme;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Commandline(), StartingDirectory(), TabTitle(), TabColor(), ProfileIndex(), Profile(), SuppressApplicationTitle(), ColorScheme());
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();
}
};
@ -241,9 +229,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_CopyFormatting = _CopyFormatting;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SingleLine(), CopyFormatting());
til::hasher h{ hasherState };
til::hash<decltype(SingleLine())>{}(h, SingleLine());
til::hash<decltype(CopyFormatting())>{}(h, CopyFormatting());
return h.finalize();
}
};
@ -288,9 +279,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TerminalArgs = _TerminalArgs.Copy();
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TerminalArgs());
til::hasher h{ hasherState };
til::hash<decltype(TerminalArgs())>{}(h, TerminalArgs());
return h.finalize();
}
};
@ -339,9 +332,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TabIndex = _TabIndex;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TabIndex());
til::hasher h{ hasherState };
til::hash<decltype(TabIndex())>{}(h, TabIndex());
return h.finalize();
}
};
@ -390,9 +385,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TabIndex = _TabIndex;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TabIndex());
til::hasher h{ hasherState };
til::hash<decltype(TabIndex())>{}(h, TabIndex());
return h.finalize();
}
};
@ -446,9 +443,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_ResizeDirection = _ResizeDirection;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(ResizeDirection());
til::hasher h{ hasherState };
til::hash<decltype(ResizeDirection())>{}(h, ResizeDirection());
return h.finalize();
}
};
@ -505,9 +504,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_FocusDirection = _FocusDirection;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(FocusDirection());
til::hasher h{ hasherState };
til::hash<decltype(FocusDirection())>{}(h, FocusDirection());
return h.finalize();
}
};
@ -564,9 +565,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Direction = _Direction;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Direction());
til::hasher h{ hasherState };
til::hash<decltype(Direction())>{}(h, Direction());
return h.finalize();
}
};
@ -613,9 +616,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Delta = _Delta;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Delta());
til::hasher h{ hasherState };
til::hash<decltype(Delta())>{}(h, Delta());
return h.finalize();
}
};
@ -665,9 +670,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Input = _Input;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Input());
til::hasher h{ hasherState };
til::hash<decltype(Input())>{}(h, Input());
return h.finalize();
}
};
@ -749,9 +756,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_SplitSize = _SplitSize;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SplitDirection(), TerminalArgs(), SplitMode(), SplitSize());
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();
}
};
@ -800,9 +812,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Target = _Target;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Target());
til::hasher h{ hasherState };
til::hash<decltype(Target())>{}(h, Target());
return h.finalize();
}
};
@ -855,9 +869,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_SchemeName = _SchemeName;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SchemeName());
til::hasher h{ hasherState };
til::hash<decltype(SchemeName())>{}(h, SchemeName());
return h.finalize();
}
};
@ -906,9 +922,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TabColor = _TabColor;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TabColor());
til::hasher h{ hasherState };
til::hash<decltype(TabColor())>{}(h, TabColor());
return h.finalize();
}
};
@ -955,9 +973,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Title = _Title;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Title());
til::hasher h{ hasherState };
til::hash<decltype(Title())>{}(h, Title());
return h.finalize();
}
};
@ -1010,9 +1030,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Commandline = _Commandline;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Commandline());
til::hasher h{ hasherState };
til::hash<decltype(Commandline())>{}(h, Commandline());
return h.finalize();
}
};
@ -1061,9 +1083,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Index = _Index;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Index());
til::hasher h{ hasherState };
til::hash<decltype(Index())>{}(h, Index());
return h.finalize();
}
};
@ -1112,9 +1136,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Index = _Index;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Index());
til::hasher h{ hasherState };
til::hash<decltype(Index())>{}(h, Index());
return h.finalize();
}
};
@ -1163,9 +1189,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Index = _Index;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Index());
til::hasher h{ hasherState };
til::hash<decltype(Index())>{}(h, Index());
return h.finalize();
}
};
@ -1221,9 +1249,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Direction = _Direction;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Direction());
til::hasher h{ hasherState };
til::hash<decltype(Direction())>{}(h, Direction());
return h.finalize();
}
};
@ -1270,9 +1300,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_RowsToScroll = _RowsToScroll;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(RowsToScroll());
til::hasher h{ hasherState };
til::hash<decltype(RowsToScroll())>{}(h, RowsToScroll());
return h.finalize();
}
};
@ -1319,9 +1351,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_RowsToScroll = _RowsToScroll;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(RowsToScroll());
til::hasher h{ hasherState };
til::hash<decltype(RowsToScroll())>{}(h, RowsToScroll());
return h.finalize();
}
};
@ -1370,9 +1404,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_LaunchMode = _LaunchMode;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(LaunchMode());
til::hasher h{ hasherState };
til::hash<decltype(LaunchMode())>{}(h, LaunchMode());
return h.finalize();
}
};
@ -1428,9 +1464,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Direction = _Direction;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Direction());
til::hasher h{ hasherState };
til::hash<decltype(Direction())>{}(h, Direction());
return h.finalize();
}
};
@ -1475,9 +1513,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_TerminalArgs = _TerminalArgs.Copy();
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TerminalArgs());
til::hasher h{ hasherState };
til::hash<decltype(TerminalArgs())>{}(h, TerminalArgs());
return h.finalize();
}
};
@ -1525,9 +1565,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_SwitcherMode = _SwitcherMode;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SwitcherMode());
til::hasher h{ hasherState };
til::hash<decltype(SwitcherMode())>{}(h, SwitcherMode());
return h.finalize();
}
};
@ -1575,9 +1617,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_SwitcherMode = _SwitcherMode;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SwitcherMode());
til::hasher h{ hasherState };
til::hash<decltype(SwitcherMode())>{}(h, SwitcherMode());
return h.finalize();
}
};
@ -1625,9 +1669,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Name = _Name;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Name());
til::hasher h{ hasherState };
til::hash<decltype(Name())>{}(h, Name());
return h.finalize();
}
};
@ -1709,9 +1755,15 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
args->_DropdownDuration = 200;
return { *args, {} };
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Name(), Desktop(), Monitor(), DropdownDuration(), ToggleVisibility());
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();
}
};
@ -1759,9 +1811,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Id = _Id;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Id);
til::hasher h{ hasherState };
til::hash<decltype(Id())>{}(h, Id());
return h.finalize();
}
};
@ -1809,9 +1863,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Clear = _Clear;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Clear);
til::hasher h{ hasherState };
til::hash<decltype(Clear())>{}(h, Clear());
return h.finalize();
}
};
@ -1858,9 +1914,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
copy->_Actions = _Actions;
return *copy;
}
size_t Hash() const
size_t Hash(size_t hasherState) const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Actions);
til::hasher h{ hasherState };
til::hash<void*>{}(h, winrt::get_abi(_Actions));
return h.finalize();
}
};
}

View File

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

View File

@ -15,13 +15,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
static InternalActionID Hash(const Model::ActionAndArgs& actionAndArgs)
{
size_t hashedAction{ HashUtils::HashProperty(actionAndArgs.Action()) };
const auto action = actionAndArgs.Action();
til::hasher hasher;
size_t hashedArgs{};
if (const auto& args{ actionAndArgs.Args() })
if (const auto args = actionAndArgs.Args())
{
// Args are defined, so hash them
hashedArgs = gsl::narrow_cast<size_t>(args.Hash());
hasher = gsl::narrow_cast<size_t>(args.Hash(hasher.finalize()));
}
else
{
@ -29,22 +28,24 @@ 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.*/ \
hashedArgs = EmptyHash<implementation::action##Args>(); \
break;
#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; \
}
ALL_SHORTCUT_ACTIONS_WITH_ARGS
#undef ON_ALL_ACTIONS_WITH_ARGS
default:
{
// Otherwise, hash nullptr.
std::hash<IActionArgs> argsHash;
hashedArgs = argsHash(nullptr);
}
break;
}
}
return hashedAction ^ hashedArgs;
hasher.write(action);
return hasher.finalize();
}
// Method Description:

View File

@ -17,54 +17,37 @@ Revision History:
#pragma once
namespace Microsoft::Terminal::Settings::Model::HashUtils
#include <til/hash.h>
namespace til
{
// This is a helper template function for hashing multiple variables in conjunction to each other.
template<typename T>
constexpr size_t HashProperty(const T& val)
struct hash<winrt::Windows::Foundation::IReference<T>>
{
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)...));
}
constexpr void operator()(hasher& h, const winrt::Windows::Foundation::IReference<T>& v) const noexcept
{
if (v)
{
til::hash<decltype(v.Value())>{}(h, v.Value());
}
}
};
template<>
constexpr size_t HashProperty(const til::color& val)
struct hash<winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs>
{
return HashProperty(val.a, val.r, val.g, val.b);
}
void operator()(hasher& h, const winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs& value) const noexcept
{
til::hash<void*>{}(h, winrt::get_abi(value));
}
};
#ifdef WINRT_Windows_Foundation_H
template<typename T>
constexpr size_t HashProperty(const winrt::Windows::Foundation::IReference<T>& val)
{
return val ? HashProperty(val.Value()) : 0;
}
#endif
#ifdef WINRT_Windows_UI_H
template<>
constexpr size_t HashProperty(const winrt::Windows::UI::Color& val)
struct hash<winrt::hstring>
{
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
};
void operator()(hasher& h, const winrt::hstring& value) const noexcept
{
h.write(reinterpret_cast<const uint8_t*>(value.data()), value.size() * sizeof(wchar_t));
}
};
}

142
src/inc/til/hash.h Normal file
View File

@ -0,0 +1,142 @@
// 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());
}
};
}