Add support for Range-based DomPrefixTree construction, fix initializer_list
Signed-off-by: Nicholas Van Sickle <nvsickle@amazon.com>
This commit is contained in:
@@ -9,9 +9,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/DOM/DomPath.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/stack.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/std/ranges/ranges.h>
|
||||
|
||||
namespace AZ::Dom
|
||||
{
|
||||
@@ -42,6 +43,19 @@ namespace AZ::Dom
|
||||
DomPrefixTree(const DomPrefixTree&) = default;
|
||||
DomPrefixTree(DomPrefixTree&&) = default;
|
||||
explicit DomPrefixTree(AZStd::initializer_list<AZStd::pair<Path, T>> init);
|
||||
template<
|
||||
class Range,
|
||||
class = AZStd::enable_if_t<
|
||||
AZStd::ranges::input_range<Range> &&
|
||||
AZStd::convertible_to<AZStd::tuple_element_t<0, AZStd::ranges::range_value_t<Range>>, Path> &&
|
||||
AZStd::convertible_to<AZStd::tuple_element_t<1, AZStd::ranges::range_value_t<Range>>, T>>>
|
||||
explicit DomPrefixTree(Range&& range)
|
||||
{
|
||||
for (auto&& [path, value] : AZStd::forward<Range>(range))
|
||||
{
|
||||
SetValue(path, value);
|
||||
}
|
||||
}
|
||||
|
||||
DomPrefixTree& operator=(const DomPrefixTree&) = default;
|
||||
DomPrefixTree& operator=(DomPrefixTree&&) = default;
|
||||
@@ -55,10 +69,12 @@ namespace AZ::Dom
|
||||
//! \see ValueAtPath
|
||||
const T* ValueAtPath(const Path& path, PrefixTreeMatch match) const;
|
||||
//! Visits a path and returns the most specific matching value or some default value.
|
||||
T ValueAtPathOrDefault(const Path& path, T&& defaultValue, PrefixTreeMatch match) const;
|
||||
template<class Deduced>
|
||||
T ValueAtPathOrDefault(const Path& path, Deduced&& defaultValue, PrefixTreeMatch match) const;
|
||||
|
||||
//! Sets the value stored at path.
|
||||
void SetValue(const Path& path, T&& value);
|
||||
template<class Deduced>
|
||||
void SetValue(const Path& path, Deduced&& value);
|
||||
//! Removes the value stored at path. If removeChildren is true, also removes any values stored at subpaths.
|
||||
void EraseValue(const Path& path, bool removedChildren = false);
|
||||
//! Removes all entries from this tree.
|
||||
|
||||
@@ -13,9 +13,9 @@ namespace AZ::Dom
|
||||
template<class T>
|
||||
DomPrefixTree<T>::DomPrefixTree(AZStd::initializer_list<AZStd::pair<Path, T>> init)
|
||||
{
|
||||
for (const auto& entry : init)
|
||||
for (const auto& [path, value] : init)
|
||||
{
|
||||
SetValue(entry.first, entry.second);
|
||||
SetValue(path, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace AZ::Dom
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template<class T>
|
||||
const T* DomPrefixTree<T>::ValueAtPath(const Path& path, PrefixTreeMatch match) const
|
||||
{
|
||||
// Const coerce the ValueAtPath result, which doesn't mutate but returns a mutable pointer
|
||||
@@ -166,14 +166,16 @@ namespace AZ::Dom
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T DomPrefixTree<T>::ValueAtPathOrDefault(const Path& path, T&& defaultValue, PrefixTreeMatch match) const
|
||||
template<class Deduced>
|
||||
T DomPrefixTree<T>::ValueAtPathOrDefault(const Path& path, Deduced&& defaultValue, PrefixTreeMatch match) const
|
||||
{
|
||||
const T* value = ValueAtPath(path, match);
|
||||
return value == nullptr ? AZStd::forward<T>(defaultValue) : *value;
|
||||
return value == nullptr ? AZStd::forward<Deduced>(defaultValue) : *value;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void DomPrefixTree<T>::SetValue(const Path& path, T&& value)
|
||||
template<class Deduced>
|
||||
void DomPrefixTree<T>::SetValue(const Path& path, Deduced&& value)
|
||||
{
|
||||
Node* node = &m_rootNode;
|
||||
for (const PathEntry& entry : path)
|
||||
@@ -181,7 +183,7 @@ namespace AZ::Dom
|
||||
// Get or create an entry in this node
|
||||
node = &node->m_values[entry];
|
||||
}
|
||||
node->m_data = AZStd::forward<T>(value);
|
||||
node->m_data = AZStd::forward<Deduced>(value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
||||
@@ -13,6 +13,29 @@ namespace AZ::Dom::Tests
|
||||
{
|
||||
using DomPrefixTreeTests = DomTestFixture;
|
||||
|
||||
TEST_F(DomPrefixTreeTests, InitializeFromInitializerList)
|
||||
{
|
||||
DomPrefixTree<int> tree({
|
||||
{ Path(), 0 },
|
||||
{ Path("/foo/bar"), 1 },
|
||||
});
|
||||
|
||||
EXPECT_EQ(0, *tree.ValueAtPath(Path(), PrefixTreeMatch::ExactPath));
|
||||
EXPECT_EQ(1, *tree.ValueAtPath(Path("/foo/bar"), PrefixTreeMatch::ExactPath));
|
||||
}
|
||||
|
||||
TEST_F(DomPrefixTreeTests, InitializeFromRange)
|
||||
{
|
||||
AZStd::vector<AZStd::pair<Path, int>> container({
|
||||
{ Path(), 21 },
|
||||
{ Path("/foo/bar"), 42 },
|
||||
});
|
||||
DomPrefixTree<int> tree(container);
|
||||
|
||||
EXPECT_EQ(21, *tree.ValueAtPath(Path(), PrefixTreeMatch::ExactPath));
|
||||
EXPECT_EQ(42, *tree.ValueAtPath(Path("/foo/bar"), PrefixTreeMatch::ExactPath));
|
||||
}
|
||||
|
||||
TEST_F(DomPrefixTreeTests, GetAndSetRoot)
|
||||
{
|
||||
DomPrefixTree<AZStd::string> tree;
|
||||
|
||||
Reference in New Issue
Block a user