Rudiments
dynamicarrayinlines.h
1// Copyright (c) 1999-2018 David Muse
2// See the COPYING file for more information.
3
4#include <rudiments/private/new.h>
5#include <rudiments/bytestring.h>
6
7template< class valuetype >
8inline
12
13template< class valuetype >
14inline
21
22template< class valuetype >
23inline
26 construct(v.initcount,v.inccount);
27 clone(v);
28}
29
30template< class valuetype >
31inline
37
38template< class valuetype >
39inline
42 if (this!=&v) {
43 clear(v.initcount,v.inccount);
45 construct(v.initcount,v.inccount);
46 clone(v);
47 }
48 return *this;
49}
50
51template< class valuetype >
52inline
55 if (this!=&v) {
56 clear();
58 construct(initcount,inccount);
59 clone(v);
60 }
61 return *this;
62}
63
64template< class valuetype >
65inline
67 uint64_t incrementcount) {
68 extents.setManageArrayValues(true);
69 totalcount=0;
70 lastcount=0;
71 initcount=initialcount;
72 inccount=incrementcount;
73 extend(initialcount);
74 curext=extents.getFirst();
75 curind=0;
76}
77
78template< class valuetype >
79inline
81
82 // extend storage to fit (do this before setting count)
83 extend(v.lastcount);
84
85 // clone counts and positions
86 totalcount=v.totalcount;
87 lastcount=v.lastcount;
88 initcount=v.initcount;
89 inccount=v.inccount;
90
91 // clone the data
92 bool managevalues=this->getManageValues();
93 bool managearrayvalues=this->getManageArrayValues();
94 for (uint64_t i=0; i<v.getCount(); i++) {
95 find(i)=node_duplicate_value(&(v.find(i)),
96 managevalues,managearrayvalues);
97 }
98
99 // clone positions
100 curind=v.curind;
101 curext=extents.getFirst();
102 for (uint64_t eind=0; eind<curind; eind++) {
103 curext=curext->getNext();
104 }
105}
106
107template< class valuetype >
108inline
110 lastcount=v.getCount();
111 bool managevalues=this->getManageValues();
112 bool managearrayvalues=this->getManageArrayValues();
113 for (uint64_t i=0; i<lastcount; i++) {
114 find(i)=node_duplicate_value(&(v[i]),
115 managevalues,managearrayvalues);
116 }
117}
118
119template< class valuetype >
120inline
122 deleteManagedValues();
123}
124
125template< class valuetype >
126inline
127void dynamicarray<valuetype>::zero(uint64_t count) {
128 set(0,0,count);
129}
130
131template< class valuetype >
132inline
133void dynamicarray<valuetype>::zero(uint64_t start, uint64_t count) {
134 set(0,start,count);
135}
136
137template< class valuetype >
138inline
139void dynamicarray<valuetype>::set(byte_t value, uint64_t count) {
140 set(value,0,count);
141}
142
143template< class valuetype >
144inline
146 uint64_t start, uint64_t count) {
147 uint64_t end=start+count;
148 for (uint64_t i=start; i<end; i++) {
149 bytestring::set(&((*this)[i]),value,sizeof(valuetype));
150 }
151}
152
153template< class valuetype >
154inline
156 extend(index+1);
157 if (index>=lastcount) {
158 lastcount=index+1;
159 }
160 // I once had (semi-clever) bounds-checking code here like:
161 //
162 // if (index>=lastcount) {
163 // return *((valuetype *)NULL);
164 // }
165 //
166 // which would successfully return a NULL/0 if valuetype was a pointer,
167 // but would throw warnings on some platforms if valuetype isn't a
168 // pointer, and would probably crash on those platforms if it managed
169 // to run.
170 //
171 // It's (apparently) conventional for the operator[] not to do any
172 // bounds checking, not even throw any exceptions, and and just attempt
173 // to access and return the requested index, possibly crashing in the
174 // process. When a program accesses via the [] opertator it's telling
175 // the compiler "trust me, I know what I'm doing".
176 //
177 // So, for now, I removed that code above and we'll just let whatever
178 // happens, happen.
179 return find(index);
180}
181
182template< class valuetype >
183inline
185 return initcount;
186}
187
188template< class valuetype >
189inline
191 return inccount;
192}
193
194template< class valuetype >
195inline
197 return lastcount;
198}
199
200template< class valuetype >
201inline
202void dynamicarray<valuetype>::extend(uint64_t count) {
203 uint64_t inc=(extents.getCount())?inccount:initcount;
204 while (totalcount<count) {
206 extents.append(newext);
207 totalcount+=inc;
208 inc=inccount;
209 }
210}
211
212template< class valuetype >
213inline
215
216 // move to the extent that contains the specified index
217 // (also calculate the index of the first element of the extent)
218 size_t eind;
219 if (index<initcount) {
220 curext=extents.getFirst();
221 curind=0;
222 eind=0;
223 } else {
224 uint64_t targetind=(index-initcount+inccount)/inccount;
225 while (curind>targetind) {
226 curext=curext->getPrevious();
227 curind--;
228 }
229 while (curind<targetind) {
230 curext=curext->getNext();
231 curind++;
232 }
233 eind=initcount+inccount*(curind-1);
234 }
235 return eind;
236}
237
238template< class valuetype >
239inline
241 // Don't be tempted to do replace [index-eind] with
242 // [index-findExtentStartIndex(index)], as that somehow
243 // breaks everything, at least with gcc-11.
244 // I imagine that findExtendStartIndex() being inline and const, but
245 // also modifying mutable variables, somehow confuses the optimizer.
246 // FIXME: now that the methods aren't const and modifying mutables,
247 // it might work
248 size_t eind=findExtentStartIndex(index);
249 return curext->getValue()[index-eind];
250}
251
252template< class valuetype >
253inline
255 return clear(initcount,inccount);
256}
257
258template< class valuetype >
259inline
261
262 bool managevalues=this->getManageValues();
263 bool managearrayvalues=this->getManageArrayValues();
264
265 // delete managed values in all extents
266 if (managevalues || managearrayvalues) {
267 uint64_t i=0;
268 uint64_t count=initcount;
269 for (curext=extents.getFirst(); i<lastcount && curext;
270 curext=curext->getNext()) {
271 valuetype *data=curext->getValue();
272 for (uint64_t j=0; i<lastcount && j<count; j++) {
273 node_delete_value(&(data[j]),
274 managevalues,managearrayvalues);
275 node_zero_value(&(data[j]));
276 i++;
277 }
278 count=inccount;
279 }
280 }
281}
282
283template< class valuetype >
284inline
286 uint64_t incrementcount) {
287
288 deleteManagedValues();
289
290 if (initialcount==initcount) {
291
292 // remove all but the first extent
293 curext=extents.getLast();
294 while (curext!=extents.getFirst()) {
296 extents.remove(curext);
297 curext=prev;
298 }
299
300 // reinit first extent
301 valuetype *ext=curext->getValue();
302 for (uint64_t i=0; i<initcount; i++) {
303 // gcc 2.91.66 on redhat 6.2 throws an internal
304 // compiler error unless we use a pointer to call
305 // the destructor. No other compilers appear to have
306 // this problem.
307 #if __GNUC__ == 2 && __GNUC_MINOR__ == 91
308 valuetype *v=&(ext[i]);
309 v->~valuetype();
310 #else
311 ext[i].~valuetype();
312 #endif
313 new(&(ext[i])) valuetype;
314 }
315
316 } else {
317
318 // reset the initial count
319 initcount=initialcount;
320
321 // remove all extents
322 extents.clear();
323
324 // reinit first extent
325 valuetype *newext=new valuetype[initcount];
326 extents.append(newext);
327 curext=extents.getFirst();
328 }
329
330 // reset the incremental count
331 inccount=incrementcount;
332
333 // reset counts
334 totalcount=initcount;
335 lastcount=0;
336
337 // reset current extent index
338 curind=0;
339
340 return true;
341}
Definition arraycollection.h:13
Definition avltree.h:11
avltreenode(valuetype value)
Definition avltreeinlines.h:555
treenode< valuetype > * getNext()
Definition avltreeinlines.h:671
treenode< valuetype > * getPrevious()
Definition avltreeinlines.h:620
valuetype getValue()
Definition avltreeinlines.h:578
static void * set(void *dest, byte_t character, size_t size)
collection & operator=(collection &c)
Definition collectioninlines.h:30
Definition dynamicarray.h:52
dynamicarray()
Definition dynamicarrayinlines.h:9
bool clear()
Definition dynamicarrayinlines.h:254
void zero(uint64_t count)
Definition dynamicarrayinlines.h:127
~dynamicarray()
Definition dynamicarrayinlines.h:121
uint64_t getCount()
Definition dynamicarrayinlines.h:196
dynamicarray< valuetype > & operator=(dynamicarray< valuetype > &v)
Definition dynamicarrayinlines.h:40
valuetype & operator[](uint64_t index)
Definition dynamicarrayinlines.h:155
void set(byte_t value, uint64_t count)
Definition dynamicarrayinlines.h:139