From eec45fe608f113f4c0fb5fa33619f44e92835e3d Mon Sep 17 00:00:00 2001
From: Hackerpilot <briancschott@gmail.com>
Date: Wed, 9 Apr 2014 11:27:25 -0700
Subject: [PATCH] Updated allocator

---
 stdx/allocator.d | 52 +++++++++++++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 23 deletions(-)

diff --git a/stdx/allocator.d b/stdx/allocator.d
index fb6db9e..3ae7c8f 100644
--- a/stdx/allocator.d
+++ b/stdx/allocator.d
@@ -559,7 +559,7 @@ struct GCAllocator
     /**
     Standard allocator methods per the semantics defined above. The $(D deallocate) and $(D reallocate) methods are $(D @system) because they may move memory around, leaving dangling pointers in user code.
     */
-    @trusted void[] allocate(size_t bytes) shared
+    @trusted void[] allocate(size_t bytes) shared nothrow pure @safe
     {
         auto p = GC.malloc(bytes);
         return p ? p[0 .. bytes] : null;
@@ -581,7 +581,7 @@ struct GCAllocator
     }
 
     /// Ditto
-    @system bool reallocate(ref void[] b, size_t newSize) shared
+    @system bool reallocate(ref void[] b, size_t newSize) shared nothrow pure
     {
         import core.exception : OutOfMemoryError;
         try
@@ -598,15 +598,20 @@ struct GCAllocator
     }
 
     /// Ditto
-    @system void deallocate(void[] b) shared
+    @system void deallocate(void[] b) shared nothrow pure
     {
         GC.free(b.ptr);
     }
 
+	static shared(GCAllocator) it() pure nothrow @property @trusted
+	{
+		return cast(typeof(return)) _it;
+	}
+
     /**
     Returns the global instance of this allocator type. The garbage collected allocator is thread-safe, therefore all of its methods and $(D it) itself are $(D shared).
     */
-    static shared GCAllocator it;
+    private static shared const GCAllocator _it;
 
     // Leave it undocummented for now.
     @trusted void collect() shared
@@ -854,7 +859,7 @@ unittest
 /**
 Returns s rounded up to a multiple of base.
 */
-private size_t roundUpToMultipleOf(size_t s, uint base)
+private size_t roundUpToMultipleOf(size_t s, uint base) pure nothrow @safe
 {
     assert(base);
     auto rem = s % base;
@@ -943,7 +948,7 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
     static assert(
         !stateSize!Prefix || Allocator.alignment >= Prefix.alignof,
         "AffixAllocator does not work with allocators offering a smaller"
-        " alignment than the prefix alignment.");
+        ~ " alignment than the prefix alignment.");
     static assert(alignment % Suffix.alignof == 0,
         "This restriction could be relaxed in the future.");
 
@@ -960,7 +965,7 @@ struct AffixAllocator(Allocator, Prefix, Suffix = void)
     parent allocator.
     */
     static if (stateSize!Allocator) Allocator parent;
-    else alias Allocator.it parent;
+    else alias parent = Allocator.it;
 
     template Impl()
     {
@@ -1118,7 +1123,7 @@ unittest
 
 unittest
 {
-    alias AffixAllocator!(Mallocator, size_t) A;
+    alias A = AffixAllocator!(Mallocator, size_t);
     auto b = A.it.allocate(10);
     A.it.prefix(b) = 10;
     assert(A.it.prefix(b) == 10);
@@ -1902,10 +1907,10 @@ struct FallbackAllocator(Primary, Fallback)
     If both $(D Primary) and $(D Fallback) are stateless, $(D FallbackAllocator)
     defines a static instance $(D it).
     */
-    static if (!stateSize!Primary && !stateSize!Fallback)
+    /+static if (!stateSize!Primary && !stateSize!Fallback)
     {
         static FallbackAllocator it;
-    }
+    }+/
 
     /**
     The alignment offered is the minimum of the two allocators' alignment.
@@ -1916,7 +1921,7 @@ struct FallbackAllocator(Primary, Fallback)
     Allocates memory trying the primary allocator first. If it returns $(D
     null), the fallback allocator is tried.
     */
-    void[] allocate(size_t s)
+    void[] allocate(size_t s) pure nothrow @safe
     {
         auto result = primary.allocate(s);
         return result ? result : fallback.allocate(s);
@@ -1959,9 +1964,9 @@ struct FallbackAllocator(Primary, Fallback)
     allocation from $(D fallback) to $(D primary).
 
     */
-    bool reallocate(ref void[] b, size_t newSize)
+    bool reallocate(ref void[] b, size_t newSize) pure nothrow @trusted
     {
-        bool crossAllocatorMove(From, To)(ref From from, ref To to)
+        bool crossAllocatorMove(From, To)(auto ref From from, auto ref To to)
         {
             auto b1 = to.allocate(newSize);
             if (!b1) return false;
@@ -2004,7 +2009,7 @@ struct FallbackAllocator(Primary, Fallback)
     */
     static if (hasMember!(Primary, "deallocate")
         || hasMember!(Fallback, "deallocate"))
-    void deallocate(void[] b)
+    void deallocate(void[] b) pure nothrow @trusted
     {
         if (primary.owns(b))
         {
@@ -2014,7 +2019,7 @@ struct FallbackAllocator(Primary, Fallback)
         else
         {
             static if (hasMember!(Fallback, "deallocate"))
-                return fallback.deallocate(b);
+                fallback.deallocate(b);
         }
     }
 }
@@ -2216,11 +2221,6 @@ struct Freelist(ParentAllocator,
     Allocates memory either off of the free list or from the parent allocator.
     */
     void[] allocate(size_t bytes)
-	in
-	{
-		assert (_root !is null);
-	}
-	body
     {
         assert(bytes < size_t.max / 2);
         if (!inRange(bytes)) return parent.allocate(bytes);
@@ -2941,7 +2941,7 @@ struct InSituRegion(size_t size, size_t minAlign = platformAlignment)
     accommodate the request. For efficiency reasons, if $(D bytes == 0) the
     function returns an empty non-null slice.
     */
-    void[] allocate(size_t bytes)
+    void[] allocate(size_t bytes) pure nothrow @trusted
     {
         // Oddity: we don't return null for null allocation. Instead, we return
         // an empty slice with a non-null ptr.
@@ -2984,7 +2984,7 @@ struct InSituRegion(size_t size, size_t minAlign = platformAlignment)
     allocation. For efficiency reasons, if $(D b is null) the function returns
     $(D false).
     */
-    bool owns(void[] b) const
+    bool owns(void[] b) const nothrow pure @trusted
     {
         // No nullptr
         return b.ptr >= _store.ptr
@@ -2994,7 +2994,7 @@ struct InSituRegion(size_t size, size_t minAlign = platformAlignment)
     /**
     Deallocates all memory allocated with this allocator.
     */
-    void deallocateAll()
+    void deallocateAll() pure nothrow @safe
     {
         _crt = _store.ptr;
     }
@@ -3716,6 +3716,12 @@ struct CascadingAllocator(alias make)
 
     /// Ditto
     void[] allocate(size_t s)
+	out (res)
+	{
+		import std.string;
+		assert (res.length == s, "res.length = %d, s = %d".format(res.length, s));
+	}
+	body
     {
         auto result = allocateNoGrow(s);
         if (result) return result;