changeset 254:812dd806f803

TreeNode: * add remove() function * indexOf now check for address to be present * indexOfSame checks for a copy of the object using operator==
author David Demelier <markand@malikania.fr>
date Thu, 02 Oct 2014 14:10:28 +0200
parents a4770082e7d6
children 8196fdb0fc48
files C++/Tests/TreeNode/main.cpp C++/TreeNode.h
diffstat 2 files changed, 119 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/C++/Tests/TreeNode/main.cpp	Thu Oct 02 11:45:24 2014 +0200
+++ b/C++/Tests/TreeNode/main.cpp	Thu Oct 02 14:10:28 2014 +0200
@@ -1241,6 +1241,38 @@
 }
 
 /* --------------------------------------------------------
+ * Remove functions
+ * -------------------------------------------------------- */
+
+TEST(Remove, index)
+{
+	Object root("root");
+
+	root.append(Object("a"));
+	root.append(Object("b"));
+	root.append(Object("c"));
+	root.remove(2);
+
+	ASSERT_EQ(2, root.countChildren());
+	ASSERT_EQ("a", root[0].name());
+	ASSERT_EQ("b", root[1].name());
+}
+
+TEST(Remove, ref)
+{
+	Object root("root");
+
+	root.append(Object("a"));
+	root.append(Object("b"));
+	root.append(Object("c"));
+	root.remove(root[2]);
+
+	ASSERT_EQ(2, root.countChildren());
+	ASSERT_EQ("a", root[0].name());
+	ASSERT_EQ("b", root[1].name());
+}
+
+/* --------------------------------------------------------
  * Miscellaneous
  * -------------------------------------------------------- */
 
@@ -1252,13 +1284,43 @@
 	root.append(Object("b"));
 	root.append(Object("c"));
 
-	try {
-		auto index = root.indexOf(Object("b"));
+	ASSERT_EQ(1, root.indexOf(root[1]));
+}
+
+TEST(Misc, indexOfFail)
+{
+	Object root("root");
+	Object notin("c");
+
+	root.append(Object("a"));
+	root.append(Object("b"));
+	root.append(Object("c"));
+
+	ASSERT_EQ(-1, root.indexOf(notin));
+}
 
-		ASSERT_EQ(index, 1);
-	} catch (const std::exception &ex) {
-		FAIL() << ex.what();
-	}
+TEST(Misc, indexOfSame)
+{
+	Object root("root");
+	Object same("a");
+
+	root.append(Object("a"));
+	root.append(Object("b"));
+	root.append(Object("c"));
+
+	ASSERT_EQ(0, root.indexOfSame(same));
+}
+
+TEST(Misc, indexOfSameFail)
+{
+	Object root("root");
+	Object same("xyz");
+
+	root.append(Object("a"));
+	root.append(Object("b"));
+	root.append(Object("c"));
+
+	ASSERT_EQ(-1, root.indexOfSame(same));
 }
 
 int main(int argc, char **argv)
--- a/C++/TreeNode.h	Thu Oct 02 11:45:24 2014 +0200
+++ b/C++/TreeNode.h	Thu Oct 02 14:10:28 2014 +0200
@@ -24,6 +24,7 @@
  * @brief N-ary tree without pointers
  */
 
+#include <algorithm>
 #include <deque>
 #include <memory>
 #include <stdexcept>
@@ -279,16 +280,61 @@
 	}
 
 	/**
-	 * Find a child in this. The type must have operator==.
+	 * Remove a child from the node at the given index.
+	 *
+	 * @param index the position index
+	 * @throw std::out_of_range if index is out of bounds
+	 */
+	void remove(unsigned index)
+	{
+		if (index >= m_children.size())
+			throw std::out_of_range("index is out of range");
+
+		m_children.erase(m_children.begin() + index);
+	}
+
+	/**
+	 * Remove a child from the node, the child must exists and no comparison test is performed, only
+	 * object addresses are compared.
+	 *
+	 * @param value the value that exists in the node
+	 * @warn the removed object must not be used after the call
+	 */
+	void remove(T &value)
+	{
+		m_children.erase(std::remove_if(m_children.begin(), m_children.end(), [&] (auto &p) {
+			return p.get() == &value;
+		}), m_children.end());
+	}
+
+	/**
+	 * Find the index of a node that is equality comparable to value but may be not in the node.
+	 *
+	 * @param value the value to compare
+	 * @return the index or -1 if not found
+	 * @see indexOf
+	 */
+	template <typename Value>
+	int indexOfSame(const Value &value, typename std::enable_if<TypeTraits<Value>::equalityComparable>::type * = nullptr)
+	{
+		for (unsigned i = 0; i < m_children.size(); ++i)
+			if (*m_children[i] == value)
+				return i;
+
+		return -1;
+	}
+
+	/**
+	 * Find a child in this node, the child address is used as the comparison so no equality operator is even called.
 	 *
 	 * @param child the child
 	 * @return the index or -1 if not found
+	 * @see indexOfSame
 	 */
-	template <typename Value>
-	int indexOf(const Value &child, typename std::enable_if<TypeTraits<Value>::equalityComparable>::type * = nullptr) const
+	int indexOf(const T &child) const
 	{
-		for (int i = 0; i < (int)m_children.size(); ++i)
-			if (*m_children[i] == child)
+		for (unsigned i = 0; i < m_children.size(); ++i)
+			if (m_children[i].get() == &child)
 				return i;
 
 		return -1;