diff --git a/source/tanya/container/buffer.d b/source/tanya/container/buffer.d index fb11853..cd1effb 100644 --- a/source/tanya/container/buffer.d +++ b/source/tanya/container/buffer.d @@ -3,6 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** + * This module contains buffers designed for C-style input/output APIs. + * * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). diff --git a/source/tanya/math/package.d b/source/tanya/math/package.d index 3537bc3..c706297 100644 --- a/source/tanya/math/package.d +++ b/source/tanya/math/package.d @@ -3,6 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** + * This package provides mathematical functions. + * * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). diff --git a/source/tanya/memory/allocator.d b/source/tanya/memory/allocator.d index dca44d0..369a189 100644 --- a/source/tanya/memory/allocator.d +++ b/source/tanya/memory/allocator.d @@ -3,6 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** + * This module contains the interface for implementing custom allocators. + * + * Allocators are classes encapsulating memory allocation strategy. This allows + * to decouple memory management from the algorithms and the data. + * * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). diff --git a/source/tanya/memory/mallocator.d b/source/tanya/memory/mallocator.d index 0c86e9d..887ade9 100644 --- a/source/tanya/memory/mallocator.d +++ b/source/tanya/memory/mallocator.d @@ -3,6 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** + * Allocator based on $(D_PSYMBOL malloc), $(D_PSYMBOL realloc) and $(D_PSYMBOL free). + * * Copyright: Eugene Wissner 2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). @@ -14,7 +16,8 @@ import core.stdc.stdlib; import tanya.memory.allocator; /** - * Wrapper for malloc/realloc/free from the C standard library. + * Wrapper for $(D_PSYMBOL malloc)/$(D_PSYMBOL realloc)/$(D_PSYMBOL free) from + * the C standard library. */ final class Mallocator : Allocator { diff --git a/source/tanya/memory/mmappool.d b/source/tanya/memory/mmappool.d index 4d64a0f..06d371d 100644 --- a/source/tanya/memory/mmappool.d +++ b/source/tanya/memory/mmappool.d @@ -3,6 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** + * Native allocator for Posix and Windows. + * * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d index f48fbd1..5293f24 100644 --- a/source/tanya/memory/package.d +++ b/source/tanya/memory/package.d @@ -3,6 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** + * Dynamic memory management. + * * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). diff --git a/source/tanya/memory/smartref.d b/source/tanya/memory/smartref.d index eda0aea..4a00672 100644 --- a/source/tanya/memory/smartref.d +++ b/source/tanya/memory/smartref.d @@ -5,6 +5,9 @@ /** * Smart pointers. * + * A smart pointer is an object that wraps a raw pointer or a reference + * (class, array) to manage its lifetime. + * * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). @@ -41,7 +44,7 @@ package final class RefCountedStore(T) if (op == "--" || op == "++") in { - assert(counter > 0); + assert(this.counter > 0); } body { @@ -63,15 +66,6 @@ package final class RefCountedStore(T) return 0; } } - - private unittest - { - auto rcs = defaultAllocator.make!(RefCountedStore!int); - assert(rcs >= 1); - assert(rcs > 0); - assert(!(rcs > 2)); - defaultAllocator.dispose(rcs); - } } package void separateDeleter(T)(RefCountedStore!T storage, @@ -107,8 +101,8 @@ struct RefCounted(T) invariant { - assert(storage is null || allocator_ !is null); - assert(storage is null || deleter !is null); + assert(this.storage is null || this.allocator_ !is null); + assert(this.storage is null || this.deleter !is null); } /** @@ -122,18 +116,13 @@ struct RefCounted(T) * * Precondition: $(D_INLINECODE allocator !is null) */ - this()(auto ref Payload!T value, - shared Allocator allocator = defaultAllocator) + this(Payload!T value, shared Allocator allocator = defaultAllocator) { this(allocator); this.storage = allocator.make!Storage(); this.deleter = &separateDeleter!(Payload!T); - move(value, this.storage.payload); - static if (__traits(isRef, value)) - { - value = null; - } + this.storage.payload = value; } /// Ditto. @@ -165,7 +154,7 @@ struct RefCounted(T) */ ~this() { - if (this.storage !is null && !(this.storage.counter && --this.storage)) + if (this.storage !is null && !(this.storage > 0 && --this.storage)) { deleter(this.storage, allocator); } @@ -218,22 +207,6 @@ struct RefCounted(T) assert(*rc == 7); } - private @nogc unittest - { - auto rc = defaultAllocator.refCounted!int(5); - - void func(RefCounted!int param) @nogc - { - assert(rc.count == 2); - rc = defaultAllocator.make!int(7); - assert(rc.count == 1); - assert(*rc == 7); - } - func(rc); - assert(rc.count == 1); - assert(*rc == 7); - } - /// Ditto. ref typeof(this) opAssign(typeof(null)) { @@ -254,7 +227,7 @@ struct RefCounted(T) return this; } - private unittest + private @nogc unittest { RefCounted!int rc; assert(!rc.isInitialized); @@ -349,6 +322,37 @@ unittest assert(*rc.storage.payload == 9); } +private @nogc unittest +{ + auto rc = defaultAllocator.refCounted!int(5); + + void func(RefCounted!int param) @nogc + { + assert(param.count == 2); + param = defaultAllocator.make!int(7); + assert(param.count == 1); + assert(*param == 7); + } + func(rc); + assert(rc.count == 1); + assert(*rc == 5); +} + +private @nogc unittest +{ + RefCounted!int rc; + + void func(RefCounted!int param) @nogc + { + assert(param.count == 0); + param = defaultAllocator.make!int(7); + assert(param.count == 1); + assert(*param == 7); + } + func(rc); + assert(rc.count == 0); +} + private unittest { RefCounted!int rc1, rc2; @@ -603,8 +607,6 @@ private @nogc unittest auto p1 = defaultAllocator.make!int(5); auto p2 = p1; auto rc = RefCounted!int(p1, defaultAllocator); - - assert(p1 is null); assert(rc.get() is p2); } @@ -651,16 +653,10 @@ struct Unique(T) * * Precondition: $(D_INLINECODE allocator !is null) */ - this()(auto ref Payload!T value, - shared Allocator allocator = defaultAllocator) + this(Payload!T value, shared Allocator allocator = defaultAllocator) { this(allocator); - - move(value, this.payload); - static if (__traits(isRef, value)) - { - value = null; - } + this.payload = value; } /// Ditto. @@ -684,10 +680,7 @@ struct Unique(T) */ ~this() { - if (this.payload !is null) - { - allocator.dispose(this.payload); - } + allocator.dispose(this.payload); } /** @@ -728,6 +721,14 @@ struct Unique(T) return this; } + /// + @nogc unittest + { + auto rc = defaultAllocator.unique!int(5); + rc = defaultAllocator.make!int(7); + assert(*rc == 7); + } + /** * Returns: Reference to the owned object. */ @@ -806,7 +807,6 @@ struct Unique(T) { auto p = defaultAllocator.make!int(5); auto s = Unique!int(p, defaultAllocator); - assert(p is null); assert(*s == 5); } @@ -912,9 +912,8 @@ private @nogc unittest { auto p1 = defaultAllocator.make!int(5); auto p2 = p1; - auto rc = Unique!int(p1, defaultAllocator); - assert(p1 is null); + auto rc = Unique!int(p1, defaultAllocator); assert(rc.get() is p2); }