From c7206e125985818279693af4169e50eed3d01010 Mon Sep 17 00:00:00 2001 From: Ilya Yaroshenko Date: Wed, 24 Oct 2018 23:14:18 +0700 Subject: [PATCH] Mir & BetterC rework: generic building blocks --- .../building_blocks/null_allocator.d | 24 ++++++------- source/stdx/allocator/common.d | 36 +++++++++++-------- source/stdx/allocator/gc_allocator.d | 14 ++++---- source/stdx/allocator/mallocator.d | 30 ++++++++-------- source/stdx/allocator/mmap_allocator.d | 8 ++--- source/stdx/allocator/package.d | 2 +- 6 files changed, 61 insertions(+), 53 deletions(-) diff --git a/source/stdx/allocator/building_blocks/null_allocator.d b/source/stdx/allocator/building_blocks/null_allocator.d index e30bfe7..287c7da 100644 --- a/source/stdx/allocator/building_blocks/null_allocator.d +++ b/source/stdx/allocator/building_blocks/null_allocator.d @@ -20,44 +20,44 @@ struct NullAllocator //size_t goodAllocSize(size_t n) shared const //{ return .goodAllocSize(this, n); } /// Always returns $(D null). - static void[] allocate(size_t) { return null; } + static void[] allocate()(size_t) { return null; } /// Always returns $(D null). - static void[] alignedAllocate(size_t, uint) { return null; } + static void[] alignedAllocate()(size_t, uint) { return null; } /// Always returns $(D null). - static void[] allocateAll() { return null; } + static void[] allocateAll()() { return null; } /** These methods return $(D false). Precondition: $(D b is null). This is because there is no other possible legitimate input. */ - static bool expand(ref void[] b, size_t s) + static bool expand()(ref void[] b, size_t s) { assert(b is null); return s == 0; } /// Ditto - static bool reallocate(ref void[] b, size_t) + static bool reallocate()(ref void[] b, size_t) { assert(b is null); return false; } /// Ditto - static bool alignedReallocate(ref void[] b, size_t, uint) + static bool alignedReallocate()(ref void[] b, size_t, uint) { assert(b is null); return false; } /// Returns $(D Ternary.no). - static Ternary owns(void[]) { return Ternary.no; } + static Ternary owns()(void[]) { return Ternary.no; } /** Returns $(D Ternary.no). */ - static Ternary resolveInternalPointer(const void*, ref void[]) + static Ternary resolveInternalPointer()(const void*, ref void[]) { return Ternary.no; } /** No-op. Precondition: $(D b is null) */ - static bool deallocate(void[] b) { assert(b is null); return true; } + static bool deallocate()(void[] b) { assert(b is null); return true; } /** No-op. */ - static bool deallocateAll() { return true; } + static bool deallocateAll()() { return true; } /** Returns $(D Ternary.yes). */ - static Ternary empty() { return Ternary.yes; } + static Ternary empty()() { return Ternary.yes; } /** Returns the $(D static) global instance of the $(D NullAllocator). */ @@ -75,7 +75,7 @@ struct NullAllocator assert(!NullAllocator.instance.reallocate(b, 42)); assert(!NullAllocator.instance.alignedReallocate(b, 42, 0)); NullAllocator.instance.deallocate(b); - NullAllocator.instance.deallocateAll(); + assert(NullAllocator.instance.deallocateAll() == true); import stdx.allocator.internal : Ternary; assert(NullAllocator.instance.empty() == Ternary.yes); diff --git a/source/stdx/allocator/common.d b/source/stdx/allocator/common.d index 8164787..8cf9a87 100644 --- a/source/stdx/allocator/common.d +++ b/source/stdx/allocator/common.d @@ -92,7 +92,7 @@ size_t goodAllocSize(A)(auto ref A a, size_t n) Returns s rounded up to a multiple of base. */ @safe @nogc nothrow pure -package size_t roundUpToMultipleOf(size_t s, uint base) +package size_t roundUpToMultipleOf()(size_t s, uint base) { assert(base); auto rem = s % base; @@ -112,7 +112,7 @@ unittest Returns `n` rounded up to a multiple of alignment, which must be a power of 2. */ @safe @nogc nothrow pure -package size_t roundUpToAlignment(size_t n, uint alignment) +package size_t roundUpToAlignment()(size_t n, uint alignment) { import stdx.allocator.internal : isPowerOf2; assert(alignment.isPowerOf2); @@ -137,7 +137,7 @@ unittest Returns `n` rounded down to a multiple of alignment, which must be a power of 2. */ @safe @nogc nothrow pure -package size_t roundDownToAlignment(size_t n, uint alignment) +package size_t roundDownToAlignment()(size_t n, uint alignment) { import stdx.allocator.internal : isPowerOf2; assert(alignment.isPowerOf2); @@ -159,7 +159,7 @@ may therefore be shorter. Returns the adjusted buffer, or null if obtaining a non-empty buffer is impossible. */ @nogc nothrow pure -package void[] roundUpToAlignment(void[] b, uint a) +package void[] roundUpToAlignment()(void[] b, uint a) { auto e = b.ptr + b.length; auto p = cast(void*) roundUpToAlignment(cast(size_t) b.ptr, a); @@ -191,7 +191,7 @@ package size_t divideRoundUp(size_t a, size_t b) Returns `s` rounded up to a multiple of `base`. */ @nogc nothrow pure -package void[] roundStartToMultipleOf(void[] s, uint base) +package void[] roundStartToMultipleOf()(void[] s, uint base) { assert(base); auto p = cast(void*) roundUpToMultipleOf( @@ -213,7 +213,7 @@ nothrow pure Returns $(D s) rounded up to the nearest power of 2. */ @safe @nogc nothrow pure -package size_t roundUpToPowerOf2(size_t s) +package size_t roundUpToPowerOf2()(size_t s) { import std.meta : AliasSeq; assert(s <= (size_t.max >> 1) + 1); @@ -250,7 +250,7 @@ unittest Returns the number of trailing zeros of $(D x). */ @safe @nogc nothrow pure -package uint trailingZeros(ulong x) +package uint trailingZeros()(ulong x) { uint result; while (result < 64 && !(x & (1UL << result))) @@ -284,7 +284,7 @@ Returns the effective alignment of `ptr`, i.e. the largest power of two that is a divisor of `ptr`. */ @nogc nothrow pure -package uint effectiveAlignment(void* ptr) +package uint effectiveAlignment()(void* ptr) { return 1U << trailingZeros(cast(size_t) ptr); } @@ -301,7 +301,7 @@ Aligns a pointer down to a specified alignment. The resulting pointer is less than or equal to the given pointer. */ @nogc nothrow pure -package void* alignDownTo(void* ptr, uint alignment) +package void* alignDownTo()(void* ptr, uint alignment) { import stdx.allocator.internal : isPowerOf2; assert(alignment.isPowerOf2); @@ -313,7 +313,7 @@ Aligns a pointer up to a specified alignment. The resulting pointer is greater than or equal to the given pointer. */ @nogc nothrow pure -package void* alignUpTo(void* ptr, uint alignment) +package void* alignUpTo()(void* ptr, uint alignment) { import stdx.allocator.internal : isPowerOf2; assert(alignment.isPowerOf2); @@ -322,14 +322,14 @@ package void* alignUpTo(void* ptr, uint alignment) } @safe @nogc nothrow pure -package bool isGoodStaticAlignment(uint x) +package bool isGoodStaticAlignment()(uint x) { import stdx.allocator.internal : isPowerOf2; return x.isPowerOf2; } @safe @nogc nothrow pure -package bool isGoodDynamicAlignment(uint x) +package bool isGoodDynamicAlignment()(uint x) { import stdx.allocator.internal : isPowerOf2; return x.isPowerOf2 && x >= (void*).sizeof; @@ -409,9 +409,17 @@ Forwards each of the methods in `funs` (if defined) to `member`. { result ~= " static if (hasMember!(typeof("~member~"), `"~fun~"`)) - auto ref "~fun~"(Parameters!(typeof("~member~"."~fun~")) args) { - return "~member~"."~fun~"(args); + static if (__traits(isTemplate, "~member~"."~fun~")) + auto ref "~fun~"(Parameters!(typeof("~member~"."~fun~"!())) args) + { + return "~member~"."~fun~"(args); + } + else + auto ref "~fun~"(Parameters!(typeof("~member~"."~fun~")) args) + { + return "~member~"."~fun~"(args); + } }\n"; } return result; diff --git a/source/stdx/allocator/gc_allocator.d b/source/stdx/allocator/gc_allocator.d index 104a5e1..f7eed26 100644 --- a/source/stdx/allocator/gc_allocator.d +++ b/source/stdx/allocator/gc_allocator.d @@ -22,7 +22,7 @@ struct GCAllocator deallocate) and $(D reallocate) methods are $(D @system) because they may move memory around, leaving dangling pointers in user code. */ - static pure nothrow @trusted void[] allocate(size_t bytes) + static pure nothrow @trusted void[] allocate()(size_t bytes) { if (!bytes) return null; auto p = GC.malloc(bytes); @@ -30,7 +30,7 @@ struct GCAllocator } /// Ditto - static @system bool expand(ref void[] b, size_t delta) + static @system bool expand()(ref void[] b, size_t delta) { if (delta == 0) return true; if (b is null) return false; @@ -53,7 +53,7 @@ struct GCAllocator } /// Ditto - static pure nothrow @system bool reallocate(ref void[] b, size_t newSize) + static pure nothrow @system bool reallocate()(ref void[] b, size_t newSize) { import core.exception : OutOfMemoryError; try @@ -71,7 +71,7 @@ struct GCAllocator /// Ditto pure nothrow - static Ternary resolveInternalPointer(const void* p, ref void[] result) + static Ternary resolveInternalPointer()(const void* p, ref void[] result) { auto r = GC.addrOf(cast(void*) p); if (!r) return Ternary.no; @@ -80,14 +80,14 @@ struct GCAllocator } /// Ditto - static pure nothrow @system bool deallocate(void[] b) + static pure nothrow @system bool deallocate()(void[] b) { GC.free(b.ptr); return true; } /// Ditto - static size_t goodAllocSize(size_t n) + static size_t goodAllocSize()(size_t n) { if (n == 0) return 0; @@ -112,7 +112,7 @@ struct GCAllocator enum GCAllocator instance = GCAllocator(); // Leave it undocummented for now. - static nothrow @trusted void collect() + static nothrow @trusted void collect()() { GC.collect(); } diff --git a/source/stdx/allocator/mallocator.d b/source/stdx/allocator/mallocator.d index 1924812..b7ffc2a 100644 --- a/source/stdx/allocator/mallocator.d +++ b/source/stdx/allocator/mallocator.d @@ -23,7 +23,7 @@ struct Mallocator programs that can afford to leak memory allocated. */ @trusted @nogc nothrow - static void[] allocate(size_t bytes) + static void[] allocate()(size_t bytes) { import core.stdc.stdlib : malloc; if (!bytes) return null; @@ -33,7 +33,7 @@ struct Mallocator /// Ditto @system @nogc nothrow - static bool deallocate(void[] b) + static bool deallocate()(void[] b) { import core.stdc.stdlib : free; free(b.ptr); @@ -42,7 +42,7 @@ struct Mallocator /// Ditto @system @nogc nothrow - static bool reallocate(ref void[] b, size_t s) + static bool reallocate()(ref void[] b, size_t s) { import core.stdc.stdlib : realloc; if (!s) @@ -124,14 +124,14 @@ version (Windows) size_t size; @nogc nothrow - static AlignInfo* opCall(void* ptr) + static AlignInfo* opCall()(void* ptr) { return cast(AlignInfo*) (ptr - AlignInfo.sizeof); } } @nogc nothrow - private void* _aligned_malloc(size_t size, size_t alignment) + private void* _aligned_malloc()(size_t size, size_t alignment) { import core.stdc.stdlib : malloc; size_t offset = alignment + size_t.sizeof * 2 - 1; @@ -153,7 +153,7 @@ version (Windows) } @nogc nothrow - private void* _aligned_realloc(void* ptr, size_t size, size_t alignment) + private void* _aligned_realloc()(void* ptr, size_t size, size_t alignment) { import core.stdc.stdlib : free; import core.stdc.string : memcpy; @@ -180,7 +180,7 @@ version (Windows) } @nogc nothrow - private void _aligned_free(void *ptr) + private void _aligned_free()(void *ptr) { import core.stdc.stdlib : free; if (!ptr) return; @@ -214,7 +214,7 @@ struct AlignedMallocator Forwards to $(D alignedAllocate(bytes, platformAlignment)). */ @trusted @nogc nothrow - static void[] allocate(size_t bytes) + static void[] allocate()(size_t bytes) { if (!bytes) return null; return alignedAllocate(bytes, alignment); @@ -228,7 +228,7 @@ struct AlignedMallocator */ version(Posix) @trusted @nogc nothrow - static void[] alignedAllocate(size_t bytes, uint a) + static void[] alignedAllocate()(size_t bytes, uint a) { import core.stdc.errno : ENOMEM, EINVAL; assert(a.isGoodDynamicAlignment); @@ -250,7 +250,7 @@ struct AlignedMallocator } else version(Windows) @trusted @nogc nothrow - static void[] alignedAllocate(size_t bytes, uint a) + static void[] alignedAllocate()(size_t bytes, uint a) { auto result = _aligned_malloc(bytes, a); return result ? result[0 .. bytes] : null; @@ -264,7 +264,7 @@ struct AlignedMallocator */ version (Posix) @system @nogc nothrow - static bool deallocate(void[] b) + static bool deallocate()(void[] b) { import core.stdc.stdlib : free; free(b.ptr); @@ -272,7 +272,7 @@ struct AlignedMallocator } else version (Windows) @system @nogc nothrow - static bool deallocate(void[] b) + static bool deallocate()(void[] b) { _aligned_free(b.ptr); return true; @@ -285,13 +285,13 @@ struct AlignedMallocator */ version (Posix) @system @nogc nothrow - static bool reallocate(ref void[] b, size_t newSize) + static bool reallocate()(ref void[] b, size_t newSize) { return Mallocator.instance.reallocate(b, newSize); } version (Windows) @system @nogc nothrow - static bool reallocate(ref void[] b, size_t newSize) + static bool reallocate()(ref void[] b, size_t newSize) { return alignedReallocate(b, newSize, alignment); } @@ -304,7 +304,7 @@ struct AlignedMallocator */ version (Windows) @system @nogc nothrow - static bool alignedReallocate(ref void[] b, size_t s, uint a) + static bool alignedReallocate()(ref void[] b, size_t s, uint a) { if (!s) { diff --git a/source/stdx/allocator/mmap_allocator.d b/source/stdx/allocator/mmap_allocator.d index a155958..df1edc8 100644 --- a/source/stdx/allocator/mmap_allocator.d +++ b/source/stdx/allocator/mmap_allocator.d @@ -28,7 +28,7 @@ struct MmapAllocator version(Posix) { /// Allocator API. - static void[] allocate(size_t bytes) + static void[] allocate()(size_t bytes) { import core.sys.posix.sys.mman : mmap, MAP_ANON, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_FAILED; @@ -40,7 +40,7 @@ struct MmapAllocator } /// Ditto - static bool deallocate(void[] b) + static bool deallocate()(void[] b) { import core.sys.posix.sys.mman : munmap; if (b.ptr) munmap(b.ptr, b.length) == 0 || assert(0); @@ -53,7 +53,7 @@ struct MmapAllocator PAGE_READWRITE, MEM_RELEASE; /// Allocator API. - static void[] allocate(size_t bytes) + static void[] allocate()(size_t bytes) { if (!bytes) return null; auto p = VirtualAlloc(null, bytes, MEM_COMMIT, PAGE_READWRITE); @@ -63,7 +63,7 @@ struct MmapAllocator } /// Ditto - static bool deallocate(void[] b) + static bool deallocate()(void[] b) { return b.ptr is null || VirtualFree(b.ptr, 0, MEM_RELEASE) != 0; } diff --git a/source/stdx/allocator/package.d b/source/stdx/allocator/package.d index 49ce53e..f2a8203 100644 --- a/source/stdx/allocator/package.d +++ b/source/stdx/allocator/package.d @@ -463,7 +463,7 @@ interface ISharedAllocator private shared ISharedAllocator _processAllocator; private IAllocator _threadAllocator; -private IAllocator setupThreadAllocator() nothrow @nogc @safe +private IAllocator setupThreadAllocator()() nothrow @nogc @safe { /* Forwards the `_threadAllocator` calls to the `processAllocator`