diff src/basic/SmallArray.d @ 206:d3c148ca429b

Major moving of files. all src now goes into src, all docs in docs.
author Anders Johnsen <skabet@gmail.com>
date Tue, 12 Aug 2008 18:14:56 +0200
parents
children e0551773a005
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/basic/SmallArray.d	Tue Aug 12 18:14:56 2008 +0200
@@ -0,0 +1,106 @@
+module basic.SmallArray;
+
+/**
+  This struct acts like a normal dynamic array, with one difference.
+  A size is given, which is how many elements are preallocated on the stack.
+
+  Example:
+  --------
+  SmallArray!(float, 4) array;
+  array ~= 1.0;
+  array ~= 2.0;
+  array ~= 3.0;
+  float[] three_floats = array[0 .. 3];
+  // The slice gives a reference to the stack, remember to .dup
+  array ~= 4.0;
+  // not using the heap yet, but after the next line all values will have been
+  // copied to the heap.
+  array ~= 5.0;
+  --------
+
+  Compared to a normal dynamic array there is 8 bytes overhead (on 32 bit cpus)
+  and ofcourse size * T.sizeof bytes for the stack allocated array.
+ */
+struct SmallArray(T, ubyte size = 8)
+{
+    T[] opSlice(size_t low, size_t high)
+    {
+        assert(high <= len && low <= high, "Array index out of range");
+        return ptr[low .. high];
+    }
+
+    T[] opSlice()
+    {
+        return ptr[0 .. len];
+    }
+    alias opSlice unsafe;
+
+    T[] safe()
+    {
+        if (len <= size)
+            return static_array[0 .. len].dup;
+        return array[0 .. len];
+    }
+
+    T[] opSliceAssign(T val, size_t low, size_t high)
+    {
+        assert(high <= len && low <= high, "Array index out of range");
+        return ptr[low .. high] = val;
+    }
+
+    T[] opSliceAssign(T val)
+    {
+        return ptr[0 .. len] = val;
+    }
+
+    T opIndex(size_t index)
+    {
+        assert(index < len, "Array index out of range");
+        return ptr[index];
+    }
+
+    T opIndexAssign(T val, size_t index)
+    {
+        assert(index < len, "Array index out of range");
+        return ptr[index] = val;
+    }
+
+    void opCatAssign(T val)
+    {
+        if (len < size)
+            static_array[len] = val;
+        else if (len == size)
+        {
+            T[] tmp = static_array[].dup;
+            array = tmp;
+            array ~= val;
+        }
+        else
+            array ~= val;
+
+        ++len;
+        if (len <= size)
+            ptr = static_array.ptr;
+        else
+            ptr = array.ptr;
+    }
+
+    size_t length() { return len; }
+
+    static SmallArray opCall()
+    {
+        SmallArray array;
+        array.ptr = array.static_array.ptr;
+        return array;
+    }
+
+private:
+    T* ptr;
+    size_t len;
+    union
+    {
+        T[] array;
+        T[size] static_array;
+    }
+}
+