1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  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 indexT* node)
 36     {
 37         if (index >= static_cast<int>(nodes.size()))
 38         {
 39             Add(node);
 40         }
 41         else
 42         {
 43             nodes.insert(nodes.begin() + indexstd::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() + pnodes.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 } } // namespace sngcm::ast
105 
106 #endif // SNGCM_AST_NODE_LIST_INCLUDED