From 938a1bb5b400c39c34f9659da4945c299467d3f0 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Tue, 25 May 2021 09:03:00 +0200 Subject: [PATCH] Replace short preconditions in the main package --- source/tanya/algorithm/iteration.d | 40 ++++- source/tanya/async/event/iocp.d | 20 ++- source/tanya/async/event/selector.d | 36 ++++- source/tanya/async/loop.d | 14 +- source/tanya/async/transport.d | 10 +- source/tanya/async/watcher.d | 12 +- source/tanya/container/array.d | 232 +++++++++++++++++++++------- source/tanya/container/buffer.d | 45 ++++-- source/tanya/container/entry.d | 24 ++- source/tanya/container/hashtable.d | 173 ++++++++++++++++----- source/tanya/container/list.d | 229 +++++++++++++++++++++------ source/tanya/container/set.d | 93 ++++++++--- source/tanya/container/string.d | 220 +++++++++++++++++++------- source/tanya/conv.d | 14 +- source/tanya/format.d | 26 +++- source/tanya/math/package.d | 6 +- source/tanya/math/random.d | 5 +- source/tanya/net/inet.d | 30 +++- source/tanya/net/ip.d | 42 ++++- source/tanya/range/adapter.d | 6 +- source/tanya/range/array.d | 24 ++- source/tanya/range/primitive.d | 12 +- source/tanya/typecons.d | 6 +- 23 files changed, 1024 insertions(+), 295 deletions(-) diff --git a/source/tanya/algorithm/iteration.d b/source/tanya/algorithm/iteration.d index 14b50fd..aae83f1 100644 --- a/source/tanya/algorithm/iteration.d +++ b/source/tanya/algorithm/iteration.d @@ -48,7 +48,11 @@ private struct SingletonByValue(E) } @property ref inout(E) front() inout - in (!empty) + in + { + assert(!empty); + } + do { return this.element.get; } @@ -56,7 +60,11 @@ private struct SingletonByValue(E) alias back = front; void popFront() - in (!empty) + in + { + assert(!empty); + } + do { this.element.nullify(); } @@ -79,8 +87,12 @@ private struct SingletonByValue(E) } ref inout(E) opIndex(size_t i) inout - in (!empty) - in (i == 0) + in + { + assert(!empty); + assert(i == 0); + } + do { return this.element.get; } @@ -98,7 +110,11 @@ private struct SingletonByRef(E) } @property ref inout(E) front() inout return - in (!empty) + in + { + assert(!empty); + } + do { return *this.element; } @@ -106,7 +122,11 @@ private struct SingletonByRef(E) alias back = front; void popFront() - in (!empty) + in + { + assert(!empty); + } + do { this.element = null; } @@ -129,8 +149,12 @@ private struct SingletonByRef(E) } ref inout(E) opIndex(size_t i) inout return - in (!empty) - in (i == 0) + in + { + assert(!empty); + assert(i == 0); + } + do { return *this.element; } diff --git a/source/tanya/async/event/iocp.d b/source/tanya/async/event/iocp.d index edcd596..df8c8d6 100644 --- a/source/tanya/async/event/iocp.d +++ b/source/tanya/async/event/iocp.d @@ -67,7 +67,11 @@ final class StreamTransport : SocketWatcher, DuplexTransport, SocketTransport * Postcondition: $(D_INLINECODE socket !is null) */ override @property OverlappedConnectedSocket socket() pure nothrow @safe @nogc - out (socket; socket !is null) + out (socket) + { + assert(socket !is null); + } + do { return cast(OverlappedConnectedSocket) socket_; } @@ -120,7 +124,11 @@ final class StreamTransport : SocketWatcher, DuplexTransport, SocketTransport * Precondition: $(D_INLINECODE protocol !is null) */ @property void protocol(Protocol protocol) pure nothrow @safe @nogc - in (protocol !is null) + in + { + assert(protocol !is null); + } + do { protocol_ = protocol; } @@ -255,8 +263,12 @@ final class IOCPLoop : Loop } private void kill(StreamTransport transport, - SocketException exception = null) @nogc - in (transport !is null) + SocketException exception = null) @nogc + in + { + assert(transport !is null); + } + do { transport.socket.shutdown(); defaultAllocator.dispose(transport.socket); diff --git a/source/tanya/async/event/selector.d b/source/tanya/async/event/selector.d index 17554fb..897ad99 100644 --- a/source/tanya/async/event/selector.d +++ b/source/tanya/async/event/selector.d @@ -75,14 +75,22 @@ package class StreamTransport : SocketWatcher, DuplexTransport, SocketTransport * Postcondition: $(D_INLINECODE socket !is null) */ override @property ConnectedSocket socket() pure nothrow @safe @nogc - out (socket; socket !is null) + out (socket) + { + assert(socket !is null); + } + do { return cast(ConnectedSocket) socket_; } private @property void socket(ConnectedSocket socket) pure nothrow @safe @nogc - in (socket !is null) + in + { + assert(socket !is null); + } + do { socket_ = socket; } @@ -106,7 +114,11 @@ package class StreamTransport : SocketWatcher, DuplexTransport, SocketTransport * Precondition: $(D_INLINECODE protocol !is null) */ @property void protocol(Protocol protocol) pure nothrow @safe @nogc - in (protocol !is null) + in + { + assert(protocol !is null); + } + do { protocol_ = protocol; } @@ -245,7 +257,11 @@ abstract class SelectorLoop : Loop */ protected void kill(StreamTransport transport, SocketException exception = null) @nogc - in (transport !is null) + in + { + assert(transport !is null); + } + do { transport.socket.shutdown(); defaultAllocator.dispose(transport.socket); @@ -267,7 +283,11 @@ abstract class SelectorLoop : Loop */ protected bool feed(StreamTransport transport, SocketException exception = null) @nogc - in (transport !is null) + in + { + assert(transport !is null); + } + do { while (transport.input.length && transport.writeReady) { @@ -330,7 +350,11 @@ abstract class SelectorLoop : Loop * connection = Connection watcher ready to accept. */ package void acceptConnections(ConnectionWatcher connection) @nogc - in (connection !is null) + in + { + assert(connection !is null); + } + do { while (true) { diff --git a/source/tanya/async/loop.d b/source/tanya/async/loop.d index c496598..6653282 100644 --- a/source/tanya/async/loop.d +++ b/source/tanya/async/loop.d @@ -262,8 +262,12 @@ abstract class Loop * $(D_PSYMBOL maxBlockTime). */ protected @property void blockTime(in Duration blockTime) @safe pure nothrow @nogc - in (blockTime <= 1.dur!"hours", "Too long to wait.") - in (!blockTime.isNegative) + in + { + assert(blockTime <= 1.dur!"hours", "Too long to wait."); + assert(!blockTime.isNegative); + } + do { blockTime_ = blockTime; } @@ -336,7 +340,11 @@ class BadLoopException : Exception * loop = The event loop. */ @property void defaultLoop(Loop loop) @nogc -in (loop !is null) +in +{ + assert(loop !is null); +} +do { defaultLoop_ = loop; } diff --git a/source/tanya/async/transport.d b/source/tanya/async/transport.d index be8c85d..349abc3 100644 --- a/source/tanya/async/transport.d +++ b/source/tanya/async/transport.d @@ -57,7 +57,10 @@ interface DuplexTransport : ReadTransport, WriteTransport * Postcondition: $(D_INLINECODE protocol !is null) */ @property Protocol protocol() pure nothrow @safe @nogc - out (protocol; protocol !is null); + out (protocol) + { + assert(protocol !is null); + } /** * Switches the protocol. @@ -70,7 +73,10 @@ interface DuplexTransport : ReadTransport, WriteTransport * Precondition: $(D_INLINECODE protocol !is null) */ @property void protocol(Protocol protocol) pure nothrow @safe @nogc - in (protocol !is null); + in + { + assert(protocol !is null); + } /** diff --git a/source/tanya/async/watcher.d b/source/tanya/async/watcher.d index 1895898..8656c94 100644 --- a/source/tanya/async/watcher.d +++ b/source/tanya/async/watcher.d @@ -52,7 +52,11 @@ abstract class SocketWatcher : Watcher * Precondition: $(D_INLINECODE socket !is null) */ this(Socket socket) pure nothrow @safe @nogc - in (socket !is null) + in + { + assert(socket !is null); + } + do { socket_ = socket; } @@ -98,7 +102,11 @@ class ConnectionWatcher : SocketWatcher * Invokes new connection callback. */ override void invoke() @nogc - in (protocolFactory !is null, "Protocol isn't set.") + in + { + assert(protocolFactory !is null, "Protocol isn't set."); + } + do { for (; !this.incoming.empty; this.incoming.removeFront()) { diff --git a/source/tanya/container/array.d b/source/tanya/container/array.d index d2e0d09..6031c21 100644 --- a/source/tanya/container/array.d +++ b/source/tanya/container/array.d @@ -36,16 +36,23 @@ struct Range(A) private E* begin, end; private A* container; - invariant (this.begin <= this.end); - invariant (this.container !is null); - invariant (this.begin >= this.container.data); - invariant (this.end <= this.container.data + this.container.length); + invariant + { + assert(this.begin <= this.end); + assert(this.container !is null); + assert(this.begin >= this.container.data); + assert(this.end <= this.container.data + this.container.length); + } private this(return ref A container, return E* begin, return E* end) @trusted - in (begin <= end) - in (begin >= container.data) - in (end <= container.data + container.length) + in + { + assert(begin <= end); + assert(begin >= container.data); + assert(end <= container.data + container.length); + } + do { this.container = &container; this.begin = begin; @@ -72,31 +79,51 @@ struct Range(A) alias opDollar = length; @property ref inout(E) front() inout - in (!empty) + in + { + assert(!empty); + } + do { return *this.begin; } @property ref inout(E) back() inout @trusted - in (!empty) + in + { + assert(!empty); + } + do { return *(this.end - 1); } void popFront() @trusted - in (!empty) + in + { + assert(!empty); + } + do { ++this.begin; } void popBack() @trusted - in (!empty) + in + { + assert(!empty); + } + do { --this.end; } ref inout(E) opIndex(size_t i) inout @trusted - in (i < length) + in + { + assert(i < length); + } + do { return *(this.begin + i); } @@ -112,15 +139,23 @@ struct Range(A) } Range opSlice(size_t i, size_t j) @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { return typeof(return)(*this.container, this.begin + i, this.begin + j); } A.ConstRange opSlice(size_t i, size_t j) const @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { return typeof(return)(*this.container, this.begin + i, this.begin + j); } @@ -149,8 +184,11 @@ struct Array(T) private T* data; private size_t capacity_; - invariant (this.length_ <= this.capacity_); - invariant (this.capacity_ == 0 || this.data !is null); + invariant + { + assert(this.length_ <= this.capacity_); + assert(this.capacity_ == 0 || this.data !is null); + } /** * Creates a new $(D_PSYMBOL Array) with the elements from a static array. @@ -276,7 +314,11 @@ struct Array(T) /// ditto this(shared Allocator allocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { allocator_ = allocator; } @@ -532,7 +574,11 @@ struct Array(T) * Precondition: $(D_INLINECODE !empty). */ void removeBack() - in (!empty) + in + { + assert(!empty); + } + do { length = length - 1; } @@ -550,7 +596,11 @@ struct Array(T) * Returns: The number of elements removed */ size_t removeBack(size_t howMany) - out (removed; removed <= howMany) + out (removed) + { + assert(removed <= howMany); + } + do { const toRemove = min(howMany, length); @@ -571,7 +621,11 @@ struct Array(T) } private inout(T)[] slice(size_t length) inout @trusted - in (length <= capacity) + in + { + assert(length <= capacity); + } + do { return this.data[0 .. length]; } @@ -593,9 +647,13 @@ struct Array(T) * Precondition: $(D_PARAM r) refers to a region of $(D_KEYWORD this). */ Range remove(scope Range r) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= end) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= end); + } + do { auto target = r.begin; auto source = r.end; @@ -745,9 +803,13 @@ struct Array(T) if (!isInfinite!R && isInputRange!R && isImplicitlyConvertible!(ElementType!R, T)) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= this.data + length) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= this.data + length); + } + do { const oldLength = length; const after = r.end - this.data; @@ -759,9 +821,13 @@ struct Array(T) /// ditto size_t insertAfter(size_t R)(Range r, T[R] el) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= this.data + length) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= this.data + length); + } + do { return insertAfter!(T[])(r, el[]); } @@ -769,9 +835,13 @@ struct Array(T) /// ditto size_t insertAfter(R)(Range r, auto ref R el) if (isImplicitlyConvertible!(R, T)) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= this.data + length) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= this.data + length); + } + do { const oldLen = length; const offset = r.end - this.data; @@ -792,20 +862,28 @@ struct Array(T) /// ditto size_t insertBefore(R)(Range r, scope R el) if (!isInfinite!R - && isInputRange!R - && isImplicitlyConvertible!(ElementType!R, T)) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= this.data + length) + && isInputRange!R + && isImplicitlyConvertible!(ElementType!R, T)) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= this.data + length); + } + do { return insertAfter(Range(this, this.data, r.begin), el); } /// ditto size_t insertBefore(size_t R)(Range r, T[R] el) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= this.data + length) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= this.data + length); + } + do { return insertBefore!(T[])(r, el[]); } @@ -813,9 +891,13 @@ struct Array(T) /// ditto size_t insertBefore(R)(Range r, auto ref R el) if (isImplicitlyConvertible!(R, T)) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= this.data + length) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= this.data + length); + } + do { const oldLen = length; const offset = r.begin - this.data; @@ -983,7 +1065,11 @@ struct Array(T) * Precondition: $(D_INLINECODE length > pos). */ ref inout(T) opIndex(size_t pos) inout @trusted - in (length > pos) + in + { + assert(length > pos); + } + do { return *(this.data + pos); } @@ -1084,7 +1170,11 @@ struct Array(T) * Precondition: $(D_INLINECODE !empty). */ @property ref inout(T) front() inout - in (!empty) + in + { + assert(!empty); + } + do { return *this.data; } @@ -1107,7 +1197,11 @@ struct Array(T) * Precondition: $(D_INLINECODE !empty). */ @property ref inout(T) back() inout @trusted - in (!empty) + in + { + assert(!empty); + } + do { return *(this.data + length - 1); } @@ -1135,16 +1229,24 @@ struct Array(T) * Precondition: $(D_INLINECODE i <= j && j <= length). */ Range opSlice(size_t i, size_t j) @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { return typeof(return)(this, this.data + i, this.data + j); } /// ditto ConstRange opSlice(size_t i, size_t j) const @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { return typeof(return)(this, this.data + i, this.data + j); } @@ -1201,8 +1303,12 @@ struct Array(T) */ Range opSliceAssign(size_t R)(T[R] value, size_t i, size_t j) @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { copy(value[], this.data[i .. j]); return opSlice(i, j); @@ -1211,8 +1317,12 @@ struct Array(T) /// ditto Range opSliceAssign(R : T)(auto ref R value, size_t i, size_t j) @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { fill(this.data[i .. j], value); return opSlice(i, j); @@ -1220,9 +1330,13 @@ struct Array(T) /// ditto Range opSliceAssign()(Range value, size_t i, size_t j) @trusted - in (i <= j) - in (j <= length) - in (j - i == value.length) + in + { + assert(i <= j); + assert(j <= length); + assert(j - i == value.length); + } + do { copy(value, this.data[i .. j]); return opSlice(i, j); diff --git a/source/tanya/container/buffer.d b/source/tanya/container/buffer.d index 5b613af..fac9a82 100644 --- a/source/tanya/container/buffer.d +++ b/source/tanya/container/buffer.d @@ -22,7 +22,11 @@ version (unittest) private int fillBuffer(ubyte[] buffer, int start = 0, int end = 10) @nogc pure nothrow - in (start < end) + in + { + assert(start < end); + } + do { auto numberRead = end - start; for (ubyte i; i < numberRead; ++i) @@ -67,9 +71,12 @@ if (isScalarType!T) /// Size by which the buffer will grow. private size_t blockSize = 8192; - invariant (this.length_ <= this.buffer_.length); - invariant (this.blockSize > 0); - invariant (this.minAvailable > 0); + invariant + { + assert(this.length_ <= this.buffer_.length); + assert(this.blockSize > 0); + assert(this.minAvailable > 0); + } /** * Creates a new read buffer. @@ -94,7 +101,11 @@ if (isScalarType!T) /// ditto this(shared Allocator allocator) - in (allocator_ is null) + in + { + assert(allocator_ is null); + } + do { allocator_ = allocator; } @@ -312,9 +323,13 @@ if (isScalarType!T) /// The position of the free area in the buffer. private size_t position; - invariant (this.blockSize > 0); - // Position can refer to an element outside the buffer if the buffer is full. - invariant (this.position <= this.buffer_.length); + invariant + { + assert(this.blockSize > 0); + // Position can refer to an element outside the buffer if the buffer is + // full. + assert(this.position <= this.buffer_.length); + } /** * Params: @@ -325,8 +340,12 @@ if (isScalarType!T) * Precondition: $(D_INLINECODE size > 0 && allocator !is null) */ this(size_t size, shared Allocator allocator = defaultAllocator) @trusted - in (size > 0) - in (allocator !is null) + in + { + assert(size > 0); + assert(allocator !is null); + } + do { this.blockSize = size; ring = size - 1; @@ -487,7 +506,11 @@ if (isScalarType!T) */ ref WriteBuffer opOpAssign(string op)(size_t length) if (op == "+") - in (length <= this.length) + in + { + assert(length <= this.length); + } + do { auto afterRing = ring + 1; auto oldStart = start; diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d index 82fa12d..02eca4f 100644 --- a/source/tanya/container/entry.d +++ b/source/tanya/container/entry.d @@ -128,14 +128,22 @@ package(tanya.container) struct HashArray(alias hasher, K, V = void) size_t length; this(shared Allocator allocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.array = Buckets(allocator); } this(T)(ref T data, shared Allocator allocator) if (is(Unqual!T == HashArray)) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.array = Buckets(data.array, allocator); this.lengthIndex = data.lengthIndex; @@ -144,7 +152,11 @@ package(tanya.container) struct HashArray(alias hasher, K, V = void) // Move constructor void move(ref HashArray data, shared Allocator allocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.array = Buckets(.move(data.array), allocator); this.lengthIndex = data.lengthIndex; @@ -225,7 +237,11 @@ package(tanya.container) struct HashArray(alias hasher, K, V = void) // Takes an index in the primes array. void rehashToSize(const size_t n) - in (n < primes.length) + in + { + assert(n < primes.length); + } + do { auto storage = typeof(this.array)(primes[n], this.array.allocator); DataLoop: foreach (ref e1; this.array[]) diff --git a/source/tanya/container/hashtable.d b/source/tanya/container/hashtable.d index 4dc80c8..723855e 100644 --- a/source/tanya/container/hashtable.d +++ b/source/tanya/container/hashtable.d @@ -71,9 +71,16 @@ struct Range(T) } void popFront() - in (!empty) - in (this.dataRange.front.status == BucketStatus.used) - out (; empty || this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.front.status == BucketStatus.used); + } + out + { + assert(empty || this.dataRange.back.status == BucketStatus.used); + } + do { do { @@ -83,9 +90,16 @@ struct Range(T) } void popBack() - in (!empty) - in (this.dataRange.back.status == BucketStatus.used) - out (; empty || this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.back.status == BucketStatus.used); + } + out + { + assert(empty || this.dataRange.back.status == BucketStatus.used); + } + do { do { @@ -95,15 +109,23 @@ struct Range(T) } @property ref inout(KV) front() inout - in (!empty) - in (this.dataRange.front.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.front.status == BucketStatus.used); + } + do { return this.dataRange.front.kv; } @property ref inout(KV) back() inout - in (!empty) - in (this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.back.status == BucketStatus.used); + } + do { return this.dataRange.back.kv; } @@ -164,9 +186,16 @@ struct ByKey(T) } @property void popFront() - in (!empty) - in (this.dataRange.front.status == BucketStatus.used) - out (; empty || this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.front.status == BucketStatus.used); + } + out + { + assert(empty || this.dataRange.back.status == BucketStatus.used); + } + do { do { @@ -176,9 +205,16 @@ struct ByKey(T) } @property void popBack() - in (!empty) - in (this.dataRange.back.status == BucketStatus.used) - out (; empty || this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.back.status == BucketStatus.used); + } + out + { + assert(empty || this.dataRange.back.status == BucketStatus.used); + } + do { do { @@ -188,15 +224,23 @@ struct ByKey(T) } @property ref inout(Key) front() inout - in (!empty) - in (this.dataRange.front.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.front.status == BucketStatus.used); + } + do { return this.dataRange.front.key; } @property ref inout(Key) back() inout - in (!empty) - in (this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.back.status == BucketStatus.used); + } + do { return this.dataRange.back.key; } @@ -257,9 +301,16 @@ struct ByValue(T) } @property void popFront() - in (!empty) - in (this.dataRange.front.status == BucketStatus.used) - out (; empty || this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.front.status == BucketStatus.used); + } + out + { + assert(empty || this.dataRange.back.status == BucketStatus.used); + } + do { do { @@ -269,9 +320,16 @@ struct ByValue(T) } @property void popBack() - in (!empty) - in (this.dataRange.back.status == BucketStatus.used) - out (; empty || this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.back.status == BucketStatus.used); + } + out + { + assert(empty || this.dataRange.back.status == BucketStatus.used); + } + do { do { @@ -281,15 +339,23 @@ struct ByValue(T) } @property ref inout(Value) front() inout - in (!empty) - in (this.dataRange.front.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.front.status == BucketStatus.used); + } + do { return this.dataRange.front.kv.value; } @property ref inout(Value) back() inout - in (!empty) - in (this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.back.status == BucketStatus.used); + } + do { return this.dataRange.back.kv.value; } @@ -347,7 +413,10 @@ if (isHashFunction!(hasher, Key)) /// ditto alias ConstByValue = .ByValue!(const HashArray); - invariant (this.data.lengthIndex < primes.length); + invariant + { + assert(this.data.lengthIndex < primes.length); + } /** * Constructor. @@ -359,7 +428,11 @@ if (isHashFunction!(hasher, Key)) * Precondition: $(D_INLINECODE allocator !is null). */ this(size_t n, shared Allocator allocator = defaultAllocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this(allocator); this.data.rehash(n); @@ -374,7 +447,11 @@ if (isHashFunction!(hasher, Key)) /// ditto this(shared Allocator allocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.data = HashArray(allocator); } @@ -394,7 +471,11 @@ if (isHashFunction!(hasher, Key)) */ this(S)(ref S init, shared Allocator allocator = defaultAllocator) if (is(Unqual!S == HashTable)) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.data = HashArray(init.data, allocator); } @@ -402,7 +483,11 @@ if (isHashFunction!(hasher, Key)) /// ditto this(S)(S init, shared Allocator allocator = defaultAllocator) if (is(S == HashTable)) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.data.move(init.data, allocator); } @@ -419,7 +504,11 @@ if (isHashFunction!(hasher, Key)) */ this(R)(scope R range, shared Allocator allocator = defaultAllocator) if (isForwardRange!R && is(ElementType!R == KeyValue) && !isInfinite!R) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this(allocator); insert(range); @@ -449,7 +538,11 @@ if (isHashFunction!(hasher, Key)) */ this(size_t n)(KeyValue[n] array, shared Allocator allocator = defaultAllocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this(allocator); insert(array[]); @@ -498,7 +591,11 @@ if (isHashFunction!(hasher, Key)) * Postcondition: $(D_INLINECODE allocator !is null) */ @property shared(Allocator) allocator() const - out (allocator; allocator !is null) + out (allocator) + { + assert(allocator !is null); + } + do { return this.data.array.allocator; } diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d index 56c8d22..90a834b 100644 --- a/source/tanya/container/list.d +++ b/source/tanya/container/list.d @@ -38,7 +38,10 @@ struct SRange(L) private EntryPointer* head; - invariant (this.head !is null); + invariant + { + assert(this.head !is null); + } private this(return ref EntryPointer head) @trusted { @@ -58,13 +61,21 @@ struct SRange(L) } @property ref inout(E) front() inout - in (!empty) + in + { + assert(!empty); + } + do { return (*this.head).content; } void popFront() @trusted - in (!empty) + in + { + assert(!empty); + } + do { this.head = &(*this.head).next; } @@ -196,7 +207,11 @@ struct SList(T) /// ditto this(shared Allocator allocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.allocator_ = allocator; } @@ -318,7 +333,11 @@ struct SList(T) * Precondition: $(D_INLINECODE !empty). */ @property ref inout(T) front() inout - in (!empty) + in + { + assert(!empty); + } + do { return this.head.content; } @@ -459,7 +478,11 @@ struct SList(T) */ size_t insertBefore(R)(Range r, R el) if (isImplicitlyConvertible!(R, T)) - in (checkRangeBelonging(r)) + in + { + assert(checkRangeBelonging(r)); + } + do { return moveEntry(*r.head, el); } @@ -476,9 +499,13 @@ struct SList(T) /// ditto size_t insertBefore(R)(Range r, scope R el) if (!isInfinite!R - && isInputRange!R - && isImplicitlyConvertible!(ElementType!R, T)) - in (checkRangeBelonging(r)) + && isInputRange!R + && isImplicitlyConvertible!(ElementType!R, T)) + in + { + assert(checkRangeBelonging(r)); + } + do { size_t inserted; foreach (e; el) @@ -503,7 +530,11 @@ struct SList(T) /// ditto size_t insertBefore()(Range r, ref T el) @trusted - in (checkRangeBelonging(r)) + in + { + assert(checkRangeBelonging(r)); + } + do { *r.head = allocator.make!Entry(el, *r.head); return 1; @@ -599,7 +630,11 @@ struct SList(T) * Precondition: $(D_INLINECODE !empty) */ void removeFront() - in (!empty) + in + { + assert(!empty); + } + do { auto n = this.head.next; @@ -634,7 +669,11 @@ struct SList(T) * Returns: The number of elements removed. */ size_t removeFront(size_t howMany) - out (removed; removed <= howMany) + out (removed) + { + assert(removed <= howMany); + } + do { size_t i; for (; i < howMany && !empty; ++i) @@ -666,7 +705,11 @@ struct SList(T) * Precondition: $(D_PARAM r) is extracted from this list. */ Range remove(scope Range r) - in (checkRangeBelonging(r)) + in + { + assert(checkRangeBelonging(r)); + } + do { auto outOfScopeList = typeof(this)(allocator); outOfScopeList.head = *r.head; @@ -700,8 +743,12 @@ struct SList(T) * $(D_PARAM range) is extracted from this list. */ Range popFirstOf(Range range) - in (!range.empty) - in (checkRangeBelonging(range)) + in + { + assert(!range.empty); + assert(checkRangeBelonging(range)); + } + do { auto next = (*range.head).next; @@ -891,8 +938,11 @@ struct DRange(L) private EntryPointer* head; private EntryPointer* tail; - invariant (this.head !is null); - invariant (this.tail !is null); + invariant + { + assert(this.head !is null); + assert(this.tail !is null); + } private this(return ref EntryPointer head, return ref EntryPointer tail) @trusted @@ -914,25 +964,41 @@ struct DRange(L) } @property ref inout(E) front() inout - in (!empty) + in + { + assert(!empty); + } + do { return (*this.head).content; } @property ref inout(E) back() inout - in (!empty) + in + { + assert(!empty); + } + do { return (*this.tail).content; } void popFront() @trusted - in (!empty) + in + { + assert(!empty); + } + do { this.head = &(*this.head).next; } void popBack() @trusted - in (!empty) + in + { + assert(!empty); + } + do { this.tail = &(*this.tail).prev; } @@ -980,9 +1046,12 @@ struct DList(T) static if (__VERSION__ < 2086) // Bug #20171. { - invariant ((this.tail is null) == (this.head is null)); - invariant (this.tail is null || this.tail.next is null); - invariant (this.head is null || this.head.prev is null); + invariant + { + assert((this.tail is null) == (this.head is null)); + assert(this.tail is null || this.tail.next is null); + assert(this.head is null || this.head.prev is null); + } } /** @@ -1087,7 +1156,11 @@ struct DList(T) /// ditto this(shared Allocator allocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.allocator_ = allocator; } @@ -1213,7 +1286,11 @@ struct DList(T) * Precondition: $(D_INLINECODE !empty). */ @property ref inout(T) front() inout - in (!empty) + in + { + assert(!empty); + } + do { return this.head.content; } @@ -1224,7 +1301,11 @@ struct DList(T) * Precondition: $(D_INLINECODE !empty). */ @property ref inout(T) back() inout - in (!empty) + in + { + assert(!empty); + } + do { return this.tail.content; } @@ -1267,8 +1348,12 @@ struct DList(T) // Returns count of the elements in the list. private size_t makeList(R)(scope ref R el, out Entry* head, out Entry* tail) @trusted - out (retLength; (retLength == 0 && head is null && tail is null) - || (retLength > 0 && head !is null && tail !is null)) + out (retLength) + { + assert((retLength == 0 && head is null && tail is null) + || (retLength > 0 && head !is null && tail !is null)); + } + do { size_t retLength; @@ -1536,7 +1621,11 @@ struct DList(T) */ size_t insertBefore(R)(Range r, R el) if (isImplicitlyConvertible!(R, T)) - in (checkRangeBelonging(r)) + in + { + assert(checkRangeBelonging(r)); + } + do { return moveFront(*r.head, el); } @@ -1552,7 +1641,11 @@ struct DList(T) /// ditto size_t insertBefore()(Range r, ref T el) @trusted - in (checkRangeBelonging(r)) + in + { + assert(checkRangeBelonging(r)); + } + do { auto temp = allocator.make!Entry(el, *r.head); @@ -1584,9 +1677,13 @@ struct DList(T) /// ditto size_t insertBefore(R)(Range r, scope R el) if (!isInfinite!R - && isInputRange!R - && isImplicitlyConvertible!(ElementType!R, T)) - in (checkRangeBelonging(r)) + && isInputRange!R + && isImplicitlyConvertible!(ElementType!R, T)) + in + { + assert(checkRangeBelonging(r)); + } + do { size_t inserted; foreach (e; el) @@ -1639,7 +1736,11 @@ struct DList(T) */ size_t insertAfter(R)(Range r, R el) @trusted if (isImplicitlyConvertible!(R, T)) - in (checkRangeBelonging(r)) + in + { + assert(checkRangeBelonging(r)); + } + do { return moveBack(*r.tail, el); } @@ -1657,7 +1758,11 @@ struct DList(T) /// ditto size_t insertAfter()(Range r, ref T el) @trusted - in (checkRangeBelonging(r)) + in + { + assert(checkRangeBelonging(r)); + } + do { auto temp = allocator.make!Entry(el, null, *r.tail); @@ -1689,9 +1794,13 @@ struct DList(T) /// ditto size_t insertAfter(R)(Range r, scope R el) if (!isInfinite!R - && isInputRange!R - && isImplicitlyConvertible!(ElementType!R, T)) - in (checkRangeBelonging(r)) + && isInputRange!R + && isImplicitlyConvertible!(ElementType!R, T)) + in + { + assert(checkRangeBelonging(r)); + } + do { return fold!((acc, x) => acc + insertAfter(r, x))(el, size_t.init); } @@ -1777,7 +1886,11 @@ struct DList(T) * Precondition: $(D_INLINECODE !empty) */ void removeFront() - in (!empty) + in + { + assert(!empty); + } + do { auto n = this.head.next; @@ -1809,7 +1922,11 @@ struct DList(T) /// ditto void removeBack() - in (!empty) + in + { + assert(!empty); + } + do { auto n = this.tail.prev; @@ -1851,7 +1968,11 @@ struct DList(T) * Returns: The number of elements removed. */ size_t removeFront(size_t howMany) - out (removed; removed <= howMany) + out (removed) + { + assert(removed <= howMany); + } + do { size_t i; for (; i < howMany && !empty; ++i) @@ -1874,7 +1995,11 @@ struct DList(T) /// ditto size_t removeBack(size_t howMany) - out (removed; removed <= howMany) + out (removed) + { + assert(removed <= howMany); + } + do { size_t i; for (; i < howMany && !empty; ++i) @@ -1906,7 +2031,11 @@ struct DList(T) * Precondition: $(D_PARAM r) is extracted from this list. */ Range remove(scope Range r) - in (checkRangeBelonging(r)) + in + { + assert(checkRangeBelonging(r)); + } + do { // Save references to the elements before and after the range. Entry* headPrev; @@ -1978,7 +2107,11 @@ struct DList(T) * $(D_PARAM range) is extracted from this list. */ Range popFirstOf(Range range) - in (!range.empty) + in + { + assert(!range.empty); + } + do { remove(Range(*range.head, *range.head)); return range; @@ -1986,7 +2119,11 @@ struct DList(T) /// ditto Range popLastOf(Range range) - in (!range.empty) + in + { + assert(!range.empty); + } + do { remove(Range(*range.tail, *range.tail)); return range; diff --git a/source/tanya/container/set.d b/source/tanya/container/set.d index 2c80f0c..ea95bc8 100644 --- a/source/tanya/container/set.d +++ b/source/tanya/container/set.d @@ -69,9 +69,16 @@ struct Range(T) } void popFront() - in (!empty) - in (this.dataRange.front.status == BucketStatus.used) - out (; empty || this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.front.status == BucketStatus.used); + } + out + { + assert(empty || this.dataRange.back.status == BucketStatus.used); + } + do { do { @@ -81,9 +88,16 @@ struct Range(T) } void popBack() - in (!empty) - in (this.dataRange.back.status == BucketStatus.used) - out (; empty || this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.back.status == BucketStatus.used); + } + out + { + assert(empty || this.dataRange.back.status == BucketStatus.used); + } + do { do { @@ -93,15 +107,23 @@ struct Range(T) } @property ref inout(E) front() inout - in (!empty) - in (this.dataRange.front.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.front.status == BucketStatus.used); + } + do { return this.dataRange.front.key; } @property ref inout(E) back() inout - in (!empty) - in (this.dataRange.back.status == BucketStatus.used) + in + { + assert(!empty); + assert(this.dataRange.back.status == BucketStatus.used); + } + do { return this.dataRange.back.key; } @@ -146,9 +168,12 @@ if (isHashFunction!(hasher, T)) /// ditto alias ConstRange = .Range!(const HashArray); - invariant (this.data.lengthIndex < primes.length); - invariant (this.data.array.length == 0 - || this.data.array.length == primes[this.data.lengthIndex]); + invariant + { + assert(this.data.lengthIndex < primes.length); + assert(this.data.array.length == 0 + || this.data.array.length == primes[this.data.lengthIndex]); + } /** * Constructor. @@ -160,7 +185,11 @@ if (isHashFunction!(hasher, T)) * Precondition: $(D_INLINECODE allocator !is null). */ this(size_t n, shared Allocator allocator = defaultAllocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this(allocator); this.data.rehash(n); @@ -175,7 +204,11 @@ if (isHashFunction!(hasher, T)) /// ditto this(shared Allocator allocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.data = HashArray(allocator); } @@ -195,7 +228,11 @@ if (isHashFunction!(hasher, T)) */ this(S)(ref S init, shared Allocator allocator = defaultAllocator) if (is(Unqual!S == Set)) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.data = HashArray(init.data, allocator); } @@ -203,7 +240,11 @@ if (isHashFunction!(hasher, T)) /// ditto this(S)(S init, shared Allocator allocator = defaultAllocator) if (is(S == Set)) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.data.move(init.data, allocator); } @@ -222,7 +263,11 @@ if (isHashFunction!(hasher, T)) if (isForwardRange!R && isImplicitlyConvertible!(ElementType!R, T) && !isInfinite!R) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this(allocator); insert(range); @@ -249,7 +294,11 @@ if (isHashFunction!(hasher, T)) * Precondition: $(D_INLINECODE allocator !is null). */ this(size_t n)(T[n] array, shared Allocator allocator = defaultAllocator) - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this(allocator); insert(array[]); @@ -297,7 +346,11 @@ if (isHashFunction!(hasher, T)) * Postcondition: $(D_INLINECODE allocator !is null) */ @property shared(Allocator) allocator() const - out (allocator; allocator !is null) + out (allocator) + { + assert(allocator !is null); + } + do { return this.data.array.allocator; } diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d index bd8f817..e25e13c 100644 --- a/source/tanya/container/string.d +++ b/source/tanya/container/string.d @@ -70,15 +70,22 @@ if (is(Unqual!E == char)) private alias ContainerType = CopyConstness!(E, String); private ContainerType* container; - invariant (this.begin <= this.end); - invariant (this.container !is null); - invariant (this.begin >= this.container.data); - invariant (this.end <= this.container.data + this.container.length); + invariant + { + assert(this.begin <= this.end); + assert(this.container !is null); + assert(this.begin >= this.container.data); + assert(this.end <= this.container.data + this.container.length); + } private this(ref ContainerType container, E* begin, E* end) @trusted - in (begin <= end) - in (begin >= container.data) - in (end <= container.data + container.length) + in + { + assert(begin <= end); + assert(begin >= container.data); + assert(end <= container.data + container.length); + } + do { this.container = &container; this.begin = begin; @@ -105,31 +112,51 @@ if (is(Unqual!E == char)) alias opDollar = length; @property ref inout(E) front() inout - in (!empty) + in + { + assert(!empty); + } + do { return *this.begin; } @property ref inout(E) back() inout @trusted - in (!empty) + in + { + assert(!empty); + } + do { return *(this.end - 1); } void popFront() @trusted - in (!empty) + in + { + assert(!empty); + } + do { ++this.begin; } void popBack() @trusted - in (!empty) + in + { + assert(!empty); + } + do { --this.end; } ref inout(E) opIndex(const size_t i) inout @trusted - in (i < length) + in + { + assert(i < length); + } + do { return *(this.begin + i); } @@ -145,15 +172,23 @@ if (is(Unqual!E == char)) } ByCodeUnit opSlice(const size_t i, const size_t j) @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { return typeof(return)(*this.container, this.begin + i, this.begin + j); } ByCodeUnit!(const E) opSlice(const size_t i, const size_t j) const @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { return typeof(return)(*this.container, this.begin + i, this.begin + j); } @@ -177,15 +212,22 @@ if (is(Unqual!E == char)) private alias ContainerType = CopyConstness!(E, String); private ContainerType* container; - invariant (this.begin <= this.end); - invariant (this.container !is null); - invariant (this.begin >= this.container.data); - invariant (this.end <= this.container.data + this.container.length); + invariant + { + assert(this.begin <= this.end); + assert(this.container !is null); + assert(this.begin >= this.container.data); + assert(this.end <= this.container.data + this.container.length); + } private this(ref ContainerType container, E* begin, E* end) @trusted - in (begin <= end) - in (begin >= container.data) - in (end <= container.data + container.length) + in + { + assert(begin <= end); + assert(begin >= container.data); + assert(end <= container.data + container.length); + } + do { this.container = &container; this.begin = begin; @@ -205,8 +247,15 @@ if (is(Unqual!E == char)) } @property dchar front() const @trusted - in (!empty) - out (chr; chr < 0xd800 || chr > 0xdfff) + in + { + assert(!empty); + } + out (chr) + { + assert(chr < 0xd800 || chr > 0xdfff); + } + do { dchar chr; ubyte units; @@ -236,7 +285,11 @@ if (is(Unqual!E == char)) } void popFront() @trusted - in (!empty) + in + { + assert(!empty); + } + do { ubyte units; if ((*begin & 0xf0) == 0xf0) @@ -282,7 +335,10 @@ struct String private char* data; private size_t capacity_; - @nogc nothrow pure @safe invariant (this.length_ <= this.capacity_); + @nogc nothrow pure @safe invariant + { + assert(this.length_ <= this.capacity_); + } /** * Constructs the string from a stringish range. @@ -372,7 +428,11 @@ struct String /// ditto this(shared Allocator allocator) @nogc nothrow pure @safe - in (allocator !is null) + in + { + assert(allocator !is null); + } + do { this.allocator_ = allocator; } @@ -451,8 +511,12 @@ struct String private void write4Bytes(ref const dchar src) @nogc nothrow pure @trusted - in (capacity - length >= 4) - in (src - 0x10000 < 0x100000) + in + { + assert(capacity - length >= 4); + assert(src - 0x10000 < 0x100000); + } + do { auto dst = this.data + length; @@ -466,7 +530,11 @@ struct String private size_t insertWideChar(C)(auto ref const C chr) @trusted if (is(C == wchar) || is(C == dchar)) - in (capacity - length >= 3) + in + { + assert(capacity - length >= 3); + } + do { auto dst = this.data + length; if (chr < 0x80) @@ -789,9 +857,13 @@ struct String const size_t i, const size_t j) if (is(Unqual!R == char)) - in (i <= j) - in (j <= length) - in (j - i == value.length) + in + { + assert(i <= j); + assert(j <= length); + assert(j - i == value.length); + } + do { auto target = opSlice(i, j); copy(value, target); @@ -803,8 +875,12 @@ struct String const size_t i, const size_t j) @nogc nothrow pure @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { copy(value[], this.data[i .. j]); return opSlice(i, j); @@ -815,8 +891,12 @@ struct String const size_t i, const size_t j) @nogc nothrow pure @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { for (auto p = this.data + i; p < this.data + j; ++p) { @@ -893,7 +973,11 @@ struct String * Precondition: $(D_INLINECODE length > pos). */ ref inout(char) opIndex(const size_t pos) inout @nogc nothrow pure @trusted - in (length > pos) + in + { + assert(length > pos); + } + do { return *(this.data + pos); } @@ -1038,8 +1122,12 @@ struct String */ ByCodeUnit!char opSlice(const size_t i, const size_t j) @nogc nothrow pure @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { return typeof(return)(this, this.data + i, this.data + j); } @@ -1047,8 +1135,12 @@ struct String /// ditto ByCodeUnit!(const char) opSlice(const size_t i, const size_t j) const @nogc nothrow pure @trusted - in (i <= j) - in (j <= length) + in + { + assert(i <= j); + assert(j <= length); + } + do { return typeof(return)(this, this.data + i, this.data + j); } @@ -1329,9 +1421,13 @@ struct String */ R remove(R)(R r) @trusted if (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= this.data + length) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= this.data + length); + } + do { auto end = this.data + this.length; copy(ByCodeUnit!char(this, r.end, end), ByCodeUnit!char(this, r.begin, end)); @@ -1377,12 +1473,16 @@ struct String */ size_t insertAfter(T, R)(R r, T el) @trusted if ((isSomeChar!T || (!isInfinite!T - && isInputRange!T - && isSomeChar!(ElementType!T))) - && (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char))) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= this.data + length) + && isInputRange!T + && isSomeChar!(ElementType!T))) + && (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char))) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= this.data + length); + } + do { const oldLength = length; const after = r.end - this.data; @@ -1407,12 +1507,16 @@ struct String /// size_t insertBefore(T, R)(R r, T el) @trusted if ((isSomeChar!T || (!isInfinite!T - && isInputRange!T - && isSomeChar!(ElementType!T))) - && (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char))) - in (r.container is &this) - in (r.begin >= this.data) - in (r.end <= this.data + length) + && isInputRange!T + && isSomeChar!(ElementType!T))) + && (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char))) + in + { + assert(r.container is &this); + assert(r.begin >= this.data); + assert(r.end <= this.data + length); + } + do { return insertAfter(R(this, this.data, r.begin), el); } diff --git a/source/tanya/conv.d b/source/tanya/conv.d index 84dc8f5..dcd6a5c 100644 --- a/source/tanya/conv.d +++ b/source/tanya/conv.d @@ -60,11 +60,15 @@ final class ConvException : Exception */ package T readIntegral(T, R)(ref R range, const ubyte base = 10) if (isInputRange!R - && isSomeChar!(ElementType!R) - && isIntegral!T - && isUnsigned!T) -in (base >= 2) -in (base <= 36) + && isSomeChar!(ElementType!R) + && isIntegral!T + && isUnsigned!T) +in +{ + assert(base >= 2); + assert(base <= 36); +} +do { T boundary = cast(T) (T.max / base); if (range.empty) diff --git a/source/tanya/format.d b/source/tanya/format.d index 32249a7..7f09285 100644 --- a/source/tanya/format.d +++ b/source/tanya/format.d @@ -1175,7 +1175,11 @@ private struct uint128 } Tuple!(uint128, uint128) divMod(ulong rhs) const @nogc nothrow pure @safe - in (rhs != uint128(), "Division by 0") + in + { + assert(rhs != uint128(), "Division by 0"); + } + do { if (rhs == 1) { @@ -1273,9 +1277,13 @@ private int indexMismatch(ulong low, ulong high) @nogc nothrow pure @safe } private char[] errol2(double value, - return ref char[512] buffer, - out int exponent) @nogc nothrow pure @safe -in (value > 9.007199254740992e15 && value < 3.40282366920938e38) + return ref char[512] buffer, + out int exponent) @nogc nothrow pure @safe +in +{ + assert(value > 9.007199254740992e15 && value < 3.40282366920938e38); +} +do { auto v = uint128(value); auto leftBoundary = v + raise2ToExp((value - previous(value)) / 2.0); @@ -1358,9 +1366,13 @@ in (value > 9.007199254740992e15 && value < 3.40282366920938e38) } private char[] errolFixed(double value, - return ref char[512] buffer, - out int exponent) @nogc nothrow pure @safe -in (value >= 16.0 && value <= 9.007199254740992e15) + return ref char[512] buffer, + out int exponent) @nogc nothrow pure @safe +in +{ + assert(value >= 16.0 && value <= 9.007199254740992e15); +} +do { auto decimal = cast(ulong) value; auto n = cast(double) decimal; diff --git a/source/tanya/math/package.d b/source/tanya/math/package.d index 3228108..f47f723 100644 --- a/source/tanya/math/package.d +++ b/source/tanya/math/package.d @@ -562,7 +562,11 @@ if (isFloatingPoint!F) */ H pow(I, G, H)(in auto ref I x, in auto ref G y, in auto ref H z) if (isIntegral!I && isIntegral!G && isIntegral!H) -in (z > 0, "Division by zero") +in +{ + assert(z > 0, "Division by zero"); +} +do { G mask = G.max / 2 + 1; H result; diff --git a/source/tanya/math/random.d b/source/tanya/math/random.d index 8a58909..ae199f6 100644 --- a/source/tanya/math/random.d +++ b/source/tanya/math/random.d @@ -92,7 +92,10 @@ abstract class EntropySource * $(D_PARAM output) length. */ Nullable!ubyte poll(out ubyte[maxGather] output) @nogc - out (length; length.isNull || length.get <= maxGather); + out (length) + { + assert(length.isNull || length.get <= maxGather); + } } version (CRuntime_Bionic) diff --git a/source/tanya/net/inet.d b/source/tanya/net/inet.d index 71467f2..65146b6 100644 --- a/source/tanya/net/inet.d +++ b/source/tanya/net/inet.d @@ -72,7 +72,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof) */ this(T)(T value) if (isUnsigned!T) - in (value <= (2 ^^ (L * 8)) - 1) + in + { + assert(value <= (2 ^^ (L * 8)) - 1); + } + do { this.value = value & StorageType.max; } @@ -83,7 +87,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof) * Precondition: $(D_INLINECODE length > 0). */ @property ubyte back() const - in (this.length > 0) + in + { + assert(this.length > 0); + } + do { return this.value & 0xff; } @@ -94,7 +102,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof) * Precondition: $(D_INLINECODE length > 0). */ @property ubyte front() const - in (this.length > 0) + in + { + assert(this.length > 0); + } + do { return (this.value >> ((this.length - 1) * 8)) & 0xff; } @@ -105,7 +117,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof) * Precondition: $(D_INLINECODE length > 0). */ void popBack() - in (this.length > 0) + in + { + assert(this.length > 0); + } + do { this.value >>= 8; --this.size; @@ -117,7 +133,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof) * Precondition: $(D_INLINECODE length > 0). */ void popFront() - in (this.length > 0) + in + { + assert(this.length > 0); + } + do { this.value &= StorageType.max >> ((StorageType.sizeof - this.length) * 8); --this.size; diff --git a/source/tanya/net/ip.d b/source/tanya/net/ip.d index c4a5b53..0f61260 100644 --- a/source/tanya/net/ip.d +++ b/source/tanya/net/ip.d @@ -755,7 +755,11 @@ private void read2Bytes(R)(ref R range, ubyte[] address) } private char toHexDigit(ubyte digit) @nogc nothrow pure @safe -in (digit < 16) +in +{ + assert(digit < 16); +} +do { return cast(char) (digit >= 10 ? (digit - 10 + 'a') : (digit + '0')); } @@ -763,7 +767,11 @@ in (digit < 16) private bool writeHexDigit(OR)(ref OR output, ubyte digit, bool groupStarted = false) -in (digit < 16) +in +{ + assert(digit < 16); +} +do { if (digit != 0 || groupStarted) { @@ -1124,7 +1132,11 @@ struct Address * Precondition: This is an IPv4 address. */ ref inout(Address4) toV4() inout @nogc nothrow pure @safe - in (this.address.peek!Address4) + in + { + assert(this.address.peek!Address4); + } + do { return this.address.get!Address4; } @@ -1147,7 +1159,11 @@ struct Address * Precondition: This is an IPv6 address. */ ref inout(Address6) toV6() inout @nogc nothrow pure @safe - in (this.address.peek!Address6) + in + { + assert(this.address.peek!Address6); + } + do { return this.address.get!Address6; } @@ -1169,7 +1185,11 @@ struct Address * $(D_PSYMBOL Address6.loopback). */ bool isLoopback() const @nogc nothrow pure @safe - in (this.address.hasValue) + in + { + assert(this.address.hasValue); + } + do { if (this.address.peek!Address4) { @@ -1195,7 +1215,11 @@ struct Address * $(D_PSYMBOL Address6.isMulticast). */ bool isMulticast() const @nogc nothrow pure @safe - in (this.address.hasValue) + in + { + assert(this.address.hasValue); + } + do { if (this.address.peek!Address4) { @@ -1220,7 +1244,11 @@ struct Address * See_Also: $(D_PSYMBOL Address4.isAny), $(D_PSYMBOL Address6.isAny). */ bool isAny() const @nogc nothrow pure @safe - in (this.address.hasValue) + in + { + assert(this.address.hasValue); + } + do { if (this.address.peek!Address4) { diff --git a/source/tanya/range/adapter.d b/source/tanya/range/adapter.d index 1a739dc..60d4c67 100644 --- a/source/tanya/range/adapter.d +++ b/source/tanya/range/adapter.d @@ -170,7 +170,11 @@ if (isArray!Array) void opCall(T)(auto ref T data) if (is(T : E)) - in (!this.data.empty) + in + { + assert(!this.data.empty); + } + do { put(this.data, data); } diff --git a/source/tanya/range/array.d b/source/tanya/range/array.d index e412fa1..6104a91 100644 --- a/source/tanya/range/array.d +++ b/source/tanya/range/array.d @@ -55,7 +55,11 @@ module tanya.range.array; * Precondition: $(D_INLINECODE array.length > 0). */ @property ref inout(T) front(T)(return scope inout(T)[] array) -in (array.length > 0) +in +{ + assert(array.length > 0); +} +do { return array[0]; } @@ -91,7 +95,11 @@ in (array.length > 0) * Precondition: $(D_INLINECODE array.length > 0). */ @property ref inout(T) back(T)(return scope inout(T)[] array) -in (array.length > 0) +in +{ + assert(array.length > 0); +} +do { return array[$ - 1]; } @@ -126,14 +134,22 @@ in (array.length > 0) * Precondition: $(D_INLINECODE array.length > 0). */ void popFront(T)(scope ref inout(T)[] array) -in (array.length > 0) +in +{ + assert(array.length > 0); +} +do { array = array[1 .. $]; } /// ditto void popBack(T)(scope ref inout(T)[] array) -in (array.length > 0) +in +{ + assert(array.length > 0); +} +do { array = array[0 .. $ - 1]; } diff --git a/source/tanya/range/primitive.d b/source/tanya/range/primitive.d index b4dcb2e..54646a6 100644 --- a/source/tanya/range/primitive.d +++ b/source/tanya/range/primitive.d @@ -1556,7 +1556,11 @@ if (isInputRange!Range && hasLvalueElements!Range) */ ElementType!R getAndPopFront(R)(ref R range) if (isInputRange!R) -in (!range.empty) +in +{ + assert(!range.empty); +} +do { static if (hasLvalueElements!R) { @@ -1609,7 +1613,11 @@ in (!range.empty) */ auto ref getAndPopBack(R)(ref R range) if (isBidirectionalRange!R) -in (!range.empty) +in +{ + assert(!range.empty); +} +do { static if (hasLvalueElements!R) { diff --git a/source/tanya/typecons.d b/source/tanya/typecons.d index 255303a..d1402cf 100644 --- a/source/tanya/typecons.d +++ b/source/tanya/typecons.d @@ -291,7 +291,11 @@ if (isTypeTuple!Specs && NoDuplicates!Specs.length == Specs.length) */ ref inout(T) get(T)() inout if (canFind!(T, Types)) - in (this.tag == staticIndexOf!(T, Types), "Variant isn't initialized") + in + { + assert(this.tag == staticIndexOf!(T, Types), "Variant isn't initialized"); + } + do { mixin("return " ~ accessor!(T, AlignedUnion!Types).accessor ~ ";"); }