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
6 template< class valuetype >
7 inline
8 dynamicarray<valuetype>::dynamicarray() {
9 init(128,32);
10 }
11
12 template< class valuetype >
13 inline
14 dynamicarray<valuetype>::dynamicarray(uint64_t initiallength,
15 uint64_t incrementlength) {
16 init((initiallength)?initiallength:128,
17 (incrementlength)?incrementlength:32);
18 }
19
20 template< class valuetype >
21 inline
22 dynamicarray<valuetype>::dynamicarray(const dynamicarray<valuetype> &v) {
23 init(v.initial,v.extlength);
24 dynamicarrayClone(v);
25 }
26
27 template< class valuetype >
28 inline
29 dynamicarray<valuetype> &dynamicarray<valuetype>::operator=(
30 const dynamicarray<valuetype> &v) {
31 if (this!=&v) {
32 clearExtentList();
33 init(v.initial,v.extlength);
34 dynamicarrayClone(v);
35 }
36 return *this;
37 }
38
39 template< class valuetype >
40 inline
41 void dynamicarray<valuetype>::init(uint64_t initiallength,
42 uint64_t incrementlength) {
43 length=0;
44 len=0;
45 initial=initiallength;
46 extlength=incrementlength;
47 extend(initiallength);
48 curext=extents.getFirst();
49 curind=0;
50 }
51
52 template< class valuetype >
53 inline
54 void dynamicarray<valuetype>::dynamicarrayClone(
55 const dynamicarray<valuetype> &v) {
56
57 // extend storage to fit (do this before setting length)
58 extend(v.len);
59
60 // clone lengths and positions
61 length=v.length;
62 len=v.len;
63 initial=v.initial;
64 extlength=v.extlength;
65
66 // clone the data
67 for (uint64_t i=0; i<v.getLength(); i++) {
68
69 // Why not just:
70 // this[i]=v[i];
71 //
72 // Some compilers don't allow v[] because the operator[] method
73 // isn't const, but v is.
74 //
75 // Also, some compilers get confused and think that
76 // this[i]=v[i]
77 // means
78 // (this[i])->operator=(v[i])
79 // and no carefully placed parentheses help.
80 //
81 // This silliness sorts both issues out.
82 find(i)=((dynamicarray<valuetype> *)&v)->find(i);
83 }
84
85 // clone positions
86 curind=v.curind;
87 curext=extents.getFirst();
88 for (uint64_t eind=0; eind<curind; eind++) {
89 curext=curext->getNext();
90 }
91 }
92
93 template< class valuetype >
94 inline
95 dynamicarray<valuetype>::~dynamicarray() {
96 clearExtentList();
97 }
98
99 template< class valuetype >
100 inline
101 valuetype &dynamicarray<valuetype>::operator[](uint64_t index) {
102 extend(index+1);
103 if (index>=len) {
104 len=index+1;
105 }
106 return find(index);
107 }
108
109 template< class valuetype >
110 inline
111 uint64_t dynamicarray<valuetype>::getInitialLength() const {
112 return initial;
113 }
114
115 template< class valuetype >
116 inline
117 uint64_t dynamicarray<valuetype>::getIncrementLength() const {
118 return extlength;
119 }
120
121 template< class valuetype >
122 inline
123 uint64_t dynamicarray<valuetype>::getLength() const {
124 return len;
125 }
126
127 template< class valuetype >
128 inline
129 void dynamicarray<valuetype>::extend(uint64_t length) {
130 uint64_t inc=(extents.getLength())?extlength:initial;
131 while (this->length<length) {
132 valuetype *newext=new valuetype[inc];
133 extents.append(newext);
134 this->length=this->length+inc;
135 inc=extlength;
136 }
137 }
138
139 template< class valuetype >
140 inline
141 valuetype &dynamicarray<valuetype>::find(uint64_t index) {
142
143 // move to the extent that contains the specified index
144 // (also calculate the index of the first element of the extent)
145 size_t eind;
146 if (index<initial) {
147 curext=extents.getFirst();
148 curind=0;
149 eind=0;
150 } else {
151 uint64_t targetind=(index-initial+extlength)/extlength;
152 while (curind>targetind) {
153 curext=curext->getPrevious();
154 curind--;
155 }
156 while (curind<targetind) {
157 curext=curext->getNext();
158 curind++;
159 }
160 eind=initial+extlength*(curind-1);
161 }
162
163 // return the value
164 return curext->getValue()[index-eind];
165 }
166
167 template< class valuetype >
168 inline
169 void dynamicarray<valuetype>::clearExtentList() {
170 curext=extents.getFirst();
171 while (curext) {
172 linkedlistnode<valuetype *> *next=curext->getNext();
173 valuetype *ext=curext->getValue();
174 delete[] ext;
175 extents.remove(curext);
176 curext=next;
177 }
178 }
179
180 template< class valuetype >
181 inline
182 void dynamicarray<valuetype>::clear() {
183 clear(initial,extlength);
184 }
185
186 template< class valuetype >
187 inline
188 void dynamicarray<valuetype>::clear(uint64_t initiallength,
189 uint64_t incrementlength) {
190
191 // remove all but the first extent
192 curext=extents.getLast();
193 while (curext!=extents.getFirst()) {
194 linkedlistnode<valuetype *> *prev=curext->getPrevious();
195 valuetype *ext=curext->getValue();
196 delete[] ext;
197 extents.remove(curext);
198 curext=prev;
199 }
200
201 // reset the initial/incremental lengths
202 initial=initiallength;
203 extlength=incrementlength;
204
205 // reinit first extent
206 valuetype *ext=curext->getValue();
207 for (uint64_t i=0; i<initial; i++) {
208 ext[i].~valuetype();
209 new(&(ext[i])) valuetype;
210 }
211
212 // reset lengths and positions
213 length=0;
214 len=0;
215 curind=0;
216 }
dynamicarray
Definition: dynamicarray.h:40
dynamicarray::dynamicarray
dynamicarray()
Definition: dynamicarrayinlines.h:8
dynamicarray::getLength
uint64_t getLength() const
Definition: dynamicarrayinlines.h:123
dynamicarray::clear
void clear()
Definition: dynamicarrayinlines.h:182
dynamicarray::~dynamicarray
~dynamicarray()
Definition: dynamicarrayinlines.h:95
dynamicarray::operator=
dynamicarray< valuetype > & operator=(const dynamicarray< valuetype > &v)
Definition: dynamicarrayinlines.h:29
dynamicarray::operator[]
valuetype & operator[](uint64_t index)
Definition: dynamicarrayinlines.h:101
linkedlistnode
Definition: linkedlist.h:11