Fixed behavior of Util::Config::Node when adding nested nodes (only leaf level can be duplicated; e.g., foo/bar and foo/bar will create one foo with two bar children, rather than two foo each with one bar).

This commit is contained in:
Bart Trzynadlowski 2017-04-11 07:03:10 +00:00
parent 901b8c3fa4
commit 9dd2b24729
2 changed files with 27 additions and 11 deletions

View file

@ -128,6 +128,10 @@
*
* TODO
* ----
* - TryGet() can be made quicker by attempting a direct lookup first. We never
* add keys with '/' in them (they are split up into nested nodes). Most
* lookups are likely to be leaf level, so a direct lookup should be possible
* first and, if it fails, the key can be retried as a nested path.
* - Define our own exceptions?
*/

View file

@ -216,7 +216,9 @@ namespace Util
SetValue<std::string>(value);
}
// Add a child node
// Add a child node. Multiple nodes of the same key may be added but only
// when specified as leaves. For example, adding "foo/bar" twice will
// result in one "foo" with two "bar" children.
template <typename T>
Node &Add(const std::string &path, const T &value)
{
@ -225,19 +227,29 @@ namespace Util
ptr_t node;
for (size_t i = 0; i < keys.size(); i++)
{
// Create node at this level
node = std::make_shared<Node>(keys[i]);
// The leaf node gets the value
if (i == keys.size() - 1)
node->SetValue(value);
// Attach node to parent and move down to next nesting level: last
// created node is new parent
AddChild(*parent, node);
parent = node.get();
bool leaf = i == keys.size() - 1;
auto it = parent->m_children.find(keys[i]);
if (leaf || it == parent->m_children.end())
{
// Create node at this level
node = std::make_shared<Node>(keys[i]);
// The leaf node gets the value
if (leaf)
node->SetValue(value);
// Attach node to parent and move down to next nesting level: last
// created node is new parent
AddChild(*parent, node);
parent = node.get();
}
else
{
// Descend deeper...
parent = it->second.get();
}
}
return *node;
}
Node &Add(const std::string &path)
{
return Add(path, std::string());