Mercurial > code
changeset 366:acb3192de1fb
Treenode:
- Rename countChildren -> childrenCount
- Inline short functions
- Add itemAt, pushItem, appendItem
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 29 Apr 2015 10:32:31 +0200 |
parents | 93c8f8a1fd3f |
children | 99484c154d8a |
files | C++/modules/Treenode/TreeNode.h C++/tests/Treenode/main.cpp |
diffstat | 2 files changed, 280 insertions(+), 135 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/modules/Treenode/TreeNode.h Wed Apr 29 09:54:54 2015 +0200 +++ b/C++/modules/Treenode/TreeNode.h Wed Apr 29 10:32:31 2015 +0200 @@ -1,5 +1,5 @@ /* - * TreeNode.h -- C++11 pointer-free N-ary tree + * TreeNode.h -- C++14 pointer-free N-ary tree * * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> * @@ -21,7 +21,7 @@ /** * @file TreeNode.h - * @brief N-ary tree without pointers + * @brief N-ary polymorphic tree without pointers */ #include <algorithm> @@ -82,7 +82,7 @@ /** * Get the real object as a reference. */ - virtual T &value() = 0; + virtual T &value() noexcept = 0; /** * Do a real polymorphic copy of the children object. @@ -96,7 +96,7 @@ * @class TreeNodeItemProxy * @brief Implements polymorphic copy for the given value */ -template <typename T, typename Value> +template <typename T, typename Value = T> class TreeNodeItemProxy final : public TreeNodeItem<T> { private: Value m_value; @@ -107,27 +107,48 @@ TreeNodeItemProxy &operator=(TreeNodeItemProxy &&) = delete; public: - inline TreeNodeItemProxy(Value &&value) + /** + * Move the value. + * + * @param value the value + */ + inline TreeNodeItemProxy(Value &&value) noexcept : m_value(std::move(value)) { } + /** + * Copy the value. + * + * @param value the value + */ inline TreeNodeItemProxy(const Value &value) : m_value(value) { } + /** + * Construct the value in-place. + * + * @param args the arguments + */ template <typename... Args> inline TreeNodeItemProxy(Args&&... args) : m_value(std::forward<Args>(args)...) { } - T &value() override + /** + * @copydoc TreeNodeItem::value + */ + T &value() noexcept override { return m_value; } + /** + * @copydoc TreeNodeItem::clone + */ std::unique_ptr<TreeNodeItem<T>> clone() const override { return std::make_unique<TreeNodeItemProxy<T, Value>>(m_value); @@ -136,10 +157,12 @@ /** * @class TreeNode - * @brief Safe C++11 N-ary tree + * @brief Safe C++14 N-ary polymorphic tree * * This class use a std::deque as the container, it allocate object on the heap to avoid useless * copy and move when adding new elements. + * + * It also supports real polymorphic copies. */ template <typename T> class TreeNode { @@ -226,6 +249,17 @@ } /** + * Push an already allocated item. + * + * @param value the value to take + */ + inline void pushItem(std::unique_ptr<TreeNodeItem<T>> value) + { + m_children.push_front(std::move(value)); + m_children.front()->value().m_parent = this; + } + + /** * Add a child node to the beginning. * * @param child the children @@ -257,13 +291,24 @@ * @param args the arguments */ template <typename... Args> - void pushNew(Args&&... args) + inline void pushNew(Args&&... args) { - m_children.emplace_front(std::make_unique<TreeNodeItemProxy<T, T>>(std::forward<Args>(args)...)); + m_children.emplace_front(std::make_unique<TreeNodeItemProxy<T>>(std::forward<Args>(args)...)); m_children.front()->value().m_parent = this; } /** + * Append an already allocated item. + * + * @param value the value to take + */ + inline void appendItem(std::unique_ptr<TreeNodeItem<T>> value) + { + m_children.push_back(std::move(value)); + m_children.back()->value().m_parent = this; + } + + /** * Add a child node to the end * * @param child the children @@ -295,9 +340,9 @@ * @param args the arguments */ template <typename... Args> - void appendNew(Args&&... args) + inline void appendNew(Args&&... args) { - m_children.emplace_back(std::make_unique<TreeNodeItemProxy<T, T>>(std::forward<Args>(args)...)); + m_children.emplace_back(std::make_unique<TreeNodeItemProxy<T>>(std::forward<Args>(args)...)); m_children.back()->value().m_parent = this; } @@ -306,7 +351,7 @@ * * @return the number of children */ - unsigned countChildren() const noexcept + inline unsigned childrenCount() const noexcept { return static_cast<unsigned>(m_children.size()); } @@ -317,7 +362,7 @@ * @return the parent node * @throw std::out_of_range if there is no parent */ - T &parent() + inline T &parent() { if (!m_parent) throw std::out_of_range("no parent"); @@ -331,7 +376,7 @@ * @return the parent node * @throw std::out_of_range if there is no parent */ - const T &parent() const + inline const T &parent() const { if (!m_parent) throw std::out_of_range("no parent"); @@ -344,7 +389,7 @@ * * @return true if root */ - bool isRoot() const noexcept + inline bool isRoot() const noexcept { return m_parent == nullptr; } @@ -354,7 +399,7 @@ * * @return true if leaf */ - bool isLeaf() const noexcept + inline bool isLeaf() const noexcept { return m_children.size() == 0; } @@ -365,7 +410,7 @@ * @param index the position index * @throw std::out_of_range if index is out of bounds */ - void remove(int index) + inline void remove(int index) { if (index < 0 || index >= static_cast<int>(m_children.size())) throw std::out_of_range("index is out of range"); @@ -380,7 +425,7 @@ * @param value the value that exists in the node * @warn the removed object must not be used after the call */ - void remove(T &value) + inline void remove(T &value) { m_children.erase(std::remove_if(m_children.begin(), m_children.end(), [&] (auto &p) { return &p->value() == &value; @@ -394,7 +439,7 @@ * @warn the removed object must not be used after the call */ template <typename Value> - void removeSame(const Value &value, typename std::enable_if<TypeTraits<Value>::equalityComparable>::type * = nullptr) + inline void removeSame(const Value &value, typename std::enable_if<TypeTraits<Value>::equalityComparable>::type * = nullptr) { m_children.erase(std::remove_if(m_children.begin(), m_children.end(), [&] (auto &p) { return p->value() == value; @@ -404,7 +449,7 @@ /** * Remove all children. */ - void clear() + inline void clear() { m_children.clear(); } @@ -498,7 +543,7 @@ * @param callback the callback */ template <typename Callback> - void map(Callback callback) + inline void map(Callback callback) { callback(static_cast<T &>(*this)); @@ -512,7 +557,7 @@ * @param dest the destination iterator */ template <typename OutputIt> - void flat(OutputIt dest) + inline void flat(OutputIt dest) { map([&] (const auto &value) { *dest++ = value; @@ -565,13 +610,47 @@ } /** + * Access a child as the node item. + * + * @warning the object is moved, thus empty + * @param index the index + * @throw std::out_of_range on out of bounds + */ + inline std::unique_ptr<TreeNodeItem<T>> itemAt(int index) && + { + return std::move(m_children.at(index)); + } + + /** + * Access a child as the node item. + * + * @param index the index + * @throw std::out_of_range on out of bounds + */ + inline std::unique_ptr<TreeNodeItem<T>> &itemAt(int index) & + { + return m_children.at(index); + } + + /** + * Access a child as the node item. + * + * @param index the index + * @throw std::out_of_range on out of bounds + */ + inline const std::unique_ptr<TreeNodeItem<T>> &itemAt(int index) const & + { + return m_children.at(index); + } + + /** * Access a child. * * @param index the index * @return the reference to the children node * @throw std::out_of_range on out of bounds */ - T &operator[](int index) + inline T &operator[](int index) { return static_cast<T &>(m_children.at(index)->value()); } @@ -583,7 +662,7 @@ * @return the reference to the children node * @throw std::out_of_range on out of bounds */ - const T &operator[](int index) const + inline const T &operator[](int index) const { return static_cast<const T &>(m_children.at(index)->value()); }
--- a/C++/tests/Treenode/main.cpp Wed Apr 29 09:54:54 2015 +0200 +++ b/C++/tests/Treenode/main.cpp Wed Apr 29 10:32:31 2015 +0200 @@ -54,7 +54,7 @@ * * ASSERT_(TRUE|FALSE) isRoot() * ASSERT_(TRUE|FALSE) isLeaf() - * ASSERT_EQ countChildren() + * ASSERT_EQ childrenCount() * ASSERT_EQ() name() * ASSERT_TRUE & addresses */ @@ -72,7 +72,7 @@ ASSERT_TRUE(object.isRoot()); ASSERT_TRUE(object.isLeaf()); - ASSERT_EQ(0, static_cast<int>(object.countChildren())); + ASSERT_EQ(0, static_cast<int>(object.childrenCount())); ASSERT_EQ("root", object.name()); } @@ -91,7 +91,7 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(1, static_cast<int>(object.countChildren())); + ASSERT_EQ(1, static_cast<int>(object.childrenCount())); ASSERT_EQ("root", object.name()); // test moved a @@ -103,7 +103,7 @@ // test original a ASSERT_TRUE(a.isRoot()); ASSERT_TRUE(a.isLeaf()); - ASSERT_EQ(0, static_cast<int>(a.countChildren())); + ASSERT_EQ(0, static_cast<int>(a.childrenCount())); } /* @@ -121,7 +121,7 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(1, static_cast<int>(object.countChildren())); + ASSERT_EQ(1, static_cast<int>(object.childrenCount())); ASSERT_EQ("root", object.name()); // test copied b @@ -133,7 +133,7 @@ // test original b ASSERT_TRUE(copy.isRoot()); ASSERT_TRUE(copy.isLeaf()); - ASSERT_EQ(0, static_cast<int>(copy.countChildren())); + ASSERT_EQ(0, static_cast<int>(copy.childrenCount())); ASSERT_EQ("b", copy.name()); } @@ -154,13 +154,13 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(2, static_cast<int>(object.countChildren())); + ASSERT_EQ(2, static_cast<int>(object.childrenCount())); ASSERT_EQ("root", object.name()); // test moved 1 ASSERT_FALSE(object[0].isRoot()); ASSERT_TRUE(object[0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0].childrenCount())); ASSERT_EQ("1", object[0].name()); ASSERT_TRUE(&object == &object[0].parent()); @@ -168,18 +168,18 @@ ASSERT_FALSE(object[1].isRoot()); ASSERT_TRUE(object[1].isLeaf()); ASSERT_EQ("2", object[1].name()); - ASSERT_EQ(0, static_cast<int>(object[1].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[1].childrenCount())); ASSERT_TRUE(&object == &object[1].parent()); // test original 1 ASSERT_TRUE(o1.isRoot()); ASSERT_TRUE(o1.isLeaf()); - ASSERT_EQ(0, static_cast<int>(o1.countChildren())); + ASSERT_EQ(0, static_cast<int>(o1.childrenCount())); // test original 2 ASSERT_TRUE(o2.isRoot()); ASSERT_TRUE(o2.isLeaf()); - ASSERT_EQ(0, static_cast<int>(o2.countChildren())); + ASSERT_EQ(0, static_cast<int>(o2.childrenCount())); } /* @@ -199,33 +199,33 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(2, static_cast<int>(object.countChildren())); + ASSERT_EQ(2, static_cast<int>(object.childrenCount())); ASSERT_EQ("root", object.name()); // test copied 1 ASSERT_FALSE(object[0].isRoot()); ASSERT_TRUE(object[0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0].childrenCount())); ASSERT_EQ("1", object[0].name()); ASSERT_TRUE(&object == &object[0].parent()); // test copied 2 ASSERT_FALSE(object[1].isRoot()); ASSERT_TRUE(object[1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[1].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[1].childrenCount())); ASSERT_EQ("2", object[1].name()); ASSERT_TRUE(&object == &object[1].parent()); // test original 1 ASSERT_TRUE(o1.isRoot()); ASSERT_TRUE(o1.isLeaf()); - ASSERT_EQ(0, static_cast<int>(o1.countChildren())); + ASSERT_EQ(0, static_cast<int>(o1.childrenCount())); ASSERT_EQ("1", o1.name()); // test original 2 ASSERT_TRUE(o2.isRoot()); ASSERT_TRUE(o2.isLeaf()); - ASSERT_EQ(0, static_cast<int>(o2.countChildren())); + ASSERT_EQ(0, static_cast<int>(o2.childrenCount())); ASSERT_EQ("2", o2.name()); } @@ -244,20 +244,20 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(1, static_cast<int>(object.countChildren())); + ASSERT_EQ(1, static_cast<int>(object.childrenCount())); ASSERT_EQ("a", object[0].name()); // test moved a ASSERT_FALSE(object[0].isRoot()); ASSERT_TRUE(object[0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0].childrenCount())); ASSERT_EQ("a", object[0].name()); ASSERT_TRUE(&object == &object[0].parent()); // test original a ASSERT_TRUE(a.isRoot()); ASSERT_TRUE(a.isLeaf()); - ASSERT_EQ(0, static_cast<int>(a.countChildren())); + ASSERT_EQ(0, static_cast<int>(a.childrenCount())); } /* @@ -275,20 +275,20 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(1, static_cast<int>(object.countChildren())); + ASSERT_EQ(1, static_cast<int>(object.childrenCount())); ASSERT_EQ("a", object[0].name()); // test copied a ASSERT_FALSE(object[0].isRoot()); ASSERT_TRUE(object[0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0].childrenCount())); ASSERT_EQ("a", object[0].name()); ASSERT_TRUE(&object == &object[0].parent()); // test original b ASSERT_TRUE(copy.isRoot()); ASSERT_TRUE(copy.isLeaf()); - ASSERT_EQ(0, static_cast<int>(copy.countChildren())); + ASSERT_EQ(0, static_cast<int>(copy.childrenCount())); ASSERT_EQ("a", copy.name()); } @@ -309,13 +309,13 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(2, static_cast<int>(object.countChildren())); + ASSERT_EQ(2, static_cast<int>(object.childrenCount())); ASSERT_EQ("root", object.name()); // test moved 2 ASSERT_FALSE(object[0].isRoot()); ASSERT_TRUE(object[0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0].childrenCount())); ASSERT_EQ("2", object[0].name()); ASSERT_TRUE(&object == &object[0].parent()); @@ -323,18 +323,18 @@ ASSERT_FALSE(object[1].isRoot()); ASSERT_TRUE(object[1].isLeaf()); ASSERT_EQ("1", object[1].name()); - ASSERT_EQ(0, static_cast<int>(object[1].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[1].childrenCount())); ASSERT_TRUE(&object == &object[1].parent()); // test original 1 ASSERT_TRUE(o1.isRoot()); ASSERT_TRUE(o1.isLeaf()); - ASSERT_EQ(0, static_cast<int>(o1.countChildren())); + ASSERT_EQ(0, static_cast<int>(o1.childrenCount())); // test original 2 ASSERT_TRUE(o2.isRoot()); ASSERT_TRUE(o2.isLeaf()); - ASSERT_EQ(0, static_cast<int>(o2.countChildren())); + ASSERT_EQ(0, static_cast<int>(o2.childrenCount())); } /* @@ -354,33 +354,33 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(2, static_cast<int>(object.countChildren())); + ASSERT_EQ(2, static_cast<int>(object.childrenCount())); ASSERT_EQ("root", object.name()); // test copied 2 ASSERT_FALSE(object[0].isRoot()); ASSERT_TRUE(object[0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0].childrenCount())); ASSERT_EQ("2", object[0].name()); ASSERT_TRUE(&object == &object[0].parent()); // test copied 1 ASSERT_FALSE(object[1].isRoot()); ASSERT_TRUE(object[1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[1].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[1].childrenCount())); ASSERT_EQ("1", object[1].name()); ASSERT_TRUE(&object == &object[1].parent()); // test original 1 ASSERT_TRUE(o1.isRoot()); ASSERT_TRUE(o1.isLeaf()); - ASSERT_EQ(0, static_cast<int>(o1.countChildren())); + ASSERT_EQ(0, static_cast<int>(o1.childrenCount())); ASSERT_EQ("1", o1.name()); // test original 2 ASSERT_TRUE(o2.isRoot()); ASSERT_TRUE(o2.isLeaf()); - ASSERT_EQ(0, static_cast<int>(o2.countChildren())); + ASSERT_EQ(0, static_cast<int>(o2.childrenCount())); ASSERT_EQ("2", o2.name()); } @@ -411,48 +411,48 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(2, static_cast<int>(object.countChildren())); + ASSERT_EQ(2, static_cast<int>(object.childrenCount())); ASSERT_EQ("root", object.name()); // test a ASSERT_FALSE(object[0].isRoot()); ASSERT_FALSE(object[0].isLeaf()); - ASSERT_EQ(2, static_cast<int>(object[0].countChildren())); + ASSERT_EQ(2, static_cast<int>(object[0].childrenCount())); ASSERT_EQ("a", object[0].name()); ASSERT_TRUE(&object == &object[0].parent()); // test b ASSERT_FALSE(object[1].isRoot()); ASSERT_FALSE(object[1].isLeaf()); - ASSERT_EQ(2, static_cast<int>(object[1].countChildren())); + ASSERT_EQ(2, static_cast<int>(object[1].childrenCount())); ASSERT_EQ("b", object[1].name()); ASSERT_TRUE(&object == &object[1].parent()); // test c ASSERT_FALSE(object[0][0].isRoot()); ASSERT_TRUE(object[0][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0][0].childrenCount())); ASSERT_EQ("c", object[0][0].name()); ASSERT_TRUE(&object[0] == &object[0][0].parent()); // test d ASSERT_FALSE(object[0][1].isRoot()); ASSERT_TRUE(object[0][1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0][1].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0][1].childrenCount())); ASSERT_EQ("d", object[0][1].name()); ASSERT_TRUE(&object[0] == &object[0][1].parent()); // test e ASSERT_FALSE(object[1][0].isRoot()); ASSERT_TRUE(object[1][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[1][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[1][0].childrenCount())); ASSERT_EQ("e", object[1][0].name()); ASSERT_TRUE(&object[1] == &object[1][0].parent()); // test f ASSERT_FALSE(object[1][1].isRoot()); ASSERT_TRUE(object[1][1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[1][1].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[1][1].childrenCount())); ASSERT_EQ("f", object[1][1].name()); ASSERT_TRUE(&object[1] == &object[1][1].parent()); } @@ -480,48 +480,48 @@ // test root ASSERT_TRUE(object.isRoot()); ASSERT_FALSE(object.isLeaf()); - ASSERT_EQ(2, static_cast<int>(object.countChildren())); + ASSERT_EQ(2, static_cast<int>(object.childrenCount())); ASSERT_EQ("root", object.name()); // test b ASSERT_FALSE(object[0].isRoot()); ASSERT_FALSE(object[0].isLeaf()); - ASSERT_EQ(2, static_cast<int>(object[0].countChildren())); + ASSERT_EQ(2, static_cast<int>(object[0].childrenCount())); ASSERT_EQ("b", object[0].name()); ASSERT_TRUE(&object == &object[0].parent()); // test a ASSERT_FALSE(object[1].isRoot()); ASSERT_FALSE(object[1].isLeaf()); - ASSERT_EQ(2, static_cast<int>(object[1].countChildren())); + ASSERT_EQ(2, static_cast<int>(object[1].childrenCount())); ASSERT_EQ("a", object[1].name()); ASSERT_TRUE(&object == &object[1].parent()); // test d ASSERT_FALSE(object[0][0].isRoot()); ASSERT_TRUE(object[0][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0][0].childrenCount())); ASSERT_EQ("d", object[0][0].name()); ASSERT_TRUE(&object[0] == &object[0][0].parent()); // test c ASSERT_FALSE(object[0][1].isRoot()); ASSERT_TRUE(object[0][1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[0][1].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[0][1].childrenCount())); ASSERT_EQ("c", object[0][1].name()); ASSERT_TRUE(&object[0] == &object[0][1].parent()); // test f ASSERT_FALSE(object[1][0].isRoot()); ASSERT_TRUE(object[1][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[1][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[1][0].childrenCount())); ASSERT_EQ("f", object[1][0].name()); ASSERT_TRUE(&object[1] == &object[1][0].parent()); // test e ASSERT_FALSE(object[1][1].isRoot()); ASSERT_TRUE(object[1][1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(object[1][1].countChildren())); + ASSERT_EQ(0, static_cast<int>(object[1][1].childrenCount())); ASSERT_EQ("e", object[1][1].name()); ASSERT_TRUE(&object[1] == &object[1][1].parent()); } @@ -538,12 +538,12 @@ // test root ASSERT_TRUE(root.isRoot()); ASSERT_TRUE(root.isLeaf()); - ASSERT_EQ(0, static_cast<int>(root.countChildren())); + ASSERT_EQ(0, static_cast<int>(root.childrenCount())); // test moved ASSERT_TRUE(moved.isRoot()); ASSERT_TRUE(moved.isLeaf()); - ASSERT_EQ(0, static_cast<int>(moved.countChildren())); + ASSERT_EQ(0, static_cast<int>(moved.childrenCount())); ASSERT_EQ("root", moved.name()); } @@ -562,7 +562,7 @@ Object moved(std::move(root)); ASSERT_TRUE(moved.isRoot()); - ASSERT_EQ(2, static_cast<int>(moved.countChildren())); + ASSERT_EQ(2, static_cast<int>(moved.childrenCount())); ASSERT_EQ("a", moved[0].name()); ASSERT_EQ("b", moved[1].name()); ASSERT_EQ("root", moved[0].parent().name()); @@ -596,13 +596,13 @@ // test root ASSERT_TRUE(moved.isRoot()); - ASSERT_EQ(2, static_cast<int>(moved.countChildren())); + ASSERT_EQ(2, static_cast<int>(moved.childrenCount())); // test a, b ASSERT_EQ("a", moved[0].name()); ASSERT_EQ("b", moved[1].name()); - ASSERT_EQ(2, static_cast<int>(moved[0].countChildren())); - ASSERT_EQ(2, static_cast<int>(moved[1].countChildren())); + ASSERT_EQ(2, static_cast<int>(moved[0].childrenCount())); + ASSERT_EQ(2, static_cast<int>(moved[1].childrenCount())); ASSERT_EQ("root", moved[0].parent().name()); ASSERT_EQ("root", moved[1].parent().name()); ASSERT_TRUE(&moved == &moved[0].parent()); @@ -645,13 +645,13 @@ // test root ASSERT_TRUE(root.isRoot()); ASSERT_TRUE(root.isLeaf()); - ASSERT_EQ(0, static_cast<int>(root.countChildren())); + ASSERT_EQ(0, static_cast<int>(root.childrenCount())); ASSERT_EQ("root", root.name()); // test copy ASSERT_TRUE(moved.isRoot()); ASSERT_TRUE(moved.isLeaf()); - ASSERT_EQ(0, static_cast<int>(moved.countChildren())); + ASSERT_EQ(0, static_cast<int>(moved.childrenCount())); ASSERT_EQ("root", moved.name()); } @@ -760,26 +760,26 @@ // test root ASSERT_TRUE(root.isRoot()); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("root", root.name()); // test a ASSERT_TRUE(root[0].isLeaf()); ASSERT_FALSE(root[0].isRoot()); ASSERT_EQ("a", root[0].name()); - ASSERT_EQ(0, static_cast<int>(root[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[0].childrenCount())); ASSERT_TRUE(&root == &root[0].parent()); // test b ASSERT_TRUE(root[1].isLeaf()); ASSERT_FALSE(root[1].isRoot()); - ASSERT_EQ(0, static_cast<int>(root[1].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[1].childrenCount())); ASSERT_TRUE(&root == &root[1].parent()); // test moved b ASSERT_TRUE(moved.isRoot()); ASSERT_TRUE(moved.isLeaf()); - ASSERT_EQ(0, static_cast<int>(moved.countChildren())); + ASSERT_EQ(0, static_cast<int>(moved.childrenCount())); ASSERT_EQ("b", moved.name()); } @@ -811,60 +811,60 @@ // test root ASSERT_TRUE(root.isRoot()); ASSERT_FALSE(root.isLeaf()); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("root", root.name()); // test a ASSERT_FALSE(root[0].isRoot()); ASSERT_FALSE(root[0].isLeaf()); - ASSERT_EQ(2, static_cast<int>(root[0].countChildren())); + ASSERT_EQ(2, static_cast<int>(root[0].childrenCount())); ASSERT_EQ("a", root[0].name()); ASSERT_TRUE(&root == &root[0].parent()); // test c ASSERT_FALSE(root[0][0].isRoot()); ASSERT_TRUE(root[0][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[0][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[0][0].childrenCount())); ASSERT_EQ("c", root[0][0].name()); ASSERT_TRUE(&root[0] == &root[0][0].parent()); // test d ASSERT_FALSE(root[0][1].isRoot()); ASSERT_TRUE(root[0][1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[0][1].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[0][1].childrenCount())); ASSERT_EQ("d", root[0][1].name()); ASSERT_TRUE(&root[0] == &root[0][1].parent()); // test b ASSERT_FALSE(root[1].isRoot()); ASSERT_TRUE(root[1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[1].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[1].childrenCount())); ASSERT_TRUE(&root == &root[1].parent()); // test moved b ASSERT_TRUE(moved.isRoot()); ASSERT_FALSE(moved.isLeaf()); - ASSERT_EQ(2, static_cast<int>(moved.countChildren())); + ASSERT_EQ(2, static_cast<int>(moved.childrenCount())); ASSERT_EQ("b", moved.name()); // test moved b-e ASSERT_FALSE(moved[0].isRoot()); ASSERT_TRUE(moved[0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(moved[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(moved[0].childrenCount())); ASSERT_EQ("e", moved[0].name()); ASSERT_TRUE(&moved == &moved[0].parent()); // test moved b-f ASSERT_FALSE(moved[1].isRoot()); ASSERT_FALSE(moved[1].isLeaf()); - ASSERT_EQ(1, static_cast<int>(moved[1].countChildren())); + ASSERT_EQ(1, static_cast<int>(moved[1].childrenCount())); ASSERT_EQ("f", moved[1].name()); ASSERT_TRUE(&moved == &moved[1].parent()); // test moved b-g ASSERT_FALSE(moved[1][0].isRoot()); ASSERT_TRUE(moved[1][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(moved[1][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(moved[1][0].childrenCount())); ASSERT_EQ("g", moved[1][0].name()); ASSERT_TRUE(&moved[1] == &moved[1][0].parent()); } @@ -890,27 +890,27 @@ // test root ASSERT_TRUE(root.isRoot()); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("root", root.name()); // test a ASSERT_TRUE(root[0].isLeaf()); ASSERT_FALSE(root[0].isRoot()); - ASSERT_EQ(0, static_cast<int>(root[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[0].childrenCount())); ASSERT_EQ("a", root[0].name()); ASSERT_TRUE(&root == &root[0].parent()); // test b ASSERT_TRUE(root[1].isLeaf()); ASSERT_FALSE(root[1].isRoot()); - ASSERT_EQ(0, static_cast<int>(root[1].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[1].childrenCount())); ASSERT_EQ("b", root[1].name()); ASSERT_TRUE(&root == &root[1].parent()); // test copied b ASSERT_TRUE(copy.isRoot()); ASSERT_TRUE(copy.isLeaf()); - ASSERT_EQ(0, static_cast<int>(copy.countChildren())); + ASSERT_EQ(0, static_cast<int>(copy.childrenCount())); ASSERT_EQ("b", copy.name()); } @@ -942,81 +942,81 @@ // test root ASSERT_TRUE(root.isRoot()); ASSERT_FALSE(root.isLeaf()); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("root", root.name()); // test a ASSERT_FALSE(root[0].isRoot()); ASSERT_FALSE(root[0].isLeaf()); - ASSERT_EQ(2, static_cast<int>(root[0].countChildren())); + ASSERT_EQ(2, static_cast<int>(root[0].childrenCount())); ASSERT_EQ("a", root[0].name()); ASSERT_TRUE(&root == &root[0].parent()); // test c ASSERT_FALSE(root[0][0].isRoot()); ASSERT_TRUE(root[0][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[0][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[0][0].childrenCount())); ASSERT_EQ("c", root[0][0].name()); ASSERT_TRUE(&root[0] == &root[0][0].parent()); // test d ASSERT_FALSE(root[0][1].isRoot()); ASSERT_TRUE(root[0][1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[0][1].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[0][1].childrenCount())); ASSERT_EQ("d", root[0][1].name()); ASSERT_TRUE(&root[0] == &root[0][1].parent()); // test b ASSERT_FALSE(root[1].isRoot()); ASSERT_FALSE(root[1].isLeaf()); - ASSERT_EQ(2, static_cast<int>(root[1].countChildren())); + ASSERT_EQ(2, static_cast<int>(root[1].childrenCount())); ASSERT_TRUE(&root == &root[1].parent()); // test e ASSERT_FALSE(root[1][0].isRoot()); ASSERT_TRUE(root[1][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[1][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[1][0].childrenCount())); ASSERT_EQ("e", root[1][0].name()); ASSERT_TRUE(&root[1] == &root[1][0].parent()); // test f ASSERT_FALSE(root[1][1].isRoot()); ASSERT_FALSE(root[1][1].isLeaf()); - ASSERT_EQ(1, static_cast<int>(root[1][1].countChildren())); + ASSERT_EQ(1, static_cast<int>(root[1][1].childrenCount())); ASSERT_EQ("f", root[1][1].name()); ASSERT_TRUE(&root[1] == &root[1][1].parent()); // test g ASSERT_FALSE(root[1][1][0].isRoot()); ASSERT_TRUE(root[1][1][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[1][1][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[1][1][0].childrenCount())); ASSERT_EQ("g", root[1][1][0].name()); ASSERT_TRUE(&root[1][1] == &root[1][1][0].parent()); // test copied b ASSERT_TRUE(copy.isRoot()); ASSERT_FALSE(copy.isLeaf()); - ASSERT_EQ(2, static_cast<int>(copy.countChildren())); + ASSERT_EQ(2, static_cast<int>(copy.childrenCount())); ASSERT_EQ("b", copy.name()); // test copied b-e ASSERT_FALSE(copy[0].isRoot()); ASSERT_TRUE(copy[0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(copy[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(copy[0].childrenCount())); ASSERT_EQ("e", copy[0].name()); ASSERT_TRUE(© == ©[0].parent()); // test copied b-f ASSERT_FALSE(copy[1].isRoot()); ASSERT_FALSE(copy[1].isLeaf()); - ASSERT_EQ(1, static_cast<int>(copy[1].countChildren())); + ASSERT_EQ(1, static_cast<int>(copy[1].childrenCount())); ASSERT_EQ("f", copy[1].name()); ASSERT_TRUE(© == ©[1].parent()); // test copied b-g ASSERT_FALSE(copy[1][0].isRoot()); ASSERT_TRUE(copy[1][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(copy[1][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(copy[1][0].childrenCount())); ASSERT_EQ("g", copy[1][0].name()); ASSERT_TRUE(©[1] == ©[1][0].parent()); } @@ -1038,12 +1038,12 @@ // test root ASSERT_TRUE(root.isRoot()); ASSERT_TRUE(root.isLeaf()); - ASSERT_EQ(0, static_cast<int>(root.countChildren())); + ASSERT_EQ(0, static_cast<int>(root.childrenCount())); // test moved ASSERT_TRUE(moved.isRoot()); ASSERT_TRUE(moved.isLeaf()); - ASSERT_EQ(0, static_cast<int>(moved.countChildren())); + ASSERT_EQ(0, static_cast<int>(moved.childrenCount())); ASSERT_EQ("root", moved.name()); } @@ -1080,48 +1080,48 @@ // test root ASSERT_TRUE(root.isRoot()); ASSERT_FALSE(root.isLeaf()); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("root", root.name()); // test a ASSERT_FALSE(root[0].isRoot()); ASSERT_FALSE(root[0].isLeaf()); - ASSERT_EQ(2, static_cast<int>(root[0].countChildren())); + ASSERT_EQ(2, static_cast<int>(root[0].childrenCount())); ASSERT_EQ("a", root[0].name()); ASSERT_TRUE(&root == &root[0].parent()); // test c ASSERT_FALSE(root[0][0].isRoot()); ASSERT_TRUE(root[0][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[0][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[0][0].childrenCount())); ASSERT_EQ("c", root[0][0].name()); ASSERT_TRUE(&root[0] == &root[0][0].parent()); // test copied x to b ASSERT_FALSE(root[1].isRoot()); ASSERT_FALSE(root[1].isLeaf()); - ASSERT_EQ(2, static_cast<int>(root[1].countChildren())); + ASSERT_EQ(2, static_cast<int>(root[1].childrenCount())); ASSERT_EQ("x", root[1].name()); ASSERT_TRUE(&root == &root[1].parent()); // test y ASSERT_FALSE(root[1][0].isRoot()); ASSERT_TRUE(root[1][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[1][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[1][0].childrenCount())); ASSERT_EQ("y", root[1][0].name()); ASSERT_TRUE(&root[1] == &root[1][0].parent()); // test z ASSERT_FALSE(root[1][1].isRoot()); ASSERT_TRUE(root[1][1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[1][1].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[1][1].childrenCount())); ASSERT_EQ("z", root[1][1].name()); ASSERT_TRUE(&root[1] == &root[1][1].parent()); // test moved ASSERT_TRUE(moved.isRoot()); ASSERT_TRUE(moved.isLeaf()); - ASSERT_EQ(0, static_cast<int>(moved.countChildren())); + ASSERT_EQ(0, static_cast<int>(moved.childrenCount())); } /* -------------------------------------------------------- @@ -1141,13 +1141,13 @@ // test root ASSERT_TRUE(root.isRoot()); ASSERT_TRUE(root.isLeaf()); - ASSERT_EQ(0, static_cast<int>(root.countChildren())); + ASSERT_EQ(0, static_cast<int>(root.childrenCount())); ASSERT_EQ("root", root.name()); // test copied ASSERT_TRUE(copy.isRoot()); ASSERT_TRUE(copy.isLeaf()); - ASSERT_EQ(0, static_cast<int>(copy.countChildren())); + ASSERT_EQ(0, static_cast<int>(copy.childrenCount())); ASSERT_EQ("root", copy.name()); } @@ -1184,66 +1184,132 @@ // test root ASSERT_TRUE(root.isRoot()); ASSERT_FALSE(root.isLeaf()); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("root", root.name()); // test a ASSERT_FALSE(root[0].isRoot()); ASSERT_FALSE(root[0].isLeaf()); - ASSERT_EQ(2, static_cast<int>(root[0].countChildren())); + ASSERT_EQ(2, static_cast<int>(root[0].childrenCount())); ASSERT_EQ("a", root[0].name()); ASSERT_TRUE(&root == &root[0].parent()); // test c ASSERT_FALSE(root[0][0].isRoot()); ASSERT_TRUE(root[0][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[0][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[0][0].childrenCount())); ASSERT_EQ("c", root[0][0].name()); ASSERT_TRUE(&root[0] == &root[0][0].parent()); // test copied x to b ASSERT_FALSE(root[1].isRoot()); ASSERT_FALSE(root[1].isLeaf()); - ASSERT_EQ(2, static_cast<int>(root[1].countChildren())); + ASSERT_EQ(2, static_cast<int>(root[1].childrenCount())); ASSERT_EQ("x", root[1].name()); ASSERT_TRUE(&root == &root[1].parent()); // test y ASSERT_FALSE(root[1][0].isRoot()); ASSERT_TRUE(root[1][0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[1][0].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[1][0].childrenCount())); ASSERT_EQ("y", root[1][0].name()); ASSERT_TRUE(&root[1] == &root[1][0].parent()); // test z ASSERT_FALSE(root[1][1].isRoot()); ASSERT_TRUE(root[1][1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(root[1][1].countChildren())); + ASSERT_EQ(0, static_cast<int>(root[1][1].childrenCount())); ASSERT_EQ("z", root[1][1].name()); ASSERT_TRUE(&root[1] == &root[1][1].parent()); // test original x ASSERT_TRUE(copy.isRoot()); ASSERT_FALSE(copy.isLeaf()); - ASSERT_EQ(2, static_cast<int>(copy.countChildren())); + ASSERT_EQ(2, static_cast<int>(copy.childrenCount())); ASSERT_EQ("x", copy.name()); // test original y ASSERT_FALSE(copy[0].isRoot()); ASSERT_TRUE(copy[0].isLeaf()); - ASSERT_EQ(0, static_cast<int>(copy[0].countChildren())); + ASSERT_EQ(0, static_cast<int>(copy[0].childrenCount())); ASSERT_EQ("y", copy[0].name()); ASSERT_TRUE(© == ©[0].parent()); // test original z ASSERT_FALSE(copy[1].isRoot()); ASSERT_TRUE(copy[1].isLeaf()); - ASSERT_EQ(0, static_cast<int>(copy[1].countChildren())); + ASSERT_EQ(0, static_cast<int>(copy[1].childrenCount())); ASSERT_EQ("z", copy[1].name()); ASSERT_TRUE(© == ©[1].parent()); } /* -------------------------------------------------------- + * Item insertions + * -------------------------------------------------------- */ + +TEST(ItemInsert, push) +{ + Object root("root"); + + root.pushItem(std::make_unique<TreeNodeItemProxy<Object>>("a")); + root.pushItem(std::make_unique<TreeNodeItemProxy<Object>>("b")); + + ASSERT_EQ(2U, root.childrenCount()); + ASSERT_EQ("b", root[0].name()); + ASSERT_EQ("a", root[1].name()); +} + +TEST(ItemInsert, append) +{ + Object root("root"); + + root.appendItem(std::make_unique<TreeNodeItemProxy<Object>>("a")); + root.appendItem(std::make_unique<TreeNodeItemProxy<Object>>("b")); + + ASSERT_EQ(2U, root.childrenCount()); + ASSERT_EQ("a", root[0].name()); + ASSERT_EQ("b", root[1].name()); +} + +/* -------------------------------------------------------- + * Item inspection + * -------------------------------------------------------- */ + +TEST(ItemInspection, ref) +{ + Object root("root"); + + root.append(Object("a")); + root.append(Object("b")); + root.append(Object("c")); + + // We only ref it, so it must be kept + std::unique_ptr<TreeNodeItem<Object>> &item = root.itemAt(0); + ASSERT_EQ("a", item->value().name()); + + // It should be empty + std::unique_ptr<TreeNodeItem<Object>> &item2 = root.itemAt(0); + ASSERT_EQ("a", item2->value().name()); +} + +TEST(ItemInspection, take) +{ + Object root("root"); + + root.append(Object("a")); + root.append(Object("b")); + root.append(Object("c")); + + // We take the unique_ptr, it is moved + std::unique_ptr<TreeNodeItem<Object>> item = std::move(root.itemAt(0)); + ASSERT_EQ("a", item->value().name()); + + // It should be empty + std::unique_ptr<TreeNodeItem<Object>> &item2 = root.itemAt(0); + ASSERT_TRUE(item2 == nullptr); +} + +/* -------------------------------------------------------- * Remove functions * -------------------------------------------------------- */ @@ -1256,7 +1322,7 @@ root.append(Object("c")); root.clear(); - ASSERT_EQ(0, static_cast<int>(root.countChildren())); + ASSERT_EQ(0, static_cast<int>(root.childrenCount())); } TEST(Remove, index) @@ -1268,7 +1334,7 @@ root.append(Object("c")); root.remove(2); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("a", root[0].name()); ASSERT_EQ("b", root[1].name()); } @@ -1282,7 +1348,7 @@ root.append(Object("c")); root.remove(root[2]); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("a", root[0].name()); ASSERT_EQ("b", root[1].name()); } @@ -1296,7 +1362,7 @@ root.append(Object("c")); root.removeSame(Object("c")); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("a", root[0].name()); ASSERT_EQ("b", root[1].name()); } @@ -1361,7 +1427,7 @@ ASSERT_TRUE(root.isRoot()); ASSERT_FALSE(root.isLeaf()); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("b", root[0].name()); ASSERT_EQ("a", root[1].name()); } @@ -1375,7 +1441,7 @@ ASSERT_TRUE(root.isRoot()); ASSERT_FALSE(root.isLeaf()); - ASSERT_EQ(2, static_cast<int>(root.countChildren())); + ASSERT_EQ(2, static_cast<int>(root.childrenCount())); ASSERT_EQ("a", root[0].name()); ASSERT_EQ("b", root[1].name()); } @@ -1510,8 +1576,8 @@ FAIL() << ex.what(); } - ASSERT_EQ(0U, root[1].countChildren()); - ASSERT_EQ(1U, root[0].countChildren()); + ASSERT_EQ(0U, root[1].childrenCount()); + ASSERT_EQ(1U, root[0].childrenCount()); ASSERT_EQ("d", root[0][0].name()); ASSERT_TRUE(&root[0][0].parent() == &root[0]); }