1
2
3
4
5
6 #ifndef SNGCM_AST_NODE_LIST_INCLUDED
7 #define SNGCM_AST_NODE_LIST_INCLUDED
8 #include <sngcm/ast/AstWriter.hpp>
9 #include <sngcm/ast/AstReader.hpp>
10 #include <vector>
11 #include <memory>
12
13 namespace sngcm { namespace ast {
14
15 template<typename T>
16 class NodeList
17 {
18 public:
19 int Count() const
20 {
21 return static_cast<int>(nodes.size());
22 }
23 T* operator[](int index) const
24 {
25 return nodes[index].get();
26 }
27 void Add(T* node)
28 {
29 nodes.push_back(std::unique_ptr<T>(node));
30 }
31 T* Release(int index)
32 {
33 return nodes[index].release();
34 }
35 void Insert(int index, T* node)
36 {
37 if (index >= static_cast<int>(nodes.size()))
38 {
39 Add(node);
40 }
41 else
42 {
43 nodes.insert(nodes.begin() + index, std::unique_ptr<T>(node));
44 }
45 }
46 void Clear()
47 {
48 nodes.clear();
49 }
50 void RemoveEmpty()
51 {
52 int p = 0;
53 int n = static_cast<int>(nodes.size());
54 for (int i = 0; i < n; ++i)
55 {
56 if (nodes[i])
57 {
58 if (p != i)
59 {
60 nodes[p].reset(nodes[i].release());
61 }
62 ++p;
63 }
64 }
65 if (p != n)
66 {
67 nodes.erase(nodes.begin() + p, nodes.end());
68 }
69 }
70 void SetParent(Node* parent)
71 {
72 for (const std::std::unique_ptr<T>&node : nodes)
73 {
74 node->SetParent(parent);
75 }
76 }
77 void Write(AstWriter& writer)
78 {
79 uint32_t n = static_cast<uint32_t>(nodes.size());
80 writer.GetBinaryWriter().WriteULEB128UInt(n);
81 for (uint32_t i = 0u; i < n; ++i)
82 {
83 writer.Write(nodes[i].get());
84 }
85 }
86 void Read(AstReader& reader)
87 {
88 uint32_t n = reader.GetBinaryReader().ReadULEB128UInt();
89 for (uint32_t i = 0u; i < n; ++i)
90 {
91 Node* node = reader.ReadNode();
92 T* asTPtrNode = dynamic_cast<T*>(node);
93 Assert(asTPtrNode, "wrong node type");
94 nodes.push_back(std::unique_ptr<T>(asTPtrNode));
95 }
96 }
97 std::std::vector<std::std::unique_ptr<T>>&Nodes(){returnnodes;}
98 std::std::vector<std::std::unique_ptr<T>>Content(){returnstd::move(nodes);}
99 void SetContent(std::std::vector<std::std::unique_ptr<T>>&&content){nodes = std::move(content);}
100 private:
101 std::vector<std::std::unique_ptr<T>>nodes;
102 };
103
104 } }
105
106 #endif // SNGCM_AST_NODE_LIST_INCLUDED