Mercurial > code
annotate C++/TreeNode.h @ 253:a4770082e7d6
TreeNode: forget to return this
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 02 Oct 2014 11:45:24 +0200 |
parents | 19bfc11f77c2 |
children | 812dd806f803 |
rev | line source |
---|---|
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * TreeNode.h -- C++11 pointer-free N-ary tree |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
19 #ifndef _TREE_NODE_H_ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
20 #define _TREE_NODE_H_ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
21 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
22 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
23 * @file TreeNode.h |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 * @brief N-ary tree without pointers |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 */ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 |
251 | 27 #include <deque> |
28 #include <memory> | |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
29 #include <stdexcept> |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
30 |
251 | 31 namespace { |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
32 |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
33 /** |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
34 * @class TypeTraits |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
35 * @brief Some checks on the type |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
36 * |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
37 * Provides the following members depending on the type: |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
38 * |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
39 * equalityComparable - If == comparison can be performed |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
40 */ |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
41 template <typename T> |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
42 class TypeTraits { |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
43 private: |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
44 /** |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
45 * @class HasEqualsTo |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
46 * @brief Check if the type is comparable |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
47 * |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
48 * Sets to true if the type T can is equality comparable. |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
49 */ |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
50 template <typename U> |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
51 class HasEqualsTo { |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
52 public: |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
53 static_assert(sizeof (char) != sizeof (long), "buy a new compiler"); |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
54 |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
55 template <typename Value> |
251 | 56 static constexpr auto check(Value *u) -> decltype(*u == *u, char(0)); |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
57 |
251 | 58 static constexpr long check(...); |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
59 |
251 | 60 static constexpr const bool value = sizeof (check((U *)0)) == sizeof (char); |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
61 }; |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
62 |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
63 public: |
251 | 64 static constexpr const bool equalityComparable = HasEqualsTo<T>::value; |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
65 }; |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
66 |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
67 } // !namespace |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
68 |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
69 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 * @class TreeNode |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
71 * @brief Safe C++11 N-ary tree |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
72 * |
251 | 73 * This class use a std::deque as the container, it allocate object on the heap to avoid useless |
74 * copy and move when adding new elements. | |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
75 */ |
251 | 76 template <typename T> |
77 class TreeNode { | |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 private: |
251 | 79 using Container = std::deque<std::unique_ptr<T>>; |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
80 |
251 | 81 TreeNode *m_parent { nullptr }; |
82 Container m_children; | |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
83 |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
84 public: |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
85 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
86 * Default constructor. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
87 */ |
251 | 88 TreeNode() = default; |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 * Copy constructor. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 * @param other the other node |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 */ |
251 | 95 TreeNode(const TreeNode &other) |
252
19bfc11f77c2
TreeNode: resurrect indexOf
David Demelier <markand@malikania.fr>
parents:
251
diff
changeset
|
96 : m_parent(nullptr) |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
97 { |
251 | 98 for (const auto &c : other.m_children) { |
99 m_children.push_back(std::make_unique<T>(*c)); | |
100 m_children.back()->m_parent = this; | |
101 } | |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
102 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
103 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
104 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 * Move constructor. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
106 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
107 * @param other the other node |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
108 */ |
251 | 109 TreeNode(TreeNode &&other) |
252
19bfc11f77c2
TreeNode: resurrect indexOf
David Demelier <markand@malikania.fr>
parents:
251
diff
changeset
|
110 : m_parent(nullptr) |
19bfc11f77c2
TreeNode: resurrect indexOf
David Demelier <markand@malikania.fr>
parents:
251
diff
changeset
|
111 , m_children(std::move(other.m_children)) |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
112 { |
251 | 113 // Update children to update to *this |
114 for (auto &c : m_children) | |
115 c->m_parent = this; | |
116 | |
117 other.m_children.clear(); | |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
118 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
119 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
120 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
121 * Copy assignment operator. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
122 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
123 * @param other the other node |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
124 */ |
251 | 125 TreeNode &operator=(const TreeNode &other) |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
126 { |
251 | 127 m_children.clear(); |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
128 |
251 | 129 for (const auto &c : other.m_children) { |
130 m_children.push_back(std::make_unique<T>(*c)); | |
131 m_children.back()->m_parent = this; | |
132 } | |
253
a4770082e7d6
TreeNode: forget to return this
David Demelier <markand@malikania.fr>
parents:
252
diff
changeset
|
133 |
a4770082e7d6
TreeNode: forget to return this
David Demelier <markand@malikania.fr>
parents:
252
diff
changeset
|
134 return *this; |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
135 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
136 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
137 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
138 * Move assignment operator. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
139 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
140 * @param other the other node |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
141 */ |
251 | 142 TreeNode &operator=(TreeNode &&other) |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
143 { |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
144 m_children = std::move(other.m_children); |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
145 |
251 | 146 // Update children to update to *this |
147 for (auto &c : m_children) | |
148 c->m_parent = this; | |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
149 |
251 | 150 other.m_children.clear(); |
253
a4770082e7d6
TreeNode: forget to return this
David Demelier <markand@malikania.fr>
parents:
252
diff
changeset
|
151 |
a4770082e7d6
TreeNode: forget to return this
David Demelier <markand@malikania.fr>
parents:
252
diff
changeset
|
152 return *this; |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
153 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
154 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
155 /** |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
156 * Add a child node to the beginning. |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
157 * |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
158 * @param child the children |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
159 */ |
251 | 160 void push(const T &child) |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
161 { |
251 | 162 m_children.push_front(std::make_unique<T>(child)); |
163 m_children.front()->m_parent = this; | |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
164 } |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
165 |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
166 /** |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
167 * Move to the beginning. |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
168 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
169 * @param child the children |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
170 */ |
251 | 171 void push(T &&child) |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
172 { |
251 | 173 m_children.push_front(std::make_unique<T>(std::move(child))); |
174 m_children.front()->m_parent = this; | |
175 } | |
176 | |
177 /** | |
178 * Construct an element at the beginning in place. | |
179 * | |
180 * @param args the arguments | |
181 */ | |
182 template <typename... Args> | |
183 void pushNew(Args&&... args) | |
184 { | |
185 m_children.emplace_front(std::make_unique<T>(std::forward<Args>(args)...)); | |
186 m_children.front()->m_parent = this; | |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
187 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
188 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
189 /** |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
190 * Add a child node to the end |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
191 * |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
192 * @param child the children |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
193 */ |
251 | 194 void append(const T &child) |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
195 { |
251 | 196 m_children.push_back(std::make_unique<T>(child)); |
197 m_children.back()->m_parent = this; | |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
198 } |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
199 |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
200 /** |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
201 * Move a child node to the end |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
202 * |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
203 * @param child the children |
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
204 */ |
251 | 205 void append(T &&child) |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
206 { |
251 | 207 m_children.push_back(std::make_unique<T>(std::move(child))); |
208 m_children.back()->m_parent = this; | |
209 } | |
210 | |
211 /** | |
212 * Construct an element at the end in place. | |
213 * | |
214 * @param args the arguments | |
215 */ | |
216 template <typename... Args> | |
217 void appendNew(Args&&... args) | |
218 { | |
219 m_children.emplace_back(std::make_unique<T>(std::forward<Args>(args)...)); | |
220 m_children.back()->m_parent = this; | |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
221 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
222 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
223 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
224 * Count the number of children in this node. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
225 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
226 * @return the number of children |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
227 */ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
228 unsigned countChildren() const |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
229 { |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
230 return static_cast<unsigned>(m_children.size()); |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
231 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
232 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
233 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
234 * Get the parent node. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
235 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
236 * @return the parent node |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
237 * @throw std::out_of_range if there is no parent |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
238 */ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
239 T &parent() |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
240 { |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
241 if (!m_parent) |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
242 throw std::out_of_range("no parent"); |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
243 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
244 return static_cast<T &>(*m_parent); |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
245 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
246 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
247 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
248 * Get the parent node. |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
249 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
250 * @return the parent node |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
251 * @throw std::out_of_range if there is no parent |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
252 */ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
253 const T &parent() const |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
254 { |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
255 if (!m_parent) |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
256 throw std::out_of_range("no parent"); |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
257 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
258 return static_cast<const T &>(*m_parent); |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
259 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
260 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
261 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
262 * Check if the node is root (no parent). |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
263 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
264 * @return true if root |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
265 */ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
266 bool isRoot() const |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
267 { |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
268 return m_parent == nullptr; |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
269 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
270 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
271 /** |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
272 * Check if the node is leaf (no children). |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
273 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
274 * @return true if leaf |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
275 */ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
276 bool isLeaf() const |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
277 { |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
278 return m_children.size() == 0; |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
279 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
280 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
281 /** |
251 | 282 * Find a child in this. The type must have operator==. |
234
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
283 * |
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
284 * @param child the child |
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
285 * @return the index or -1 if not found |
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
286 */ |
235
0e3ccc204bc2
TreeNode: be more flexible
David Demelier <markand@malikania.fr>
parents:
234
diff
changeset
|
287 template <typename Value> |
251 | 288 int indexOf(const Value &child, typename std::enable_if<TypeTraits<Value>::equalityComparable>::type * = nullptr) const |
234
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
289 { |
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
290 for (int i = 0; i < (int)m_children.size(); ++i) |
252
19bfc11f77c2
TreeNode: resurrect indexOf
David Demelier <markand@malikania.fr>
parents:
251
diff
changeset
|
291 if (*m_children[i] == child) |
234
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
292 return i; |
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
293 |
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
294 return -1; |
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
295 } |
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
296 |
99f8b9aedfb3
TreeNode: add child index to search a children
David Demelier <markand@malikania.fr>
parents:
233
diff
changeset
|
297 /** |
251 | 298 * Access a child. |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
299 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
300 * @param index the index |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
301 * @return the reference to the children node |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
302 * @throw std::out_of_range on out of bounds |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
303 */ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
304 T &operator[](int index) |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
305 { |
251 | 306 return static_cast<T &>(*m_children.at(index)); |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
307 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
308 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
309 /** |
251 | 310 * Access a child. |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
311 * |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
312 * @param index the index |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
313 * @return the reference to the children node |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
314 * @throw std::out_of_range on out of bounds |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
315 */ |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
316 const T &operator[](int index) const |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
317 { |
251 | 318 return static_cast<const T &>(*m_children.at(index)); |
233
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
319 } |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
320 }; |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
321 |
29eb8748b686
Add TreeNode, a N-ary tree implementation without pointers
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
322 #endif // !_TREE_NODE_H_ |