Add support for Range-based DomPrefixTree construction, fix initializer_list

Signed-off-by: Nicholas Van Sickle <nvsickle@amazon.com>
monroegm-disable-blank-issue-2
Nicholas Van Sickle 4 years ago
parent e149abe550
commit f60a24e07d

@ -9,9 +9,10 @@
#pragma once #pragma once
#include <AzCore/DOM/DomPath.h> #include <AzCore/DOM/DomPath.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/containers/stack.h> #include <AzCore/std/containers/stack.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/optional.h> #include <AzCore/std/optional.h>
#include <AzCore/std/ranges/ranges.h>
namespace AZ::Dom namespace AZ::Dom
{ {
@ -42,6 +43,19 @@ namespace AZ::Dom
DomPrefixTree(const DomPrefixTree&) = default; DomPrefixTree(const DomPrefixTree&) = default;
DomPrefixTree(DomPrefixTree&&) = default; DomPrefixTree(DomPrefixTree&&) = default;
explicit DomPrefixTree(AZStd::initializer_list<AZStd::pair<Path, T>> init); 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=(const DomPrefixTree&) = default;
DomPrefixTree& operator=(DomPrefixTree&&) = default; DomPrefixTree& operator=(DomPrefixTree&&) = default;
@ -55,10 +69,12 @@ namespace AZ::Dom
//! \see ValueAtPath //! \see ValueAtPath
const T* ValueAtPath(const Path& path, PrefixTreeMatch match) const; const T* ValueAtPath(const Path& path, PrefixTreeMatch match) const;
//! Visits a path and returns the most specific matching value or some default value. //! 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. //! 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. //! 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); void EraseValue(const Path& path, bool removedChildren = false);
//! Removes all entries from this tree. //! Removes all entries from this tree.

@ -13,9 +13,9 @@ namespace AZ::Dom
template<class T> template<class T>
DomPrefixTree<T>::DomPrefixTree(AZStd::initializer_list<AZStd::pair<Path, T>> init) 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);
} }
} }
@ -166,14 +166,16 @@ namespace AZ::Dom
} }
template<class T> 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); 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> 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; Node* node = &m_rootNode;
for (const PathEntry& entry : path) for (const PathEntry& entry : path)
@ -181,7 +183,7 @@ namespace AZ::Dom
// Get or create an entry in this node // Get or create an entry in this node
node = &node->m_values[entry]; node = &node->m_values[entry];
} }
node->m_data = AZStd::forward<T>(value); node->m_data = AZStd::forward<Deduced>(value);
} }
template<class T> template<class T>

@ -13,6 +13,29 @@ namespace AZ::Dom::Tests
{ {
using DomPrefixTreeTests = DomTestFixture; 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) TEST_F(DomPrefixTreeTests, GetAndSetRoot)
{ {
DomPrefixTree<AZStd::string> tree; DomPrefixTree<AZStd::string> tree;

Loading…
Cancel
Save