X-Git-Url: http://git.buserror.net/cgi-bin/gitweb.cgi?p=polintos%2Fscott%2Fpriv.git;a=blobdiff_plain;f=include%2Fc%2B%2B%2Futil%2Farray.h;fp=include%2Fc%2B%2B%2Futil%2Farray.h;h=80ba1c76965b47779ec6003b7f730cb0b6e84396;hp=0000000000000000000000000000000000000000;hb=cc1bee96fd874ff2c85c765f81ec2f4ba4584b9d;hpb=9fa824211a5dcb9a87d18b45d604599748dbff6c diff --git a/include/c++/util/array.h b/include/c++/util/array.h new file mode 100644 index 0000000..80ba1c7 --- /dev/null +++ b/include/c++/util/array.h @@ -0,0 +1,305 @@ +// util/array.h -- Dynamically sized arrays +// +// This software is copyright (c) 2007 Scott Wood . +// +// 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 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 + struct GrowableArray : public MutableArray { + using MutableArray::ptr; + using MutableArray::count; + size_t bufsize; + + GrowableArray() + { + bufsize = 0; + } + + GrowableArray(NullArray na) : MutableArray(na) + { + bufsize = 0; + } + + GrowableArray(T *PTR, size_t COUNT) : MutableArray(PTR, COUNT) + { + bufsize = COUNT; + } + + GrowableArray(T *PTR, size_t COUNT, size_t BUFSIZE) : + MutableArray(PTR, COUNT) + { + bufsize = BUFSIZE; + } + + GrowableArray(MutableArray &ma) : MutableArray(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 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 ma) + { + ptr = ma.ptr; + count = ma.count; + } + + MutableArray constcast() + { + MutableArray ma; + ma.ptr = const_cast(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 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 + static inline Array + countarray(const char *ptr) + { + Array ret; + ret.ptr = reinterpret_cast(ptr); + ret.count = strlen(ptr); + return ret; + } + + template + static inline MutableArray + countarray(char *ptr) + { + MutableArray ret; + ret.ptr = reinterpret_cast(ptr); + ret.count = strlen(ptr); + return ret; + } + } + + using namespace Arrays; +} + +#endif