Having insomnia has left me with a certain gifted curse. :P
I've been thinking, and i think i've written BitArray all wrong, in order to better structure it i would break it up into four something parts. The following would remove the complication of 'isCompact' and the union, the code can be @safe (rather than @trusted).
BitString, this is the main of BitArray, handles all basic operations but doesn't manage memory of any kind.
BitArrayRange, which is a reference forwarding for a BitString including various range functions.
Then we come to memory management. This can be done simply as wrappers.
BitArray - Memory management and dynamically allocates/reallocates as needed BitArrayFixed - Template that includes a fixed size of memory for small memory optimization.
It goes something like... (API not yet decided fully, but you should get the idea)
BitString { //bitfields for start/ending size_t[]* bulkRaw; //pointer to the array? inout(ubyte[]) noEndianBulkRaw() inout { return cast(inout(ubyte[])) bulkRaw; } this(size[]* raw) { bulkRaw = raw; } //binaryOperators and opIndex, etc //length modifier, but no memory re-allocation allowed } //Template with bool isConst? //BitStringRange(bool isConst) { // static if (isConst) { const(BitString)* array; } // else { BitString* array; } BitStringRange { BitString* array; ulong start, end; //forwarding operators for start/end //range functions } BitArray { BitString array; size_t[] rawMemory; alias array this; //include length modifiers and dynamic allocation void init() {} //opCast can convert to BitArrayFixed? } BitArrayFixed(int fixedSize) { BitString array; size_t[fixedSize] rawMemory; alias array this; void init(){ array = BitString(rawMemory); } //opCast can convert to BitArray? } Thoughts and comments?