This commit is contained in:
Leonard Hecker 2021-07-17 20:35:47 +02:00
parent 8947909121
commit 574fc06d43
34 changed files with 2833 additions and 117 deletions

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018-2021 Martin Ankerl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,9 @@
### Notes for Future Maintainers
The provenance information (where it came from and which commit) is stored in the file `cgmanifest.json` in the same directory as this readme.
Please update the provenance information in that file when ingesting an updated version of the dependent library.
That provenance file is automatically read and inventoried by Microsoft systems to ensure compliance with appropiate governance standards.
## Updates
Get updates from here: https://github.com/martinus/robin-hood-hashing

View file

@ -0,0 +1,14 @@
{
"Registrations": [
{
"component": {
"type": "git",
"git": {
"repositoryUrl": "https://github.com/martinus/robin-hood-hashing",
"commitHash": "24b3f50f9532153edc23b29ae277dcccfd75a462"
}
}
}
],
"Version": 1
}

File diff suppressed because it is too large Load diff

View file

@ -47,10 +47,10 @@ void UnicodeStorage::Erase(const key_type key) noexcept
// - rowMap - A map of the old row IDs to the new row IDs.
// - width - The width of the new row. Remove any items that are beyond the row width.
// - Use nullopt if we're not resizing the width of the row, just renumbering the rows.
void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width)
void UnicodeStorage::Remap(const robin_hood::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width)
{
// Make a temporary map to hold all the new row positioning
std::unordered_map<key_type, mapped_type> newMap;
robin_hood::unordered_map<key_type, mapped_type> newMap;
// Walk through every stored item.
for (const auto& pair : _map)

View file

@ -18,7 +18,7 @@ Author(s):
#include <unordered_map>
#include <climits>
// std::unordered_map needs help to know how to hash a COORD
// robin_hood::unordered_map needs help to know how to hash a COORD
namespace std
{
template<>
@ -55,10 +55,10 @@ public:
void Erase(const key_type key) noexcept;
void Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width);
void Remap(const robin_hood::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width);
private:
std::unordered_map<key_type, mapped_type> _map;
robin_hood::unordered_map<key_type, mapped_type> _map;
#ifdef UNIT_TESTING
friend class UnicodeStorageTests;

View file

@ -964,7 +964,7 @@ UnicodeStorage& TextBuffer::GetUnicodeStorage() noexcept
// - newRowWidth - Optional new value for the row width.
void TextBuffer::_RefreshRowIDs(std::optional<SHORT> newRowWidth)
{
std::unordered_map<SHORT, SHORT> rowMap;
robin_hood::unordered_map<SHORT, SHORT> rowMap;
SHORT i = 0;
for (auto& it : _storage)
{
@ -1309,7 +1309,7 @@ void TextBuffer::_PruneHyperlinks()
// Move to unordered set so we can use hashed lookup of IDs instead of linear search.
// Only make it an unordered set now because set always heap allocates but vector
// doesn't when the set is empty (saving an allocation in the common case of no links.)
std::unordered_set<uint16_t> firstRowRefs{ hyperlinks.cbegin(), hyperlinks.cend() };
robin_hood::unordered_set<uint16_t> firstRowRefs{ hyperlinks.cbegin(), hyperlinks.cend() };
const auto total = TotalRowCount();
// Loop through all the rows in the buffer except the first row -
@ -1944,7 +1944,7 @@ std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoi
// map to keep track of colors:
// keys are colors represented by COLORREF
// values are indices of the corresponding colors in the color table
std::unordered_map<COLORREF, int> colorMap;
robin_hood::unordered_map<COLORREF, int> colorMap;
int nextColorIndex = 1; // leave 0 for the default color and start from 1.
// RTF color table
@ -2473,7 +2473,7 @@ void TextBuffer::CopyHyperlinkMaps(const TextBuffer& other)
const size_t TextBuffer::AddPatternRecognizer(const std::wstring_view regexString)
{
++_currentPatternId;
_idsAndPatterns.emplace(std::make_pair(_currentPatternId, regexString));
_idsAndPatterns.emplace(_currentPatternId, regexString);
return _currentPatternId;
}

View file

@ -213,8 +213,8 @@ private:
// storage location for glyphs that can't fit into the buffer normally
UnicodeStorage _unicodeStorage;
std::unordered_map<uint16_t, std::wstring> _hyperlinkMap;
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
robin_hood::unordered_map<uint16_t, std::wstring> _hyperlinkMap;
robin_hood::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
uint16_t _currentHyperlinkId;
void _RefreshRowIDs(std::optional<SHORT> newRowWidth);
@ -247,7 +247,7 @@ private:
void _PruneHyperlinks();
std::unordered_map<size_t, std::wstring> _idsAndPatterns;
robin_hood::unordered_map<size_t, std::wstring> _idsAndPatterns;
size_t _currentPatternId;
#ifdef UNIT_TESTING

View file

@ -62,7 +62,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::com_ptr<IVirtualDesktopManager> _desktopManager{ nullptr };
std::unordered_map<uint64_t, winrt::Microsoft::Terminal::Remoting::IPeasant> _peasants;
robin_hood::unordered_map<uint64_t, winrt::Microsoft::Terminal::Remoting::IPeasant> _peasants;
std::vector<Remoting::WindowActivatedArgs> _mruPeasants;

View file

@ -137,7 +137,7 @@ namespace winrt::TerminalApp::implementation
void _choosingItemContainer(Windows::UI::Xaml::Controls::ListViewBase const& sender, Windows::UI::Xaml::Controls::ChoosingItemContainerEventArgs const& args);
void _containerContentChanging(Windows::UI::Xaml::Controls::ListViewBase const& sender, Windows::UI::Xaml::Controls::ContainerContentChangingEventArgs const& args);
winrt::TerminalApp::PaletteItemTemplateSelector _itemTemplateSelector{ nullptr };
std::unordered_map<Windows::UI::Xaml::DataTemplate, std::unordered_set<Windows::UI::Xaml::Controls::Primitives::SelectorItem>> _listViewItemsCache;
robin_hood::unordered_map<Windows::UI::Xaml::DataTemplate, robin_hood::unordered_set<Windows::UI::Xaml::Controls::Primitives::SelectorItem>> _listViewItemsCache;
Windows::UI::Xaml::DataTemplate _listItemTemplate;
friend class TerminalAppLocalTests::TabTests;

View file

@ -40,7 +40,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TYPED_EVENT(Closed, Control::SearchBoxControl, Windows::UI::Xaml::RoutedEventArgs);
private:
std::unordered_set<winrt::Windows::Foundation::IInspectable> _focusableElements;
robin_hood::unordered_set<winrt::Windows::Foundation::IInspectable> _focusableElements;
bool _GoForward();
bool _CaseSensitive();

View file

@ -105,7 +105,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// from json. Each type of IActionArgs that can accept arbitrary args should be
// placed into this map, with the corresponding deserializer function as the
// value.
static const std::unordered_map<ShortcutAction, std::pair<ParseActionFunction, SerializeActionFunction>> argSerializerMap{
static const robin_hood::unordered_map<ShortcutAction, std::pair<ParseActionFunction, SerializeActionFunction>> argSerializerMap{
// These are special cases.
// - QuakeMode: deserializes into a GlobalSummon, so we don't need a serializer
@ -306,7 +306,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// Use a magic static to initialize this map, because we won't be able
// to load the resources at _init_, only at runtime.
static const auto GeneratedActionNames = []() {
return std::unordered_map<ShortcutAction, winrt::hstring>{
return robin_hood::unordered_map<ShortcutAction, winrt::hstring>{
{ ShortcutAction::AdjustFontSize, RS_(L"AdjustFontSizeCommandKey") },
{ ShortcutAction::CloseOtherTabs, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::ClosePane, RS_(L"ClosePaneCommandKey") },

View file

@ -8,6 +8,145 @@
#include "ActionMap.g.cpp"
namespace til
{
template<typename D, typename T, typename Iterator>
struct iterator : winrt::implements<iterator<D, T, Iterator>, winrt::Windows::Foundation::Collections::IIterator<T>>
{
iterator(D* owner, Iterator&& current, Iterator&& end) noexcept :
m_current{ std::move(current) },
m_end{ std::move(end) }
{
m_owner.copy_from(owner);
}
T Current() const
{
if (m_current == m_end)
{
throw winrt::hresult_out_of_bounds();
}
return winrt::make<winrt::impl::key_value_pair<T>>(m_current->first, m_current->second);
}
bool HasCurrent() const
{
return m_current != m_end;
}
bool MoveNext()
{
if (m_current != m_end)
{
++m_current;
}
return m_current != m_end;
}
uint32_t GetMany(winrt::array_view<T> values)
{
auto output = values.begin();
const auto end = values.end();
while (output != end && m_current != m_end)
{
*output = winrt::make<winrt::impl::key_value_pair<T>>(m_current->first, m_current->second);
++output;
++m_current;
}
return static_cast<uint32_t>(output - values.begin());
}
private:
winrt::com_ptr<D> m_owner;
Iterator m_current;
const Iterator m_end;
};
template<typename K, typename V, typename Container>
struct map_impl : winrt::implements<map_impl<K, V, Container>, winrt::Windows::Foundation::Collections::IMap<K, V>, winrt::Windows::Foundation::Collections::IMapView<K, V>, winrt::Windows::Foundation::Collections::IIterable<winrt::Windows::Foundation::Collections::IKeyValuePair<K, V>>>
{
explicit map_impl(Container&& values) :
m_values(std::forward<Container>(values))
{
}
// IIterable
winrt::Windows::Foundation::Collections::IIterator<winrt::Windows::Foundation::Collections::IKeyValuePair<K, V>> First()
{
using D = typename map_impl<K, V, Container>;
using T = winrt::Windows::Foundation::Collections::IKeyValuePair<K, V>;
using Iterator = decltype(m_values.begin());
return winrt::make<til::iterator<D, T, Iterator>>(this, m_values.begin(), m_values.end());
}
// IMapView
V Lookup(const K& key) const
{
const auto pair = m_values.find(key);
if (pair == m_values.end())
{
throw winrt::hresult_out_of_bounds();
}
return pair->second;
}
uint32_t Size() const noexcept
{
return static_cast<uint32_t>(m_values.size());
}
bool HasKey(const K& key) const noexcept
{
return m_values.contains(key);
}
void Split(winrt::Windows::Foundation::Collections::IMapView<K, V>& first, winrt::Windows::Foundation::Collections::IMapView<K, V>& second) const noexcept
{
first = nullptr;
second = nullptr;
}
// IMap
winrt::Windows::Foundation::Collections::IMapView<K, V> GetView() const
{
return *this;
}
bool Insert(const K& key, const V& value)
{
return !m_values.insert_or_assign(key, value).second;
}
void Remove(const K& key)
{
m_values.erase(key);
}
void Clear() noexcept
{
m_values.clear();
}
private:
Container m_values;
//robin_hood::unordered_map<int, int> m_values;
};
template<typename K, typename V, typename Container>
auto single_threaded_map(Container&& values)
{
return winrt::make<map_impl<K, V, Container>>(std::forward<Container>(values));
}
}
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Control;
@ -48,7 +187,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
ActionMap::ActionMap() :
_NestedCommands{ single_threaded_map<hstring, Model::Command>() },
_NestedCommands{ til::single_threaded_map<hstring, Model::Command>(robin_hood::unordered_map<hstring, Model::Command>{}) },
_IterableCommands{ single_threaded_vector<Model::Command>() }
{
}
@ -97,7 +236,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return std::nullopt;
}
static void RegisterShortcutAction(ShortcutAction shortcutAction, std::unordered_map<hstring, Model::ActionAndArgs>& list, std::unordered_set<InternalActionID>& visited)
static void RegisterShortcutAction(ShortcutAction shortcutAction, robin_hood::unordered_map<hstring, Model::ActionAndArgs>& list, std::unordered_set<InternalActionID>& visited)
{
const auto actionAndArgs{ make_self<ActionAndArgs>(shortcutAction) };
if (actionAndArgs->Action() != ShortcutAction::Invalid)
@ -121,7 +260,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
if (!_AvailableActionsCache)
{
// populate _AvailableActionsCache
std::unordered_map<hstring, Model::ActionAndArgs> availableActions;
robin_hood::unordered_map<hstring, Model::ActionAndArgs> availableActions;
std::unordered_set<InternalActionID> visitedActionIDs;
_PopulateAvailableActionsWithStandardCommands(availableActions, visitedActionIDs);
@ -130,12 +269,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
ALL_SHORTCUT_ACTIONS
#undef ON_ALL_ACTIONS
_AvailableActionsCache = single_threaded_map<hstring, Model::ActionAndArgs>(std::move(availableActions));
_AvailableActionsCache = til::single_threaded_map<hstring, Model::ActionAndArgs>(std::move(availableActions));
}
return _AvailableActionsCache.GetView();
}
void ActionMap::_PopulateAvailableActionsWithStandardCommands(std::unordered_map<hstring, Model::ActionAndArgs>& availableActions, std::unordered_set<InternalActionID>& visitedActionIDs) const
void ActionMap::_PopulateAvailableActionsWithStandardCommands(robin_hood::unordered_map<hstring, Model::ActionAndArgs>& availableActions, std::unordered_set<InternalActionID>& visitedActionIDs) const
{
// Update AvailableActions and visitedActionIDs with our current layer
for (const auto& [actionID, cmd] : _ActionMap)
@ -175,11 +314,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
if (!_NameMapCache)
{
// populate _NameMapCache
std::unordered_map<hstring, Model::Command> nameMap{};
robin_hood::unordered_map<hstring, Model::Command> nameMap{};
_PopulateNameMapWithSpecialCommands(nameMap);
_PopulateNameMapWithStandardCommands(nameMap);
_NameMapCache = single_threaded_map<hstring, Model::Command>(std::move(nameMap));
_NameMapCache = til::single_threaded_map<hstring, Model::Command>(std::move(nameMap));
}
return _NameMapCache.GetView();
}
@ -190,7 +329,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// - Performs a top-down approach by going to the root first, then recursively adding the nested commands layer-by-layer.
// Arguments:
// - nameMap: the nameMap we're populating. This maps the name (hstring) of a command to the command itself.
void ActionMap::_PopulateNameMapWithSpecialCommands(std::unordered_map<hstring, Model::Command>& nameMap) const
void ActionMap::_PopulateNameMapWithSpecialCommands(robin_hood::unordered_map<hstring, Model::Command>& nameMap) const
{
// Update NameMap with our parents.
// Starting with this means we're doing a top-down approach.
@ -229,7 +368,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// Arguments:
// - nameMap: the nameMap we're populating. This maps the name (hstring) of a command to the command itself.
// There should only ever by one of each command (identified by the actionID) in the nameMap.
void ActionMap::_PopulateNameMapWithStandardCommands(std::unordered_map<hstring, Model::Command>& nameMap) const
void ActionMap::_PopulateNameMapWithStandardCommands(robin_hood::unordered_map<hstring, Model::Command>& nameMap) const
{
std::unordered_set<InternalActionID> visitedActionIDs;
for (const auto& cmd : _GetCumulativeActions())
@ -264,10 +403,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
cumulativeActions.reserve(_MaskingActions.size() + _ActionMap.size());
// masking actions have priority. Actions here are constructed from consolidating an inherited action with changes we've found when populating this layer.
std::transform(_MaskingActions.begin(), _MaskingActions.end(), std::back_inserter(cumulativeActions), [](std::pair<InternalActionID, Model::Command> actionPair) {
std::transform(_MaskingActions.begin(), _MaskingActions.end(), std::back_inserter(cumulativeActions), [](const auto& actionPair) {
return actionPair.second;
});
std::transform(_ActionMap.begin(), _ActionMap.end(), std::back_inserter(cumulativeActions), [](std::pair<InternalActionID, Model::Command> actionPair) {
std::transform(_ActionMap.begin(), _ActionMap.end(), std::back_inserter(cumulativeActions), [](const auto& actionPair) {
return actionPair.second;
});
@ -287,7 +426,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
if (!_GlobalHotkeysCache)
{
std::unordered_map<Control::KeyChord, Model::Command, KeyChordHash, KeyChordEquality> globalHotkeys;
robin_hood::unordered_map<Control::KeyChord, Model::Command, KeyChordHash, KeyChordEquality> globalHotkeys;
for (const auto& [keys, cmd] : KeyBindings())
{
// Only populate GlobalHotkeys with actions whose
@ -297,7 +436,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
globalHotkeys.emplace(keys, cmd);
}
}
_GlobalHotkeysCache = single_threaded_map<Control::KeyChord, Model::Command>(std::move(globalHotkeys));
_GlobalHotkeysCache = til::single_threaded_map<Control::KeyChord, Model::Command>(std::move(globalHotkeys));
}
return _GlobalHotkeysCache.GetView();
}
@ -307,11 +446,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
if (!_KeyBindingMapCache)
{
// populate _KeyBindingMapCache
std::unordered_map<KeyChord, Model::Command, KeyChordHash, KeyChordEquality> keyBindingsMap;
robin_hood::unordered_map<KeyChord, Model::Command, KeyChordHash, KeyChordEquality> keyBindingsMap;
std::unordered_set<KeyChord, KeyChordHash, KeyChordEquality> unboundKeys;
_PopulateKeyBindingMapWithStandardCommands(keyBindingsMap, unboundKeys);
_KeyBindingMapCache = single_threaded_map<KeyChord, Model::Command>(std::move(keyBindingsMap));
_KeyBindingMapCache = til::single_threaded_map<KeyChord, Model::Command>(std::move(keyBindingsMap));
}
return _KeyBindingMapCache.GetView();
}
@ -323,7 +462,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// Arguments:
// - keyBindingsMap: the keyBindingsMap we're populating. This maps the key chord of a command to the command itself.
// - unboundKeys: a set of keys that are explicitly unbound
void ActionMap::_PopulateKeyBindingMapWithStandardCommands(std::unordered_map<KeyChord, Model::Command, KeyChordHash, KeyChordEquality>& keyBindingsMap, std::unordered_set<Control::KeyChord, KeyChordHash, KeyChordEquality>& unboundKeys) const
void ActionMap::_PopulateKeyBindingMapWithStandardCommands(robin_hood::unordered_map<KeyChord, Model::Command, KeyChordHash, KeyChordEquality>& keyBindingsMap, std::unordered_set<Control::KeyChord, KeyChordHash, KeyChordEquality>& unboundKeys) const
{
// Update KeyBindingsMap with our current layer
for (const auto& [keys, actionID] : _KeyMap)

View file

@ -81,10 +81,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
std::optional<Model::Command> _GetActionByID(const InternalActionID actionID) const;
std::optional<Model::Command> _GetActionByKeyChordInternal(Control::KeyChord const& keys) const;
void _PopulateAvailableActionsWithStandardCommands(std::unordered_map<hstring, Model::ActionAndArgs>& availableActions, std::unordered_set<InternalActionID>& visitedActionIDs) const;
void _PopulateNameMapWithSpecialCommands(std::unordered_map<hstring, Model::Command>& nameMap) const;
void _PopulateNameMapWithStandardCommands(std::unordered_map<hstring, Model::Command>& nameMap) const;
void _PopulateKeyBindingMapWithStandardCommands(std::unordered_map<Control::KeyChord, Model::Command, KeyChordHash, KeyChordEquality>& keyBindingsMap, std::unordered_set<Control::KeyChord, KeyChordHash, KeyChordEquality>& unboundKeys) const;
void _PopulateAvailableActionsWithStandardCommands(robin_hood::unordered_map<hstring, Model::ActionAndArgs>& availableActions, std::unordered_set<InternalActionID>& visitedActionIDs) const;
void _PopulateNameMapWithSpecialCommands(robin_hood::unordered_map<hstring, Model::Command>& nameMap) const;
void _PopulateNameMapWithStandardCommands(robin_hood::unordered_map<hstring, Model::Command>& nameMap) const;
void _PopulateKeyBindingMapWithStandardCommands(robin_hood::unordered_map<Control::KeyChord, Model::Command, KeyChordHash, KeyChordEquality>& keyBindingsMap, std::unordered_set<Control::KeyChord, KeyChordHash, KeyChordEquality>& unboundKeys) const;
std::vector<Model::Command> _GetCumulativeActions() const noexcept;
void _TryUpdateActionMap(const Model::Command& cmd, Model::Command& oldCmd, Model::Command& consolidatedCmd);
@ -97,8 +97,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
Windows::Foundation::Collections::IMap<Control::KeyChord, Model::Command> _KeyBindingMapCache{ nullptr };
Windows::Foundation::Collections::IMap<hstring, Model::Command> _NestedCommands{ nullptr };
Windows::Foundation::Collections::IVector<Model::Command> _IterableCommands{ nullptr };
std::unordered_map<Control::KeyChord, InternalActionID, KeyChordHash, KeyChordEquality> _KeyMap;
std::unordered_map<InternalActionID, Model::Command> _ActionMap;
robin_hood::unordered_map<Control::KeyChord, InternalActionID, KeyChordHash, KeyChordEquality> _KeyMap;
robin_hood::unordered_map<InternalActionID, Model::Command> _ActionMap;
// Masking Actions:
// These are actions that were introduced in an ancestor,
@ -111,7 +111,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// Additionally, these commands to not need to be serialized,
// whereas those in _ActionMap do. These actions provide more data
// than is necessary to be serialized.
std::unordered_map<InternalActionID, Model::Command> _MaskingActions;
robin_hood::unordered_map<InternalActionID, Model::Command> _MaskingActions;
friend class SettingsModelLocalTests::KeyBindingsTests;
friend class SettingsModelLocalTests::DeserializationTests;

View file

@ -11,52 +11,6 @@
constexpr std::wstring_view stateFileName{ L"state.json" };
namespace Microsoft::Terminal::Settings::Model::JsonUtils
{
// This trait exists in order to serialize the std::unordered_set for GeneratedProfiles.
template<typename T>
struct ConversionTrait<std::unordered_set<T>>
{
std::unordered_set<T> FromJson(const Json::Value& json) const
{
ConversionTrait<T> trait;
std::unordered_set<T> val;
val.reserve(json.size());
for (const auto& element : json)
{
val.emplace(trait.FromJson(element));
}
return val;
}
bool CanConvert(const Json::Value& json) const
{
ConversionTrait<T> trait;
return json.isArray() && std::all_of(json.begin(), json.end(), [trait](const auto& json) -> bool { return trait.CanConvert(json); });
}
Json::Value ToJson(const std::unordered_set<T>& val)
{
ConversionTrait<T> trait;
Json::Value json{ Json::arrayValue };
for (const auto& key : val)
{
json.append(trait.ToJson(key));
}
return json;
}
std::string TypeDescription() const
{
return fmt::format("{}[]", ConversionTrait<GUID>{}.TypeDescription());
}
};
}
using namespace ::Microsoft::Terminal::Settings::Model;
namespace winrt::Microsoft::Terminal::Settings::Model::implementation

View file

@ -22,7 +22,7 @@ Abstract:
// It provides X with the following arguments:
// (type, function name, JSON key, ...variadic construction arguments)
#define MTSM_APPLICATION_STATE_FIELDS(X) \
X(std::unordered_set<winrt::guid>, GeneratedProfiles, "generatedProfiles")
X(robin_hood::unordered_set<winrt::guid>, GeneratedProfiles, "generatedProfiles")
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{

View file

@ -107,7 +107,7 @@ void CascadiaSettings::_CopyProfileInheritanceTree(winrt::com_ptr<CascadiaSettin
}
auto dummyRootClone{ winrt::make_self<Profile>() };
std::unordered_map<void*, winrt::com_ptr<Profile>> visited{};
robin_hood::unordered_map<void*, winrt::com_ptr<Profile>> visited{};
if (_userDefaultProfileSettings)
{

View file

@ -143,9 +143,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
void _LoadDynamicProfiles();
void _LoadFragmentExtensions();
void _ApplyJsonStubsHelper(const std::wstring_view directory, const std::unordered_set<std::wstring>& ignoredNamespaces);
std::unordered_set<std::string> _AccumulateJsonFilesInDirectory(const std::wstring_view directory);
void _ParseAndLayerFragmentFiles(const std::unordered_set<std::string> files, const winrt::hstring source);
void _ApplyJsonStubsHelper(const std::wstring_view directory, const robin_hood::unordered_set<std::wstring>& ignoredNamespaces);
robin_hood::unordered_set<std::string> _AccumulateJsonFilesInDirectory(const std::wstring_view directory);
void _ParseAndLayerFragmentFiles(const robin_hood::unordered_set<std::string> files, const winrt::hstring source);
static const std::filesystem::path& _SettingsPath();
static std::optional<std::string> _ReadUserSettings();

View file

@ -342,7 +342,7 @@ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings CascadiaSettings::
// - <none>
void CascadiaSettings::_LoadDynamicProfiles()
{
std::unordered_set<std::wstring> ignoredNamespaces;
robin_hood::unordered_set<std::wstring> ignoredNamespaces;
const auto disabledProfileSources = CascadiaSettings::_GetDisabledProfileSourcesJsonObject(_userSettings);
if (disabledProfileSources.isArray())
{
@ -387,7 +387,7 @@ void CascadiaSettings::_LoadDynamicProfiles()
void CascadiaSettings::_LoadFragmentExtensions()
{
// First, accumulate the namespaces the user wants to ignore
std::unordered_set<std::wstring> ignoredNamespaces;
robin_hood::unordered_set<std::wstring> ignoredNamespaces;
const auto disabledProfileSources = CascadiaSettings::_GetDisabledProfileSourcesJsonObject(_userSettings);
if (disabledProfileSources.isArray())
{
@ -459,7 +459,7 @@ void CascadiaSettings::_LoadFragmentExtensions()
// Arguments:
// - The directory to find json files in
// - The set of ignored namespaces
void CascadiaSettings::_ApplyJsonStubsHelper(const std::wstring_view directory, const std::unordered_set<std::wstring>& ignoredNamespaces)
void CascadiaSettings::_ApplyJsonStubsHelper(const std::wstring_view directory, const robin_hood::unordered_set<std::wstring>& ignoredNamespaces)
{
// The json files should be within subdirectories where the subdirectory name is the app name
for (const auto& fragmentExtFolder : std::filesystem::directory_iterator(directory))
@ -483,9 +483,9 @@ void CascadiaSettings::_ApplyJsonStubsHelper(const std::wstring_view directory,
// - directory: the directory to search
// Return Value:
// - A set containing all the found file data
std::unordered_set<std::string> CascadiaSettings::_AccumulateJsonFilesInDirectory(const std::wstring_view directory)
robin_hood::unordered_set<std::string> CascadiaSettings::_AccumulateJsonFilesInDirectory(const std::wstring_view directory)
{
std::unordered_set<std::string> jsonFiles;
robin_hood::unordered_set<std::string> jsonFiles;
for (const auto& fragmentExt : std::filesystem::directory_iterator(directory))
{
@ -507,7 +507,7 @@ std::unordered_set<std::string> CascadiaSettings::_AccumulateJsonFilesInDirector
// Arguments:
// - files: the set of json files (each item in the set is the file data)
// - source: the location the files came from
void CascadiaSettings::_ParseAndLayerFragmentFiles(const std::unordered_set<std::string> files, const winrt::hstring source)
void CascadiaSettings::_ParseAndLayerFragmentFiles(const robin_hood::unordered_set<std::string> files, const winrt::hstring source)
{
for (const auto& file : files)
{

View file

@ -208,6 +208,54 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
};
#endif
#ifdef ROBIN_HOOD_H_INCLUDED
template<bool IsFlat, size_t MaxLoadFactor100, typename Key, typename Hash, typename KeyEqual>
struct ConversionTrait<robin_hood::detail::Table<IsFlat, MaxLoadFactor100, Key, void, Hash, KeyEqual>>
{
private:
using map_type = robin_hood::detail::Table<IsFlat, MaxLoadFactor100, Key, void, Hash, KeyEqual>;
public:
map_type FromJson(const Json::Value& json) const
{
map_type val;
val.reserve(json.size());
ConversionTrait<Key> trait;
for (const auto& element : json)
{
val.emplace(trait.FromJson(element));
}
return val;
}
bool CanConvert(const Json::Value& json) const
{
ConversionTrait<Key> trait;
return json.isArray() && std::all_of(json.begin(), json.end(), [trait](const auto& json) -> bool { return trait.CanConvert(json); });
}
Json::Value ToJson(const map_type& val)
{
Json::Value json{ Json::arrayValue };
ConversionTrait<Key> trait;
for (const auto& key : val)
{
json.append(trait.ToJson(key));
}
return json;
}
std::string TypeDescription() const
{
return fmt::format("{}[]", ConversionTrait<GUID>{}.TypeDescription());
}
};
#endif
template<>
struct ConversionTrait<bool>
{

View file

@ -152,7 +152,7 @@ winrt::com_ptr<Profile> Profile::CopySettings(winrt::com_ptr<Profile> source)
// - visited - a map of which Profiles have been visited, and, if so, a reference to the Profile's clone
// Return Value:
// - a clone in both inheritance structure and Profile values of sourceGraph
winrt::com_ptr<Profile> Profile::CloneInheritanceGraph(winrt::com_ptr<Profile> sourceGraph, winrt::com_ptr<Profile> cloneGraph, std::unordered_map<void*, winrt::com_ptr<Profile>>& visited)
winrt::com_ptr<Profile> Profile::CloneInheritanceGraph(winrt::com_ptr<Profile> sourceGraph, winrt::com_ptr<Profile> cloneGraph, robin_hood::unordered_map<void*, winrt::com_ptr<Profile>>& visited)
{
// If this is an unexplored Profile
// and we have parents...

View file

@ -87,7 +87,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return Name();
}
static com_ptr<Profile> CloneInheritanceGraph(com_ptr<Profile> oldProfile, com_ptr<Profile> newProfile, std::unordered_map<void*, com_ptr<Profile>>& visited);
static com_ptr<Profile> CloneInheritanceGraph(com_ptr<Profile> oldProfile, com_ptr<Profile> newProfile, robin_hood::unordered_map<void*, com_ptr<Profile>>& visited);
static com_ptr<Profile> CopySettings(com_ptr<Profile> source);
static void InsertParentHelper(com_ptr<Profile> child, com_ptr<Profile> parent, std::optional<size_t> index = std::nullopt);

View file

@ -43,8 +43,8 @@ struct case_insensitive_equality
}
};
std::unordered_map<std::wstring,
std::unordered_map<std::wstring,
robin_hood::unordered_map<std::wstring,
robin_hood::unordered_map<std::wstring,
std::wstring,
case_insensitive_hash,
case_insensitive_equality>,

View file

@ -160,7 +160,7 @@ using Microsoft::Console::Interactivity::ServiceLocator;
try
{
// Convert real Windows NT modifier bit into bizarre Console bits
std::unordered_set<ModifierKeyState> consoleModKeyState = FromVkKeyScan(zeroControlKeyState);
robin_hood::unordered_set<ModifierKeyState> consoleModKeyState = FromVkKeyScan(zeroControlKeyState);
if (zeroVKey == keyEvent->GetVirtualKeyCode() &&
keyEvent->DoActiveModifierKeysMatch(consoleModKeyState))

View file

@ -94,6 +94,8 @@
#include <dynamic_bitset.hpp>
#pragma warning(pop)
#include <robin_hood.h>
// {fmt}, a C++20-compatible formatting library
#include <fmt/format.h>
#include <fmt/compile.h>

View file

@ -9,7 +9,7 @@
// use constexpr std::sort during construction.
//
// Until we can use C++20, this is no cheaper than using
// a static std::unordered_map that is initialized at
// a static robin_hood::unordered_map that is initialized at
// startup or on first use.
// To build something that can be constexpr as of C++17,
// use til::presorted_static_map and make certain that

View file

@ -89,7 +89,7 @@ namespace Microsoft::Console::Interactivity::Win32
// eventually overflowing the stack.
// We aren't using this as a cheap locking
// mechanism for multi-threaded code.
std::unordered_map<EVENTID, bool> _signalEventFiring;
robin_hood::unordered_map<EVENTID, bool> _signalEventFiring;
[[nodiscard]] HRESULT _EnsureValidHwnd() const;

View file

@ -86,8 +86,8 @@ namespace Microsoft::Console::Render
void _BuildFontRenderData(const FontInfoDesired& desired, FontInfo& actual, const int dpi);
Microsoft::WRL::ComPtr<IDWriteTextFormat> _BuildTextFormat(const DxFontInfo fontInfo, const std::wstring_view localeName);
std::unordered_map<FontAttributeMapKey, ::Microsoft::WRL::ComPtr<IDWriteTextFormat>> _textFormatMap;
std::unordered_map<FontAttributeMapKey, ::Microsoft::WRL::ComPtr<IDWriteFontFace1>> _fontFaceMap;
robin_hood::unordered_map<FontAttributeMapKey, ::Microsoft::WRL::ComPtr<IDWriteTextFormat>> _textFormatMap;
robin_hood::unordered_map<FontAttributeMapKey, ::Microsoft::WRL::ComPtr<IDWriteFontFace1>> _fontFaceMap;
::Microsoft::WRL::ComPtr<IBoxDrawingEffect> _boxDrawingEffect;
::Microsoft::WRL::ComPtr<IDWriteFontFallback> _systemFontFallback;

View file

@ -39,7 +39,7 @@ namespace winrt::MonarchPeasantSample::implementation
uint64_t _thisPeasantID{ 0 };
uint64_t _mostRecentPeasant{ 0 };
WindowingBehavior _windowingBehavior{ WindowingBehavior::UseNew };
std::unordered_map<uint64_t, winrt::MonarchPeasantSample::IPeasant> _peasants;
robin_hood::unordered_map<uint64_t, winrt::MonarchPeasantSample::IPeasant> _peasants;
winrt::MonarchPeasantSample::IPeasant _getPeasant(uint64_t peasantID);
void _setMostRecentPeasant(const uint64_t peasantID);

View file

@ -72,7 +72,7 @@ void KeyEvent::ActivateModifierKey(const ModifierKeyState modifierKey) noexcept
SetActiveModifierKeys(keys);
}
bool KeyEvent::DoActiveModifierKeysMatch(const std::unordered_set<ModifierKeyState>& consoleModifiers) const noexcept
bool KeyEvent::DoActiveModifierKeysMatch(const robin_hood::unordered_set<ModifierKeyState>& consoleModifiers) const noexcept
{
DWORD consoleBits = 0;
for (const ModifierKeyState& mod : consoleModifiers)

View file

@ -22,9 +22,9 @@ constexpr bool RuntimeIsFlagSet(const DWORD flags, const DWORD flag) noexcept
return !!(flags & flag);
}
std::unordered_set<ModifierKeyState> FromVkKeyScan(const short vkKeyScanFlags)
robin_hood::unordered_set<ModifierKeyState> FromVkKeyScan(const short vkKeyScanFlags)
{
std::unordered_set<ModifierKeyState> keyState;
robin_hood::unordered_set<ModifierKeyState> keyState;
switch (vkKeyScanFlags)
{
@ -103,9 +103,9 @@ static_assert(size(ModifierKeyStateTranslationTable) == static_cast<int>(Modifie
// - flags - legacy bitset to expand
// Return Value:
// - set of ModifierKeyState values that represent flags
std::unordered_set<ModifierKeyState> FromConsoleControlKeyFlags(const DWORD flags)
robin_hood::unordered_set<ModifierKeyState> FromConsoleControlKeyFlags(const DWORD flags)
{
std::unordered_set<ModifierKeyState> keyStates;
robin_hood::unordered_set<ModifierKeyState> keyStates;
for (const ModifierKeyStateMapping& mapping : ModifierKeyStateTranslationTable)
{

View file

@ -121,7 +121,7 @@ namespace Microsoft::Console::Types
// eventually overflowing the stack.
// We aren't using this as a cheap locking
// mechanism for multi-threaded code.
std::unordered_map<EVENTID, bool> _signalFiringMapping{};
robin_hood::unordered_map<EVENTID, bool> _signalFiringMapping{};
const COORD _getScreenBufferCoords() const noexcept;
const TextBuffer& _getTextBuffer() const noexcept;

View file

@ -46,6 +46,6 @@ private:
bool _checkFallbackViaCache(const std::wstring_view glyph) const;
static unsigned int _extractCodepoint(const std::wstring_view glyph) noexcept;
mutable std::unordered_map<std::wstring, bool> _fallbackCache;
mutable robin_hood::unordered_map<std::wstring, bool> _fallbackCache;
std::function<bool(std::wstring_view)> _pfnFallbackMethod;
};

View file

@ -113,8 +113,8 @@ enum class ModifierKeyState
ENUM_COUNT // must be the last element in the enum class
};
std::unordered_set<ModifierKeyState> FromVkKeyScan(const short vkKeyScanFlags);
std::unordered_set<ModifierKeyState> FromConsoleControlKeyFlags(const DWORD flags);
robin_hood::unordered_set<ModifierKeyState> FromVkKeyScan(const short vkKeyScanFlags);
robin_hood::unordered_set<ModifierKeyState> FromConsoleControlKeyFlags(const DWORD flags);
DWORD ToConsoleControlKeyFlag(const ModifierKeyState modifierKey) noexcept;
class KeyEvent : public IInputEvent
@ -297,7 +297,7 @@ public:
void SetActiveModifierKeys(const DWORD activeModifierKeys) noexcept;
void DeactivateModifierKey(const ModifierKeyState modifierKey) noexcept;
void ActivateModifierKey(const ModifierKeyState modifierKey) noexcept;
bool DoActiveModifierKeysMatch(const std::unordered_set<ModifierKeyState>& consoleModifiers) const noexcept;
bool DoActiveModifierKeysMatch(const robin_hood::unordered_set<ModifierKeyState>& consoleModifiers) const noexcept;
bool IsCommandLineEditingKey() const noexcept;
bool IsPopupKey() const noexcept;