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
9  init(128,32);
10 }
11 
12 template< class valuetype >
13 inline
15  uint64_t incrementlength) {
16  init((initiallength)?initiallength:128,
17  (incrementlength)?incrementlength:32);
18 }
19 
20 template< class valuetype >
21 inline
23  init(v.initial,v.extlength);
24  dynamicarrayClone(v);
25 }
26 
27 template< class valuetype >
28 inline
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
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
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
112  return initial;
113 }
114 
115 template< class valuetype >
116 inline
118  return extlength;
119 }
120 
121 template< class valuetype >
122 inline
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
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
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 }
Definition: dynamicarray.h:40
dynamicarray()
Definition: dynamicarrayinlines.h:8
uint64_t getLength() const
Definition: dynamicarrayinlines.h:123
void clear()
Definition: dynamicarrayinlines.h:182
~dynamicarray()
Definition: dynamicarrayinlines.h:95
dynamicarray< valuetype > & operator=(const dynamicarray< valuetype > &v)
Definition: dynamicarrayinlines.h:29
valuetype & operator[](uint64_t index)
Definition: dynamicarrayinlines.h:101
Definition: linkedlist.h:11