--- /dev/null
+// util/array.h -- Dynamically sized arrays
+//
+// This software is copyright (c) 2007 Scott Wood <scott@buserror.net>.
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors or contributors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is hereby granted to everyone, free of charge, to use, copy,
+// modify, prepare derivative works of, publish, distribute, perform,
+// sublicense, and/or sell copies of the Software, provided that the above
+// copyright notice and disclaimer of warranty be included in all copies or
+// substantial portions of this software.
+
+#ifndef _UTIL_ARRAY_H
+#define _UTIL_ARRAY_H
+
+namespace System {
+namespace RunTime {
+ class ORBMM;
+}}
+
+namespace Util {
+ namespace Arrays {
+ struct ArrayException
+ {
+ };
+
+ class NullArray {
+ };
+
+ static const NullArray nullarray = {};
+
+ template<typename T, typename Alloc = ::System::RunTime::ORBMM> struct MutableArray {
+ T *ptr;
+ size_t count;
+
+ bool valid_index(size_t index)
+ {
+ return index >= 0 && index < count;
+ }
+
+ T &operator[](size_t index)
+ {
+#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
+ if (!valid_index(index))
+ throw ArrayException();
+#endif
+
+ return ptr[index];
+ }
+
+ MutableArray()
+ {
+ ptr = NULL;
+ count = 0;
+ }
+
+ MutableArray(NullArray na)
+ {
+ ptr = NULL;
+ count = 0;
+ }
+
+ MutableArray(T *PTR, size_t COUNT)
+ {
+ ptr = PTR;
+ count = COUNT;
+ }
+
+ MutableArray &slice_nocheck(size_t first, size_t newcount)
+ {
+ MutableArray ret;
+ ret.ptr = ptr + first;
+ ret.count = newcount;
+ return ret;
+ }
+
+ MutableArray &slice_nocheck(size_t first)
+ {
+ MutableArray ret;
+ ret.ptr = ptr + first;
+ ret.count = count - first;
+ return ret;
+ }
+
+ MutableArray &slice(size_t first, size_t count)
+ {
+#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
+ if (!valid_index(first) || !valid_index(first + count - 1))
+ throw ArrayException();
+#endif
+
+ return slice_nocheck(first, count);
+ }
+
+ MutableArray &slice(size_t first)
+ {
+#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
+ if (!valid_index(first))
+ throw ArrayException();
+#endif
+
+ return slice_nocheck(first);
+ }
+
+ MutableArray copy()
+ {
+ MutableArray new_arr;
+ new_arr.ptr = new(Alloc()) T[count];
+ new_arr.count = count;
+ memcpy(new_arr.ptr, ptr, count);
+ return new_arr;
+ }
+ };
+
+ template<typename T, typename Alloc = ::System::RunTime::ORBMM>
+ struct GrowableArray : public MutableArray<T, Alloc> {
+ using MutableArray<T, Alloc>::ptr;
+ using MutableArray<T, Alloc>::count;
+ size_t bufsize;
+
+ GrowableArray()
+ {
+ bufsize = 0;
+ }
+
+ GrowableArray(NullArray na) : MutableArray<T, Alloc>(na)
+ {
+ bufsize = 0;
+ }
+
+ GrowableArray(T *PTR, size_t COUNT) : MutableArray<T, Alloc>(PTR, COUNT)
+ {
+ bufsize = COUNT;
+ }
+
+ GrowableArray(T *PTR, size_t COUNT, size_t BUFSIZE) :
+ MutableArray<T, Alloc>(PTR, COUNT)
+ {
+ bufsize = BUFSIZE;
+ }
+
+ GrowableArray(MutableArray<T, Alloc> &ma) : MutableArray<T, Alloc>(ma)
+ {
+ bufsize = count;
+ }
+
+ void grow(size_t newsize)
+ {
+ if (newsize <= bufsize)
+ return;
+
+ T *oldptr = ptr;
+ T *newptr = new(Alloc()) T[newsize];
+
+ memcpy(newptr, ptr, count * sizeof(T));
+
+ ptr = newptr;
+ ll_smp_membar_store_after_store();
+ bufsize = newsize;
+ ll_smp_membar_any_after_store();
+
+ Alloc::release(oldptr);
+ }
+
+ // Caller must sync against all writers.
+ void append(T *newptr, size_t len, size_t max = ULONG_MAX)
+ {
+ if (count + len < count)
+ throw ArrayException();
+
+ if (count + len > max)
+ throw ArrayException();
+
+ if (count + len > bufsize)
+ grow(ll_get_order_round_up(count + len));
+
+ memcpy(ptr + count, newptr, len * sizeof(T));
+ count += len;
+ }
+ };
+
+ template<typename T, typename Alloc = ::System::RunTime::ORBMM> struct Array {
+ const T *ptr;
+ size_t count;
+
+ bool valid_index(size_t index)
+ {
+ return index >= 0 && index < count;
+ }
+
+ const T &operator[](size_t index)
+ {
+#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
+ if (!valid_index(index))
+ throw ArrayException();
+#endif
+
+ return ptr[index];
+ }
+
+ Array()
+ {
+ ptr = NULL;
+ count = 0;
+ }
+
+ Array(NullArray na)
+ {
+ ptr = NULL;
+ count = 0;
+ }
+
+ Array(const T *PTR, size_t COUNT)
+ {
+ ptr = PTR;
+ count = COUNT;
+ }
+
+ Array(MutableArray<T, Alloc> ma)
+ {
+ ptr = ma.ptr;
+ count = ma.count;
+ }
+
+ MutableArray<T, Alloc> constcast()
+ {
+ MutableArray<T, Alloc> ma;
+ ma.ptr = const_cast<T>(ptr);
+ ma.count = count;
+ return ma;
+ }
+
+ Array &slice_nocheck(size_t first, size_t newcount)
+ {
+ Array ret;
+ ret.ptr = ptr + first;
+ ret.count = newcount;
+ return ret;
+ }
+
+ Array &slice_nocheck(size_t first)
+ {
+ Array ret;
+ ret.ptr = ptr + first;
+ ret.count = count - first;
+ return ret;
+ }
+
+ Array &slice(size_t first, size_t count)
+ {
+#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
+ if (!valid_index(first) || !valid_index(first + count - 1))
+ throw ArrayException();
+#endif
+
+ return slice_nocheck(first, count);
+ }
+
+ Array &slice(size_t first)
+ {
+#ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
+ if (!valid_index(first))
+ throw ArrayException();
+#endif
+
+ return slice_nocheck(first);
+ }
+
+ MutableArray<T, Alloc> copy()
+ {
+ MutableArray<T, Alloc> new_arr;
+ new_arr.ptr = new(Alloc()) T[count];
+ new_arr.count = count;
+ memcpy(new_arr.ptr, ptr, count);
+ return new_arr;
+ }
+ };
+
+ template<typename Alloc>
+ static inline Array<uint8_t, Alloc>
+ countarray(const char *ptr)
+ {
+ Array<uint8_t, Alloc> ret;
+ ret.ptr = reinterpret_cast<const uint8_t *>(ptr);
+ ret.count = strlen(ptr);
+ return ret;
+ }
+
+ template<typename Alloc>
+ static inline MutableArray<uint8_t, Alloc>
+ countarray(char *ptr)
+ {
+ MutableArray<uint8_t, Alloc> ret;
+ ret.ptr = reinterpret_cast<uint8_t *>(ptr);
+ ret.count = strlen(ptr);
+ return ret;
+ }
+ }
+
+ using namespace Arrays;
+}
+
+#endif