1/*
2 * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved.
3
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#ifndef _TVG_ARRAY_H_
24#define _TVG_ARRAY_H_
25
26#include <memory.h>
27
28namespace tvg
29{
30
31template<class T>
32struct Array
33{
34 T* data = nullptr;
35 uint32_t count = 0;
36 uint32_t reserved = 0;
37
38 Array(){}
39
40 Array(const Array& rhs)
41 {
42 reset();
43 *this = rhs;
44 }
45
46 void push(T element)
47 {
48 if (count + 1 > reserved) {
49 reserved = count + (count + 2) / 2;
50 data = static_cast<T*>(realloc(data, sizeof(T) * reserved));
51 }
52 data[count++] = element;
53 }
54
55 void push(Array<T>& rhs)
56 {
57 grow(rhs.count);
58 memcpy(data + count, rhs.data, rhs.count * sizeof(T));
59 count += rhs.count;
60 }
61
62 bool reserve(uint32_t size)
63 {
64 if (size > reserved) {
65 reserved = size;
66 data = static_cast<T*>(realloc(data, sizeof(T) * reserved));
67 }
68 return true;
69 }
70
71 bool grow(uint32_t size)
72 {
73 return reserve(count + size);
74 }
75
76 T* end() const
77 {
78 return data + count;
79 }
80
81 T& last()
82 {
83 return data[count - 1];
84 }
85
86 T& first()
87 {
88 return data[0];
89 }
90
91 void pop()
92 {
93 if (count > 0) --count;
94 }
95
96 void reset()
97 {
98 free(data);
99 data = nullptr;
100 count = reserved = 0;
101 }
102
103 void clear()
104 {
105 count = 0;
106 }
107
108 bool empty() const
109 {
110 return count == 0;
111 }
112
113 void operator=(const Array& rhs)
114 {
115 reserve(rhs.count);
116 if (rhs.count > 0) memcpy(data, rhs.data, sizeof(T) * rhs.count);
117 count = rhs.count;
118 }
119
120 ~Array()
121 {
122 free(data);
123 }
124};
125
126}
127
128#endif //_TVG_ARRAY_H_
129