2 #include <score/tools/Debug.hpp>
4 #include <ossia/detail/algorithms.hpp>
5 #include <ossia/detail/ssize.hpp>
18 auto& child_at(
const std::list<T>& list,
int index)
20 SCORE_ASSERT(index >= 0 && index < std::ssize(list));
21 auto it = list.begin();
22 std::advance(it, index);
27 auto& child_at(std::list<T>& list,
int index)
29 SCORE_ASSERT(index >= 0 && index < std::ssize(list));
30 auto it = list.begin();
31 std::advance(it, index);
36 int index_of_child(
const std::list<T>& list,
const T* child)
39 const auto end = list.end();
40 for(
auto it = list.begin(); it != end; ++it)
50 template <
typename DataType>
55 std::list<TreeNode> m_children;
56 using impl_type = std::list<TreeNode>;
59 using iterator =
typename impl_type::iterator;
60 using const_iterator =
typename impl_type::const_iterator;
62 auto begin() noexcept {
return m_children.begin(); }
63 auto begin()
const noexcept {
return cbegin(); }
64 auto cbegin()
const noexcept {
return m_children.cbegin(); }
66 auto end() noexcept {
return m_children.end(); }
67 auto end()
const noexcept {
return cend(); }
68 auto cend()
const noexcept {
return m_children.cend(); }
74 : DataType(
static_cast<const DataType&
>(other))
75 , m_parent{other.m_parent}
76 , m_children(other.m_children)
78 for(
auto& child : m_children)
79 child.setParent(
this);
83 : DataType(std::move(
static_cast<DataType&&
>(other)))
84 , m_parent{other.m_parent}
85 , m_children(std::move(other.m_children))
87 for(
auto& child : m_children)
88 child.setParent(
this);
93 static_cast<DataType&
>(*this) =
static_cast<const DataType&
>(source);
94 m_parent = source.m_parent;
96 m_children = source.m_children;
97 for(
auto& child : m_children)
99 child.setParent(
this);
107 static_cast<DataType&
>(*this) =
static_cast<DataType&&
>(source);
108 m_parent = source.m_parent;
110 m_children = std::move(source.m_children);
111 for(
auto& child : m_children)
113 child.setParent(
this);
120 : DataType(std::move(data))
132 void push_back(
const TreeNode& child) noexcept
134 m_children.push_back(child);
136 auto& cld = m_children.back();
140 void push_back(
TreeNode&& child) noexcept
142 m_children.push_back(std::move(child));
144 auto& cld = m_children.back();
148 template <
typename... Args>
149 auto& emplace_back(Args&&... args) noexcept
151 m_children.emplace_back(std::forward<Args>(args)...);
153 auto& cld = m_children.back();
158 template <
typename... Args>
159 auto& insert(Args&&... args) noexcept
161 auto& n = *m_children.insert(std::forward<Args>(args)...);
166 template <
typename... Args>
167 auto& emplace(Args&&... args) noexcept
169 auto& n = *m_children.emplace(std::forward<Args>(args)...);
174 TreeNode* parent()
const noexcept {
return m_parent; }
176 bool hasChild(std::size_t index)
const noexcept {
return m_children.size() > index; }
178 TreeNode& childAt(
int index) noexcept {
return child_at(m_children, index); }
180 const TreeNode& childAt(
int index)
const noexcept
182 return child_at(m_children, index);
186 int indexOfChild(
const TreeNode* child)
const noexcept
188 return index_of_child(m_children, child);
191 auto iterOfChild(
const TreeNode* child) noexcept
193 const auto end = m_children.end();
194 for(
auto it = m_children.begin(); it != end; ++it)
202 int childCount()
const noexcept {
return m_children.size(); }
204 bool hasChildren()
const noexcept {
return !m_children.empty(); }
206 const auto& children()
const noexcept {
return m_children; }
208 auto takeChildren() noexcept
210 auto cld = std::move(m_children);
213 for(
auto& child : cld)
214 child.setParent(
nullptr);
219 void moveChildren(
TreeNode& newParent) noexcept
221 auto cld = std::move(m_children);
227 newParent.push_back(std::move(child));
231 void reserve(std::size_t s) noexcept
235 void resize(std::size_t s) noexcept { m_children.resize(s); }
237 auto erase(const_iterator it) noexcept {
return m_children.erase(it); }
239 auto erase(const_iterator it_beg, const_iterator it_end) noexcept
241 return m_children.erase(it_beg, it_end);
244 void setParent(
TreeNode* parent) noexcept { m_parent = parent; }
246 template <
typename Fun>
247 void visit(Fun f)
const noexcept(noexcept(f(std::declval<TreeNode>())))
251 for(
const auto& child : m_children)
259 template <
typename Node_T>
260 bool isAncestor(
const Node_T& gramps,
const Node_T* node) noexcept
262 auto parent = node->parent();
269 return isAncestor(gramps, parent);
293 template <
typename Node_T>
294 std::vector<Node_T*> filterUniqueParents(std::vector<Node_T*>& nodes) noexcept
296 std::vector<Node_T*> cleaned_nodes;
298 ossia::remove_duplicates(nodes);
300 cleaned_nodes.reserve(nodes.size());
306 if(ossia::any_of(nodes, [&](Node_T* other) {
309 return isAncestor(*other, n);
316 cleaned_nodes.push_back(n);
320 return cleaned_nodes;
Definition: TreeNode.hpp:52