Branch data Line data Source code
1 : : #pragma once
2 : :
3 : : #include "std-includes.h"
4 : :
5 : : //Note: T must be a pointer type, or stuff will screw up. To make a pointer last longer than this object, assign nullptr to it and it won't free the old one.
6 : : template<typename T> class autoptr {
7 : : T ptr;
8 : : public:
9 : : operator T() const
10 : : {
11 : 354 : return ptr;
12 : : }
13 : :
14 : : autoptr& operator=(T ptr_)
15 : : {
16 : 84 : ptr = ptr_;
17 : 69 : return *this;
18 : : }
19 : :
20 : 123 : autoptr()
21 : : {
22 : 123 : ptr = nullptr;
23 : : }
24 : :
25 : 988279 : autoptr(T ptr_)
26 : : {
27 : 985429 : ptr = ptr_;
28 : : }
29 : :
30 : : autoptr(const autoptr<T>& ptr_)
31 : : {
32 : : ptr = ptr_.ptr;
33 : : }
34 : :
35 : 988447 : ~autoptr()
36 : : {
37 [ + + ]: 988447 : if (ptr) free((void*)ptr);
38 : 988447 : }
39 : : };
40 : :
41 : : template<typename T> class autoarray {
42 : : public:
43 : : int count;
44 : :
45 : : private:
46 : : T* ptr;
47 : : int bufferlen;
48 : :
49 : : T dummy;
50 : : static const int default_size = 128;
51 : :
52 : 0 : const T& getconst(int id) const
53 : : {
54 [ # # ]: 0 : if (id < 0) return dummy;
55 [ # # ]: 0 : if (id >= count) return dummy;
56 : 0 : return ptr[id];
57 : : }
58 : :
59 : 1035668 : T& get(int id)
60 : : {
61 [ - + ]: 1035668 : if (id < 0) return dummy;
62 [ + + ]: 1035668 : if (id >= bufferlen - 4)
63 : : {
64 : 22 : resize(id);
65 : : }
66 [ + + ]: 1035668 : if (id >= count)
67 : : {
68 [ + + ]: 77352 : for (int i = count;i <= id;i++) new(ptr + i) T();
69 : 38658 : count = id + 1;
70 : : }
71 : 1035668 : return ptr[id];
72 : : }
73 : :
74 : 22 : void resize(int size)
75 : : {
76 : 22 : int oldlen = count;
77 [ + + ]: 44 : while (bufferlen <= size + 4) bufferlen *= 2;
78 : 22 : T *old = ptr;
79 : 22 : ptr = (T*)malloc(sizeof(T)*(size_t)bufferlen);
80 [ + + ]: 67662 : for(int i = 0; i < oldlen; i++){
81 : 67640 : new(ptr + i) T();
82 : 67640 : ptr[i] = static_cast<T &&>(old[i]);
83 : : }
84 : 22 : free(old);
85 : 22 : memset(ptr + oldlen, 0, (size_t)(bufferlen - oldlen) * sizeof(T));
86 : 22 : }
87 : :
88 : : public:
89 : :
90 : 3384 : void reset(int keep = 0)
91 : : {
92 [ + + ]: 3384 : if (keep >= count) return;
93 [ + + ]: 753 : for (int i = keep;i < count;i++) ptr[i].~T();
94 : 339 : memset(ptr + keep, 0, (size_t)(count - keep) * sizeof(T));
95 [ + - ]: 339 : if (keep < bufferlen / 2)
96 : : {
97 [ + - + + ]: 924 : while (keep < bufferlen / 2 && bufferlen>8) bufferlen /= 2;
98 : 339 : T *old = ptr;
99 : 339 : ptr = (T*)malloc(sizeof(T)*(size_t)bufferlen);
100 [ + + ]: 342 : for(int i = 0; i < keep; i++){
101 : 3 : new(ptr + i) T();
102 : 3 : ptr[i] = static_cast<T &&>(old[i]);
103 : : }
104 : 339 : free(old);
105 : :
106 : : }
107 : 339 : count = keep;
108 : : }
109 : :
110 : : T& operator[](int id)
111 : : {
112 : 996841 : return get(id);
113 : : }
114 : :
115 : : const T& operator[](int id) const
116 : : {
117 : 0 : return getconst(id);
118 : : }
119 : :
120 : : operator T*()
121 : : {
122 : : return ptr;
123 : : }
124 : :
125 : : operator const T*() const
126 : : {
127 : : return ptr;
128 : : }
129 : :
130 : 38037 : T& append(const T& item)
131 : : {
132 : 38037 : return (get(count) = item);
133 : : }
134 : :
135 : : //insert is not safe for non pod types!!!
136 : : void insert(int pos)
137 : : {
138 : : if (pos<0 || pos>count) return;
139 : : if (count >= bufferlen - 4)
140 : : {
141 : : resize(count);
142 : : }
143 : : memmove(ptr + pos + 1, ptr + pos, sizeof(T)*(count - pos));
144 : : memset(ptr + pos, 0, sizeof(T));
145 : : new(ptr + pos) T();
146 : : count++;
147 : : }
148 : :
149 : : void insert(int pos, const T& item)
150 : : {
151 : : if (pos<0 || pos>count) return;
152 : : if (count >= bufferlen - 4)
153 : : {
154 : : resize(count);
155 : : }
156 : : memmove(ptr + pos + 1, ptr + pos, sizeof(T)*(size_t)(count - pos));
157 : : memset(ptr + pos, 0, sizeof(T));
158 : : new(ptr + pos) T();
159 : : ptr[pos] = item;
160 : : count++;
161 : : }
162 : :
163 : 27 : void remove(int id)
164 : : {
165 [ + - + - ]: 27 : if (id < 0 || id >= count) return;
166 : 27 : count--;
167 : 27 : ptr[id].~T();
168 [ - + ]: 27 : for(int i = id; i < count; i++){
169 : 0 : ptr[i] = static_cast<T &&>(ptr[i+1]);
170 : : }
171 : : }
172 : :
173 : 2250 : autoarray()
174 : 906 : {
175 : 2250 : ptr = (T*)malloc(sizeof(T) * default_size);
176 : 2250 : memset(ptr, 0, default_size*sizeof(T));
177 : 2250 : bufferlen = default_size;
178 : 2250 : count = 0;
179 : 2250 : }
180 : :
181 : 2250 : ~autoarray()
182 : : {
183 [ + + ]: 1456 : for (int i = 0;i < count;i++) ptr[i].~T();
184 : 2250 : free(ptr);
185 : 2250 : }
186 : :
187 : : #ifdef SERIALIZER
188 : : void serialize(serializer& s)
189 : : {
190 : : if (s.serializing) s(count);
191 : : else
192 : : {
193 : : int i;
194 : : s(i);
195 : : get(i - 1);
196 : : }
197 : : for (int i = 0;i < count;i++) s(ptr[i]);
198 : : }
199 : : #endif
200 : : #define SERIALIZER_BANNED
201 : : };
|