-
Notifications
You must be signed in to change notification settings - Fork 1
/
treemodelitem.h
83 lines (63 loc) · 2.32 KB
/
treemodelitem.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#ifndef TREEMODELITEM_H
#define TREEMODELITEM_H
#include <ObserverPointer>
#include <memory>
#include <vector>
template <typename T>
class TreeModelItem
{
public:
using Derived = T;
using Base = TreeModelItem<T>;
using ItemPointer = ObserverPointer<Derived>;
using ItemHolder = std::unique_ptr<Derived>;
TreeModelItem() noexcept = default;
TreeModelItem(const TreeModelItem &) = delete;
TreeModelItem(TreeModelItem &&) noexcept = default;
~TreeModelItem() = default;
TreeModelItem &operator=(const TreeModelItem &) = delete;
TreeModelItem &operator=(TreeModelItem &&) noexcept = default;
ItemPointer createChild(qsizetype row = -1)
{
row = row == - 1 ? childCount() : row;
insert(row, std::make_unique<Derived>());
return child(row);
}
ItemPointer parent() const noexcept { return m_parent; }
qsizetype row() const noexcept
{
if (!m_parent)
return -1;
const auto pred = [this](const ItemHolder &p) { return this == p.get(); };
const auto it = std::find_if(m_parent->m_children.begin(), m_parent->m_children.end(), pred);
return {it - m_parent->m_children.begin()};
}
std::vector<ItemHolder> &children() noexcept { return m_children; }
const std::vector<ItemHolder> &children() const noexcept { return m_children; }
ItemPointer child(qsizetype row) const noexcept
{
return ItemPointer(m_children[size_t(row)].get());
}
qsizetype childCount() const noexcept { return qsizetype(m_children.size()); }
void append(ItemHolder item) { insert(childCount(), std::move(item)); }
void insert(qsizetype row, ItemHolder item)
{
Q_ASSERT(row >= 0 && row <= childCount());
item->m_parent = ItemPointer(static_cast<Derived *>(this));
m_children.insert(m_children.begin() + row, std::move(item));
}
[[nodiscard]] ItemHolder take(qsizetype row) noexcept
{
Q_ASSERT(row >= 0 && row < childCount());
ItemHolder result;
std::swap(result, m_children[row]);
result->m_parent = nullptr;
m_children.erase(m_children.begin() + row);
return result;
}
void remove(qsizetype row) noexcept { (void)take(row); }
private:
ItemPointer m_parent;
std::vector<ItemHolder> m_children;
};
#endif // TREEMODELITEM_H