1 // util/array.h -- Dynamically sized arrays
3 // This software is copyright (c) 2007 Scott Wood <scott@buserror.net>.
5 // This software is provided 'as-is', without any express or implied warranty.
6 // In no event will the authors or contributors be held liable for any damages
7 // arising from the use of this software.
9 // Permission is hereby granted to everyone, free of charge, to use, copy,
10 // modify, prepare derivative works of, publish, distribute, perform,
11 // sublicense, and/or sell copies of the Software, provided that the above
12 // copyright notice and disclaimer of warranty be included in all copies or
13 // substantial portions of this software.
32 static const NullArray nullarray = {};
34 template<typename T, typename Alloc = ::System::RunTime::ORBMM> struct MutableArray {
38 bool valid_index(size_t index)
40 return index >= 0 && index < count;
43 T &operator[](size_t index)
45 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
46 if (!valid_index(index))
47 throw ArrayException();
59 MutableArray(NullArray na)
65 MutableArray(T *PTR, size_t COUNT)
71 MutableArray &slice_nocheck(size_t first, size_t newcount)
74 ret.ptr = ptr + first;
79 MutableArray &slice_nocheck(size_t first)
82 ret.ptr = ptr + first;
83 ret.count = count - first;
87 MutableArray &slice(size_t first, size_t count)
89 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
90 if (!valid_index(first) || !valid_index(first + count - 1))
91 throw ArrayException();
94 return slice_nocheck(first, count);
97 MutableArray &slice(size_t first)
99 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
100 if (!valid_index(first))
101 throw ArrayException();
104 return slice_nocheck(first);
109 MutableArray new_arr;
110 new_arr.ptr = new(Alloc()) T[count];
111 new_arr.count = count;
112 memcpy(new_arr.ptr, ptr, count);
117 template<typename T, typename Alloc = ::System::RunTime::ORBMM>
118 struct GrowableArray : public MutableArray<T, Alloc> {
119 using MutableArray<T, Alloc>::ptr;
120 using MutableArray<T, Alloc>::count;
128 GrowableArray(NullArray na) : MutableArray<T, Alloc>(na)
133 GrowableArray(T *PTR, size_t COUNT) : MutableArray<T, Alloc>(PTR, COUNT)
138 GrowableArray(T *PTR, size_t COUNT, size_t BUFSIZE) :
139 MutableArray<T, Alloc>(PTR, COUNT)
144 GrowableArray(MutableArray<T, Alloc> &ma) : MutableArray<T, Alloc>(ma)
149 void grow(size_t newsize)
151 if (newsize <= bufsize)
155 T *newptr = new(Alloc()) T[newsize];
157 memcpy(newptr, ptr, count * sizeof(T));
160 ll_smp_membar_store_after_store();
162 ll_smp_membar_any_after_store();
164 Alloc::release(oldptr);
167 // Caller must sync against all writers.
168 void append(T *newptr, size_t len, size_t max = ULONG_MAX)
170 if (count + len < count)
171 throw ArrayException();
173 if (count + len > max)
174 throw ArrayException();
176 if (count + len > bufsize)
177 grow(ll_get_order_round_up(count + len));
179 memcpy(ptr + count, newptr, len * sizeof(T));
184 template<typename T, typename Alloc = ::System::RunTime::ORBMM> struct Array {
188 bool valid_index(size_t index)
190 return index >= 0 && index < count;
193 const T &operator[](size_t index)
195 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
196 if (!valid_index(index))
197 throw ArrayException();
215 Array(const T *PTR, size_t COUNT)
221 Array(MutableArray<T, Alloc> ma)
227 MutableArray<T, Alloc> constcast()
229 MutableArray<T, Alloc> ma;
230 ma.ptr = const_cast<T>(ptr);
235 Array &slice_nocheck(size_t first, size_t newcount)
238 ret.ptr = ptr + first;
239 ret.count = newcount;
243 Array &slice_nocheck(size_t first)
246 ret.ptr = ptr + first;
247 ret.count = count - first;
251 Array &slice(size_t first, size_t count)
253 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
254 if (!valid_index(first) || !valid_index(first + count - 1))
255 throw ArrayException();
258 return slice_nocheck(first, count);
261 Array &slice(size_t first)
263 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
264 if (!valid_index(first))
265 throw ArrayException();
268 return slice_nocheck(first);
271 MutableArray<T, Alloc> copy()
273 MutableArray<T, Alloc> new_arr;
274 new_arr.ptr = new(Alloc()) T[count];
275 new_arr.count = count;
276 memcpy(new_arr.ptr, ptr, count);
281 template<typename Alloc>
282 static inline Array<uint8_t, Alloc>
283 countarray(const char *ptr)
285 Array<uint8_t, Alloc> ret;
286 ret.ptr = reinterpret_cast<const uint8_t *>(ptr);
287 ret.count = strlen(ptr);
291 template<typename Alloc>
292 static inline MutableArray<uint8_t, Alloc>
293 countarray(char *ptr)
295 MutableArray<uint8_t, Alloc> ret;
296 ret.ptr = reinterpret_cast<uint8_t *>(ptr);
297 ret.count = strlen(ptr);
302 using namespace Arrays;