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
#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;

Loading…
Cancel
Save