Support for deep copies via assignment operator. This will pave the way for elimination of Ptr_t and ConstPtr_t.

This commit is contained in:
Bart Trzynadlowski 2016-08-18 04:14:36 +00:00
parent 5652aab91f
commit fbeeb3c922
3 changed files with 66 additions and 27 deletions

View file

@ -203,29 +203,13 @@ namespace Util
parent.m_children[node->m_key] = node;
}
Node::Node()
{
//std::cout << "Created " << "<null>" << " (" << this << ")" << std::endl;
}
Node::Node(const std::string &key)
: m_key(key)
{
//std::cout << "Created " << key << " (" << this << ")" << std::endl;
}
Node::Node(const std::string &key, const std::string &value)
: m_key(key),
m_value(value)
{
//std::cout << "Created " << key << '=' << value << " (" << this << ")" << std::endl;
}
// Deep copy
Node::Node(const Node &that)
: m_key(that.m_key),
m_value(that.m_value)
void Node::DeepCopy(const Node &that)
{
if (this == &that)
return;
Destroy();
*const_cast<std::string *>(&m_key) = that.m_key;
m_value = that.m_value;
for (Ptr_t child = that.m_first_child; child; child = child->m_next_sibling)
{
Ptr_t copied_child = std::make_shared<Node>(*child);
@ -233,9 +217,40 @@ namespace Util
}
}
Node &Node::operator=(const Node &rhs)
{
DeepCopy(rhs);
return *this;
}
Node::Node()
{
//std::cout << "<<< Created " << "<null>" << " (" << this << ")" << std::endl;
}
Node::Node(const std::string &key)
: m_key(key)
{
//std::cout << "<<< Created " << key << " (" << this << ")" << std::endl;
}
Node::Node(const std::string &key, const std::string &value)
: m_key(key),
m_value(value)
{
//std::cout << "<<< Created " << key << '=' << value << " (" << this << ")" << std::endl;
}
Node::Node(const Node &that)
: m_key(that.m_key),
m_value(that.m_value)
{
DeepCopy(that);
}
Node::~Node()
{
//std::cout << "Destroyed " << m_key << " (" << this << ")" << std::endl;
//std::cout << ">>> Destroyed " << m_key << " (" << this << ")" << std::endl;
}
Node::Ptr_t CreateEmpty()

View file

@ -25,7 +25,17 @@ namespace Util
std::string m_value;
static Node s_empty_node; // key, value, and children must always be empty
void Destroy()
{
m_next_sibling.reset();
m_first_child.reset();
m_last_child.reset();
m_children.clear();
m_value.clear();
}
void AddChild(Node &parent, Ptr_t &node);
void DeepCopy(const Node &that);
Node(); // prohibit accidental/unintentional creation of blank nodes
friend Ptr_t CreateEmpty();
@ -199,6 +209,7 @@ namespace Util
std::string ToString(size_t indent_level = 0) const;
Node &Add(const std::string &key, const std::string &value = "");
void Set(const std::string &key, const std::string &value);
Node &operator=(const Node &rhs);
Node(const std::string &key);
Node(const std::string &key, const std::string &value);
Node(const Node &that);

View file

@ -63,13 +63,26 @@ int main()
std::cout << "game/roms/crom/name=" << global["game/roms/crom/name"].Value() << " (expected: bar.bin)" << std::endl << std::endl;
test_results.push_back({ "Lookup", global["game/roms/crom/name"].Value() == "bar.bin" });
// Make a copy
std::cout << "Copy:" << std::endl << std::endl;
// Make a copy using copy constructor
std::cout << "Copy constructed:" << std::endl << std::endl;
Util::Config::Node::Ptr_t copy = std::make_shared<Util::Config::Node>(*root);
copy->Print();
std::cout << std::endl;
test_results.push_back({ "Copy", copy->ToString() == root->ToString() });
test_results.push_back({ "Copy constructed", copy->ToString() == root->ToString() });
// Make a copy using assignment operator
std::cout << "Copy by assignment:" << std::endl << std::endl;
Util::Config::Node copy2("foo", "bar");
copy2.Add("x/y/z", "test");
copy2.Add("dummy", "value");
std::cout << "Initially set to:" << std::endl;
copy2.Print();
copy2 = *root;
std::cout << "Copy of \"global\":" << std::endl;
copy2.Print();
std::cout << std::endl;
test_results.push_back({ "Copy by assignment", copy2.ToString() == root->ToString() });
// Parse from XML
const char *xml =
"<game name=\"scud\"> \n"