Replace short preconditions in the main package

This commit is contained in:
Eugen Wissner 2021-05-25 09:03:00 +02:00
parent b62cbb0647
commit 938a1bb5b4
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
23 changed files with 1024 additions and 295 deletions

View File

@ -48,7 +48,11 @@ private struct SingletonByValue(E)
} }
@property ref inout(E) front() inout @property ref inout(E) front() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return this.element.get; return this.element.get;
} }
@ -56,7 +60,11 @@ private struct SingletonByValue(E)
alias back = front; alias back = front;
void popFront() void popFront()
in (!empty) in
{
assert(!empty);
}
do
{ {
this.element.nullify(); this.element.nullify();
} }
@ -79,8 +87,12 @@ private struct SingletonByValue(E)
} }
ref inout(E) opIndex(size_t i) inout ref inout(E) opIndex(size_t i) inout
in (!empty) in
in (i == 0) {
assert(!empty);
assert(i == 0);
}
do
{ {
return this.element.get; return this.element.get;
} }
@ -98,7 +110,11 @@ private struct SingletonByRef(E)
} }
@property ref inout(E) front() inout return @property ref inout(E) front() inout return
in (!empty) in
{
assert(!empty);
}
do
{ {
return *this.element; return *this.element;
} }
@ -106,7 +122,11 @@ private struct SingletonByRef(E)
alias back = front; alias back = front;
void popFront() void popFront()
in (!empty) in
{
assert(!empty);
}
do
{ {
this.element = null; this.element = null;
} }
@ -129,8 +149,12 @@ private struct SingletonByRef(E)
} }
ref inout(E) opIndex(size_t i) inout return ref inout(E) opIndex(size_t i) inout return
in (!empty) in
in (i == 0) {
assert(!empty);
assert(i == 0);
}
do
{ {
return *this.element; return *this.element;
} }

View File

@ -67,7 +67,11 @@ final class StreamTransport : SocketWatcher, DuplexTransport, SocketTransport
* Postcondition: $(D_INLINECODE socket !is null) * Postcondition: $(D_INLINECODE socket !is null)
*/ */
override @property OverlappedConnectedSocket socket() pure nothrow @safe @nogc override @property OverlappedConnectedSocket socket() pure nothrow @safe @nogc
out (socket; socket !is null) out (socket)
{
assert(socket !is null);
}
do
{ {
return cast(OverlappedConnectedSocket) socket_; return cast(OverlappedConnectedSocket) socket_;
} }
@ -120,7 +124,11 @@ final class StreamTransport : SocketWatcher, DuplexTransport, SocketTransport
* Precondition: $(D_INLINECODE protocol !is null) * Precondition: $(D_INLINECODE protocol !is null)
*/ */
@property void protocol(Protocol protocol) pure nothrow @safe @nogc @property void protocol(Protocol protocol) pure nothrow @safe @nogc
in (protocol !is null) in
{
assert(protocol !is null);
}
do
{ {
protocol_ = protocol; protocol_ = protocol;
} }
@ -256,7 +264,11 @@ final class IOCPLoop : Loop
private void kill(StreamTransport transport, private void kill(StreamTransport transport,
SocketException exception = null) @nogc SocketException exception = null) @nogc
in (transport !is null) in
{
assert(transport !is null);
}
do
{ {
transport.socket.shutdown(); transport.socket.shutdown();
defaultAllocator.dispose(transport.socket); defaultAllocator.dispose(transport.socket);

View File

@ -75,14 +75,22 @@ package class StreamTransport : SocketWatcher, DuplexTransport, SocketTransport
* Postcondition: $(D_INLINECODE socket !is null) * Postcondition: $(D_INLINECODE socket !is null)
*/ */
override @property ConnectedSocket socket() pure nothrow @safe @nogc override @property ConnectedSocket socket() pure nothrow @safe @nogc
out (socket; socket !is null) out (socket)
{
assert(socket !is null);
}
do
{ {
return cast(ConnectedSocket) socket_; return cast(ConnectedSocket) socket_;
} }
private @property void socket(ConnectedSocket socket) private @property void socket(ConnectedSocket socket)
pure nothrow @safe @nogc pure nothrow @safe @nogc
in (socket !is null) in
{
assert(socket !is null);
}
do
{ {
socket_ = socket; socket_ = socket;
} }
@ -106,7 +114,11 @@ package class StreamTransport : SocketWatcher, DuplexTransport, SocketTransport
* Precondition: $(D_INLINECODE protocol !is null) * Precondition: $(D_INLINECODE protocol !is null)
*/ */
@property void protocol(Protocol protocol) pure nothrow @safe @nogc @property void protocol(Protocol protocol) pure nothrow @safe @nogc
in (protocol !is null) in
{
assert(protocol !is null);
}
do
{ {
protocol_ = protocol; protocol_ = protocol;
} }
@ -245,7 +257,11 @@ abstract class SelectorLoop : Loop
*/ */
protected void kill(StreamTransport transport, protected void kill(StreamTransport transport,
SocketException exception = null) @nogc SocketException exception = null) @nogc
in (transport !is null) in
{
assert(transport !is null);
}
do
{ {
transport.socket.shutdown(); transport.socket.shutdown();
defaultAllocator.dispose(transport.socket); defaultAllocator.dispose(transport.socket);
@ -267,7 +283,11 @@ abstract class SelectorLoop : Loop
*/ */
protected bool feed(StreamTransport transport, protected bool feed(StreamTransport transport,
SocketException exception = null) @nogc SocketException exception = null) @nogc
in (transport !is null) in
{
assert(transport !is null);
}
do
{ {
while (transport.input.length && transport.writeReady) while (transport.input.length && transport.writeReady)
{ {
@ -330,7 +350,11 @@ abstract class SelectorLoop : Loop
* connection = Connection watcher ready to accept. * connection = Connection watcher ready to accept.
*/ */
package void acceptConnections(ConnectionWatcher connection) @nogc package void acceptConnections(ConnectionWatcher connection) @nogc
in (connection !is null) in
{
assert(connection !is null);
}
do
{ {
while (true) while (true)
{ {

View File

@ -262,8 +262,12 @@ abstract class Loop
* $(D_PSYMBOL maxBlockTime). * $(D_PSYMBOL maxBlockTime).
*/ */
protected @property void blockTime(in Duration blockTime) @safe pure nothrow @nogc protected @property void blockTime(in Duration blockTime) @safe pure nothrow @nogc
in (blockTime <= 1.dur!"hours", "Too long to wait.") in
in (!blockTime.isNegative) {
assert(blockTime <= 1.dur!"hours", "Too long to wait.");
assert(!blockTime.isNegative);
}
do
{ {
blockTime_ = blockTime; blockTime_ = blockTime;
} }
@ -336,7 +340,11 @@ class BadLoopException : Exception
* loop = The event loop. * loop = The event loop.
*/ */
@property void defaultLoop(Loop loop) @nogc @property void defaultLoop(Loop loop) @nogc
in (loop !is null) in
{
assert(loop !is null);
}
do
{ {
defaultLoop_ = loop; defaultLoop_ = loop;
} }

View File

@ -57,7 +57,10 @@ interface DuplexTransport : ReadTransport, WriteTransport
* Postcondition: $(D_INLINECODE protocol !is null) * Postcondition: $(D_INLINECODE protocol !is null)
*/ */
@property Protocol protocol() pure nothrow @safe @nogc @property Protocol protocol() pure nothrow @safe @nogc
out (protocol; protocol !is null); out (protocol)
{
assert(protocol !is null);
}
/** /**
* Switches the protocol. * Switches the protocol.
@ -70,7 +73,10 @@ interface DuplexTransport : ReadTransport, WriteTransport
* Precondition: $(D_INLINECODE protocol !is null) * Precondition: $(D_INLINECODE protocol !is null)
*/ */
@property void protocol(Protocol protocol) pure nothrow @safe @nogc @property void protocol(Protocol protocol) pure nothrow @safe @nogc
in (protocol !is null); in
{
assert(protocol !is null);
}
/** /**

View File

@ -52,7 +52,11 @@ abstract class SocketWatcher : Watcher
* Precondition: $(D_INLINECODE socket !is null) * Precondition: $(D_INLINECODE socket !is null)
*/ */
this(Socket socket) pure nothrow @safe @nogc this(Socket socket) pure nothrow @safe @nogc
in (socket !is null) in
{
assert(socket !is null);
}
do
{ {
socket_ = socket; socket_ = socket;
} }
@ -98,7 +102,11 @@ class ConnectionWatcher : SocketWatcher
* Invokes new connection callback. * Invokes new connection callback.
*/ */
override void invoke() @nogc 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()) for (; !this.incoming.empty; this.incoming.removeFront())
{ {

View File

@ -36,16 +36,23 @@ struct Range(A)
private E* begin, end; private E* begin, end;
private A* container; private A* container;
invariant (this.begin <= this.end); invariant
invariant (this.container !is null); {
invariant (this.begin >= this.container.data); assert(this.begin <= this.end);
invariant (this.end <= this.container.data + this.container.length); 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) private this(return ref A container, return E* begin, return E* end)
@trusted @trusted
in (begin <= end) in
in (begin >= container.data) {
in (end <= container.data + container.length) assert(begin <= end);
assert(begin >= container.data);
assert(end <= container.data + container.length);
}
do
{ {
this.container = &container; this.container = &container;
this.begin = begin; this.begin = begin;
@ -72,31 +79,51 @@ struct Range(A)
alias opDollar = length; alias opDollar = length;
@property ref inout(E) front() inout @property ref inout(E) front() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return *this.begin; return *this.begin;
} }
@property ref inout(E) back() inout @trusted @property ref inout(E) back() inout @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
return *(this.end - 1); return *(this.end - 1);
} }
void popFront() @trusted void popFront() @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
++this.begin; ++this.begin;
} }
void popBack() @trusted void popBack() @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
--this.end; --this.end;
} }
ref inout(E) opIndex(size_t i) inout @trusted ref inout(E) opIndex(size_t i) inout @trusted
in (i < length) in
{
assert(i < length);
}
do
{ {
return *(this.begin + i); return *(this.begin + i);
} }
@ -112,15 +139,23 @@ struct Range(A)
} }
Range opSlice(size_t i, size_t j) @trusted Range opSlice(size_t i, size_t j) @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
return typeof(return)(*this.container, this.begin + i, this.begin + j); return typeof(return)(*this.container, this.begin + i, this.begin + j);
} }
A.ConstRange opSlice(size_t i, size_t j) const @trusted A.ConstRange opSlice(size_t i, size_t j) const @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
return typeof(return)(*this.container, this.begin + i, this.begin + j); return typeof(return)(*this.container, this.begin + i, this.begin + j);
} }
@ -149,8 +184,11 @@ struct Array(T)
private T* data; private T* data;
private size_t capacity_; private size_t capacity_;
invariant (this.length_ <= this.capacity_); invariant
invariant (this.capacity_ == 0 || this.data !is null); {
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. * Creates a new $(D_PSYMBOL Array) with the elements from a static array.
@ -276,7 +314,11 @@ struct Array(T)
/// ditto /// ditto
this(shared Allocator allocator) this(shared Allocator allocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
allocator_ = allocator; allocator_ = allocator;
} }
@ -532,7 +574,11 @@ struct Array(T)
* Precondition: $(D_INLINECODE !empty). * Precondition: $(D_INLINECODE !empty).
*/ */
void removeBack() void removeBack()
in (!empty) in
{
assert(!empty);
}
do
{ {
length = length - 1; length = length - 1;
} }
@ -550,7 +596,11 @@ struct Array(T)
* Returns: The number of elements removed * Returns: The number of elements removed
*/ */
size_t removeBack(size_t howMany) size_t removeBack(size_t howMany)
out (removed; removed <= howMany) out (removed)
{
assert(removed <= howMany);
}
do
{ {
const toRemove = min(howMany, length); const toRemove = min(howMany, length);
@ -571,7 +621,11 @@ struct Array(T)
} }
private inout(T)[] slice(size_t length) inout @trusted private inout(T)[] slice(size_t length) inout @trusted
in (length <= capacity) in
{
assert(length <= capacity);
}
do
{ {
return this.data[0 .. length]; return this.data[0 .. length];
} }
@ -593,9 +647,13 @@ struct Array(T)
* Precondition: $(D_PARAM r) refers to a region of $(D_KEYWORD this). * Precondition: $(D_PARAM r) refers to a region of $(D_KEYWORD this).
*/ */
Range remove(scope Range r) Range remove(scope Range r)
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= end) assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= end);
}
do
{ {
auto target = r.begin; auto target = r.begin;
auto source = r.end; auto source = r.end;
@ -745,9 +803,13 @@ struct Array(T)
if (!isInfinite!R if (!isInfinite!R
&& isInputRange!R && isInputRange!R
&& isImplicitlyConvertible!(ElementType!R, T)) && isImplicitlyConvertible!(ElementType!R, T))
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= this.data + length) assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
do
{ {
const oldLength = length; const oldLength = length;
const after = r.end - this.data; const after = r.end - this.data;
@ -759,9 +821,13 @@ struct Array(T)
/// ditto /// ditto
size_t insertAfter(size_t R)(Range r, T[R] el) size_t insertAfter(size_t R)(Range r, T[R] el)
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= this.data + length) assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
do
{ {
return insertAfter!(T[])(r, el[]); return insertAfter!(T[])(r, el[]);
} }
@ -769,9 +835,13 @@ struct Array(T)
/// ditto /// ditto
size_t insertAfter(R)(Range r, auto ref R el) size_t insertAfter(R)(Range r, auto ref R el)
if (isImplicitlyConvertible!(R, T)) if (isImplicitlyConvertible!(R, T))
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= this.data + length) assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
do
{ {
const oldLen = length; const oldLen = length;
const offset = r.end - this.data; const offset = r.end - this.data;
@ -794,18 +864,26 @@ struct Array(T)
if (!isInfinite!R if (!isInfinite!R
&& isInputRange!R && isInputRange!R
&& isImplicitlyConvertible!(ElementType!R, T)) && isImplicitlyConvertible!(ElementType!R, T))
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= this.data + length) 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); return insertAfter(Range(this, this.data, r.begin), el);
} }
/// ditto /// ditto
size_t insertBefore(size_t R)(Range r, T[R] el) size_t insertBefore(size_t R)(Range r, T[R] el)
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= this.data + length) assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
do
{ {
return insertBefore!(T[])(r, el[]); return insertBefore!(T[])(r, el[]);
} }
@ -813,9 +891,13 @@ struct Array(T)
/// ditto /// ditto
size_t insertBefore(R)(Range r, auto ref R el) size_t insertBefore(R)(Range r, auto ref R el)
if (isImplicitlyConvertible!(R, T)) if (isImplicitlyConvertible!(R, T))
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= this.data + length) assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
do
{ {
const oldLen = length; const oldLen = length;
const offset = r.begin - this.data; const offset = r.begin - this.data;
@ -983,7 +1065,11 @@ struct Array(T)
* Precondition: $(D_INLINECODE length > pos). * Precondition: $(D_INLINECODE length > pos).
*/ */
ref inout(T) opIndex(size_t pos) inout @trusted ref inout(T) opIndex(size_t pos) inout @trusted
in (length > pos) in
{
assert(length > pos);
}
do
{ {
return *(this.data + pos); return *(this.data + pos);
} }
@ -1084,7 +1170,11 @@ struct Array(T)
* Precondition: $(D_INLINECODE !empty). * Precondition: $(D_INLINECODE !empty).
*/ */
@property ref inout(T) front() inout @property ref inout(T) front() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return *this.data; return *this.data;
} }
@ -1107,7 +1197,11 @@ struct Array(T)
* Precondition: $(D_INLINECODE !empty). * Precondition: $(D_INLINECODE !empty).
*/ */
@property ref inout(T) back() inout @trusted @property ref inout(T) back() inout @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
return *(this.data + length - 1); return *(this.data + length - 1);
} }
@ -1135,16 +1229,24 @@ struct Array(T)
* Precondition: $(D_INLINECODE i <= j && j <= length). * Precondition: $(D_INLINECODE i <= j && j <= length).
*/ */
Range opSlice(size_t i, size_t j) @trusted Range opSlice(size_t i, size_t j) @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
return typeof(return)(this, this.data + i, this.data + j); return typeof(return)(this, this.data + i, this.data + j);
} }
/// ditto /// ditto
ConstRange opSlice(size_t i, size_t j) const @trusted ConstRange opSlice(size_t i, size_t j) const @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
return typeof(return)(this, this.data + i, this.data + j); 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) Range opSliceAssign(size_t R)(T[R] value, size_t i, size_t j)
@trusted @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
copy(value[], this.data[i .. j]); copy(value[], this.data[i .. j]);
return opSlice(i, j); return opSlice(i, j);
@ -1211,8 +1317,12 @@ struct Array(T)
/// ditto /// ditto
Range opSliceAssign(R : T)(auto ref R value, size_t i, size_t j) Range opSliceAssign(R : T)(auto ref R value, size_t i, size_t j)
@trusted @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
fill(this.data[i .. j], value); fill(this.data[i .. j], value);
return opSlice(i, j); return opSlice(i, j);
@ -1220,9 +1330,13 @@ struct Array(T)
/// ditto /// ditto
Range opSliceAssign()(Range value, size_t i, size_t j) @trusted Range opSliceAssign()(Range value, size_t i, size_t j) @trusted
in (i <= j) in
in (j <= length) {
in (j - i == value.length) assert(i <= j);
assert(j <= length);
assert(j - i == value.length);
}
do
{ {
copy(value, this.data[i .. j]); copy(value, this.data[i .. j]);
return opSlice(i, j); return opSlice(i, j);

View File

@ -22,7 +22,11 @@ version (unittest)
private int fillBuffer(ubyte[] buffer, private int fillBuffer(ubyte[] buffer,
int start = 0, int start = 0,
int end = 10) @nogc pure nothrow int end = 10) @nogc pure nothrow
in (start < end) in
{
assert(start < end);
}
do
{ {
auto numberRead = end - start; auto numberRead = end - start;
for (ubyte i; i < numberRead; ++i) for (ubyte i; i < numberRead; ++i)
@ -67,9 +71,12 @@ if (isScalarType!T)
/// Size by which the buffer will grow. /// Size by which the buffer will grow.
private size_t blockSize = 8192; private size_t blockSize = 8192;
invariant (this.length_ <= this.buffer_.length); invariant
invariant (this.blockSize > 0); {
invariant (this.minAvailable > 0); assert(this.length_ <= this.buffer_.length);
assert(this.blockSize > 0);
assert(this.minAvailable > 0);
}
/** /**
* Creates a new read buffer. * Creates a new read buffer.
@ -94,7 +101,11 @@ if (isScalarType!T)
/// ditto /// ditto
this(shared Allocator allocator) this(shared Allocator allocator)
in (allocator_ is null) in
{
assert(allocator_ is null);
}
do
{ {
allocator_ = allocator; allocator_ = allocator;
} }
@ -312,9 +323,13 @@ if (isScalarType!T)
/// The position of the free area in the buffer. /// The position of the free area in the buffer.
private size_t position; private size_t position;
invariant (this.blockSize > 0); invariant
// Position can refer to an element outside the buffer if the buffer is full. {
invariant (this.position <= this.buffer_.length); 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: * Params:
@ -325,8 +340,12 @@ if (isScalarType!T)
* Precondition: $(D_INLINECODE size > 0 && allocator !is null) * Precondition: $(D_INLINECODE size > 0 && allocator !is null)
*/ */
this(size_t size, shared Allocator allocator = defaultAllocator) @trusted this(size_t size, shared Allocator allocator = defaultAllocator) @trusted
in (size > 0) in
in (allocator !is null) {
assert(size > 0);
assert(allocator !is null);
}
do
{ {
this.blockSize = size; this.blockSize = size;
ring = size - 1; ring = size - 1;
@ -487,7 +506,11 @@ if (isScalarType!T)
*/ */
ref WriteBuffer opOpAssign(string op)(size_t length) ref WriteBuffer opOpAssign(string op)(size_t length)
if (op == "+") if (op == "+")
in (length <= this.length) in
{
assert(length <= this.length);
}
do
{ {
auto afterRing = ring + 1; auto afterRing = ring + 1;
auto oldStart = start; auto oldStart = start;

View File

@ -128,14 +128,22 @@ package(tanya.container) struct HashArray(alias hasher, K, V = void)
size_t length; size_t length;
this(shared Allocator allocator) this(shared Allocator allocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.array = Buckets(allocator); this.array = Buckets(allocator);
} }
this(T)(ref T data, shared Allocator allocator) this(T)(ref T data, shared Allocator allocator)
if (is(Unqual!T == HashArray)) if (is(Unqual!T == HashArray))
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.array = Buckets(data.array, allocator); this.array = Buckets(data.array, allocator);
this.lengthIndex = data.lengthIndex; this.lengthIndex = data.lengthIndex;
@ -144,7 +152,11 @@ package(tanya.container) struct HashArray(alias hasher, K, V = void)
// Move constructor // Move constructor
void move(ref HashArray data, shared Allocator allocator) 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.array = Buckets(.move(data.array), allocator);
this.lengthIndex = data.lengthIndex; 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. // Takes an index in the primes array.
void rehashToSize(const size_t n) 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); auto storage = typeof(this.array)(primes[n], this.array.allocator);
DataLoop: foreach (ref e1; this.array[]) DataLoop: foreach (ref e1; this.array[])

View File

@ -71,9 +71,16 @@ struct Range(T)
} }
void popFront() void popFront()
in (!empty) in
in (this.dataRange.front.status == BucketStatus.used) {
out (; empty || this.dataRange.back.status == BucketStatus.used) assert(!empty);
assert(this.dataRange.front.status == BucketStatus.used);
}
out
{
assert(empty || this.dataRange.back.status == BucketStatus.used);
}
do
{ {
do do
{ {
@ -83,9 +90,16 @@ struct Range(T)
} }
void popBack() void popBack()
in (!empty) in
in (this.dataRange.back.status == BucketStatus.used) {
out (; empty || this.dataRange.back.status == BucketStatus.used) assert(!empty);
assert(this.dataRange.back.status == BucketStatus.used);
}
out
{
assert(empty || this.dataRange.back.status == BucketStatus.used);
}
do
{ {
do do
{ {
@ -95,15 +109,23 @@ struct Range(T)
} }
@property ref inout(KV) front() inout @property ref inout(KV) front() inout
in (!empty) in
in (this.dataRange.front.status == BucketStatus.used) {
assert(!empty);
assert(this.dataRange.front.status == BucketStatus.used);
}
do
{ {
return this.dataRange.front.kv; return this.dataRange.front.kv;
} }
@property ref inout(KV) back() inout @property ref inout(KV) back() inout
in (!empty) in
in (this.dataRange.back.status == BucketStatus.used) {
assert(!empty);
assert(this.dataRange.back.status == BucketStatus.used);
}
do
{ {
return this.dataRange.back.kv; return this.dataRange.back.kv;
} }
@ -164,9 +186,16 @@ struct ByKey(T)
} }
@property void popFront() @property void popFront()
in (!empty) in
in (this.dataRange.front.status == BucketStatus.used) {
out (; empty || this.dataRange.back.status == BucketStatus.used) assert(!empty);
assert(this.dataRange.front.status == BucketStatus.used);
}
out
{
assert(empty || this.dataRange.back.status == BucketStatus.used);
}
do
{ {
do do
{ {
@ -176,9 +205,16 @@ struct ByKey(T)
} }
@property void popBack() @property void popBack()
in (!empty) in
in (this.dataRange.back.status == BucketStatus.used) {
out (; empty || this.dataRange.back.status == BucketStatus.used) assert(!empty);
assert(this.dataRange.back.status == BucketStatus.used);
}
out
{
assert(empty || this.dataRange.back.status == BucketStatus.used);
}
do
{ {
do do
{ {
@ -188,15 +224,23 @@ struct ByKey(T)
} }
@property ref inout(Key) front() inout @property ref inout(Key) front() inout
in (!empty) in
in (this.dataRange.front.status == BucketStatus.used) {
assert(!empty);
assert(this.dataRange.front.status == BucketStatus.used);
}
do
{ {
return this.dataRange.front.key; return this.dataRange.front.key;
} }
@property ref inout(Key) back() inout @property ref inout(Key) back() inout
in (!empty) in
in (this.dataRange.back.status == BucketStatus.used) {
assert(!empty);
assert(this.dataRange.back.status == BucketStatus.used);
}
do
{ {
return this.dataRange.back.key; return this.dataRange.back.key;
} }
@ -257,9 +301,16 @@ struct ByValue(T)
} }
@property void popFront() @property void popFront()
in (!empty) in
in (this.dataRange.front.status == BucketStatus.used) {
out (; empty || this.dataRange.back.status == BucketStatus.used) assert(!empty);
assert(this.dataRange.front.status == BucketStatus.used);
}
out
{
assert(empty || this.dataRange.back.status == BucketStatus.used);
}
do
{ {
do do
{ {
@ -269,9 +320,16 @@ struct ByValue(T)
} }
@property void popBack() @property void popBack()
in (!empty) in
in (this.dataRange.back.status == BucketStatus.used) {
out (; empty || this.dataRange.back.status == BucketStatus.used) assert(!empty);
assert(this.dataRange.back.status == BucketStatus.used);
}
out
{
assert(empty || this.dataRange.back.status == BucketStatus.used);
}
do
{ {
do do
{ {
@ -281,15 +339,23 @@ struct ByValue(T)
} }
@property ref inout(Value) front() inout @property ref inout(Value) front() inout
in (!empty) in
in (this.dataRange.front.status == BucketStatus.used) {
assert(!empty);
assert(this.dataRange.front.status == BucketStatus.used);
}
do
{ {
return this.dataRange.front.kv.value; return this.dataRange.front.kv.value;
} }
@property ref inout(Value) back() inout @property ref inout(Value) back() inout
in (!empty) in
in (this.dataRange.back.status == BucketStatus.used) {
assert(!empty);
assert(this.dataRange.back.status == BucketStatus.used);
}
do
{ {
return this.dataRange.back.kv.value; return this.dataRange.back.kv.value;
} }
@ -347,7 +413,10 @@ if (isHashFunction!(hasher, Key))
/// ditto /// ditto
alias ConstByValue = .ByValue!(const HashArray); alias ConstByValue = .ByValue!(const HashArray);
invariant (this.data.lengthIndex < primes.length); invariant
{
assert(this.data.lengthIndex < primes.length);
}
/** /**
* Constructor. * Constructor.
@ -359,7 +428,11 @@ if (isHashFunction!(hasher, Key))
* Precondition: $(D_INLINECODE allocator !is null). * Precondition: $(D_INLINECODE allocator !is null).
*/ */
this(size_t n, shared Allocator allocator = defaultAllocator) this(size_t n, shared Allocator allocator = defaultAllocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this(allocator); this(allocator);
this.data.rehash(n); this.data.rehash(n);
@ -374,7 +447,11 @@ if (isHashFunction!(hasher, Key))
/// ditto /// ditto
this(shared Allocator allocator) this(shared Allocator allocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.data = HashArray(allocator); this.data = HashArray(allocator);
} }
@ -394,7 +471,11 @@ if (isHashFunction!(hasher, Key))
*/ */
this(S)(ref S init, shared Allocator allocator = defaultAllocator) this(S)(ref S init, shared Allocator allocator = defaultAllocator)
if (is(Unqual!S == HashTable)) if (is(Unqual!S == HashTable))
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.data = HashArray(init.data, allocator); this.data = HashArray(init.data, allocator);
} }
@ -402,7 +483,11 @@ if (isHashFunction!(hasher, Key))
/// ditto /// ditto
this(S)(S init, shared Allocator allocator = defaultAllocator) this(S)(S init, shared Allocator allocator = defaultAllocator)
if (is(S == HashTable)) if (is(S == HashTable))
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.data.move(init.data, allocator); this.data.move(init.data, allocator);
} }
@ -419,7 +504,11 @@ if (isHashFunction!(hasher, Key))
*/ */
this(R)(scope R range, shared Allocator allocator = defaultAllocator) this(R)(scope R range, shared Allocator allocator = defaultAllocator)
if (isForwardRange!R && is(ElementType!R == KeyValue) && !isInfinite!R) if (isForwardRange!R && is(ElementType!R == KeyValue) && !isInfinite!R)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this(allocator); this(allocator);
insert(range); insert(range);
@ -449,7 +538,11 @@ if (isHashFunction!(hasher, Key))
*/ */
this(size_t n)(KeyValue[n] array, this(size_t n)(KeyValue[n] array,
shared Allocator allocator = defaultAllocator) shared Allocator allocator = defaultAllocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this(allocator); this(allocator);
insert(array[]); insert(array[]);
@ -498,7 +591,11 @@ if (isHashFunction!(hasher, Key))
* Postcondition: $(D_INLINECODE allocator !is null) * Postcondition: $(D_INLINECODE allocator !is null)
*/ */
@property shared(Allocator) allocator() const @property shared(Allocator) allocator() const
out (allocator; allocator !is null) out (allocator)
{
assert(allocator !is null);
}
do
{ {
return this.data.array.allocator; return this.data.array.allocator;
} }

View File

@ -38,7 +38,10 @@ struct SRange(L)
private EntryPointer* head; private EntryPointer* head;
invariant (this.head !is null); invariant
{
assert(this.head !is null);
}
private this(return ref EntryPointer head) @trusted private this(return ref EntryPointer head) @trusted
{ {
@ -58,13 +61,21 @@ struct SRange(L)
} }
@property ref inout(E) front() inout @property ref inout(E) front() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return (*this.head).content; return (*this.head).content;
} }
void popFront() @trusted void popFront() @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
this.head = &(*this.head).next; this.head = &(*this.head).next;
} }
@ -196,7 +207,11 @@ struct SList(T)
/// ditto /// ditto
this(shared Allocator allocator) this(shared Allocator allocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.allocator_ = allocator; this.allocator_ = allocator;
} }
@ -318,7 +333,11 @@ struct SList(T)
* Precondition: $(D_INLINECODE !empty). * Precondition: $(D_INLINECODE !empty).
*/ */
@property ref inout(T) front() inout @property ref inout(T) front() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return this.head.content; return this.head.content;
} }
@ -459,7 +478,11 @@ struct SList(T)
*/ */
size_t insertBefore(R)(Range r, R el) size_t insertBefore(R)(Range r, R el)
if (isImplicitlyConvertible!(R, T)) if (isImplicitlyConvertible!(R, T))
in (checkRangeBelonging(r)) in
{
assert(checkRangeBelonging(r));
}
do
{ {
return moveEntry(*r.head, el); return moveEntry(*r.head, el);
} }
@ -478,7 +501,11 @@ struct SList(T)
if (!isInfinite!R if (!isInfinite!R
&& isInputRange!R && isInputRange!R
&& isImplicitlyConvertible!(ElementType!R, T)) && isImplicitlyConvertible!(ElementType!R, T))
in (checkRangeBelonging(r)) in
{
assert(checkRangeBelonging(r));
}
do
{ {
size_t inserted; size_t inserted;
foreach (e; el) foreach (e; el)
@ -503,7 +530,11 @@ struct SList(T)
/// ditto /// ditto
size_t insertBefore()(Range r, ref T el) @trusted 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); *r.head = allocator.make!Entry(el, *r.head);
return 1; return 1;
@ -599,7 +630,11 @@ struct SList(T)
* Precondition: $(D_INLINECODE !empty) * Precondition: $(D_INLINECODE !empty)
*/ */
void removeFront() void removeFront()
in (!empty) in
{
assert(!empty);
}
do
{ {
auto n = this.head.next; auto n = this.head.next;
@ -634,7 +669,11 @@ struct SList(T)
* Returns: The number of elements removed. * Returns: The number of elements removed.
*/ */
size_t removeFront(size_t howMany) size_t removeFront(size_t howMany)
out (removed; removed <= howMany) out (removed)
{
assert(removed <= howMany);
}
do
{ {
size_t i; size_t i;
for (; i < howMany && !empty; ++i) for (; i < howMany && !empty; ++i)
@ -666,7 +705,11 @@ struct SList(T)
* Precondition: $(D_PARAM r) is extracted from this list. * Precondition: $(D_PARAM r) is extracted from this list.
*/ */
Range remove(scope Range r) Range remove(scope Range r)
in (checkRangeBelonging(r)) in
{
assert(checkRangeBelonging(r));
}
do
{ {
auto outOfScopeList = typeof(this)(allocator); auto outOfScopeList = typeof(this)(allocator);
outOfScopeList.head = *r.head; outOfScopeList.head = *r.head;
@ -700,8 +743,12 @@ struct SList(T)
* $(D_PARAM range) is extracted from this list. * $(D_PARAM range) is extracted from this list.
*/ */
Range popFirstOf(Range range) Range popFirstOf(Range range)
in (!range.empty) in
in (checkRangeBelonging(range)) {
assert(!range.empty);
assert(checkRangeBelonging(range));
}
do
{ {
auto next = (*range.head).next; auto next = (*range.head).next;
@ -891,8 +938,11 @@ struct DRange(L)
private EntryPointer* head; private EntryPointer* head;
private EntryPointer* tail; private EntryPointer* tail;
invariant (this.head !is null); invariant
invariant (this.tail !is null); {
assert(this.head !is null);
assert(this.tail !is null);
}
private this(return ref EntryPointer head, return ref EntryPointer tail) private this(return ref EntryPointer head, return ref EntryPointer tail)
@trusted @trusted
@ -914,25 +964,41 @@ struct DRange(L)
} }
@property ref inout(E) front() inout @property ref inout(E) front() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return (*this.head).content; return (*this.head).content;
} }
@property ref inout(E) back() inout @property ref inout(E) back() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return (*this.tail).content; return (*this.tail).content;
} }
void popFront() @trusted void popFront() @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
this.head = &(*this.head).next; this.head = &(*this.head).next;
} }
void popBack() @trusted void popBack() @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
this.tail = &(*this.tail).prev; this.tail = &(*this.tail).prev;
} }
@ -980,9 +1046,12 @@ struct DList(T)
static if (__VERSION__ < 2086) // Bug #20171. static if (__VERSION__ < 2086) // Bug #20171.
{ {
invariant ((this.tail is null) == (this.head is null)); invariant
invariant (this.tail is null || this.tail.next is null); {
invariant (this.head is null || this.head.prev is null); 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 /// ditto
this(shared Allocator allocator) this(shared Allocator allocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.allocator_ = allocator; this.allocator_ = allocator;
} }
@ -1213,7 +1286,11 @@ struct DList(T)
* Precondition: $(D_INLINECODE !empty). * Precondition: $(D_INLINECODE !empty).
*/ */
@property ref inout(T) front() inout @property ref inout(T) front() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return this.head.content; return this.head.content;
} }
@ -1224,7 +1301,11 @@ struct DList(T)
* Precondition: $(D_INLINECODE !empty). * Precondition: $(D_INLINECODE !empty).
*/ */
@property ref inout(T) back() inout @property ref inout(T) back() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return this.tail.content; return this.tail.content;
} }
@ -1267,8 +1348,12 @@ struct DList(T)
// Returns count of the elements in the list. // Returns count of the elements in the list.
private size_t makeList(R)(scope ref R el, out Entry* head, out Entry* tail) private size_t makeList(R)(scope ref R el, out Entry* head, out Entry* tail)
@trusted @trusted
out (retLength; (retLength == 0 && head is null && tail is null) out (retLength)
|| (retLength > 0 && head !is null && tail !is null)) {
assert((retLength == 0 && head is null && tail is null)
|| (retLength > 0 && head !is null && tail !is null));
}
do
{ {
size_t retLength; size_t retLength;
@ -1536,7 +1621,11 @@ struct DList(T)
*/ */
size_t insertBefore(R)(Range r, R el) size_t insertBefore(R)(Range r, R el)
if (isImplicitlyConvertible!(R, T)) if (isImplicitlyConvertible!(R, T))
in (checkRangeBelonging(r)) in
{
assert(checkRangeBelonging(r));
}
do
{ {
return moveFront(*r.head, el); return moveFront(*r.head, el);
} }
@ -1552,7 +1641,11 @@ struct DList(T)
/// ditto /// ditto
size_t insertBefore()(Range r, ref T el) @trusted 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); auto temp = allocator.make!Entry(el, *r.head);
@ -1586,7 +1679,11 @@ struct DList(T)
if (!isInfinite!R if (!isInfinite!R
&& isInputRange!R && isInputRange!R
&& isImplicitlyConvertible!(ElementType!R, T)) && isImplicitlyConvertible!(ElementType!R, T))
in (checkRangeBelonging(r)) in
{
assert(checkRangeBelonging(r));
}
do
{ {
size_t inserted; size_t inserted;
foreach (e; el) foreach (e; el)
@ -1639,7 +1736,11 @@ struct DList(T)
*/ */
size_t insertAfter(R)(Range r, R el) @trusted size_t insertAfter(R)(Range r, R el) @trusted
if (isImplicitlyConvertible!(R, T)) if (isImplicitlyConvertible!(R, T))
in (checkRangeBelonging(r)) in
{
assert(checkRangeBelonging(r));
}
do
{ {
return moveBack(*r.tail, el); return moveBack(*r.tail, el);
} }
@ -1657,7 +1758,11 @@ struct DList(T)
/// ditto /// ditto
size_t insertAfter()(Range r, ref T el) @trusted 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); auto temp = allocator.make!Entry(el, null, *r.tail);
@ -1691,7 +1796,11 @@ struct DList(T)
if (!isInfinite!R if (!isInfinite!R
&& isInputRange!R && isInputRange!R
&& isImplicitlyConvertible!(ElementType!R, T)) && isImplicitlyConvertible!(ElementType!R, T))
in (checkRangeBelonging(r)) in
{
assert(checkRangeBelonging(r));
}
do
{ {
return fold!((acc, x) => acc + insertAfter(r, x))(el, size_t.init); return fold!((acc, x) => acc + insertAfter(r, x))(el, size_t.init);
} }
@ -1777,7 +1886,11 @@ struct DList(T)
* Precondition: $(D_INLINECODE !empty) * Precondition: $(D_INLINECODE !empty)
*/ */
void removeFront() void removeFront()
in (!empty) in
{
assert(!empty);
}
do
{ {
auto n = this.head.next; auto n = this.head.next;
@ -1809,7 +1922,11 @@ struct DList(T)
/// ditto /// ditto
void removeBack() void removeBack()
in (!empty) in
{
assert(!empty);
}
do
{ {
auto n = this.tail.prev; auto n = this.tail.prev;
@ -1851,7 +1968,11 @@ struct DList(T)
* Returns: The number of elements removed. * Returns: The number of elements removed.
*/ */
size_t removeFront(size_t howMany) size_t removeFront(size_t howMany)
out (removed; removed <= howMany) out (removed)
{
assert(removed <= howMany);
}
do
{ {
size_t i; size_t i;
for (; i < howMany && !empty; ++i) for (; i < howMany && !empty; ++i)
@ -1874,7 +1995,11 @@ struct DList(T)
/// ditto /// ditto
size_t removeBack(size_t howMany) size_t removeBack(size_t howMany)
out (removed; removed <= howMany) out (removed)
{
assert(removed <= howMany);
}
do
{ {
size_t i; size_t i;
for (; i < howMany && !empty; ++i) for (; i < howMany && !empty; ++i)
@ -1906,7 +2031,11 @@ struct DList(T)
* Precondition: $(D_PARAM r) is extracted from this list. * Precondition: $(D_PARAM r) is extracted from this list.
*/ */
Range remove(scope Range r) Range remove(scope Range r)
in (checkRangeBelonging(r)) in
{
assert(checkRangeBelonging(r));
}
do
{ {
// Save references to the elements before and after the range. // Save references to the elements before and after the range.
Entry* headPrev; Entry* headPrev;
@ -1978,7 +2107,11 @@ struct DList(T)
* $(D_PARAM range) is extracted from this list. * $(D_PARAM range) is extracted from this list.
*/ */
Range popFirstOf(Range range) Range popFirstOf(Range range)
in (!range.empty) in
{
assert(!range.empty);
}
do
{ {
remove(Range(*range.head, *range.head)); remove(Range(*range.head, *range.head));
return range; return range;
@ -1986,7 +2119,11 @@ struct DList(T)
/// ditto /// ditto
Range popLastOf(Range range) Range popLastOf(Range range)
in (!range.empty) in
{
assert(!range.empty);
}
do
{ {
remove(Range(*range.tail, *range.tail)); remove(Range(*range.tail, *range.tail));
return range; return range;

View File

@ -69,9 +69,16 @@ struct Range(T)
} }
void popFront() void popFront()
in (!empty) in
in (this.dataRange.front.status == BucketStatus.used) {
out (; empty || this.dataRange.back.status == BucketStatus.used) assert(!empty);
assert(this.dataRange.front.status == BucketStatus.used);
}
out
{
assert(empty || this.dataRange.back.status == BucketStatus.used);
}
do
{ {
do do
{ {
@ -81,9 +88,16 @@ struct Range(T)
} }
void popBack() void popBack()
in (!empty) in
in (this.dataRange.back.status == BucketStatus.used) {
out (; empty || this.dataRange.back.status == BucketStatus.used) assert(!empty);
assert(this.dataRange.back.status == BucketStatus.used);
}
out
{
assert(empty || this.dataRange.back.status == BucketStatus.used);
}
do
{ {
do do
{ {
@ -93,15 +107,23 @@ struct Range(T)
} }
@property ref inout(E) front() inout @property ref inout(E) front() inout
in (!empty) in
in (this.dataRange.front.status == BucketStatus.used) {
assert(!empty);
assert(this.dataRange.front.status == BucketStatus.used);
}
do
{ {
return this.dataRange.front.key; return this.dataRange.front.key;
} }
@property ref inout(E) back() inout @property ref inout(E) back() inout
in (!empty) in
in (this.dataRange.back.status == BucketStatus.used) {
assert(!empty);
assert(this.dataRange.back.status == BucketStatus.used);
}
do
{ {
return this.dataRange.back.key; return this.dataRange.back.key;
} }
@ -146,9 +168,12 @@ if (isHashFunction!(hasher, T))
/// ditto /// ditto
alias ConstRange = .Range!(const HashArray); alias ConstRange = .Range!(const HashArray);
invariant (this.data.lengthIndex < primes.length); invariant
invariant (this.data.array.length == 0 {
assert(this.data.lengthIndex < primes.length);
assert(this.data.array.length == 0
|| this.data.array.length == primes[this.data.lengthIndex]); || this.data.array.length == primes[this.data.lengthIndex]);
}
/** /**
* Constructor. * Constructor.
@ -160,7 +185,11 @@ if (isHashFunction!(hasher, T))
* Precondition: $(D_INLINECODE allocator !is null). * Precondition: $(D_INLINECODE allocator !is null).
*/ */
this(size_t n, shared Allocator allocator = defaultAllocator) this(size_t n, shared Allocator allocator = defaultAllocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this(allocator); this(allocator);
this.data.rehash(n); this.data.rehash(n);
@ -175,7 +204,11 @@ if (isHashFunction!(hasher, T))
/// ditto /// ditto
this(shared Allocator allocator) this(shared Allocator allocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.data = HashArray(allocator); this.data = HashArray(allocator);
} }
@ -195,7 +228,11 @@ if (isHashFunction!(hasher, T))
*/ */
this(S)(ref S init, shared Allocator allocator = defaultAllocator) this(S)(ref S init, shared Allocator allocator = defaultAllocator)
if (is(Unqual!S == Set)) if (is(Unqual!S == Set))
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.data = HashArray(init.data, allocator); this.data = HashArray(init.data, allocator);
} }
@ -203,7 +240,11 @@ if (isHashFunction!(hasher, T))
/// ditto /// ditto
this(S)(S init, shared Allocator allocator = defaultAllocator) this(S)(S init, shared Allocator allocator = defaultAllocator)
if (is(S == Set)) if (is(S == Set))
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.data.move(init.data, allocator); this.data.move(init.data, allocator);
} }
@ -222,7 +263,11 @@ if (isHashFunction!(hasher, T))
if (isForwardRange!R if (isForwardRange!R
&& isImplicitlyConvertible!(ElementType!R, T) && isImplicitlyConvertible!(ElementType!R, T)
&& !isInfinite!R) && !isInfinite!R)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this(allocator); this(allocator);
insert(range); insert(range);
@ -249,7 +294,11 @@ if (isHashFunction!(hasher, T))
* Precondition: $(D_INLINECODE allocator !is null). * Precondition: $(D_INLINECODE allocator !is null).
*/ */
this(size_t n)(T[n] array, shared Allocator allocator = defaultAllocator) this(size_t n)(T[n] array, shared Allocator allocator = defaultAllocator)
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this(allocator); this(allocator);
insert(array[]); insert(array[]);
@ -297,7 +346,11 @@ if (isHashFunction!(hasher, T))
* Postcondition: $(D_INLINECODE allocator !is null) * Postcondition: $(D_INLINECODE allocator !is null)
*/ */
@property shared(Allocator) allocator() const @property shared(Allocator) allocator() const
out (allocator; allocator !is null) out (allocator)
{
assert(allocator !is null);
}
do
{ {
return this.data.array.allocator; return this.data.array.allocator;
} }

View File

@ -70,15 +70,22 @@ if (is(Unqual!E == char))
private alias ContainerType = CopyConstness!(E, String); private alias ContainerType = CopyConstness!(E, String);
private ContainerType* container; private ContainerType* container;
invariant (this.begin <= this.end); invariant
invariant (this.container !is null); {
invariant (this.begin >= this.container.data); assert(this.begin <= this.end);
invariant (this.end <= this.container.data + this.container.length); 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 private this(ref ContainerType container, E* begin, E* end) @trusted
in (begin <= end) in
in (begin >= container.data) {
in (end <= container.data + container.length) assert(begin <= end);
assert(begin >= container.data);
assert(end <= container.data + container.length);
}
do
{ {
this.container = &container; this.container = &container;
this.begin = begin; this.begin = begin;
@ -105,31 +112,51 @@ if (is(Unqual!E == char))
alias opDollar = length; alias opDollar = length;
@property ref inout(E) front() inout @property ref inout(E) front() inout
in (!empty) in
{
assert(!empty);
}
do
{ {
return *this.begin; return *this.begin;
} }
@property ref inout(E) back() inout @trusted @property ref inout(E) back() inout @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
return *(this.end - 1); return *(this.end - 1);
} }
void popFront() @trusted void popFront() @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
++this.begin; ++this.begin;
} }
void popBack() @trusted void popBack() @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
--this.end; --this.end;
} }
ref inout(E) opIndex(const size_t i) inout @trusted ref inout(E) opIndex(const size_t i) inout @trusted
in (i < length) in
{
assert(i < length);
}
do
{ {
return *(this.begin + i); return *(this.begin + i);
} }
@ -145,15 +172,23 @@ if (is(Unqual!E == char))
} }
ByCodeUnit opSlice(const size_t i, const size_t j) @trusted ByCodeUnit opSlice(const size_t i, const size_t j) @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
return typeof(return)(*this.container, this.begin + i, this.begin + j); 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 ByCodeUnit!(const E) opSlice(const size_t i, const size_t j) const @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
return typeof(return)(*this.container, this.begin + i, this.begin + j); 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 alias ContainerType = CopyConstness!(E, String);
private ContainerType* container; private ContainerType* container;
invariant (this.begin <= this.end); invariant
invariant (this.container !is null); {
invariant (this.begin >= this.container.data); assert(this.begin <= this.end);
invariant (this.end <= this.container.data + this.container.length); 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 private this(ref ContainerType container, E* begin, E* end) @trusted
in (begin <= end) in
in (begin >= container.data) {
in (end <= container.data + container.length) assert(begin <= end);
assert(begin >= container.data);
assert(end <= container.data + container.length);
}
do
{ {
this.container = &container; this.container = &container;
this.begin = begin; this.begin = begin;
@ -205,8 +247,15 @@ if (is(Unqual!E == char))
} }
@property dchar front() const @trusted @property dchar front() const @trusted
in (!empty) in
out (chr; chr < 0xd800 || chr > 0xdfff) {
assert(!empty);
}
out (chr)
{
assert(chr < 0xd800 || chr > 0xdfff);
}
do
{ {
dchar chr; dchar chr;
ubyte units; ubyte units;
@ -236,7 +285,11 @@ if (is(Unqual!E == char))
} }
void popFront() @trusted void popFront() @trusted
in (!empty) in
{
assert(!empty);
}
do
{ {
ubyte units; ubyte units;
if ((*begin & 0xf0) == 0xf0) if ((*begin & 0xf0) == 0xf0)
@ -282,7 +335,10 @@ struct String
private char* data; private char* data;
private size_t capacity_; 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. * Constructs the string from a stringish range.
@ -372,7 +428,11 @@ struct String
/// ditto /// ditto
this(shared Allocator allocator) @nogc nothrow pure @safe this(shared Allocator allocator) @nogc nothrow pure @safe
in (allocator !is null) in
{
assert(allocator !is null);
}
do
{ {
this.allocator_ = allocator; this.allocator_ = allocator;
} }
@ -451,8 +511,12 @@ struct String
private void write4Bytes(ref const dchar src) private void write4Bytes(ref const dchar src)
@nogc nothrow pure @trusted @nogc nothrow pure @trusted
in (capacity - length >= 4) in
in (src - 0x10000 < 0x100000) {
assert(capacity - length >= 4);
assert(src - 0x10000 < 0x100000);
}
do
{ {
auto dst = this.data + length; auto dst = this.data + length;
@ -466,7 +530,11 @@ struct String
private size_t insertWideChar(C)(auto ref const C chr) @trusted private size_t insertWideChar(C)(auto ref const C chr) @trusted
if (is(C == wchar) || is(C == dchar)) if (is(C == wchar) || is(C == dchar))
in (capacity - length >= 3) in
{
assert(capacity - length >= 3);
}
do
{ {
auto dst = this.data + length; auto dst = this.data + length;
if (chr < 0x80) if (chr < 0x80)
@ -789,9 +857,13 @@ struct String
const size_t i, const size_t i,
const size_t j) const size_t j)
if (is(Unqual!R == char)) if (is(Unqual!R == char))
in (i <= j) in
in (j <= length) {
in (j - i == value.length) assert(i <= j);
assert(j <= length);
assert(j - i == value.length);
}
do
{ {
auto target = opSlice(i, j); auto target = opSlice(i, j);
copy(value, target); copy(value, target);
@ -803,8 +875,12 @@ struct String
const size_t i, const size_t i,
const size_t j) const size_t j)
@nogc nothrow pure @trusted @nogc nothrow pure @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
copy(value[], this.data[i .. j]); copy(value[], this.data[i .. j]);
return opSlice(i, j); return opSlice(i, j);
@ -815,8 +891,12 @@ struct String
const size_t i, const size_t i,
const size_t j) const size_t j)
@nogc nothrow pure @trusted @nogc nothrow pure @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
for (auto p = this.data + i; p < this.data + j; ++p) for (auto p = this.data + i; p < this.data + j; ++p)
{ {
@ -893,7 +973,11 @@ struct String
* Precondition: $(D_INLINECODE length > pos). * Precondition: $(D_INLINECODE length > pos).
*/ */
ref inout(char) opIndex(const size_t pos) inout @nogc nothrow pure @trusted 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); return *(this.data + pos);
} }
@ -1038,8 +1122,12 @@ struct String
*/ */
ByCodeUnit!char opSlice(const size_t i, const size_t j) ByCodeUnit!char opSlice(const size_t i, const size_t j)
@nogc nothrow pure @trusted @nogc nothrow pure @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
return typeof(return)(this, this.data + i, this.data + j); return typeof(return)(this, this.data + i, this.data + j);
} }
@ -1047,8 +1135,12 @@ struct String
/// ditto /// ditto
ByCodeUnit!(const char) opSlice(const size_t i, const size_t j) ByCodeUnit!(const char) opSlice(const size_t i, const size_t j)
const @nogc nothrow pure @trusted const @nogc nothrow pure @trusted
in (i <= j) in
in (j <= length) {
assert(i <= j);
assert(j <= length);
}
do
{ {
return typeof(return)(this, this.data + i, this.data + j); return typeof(return)(this, this.data + i, this.data + j);
} }
@ -1329,9 +1421,13 @@ struct String
*/ */
R remove(R)(R r) @trusted R remove(R)(R r) @trusted
if (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)) if (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char))
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= this.data + length) assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
do
{ {
auto end = this.data + this.length; auto end = this.data + this.length;
copy(ByCodeUnit!char(this, r.end, end), ByCodeUnit!char(this, r.begin, end)); copy(ByCodeUnit!char(this, r.end, end), ByCodeUnit!char(this, r.begin, end));
@ -1380,9 +1476,13 @@ struct String
&& isInputRange!T && isInputRange!T
&& isSomeChar!(ElementType!T))) && isSomeChar!(ElementType!T)))
&& (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char))) && (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)))
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= this.data + length) assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
do
{ {
const oldLength = length; const oldLength = length;
const after = r.end - this.data; const after = r.end - this.data;
@ -1410,9 +1510,13 @@ struct String
&& isInputRange!T && isInputRange!T
&& isSomeChar!(ElementType!T))) && isSomeChar!(ElementType!T)))
&& (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char))) && (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)))
in (r.container is &this) in
in (r.begin >= this.data) {
in (r.end <= this.data + length) 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); return insertAfter(R(this, this.data, r.begin), el);
} }

View File

@ -63,8 +63,12 @@ if (isInputRange!R
&& isSomeChar!(ElementType!R) && isSomeChar!(ElementType!R)
&& isIntegral!T && isIntegral!T
&& isUnsigned!T) && isUnsigned!T)
in (base >= 2) in
in (base <= 36) {
assert(base >= 2);
assert(base <= 36);
}
do
{ {
T boundary = cast(T) (T.max / base); T boundary = cast(T) (T.max / base);
if (range.empty) if (range.empty)

View File

@ -1175,7 +1175,11 @@ private struct uint128
} }
Tuple!(uint128, uint128) divMod(ulong rhs) const @nogc nothrow pure @safe 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) if (rhs == 1)
{ {
@ -1275,7 +1279,11 @@ private int indexMismatch(ulong low, ulong high) @nogc nothrow pure @safe
private char[] errol2(double value, private char[] errol2(double value,
return ref char[512] buffer, return ref char[512] buffer,
out int exponent) @nogc nothrow pure @safe out int exponent) @nogc nothrow pure @safe
in (value > 9.007199254740992e15 && value < 3.40282366920938e38) in
{
assert(value > 9.007199254740992e15 && value < 3.40282366920938e38);
}
do
{ {
auto v = uint128(value); auto v = uint128(value);
auto leftBoundary = v + raise2ToExp((value - previous(value)) / 2.0); auto leftBoundary = v + raise2ToExp((value - previous(value)) / 2.0);
@ -1360,7 +1368,11 @@ in (value > 9.007199254740992e15 && value < 3.40282366920938e38)
private char[] errolFixed(double value, private char[] errolFixed(double value,
return ref char[512] buffer, return ref char[512] buffer,
out int exponent) @nogc nothrow pure @safe out int exponent) @nogc nothrow pure @safe
in (value >= 16.0 && value <= 9.007199254740992e15) in
{
assert(value >= 16.0 && value <= 9.007199254740992e15);
}
do
{ {
auto decimal = cast(ulong) value; auto decimal = cast(ulong) value;
auto n = cast(double) decimal; auto n = cast(double) decimal;

View File

@ -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) 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) 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; G mask = G.max / 2 + 1;
H result; H result;

View File

@ -92,7 +92,10 @@ abstract class EntropySource
* $(D_PARAM output) length. * $(D_PARAM output) length.
*/ */
Nullable!ubyte poll(out ubyte[maxGather] output) @nogc 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) version (CRuntime_Bionic)

View File

@ -72,7 +72,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof)
*/ */
this(T)(T value) this(T)(T value)
if (isUnsigned!T) if (isUnsigned!T)
in (value <= (2 ^^ (L * 8)) - 1) in
{
assert(value <= (2 ^^ (L * 8)) - 1);
}
do
{ {
this.value = value & StorageType.max; this.value = value & StorageType.max;
} }
@ -83,7 +87,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof)
* Precondition: $(D_INLINECODE length > 0). * Precondition: $(D_INLINECODE length > 0).
*/ */
@property ubyte back() const @property ubyte back() const
in (this.length > 0) in
{
assert(this.length > 0);
}
do
{ {
return this.value & 0xff; return this.value & 0xff;
} }
@ -94,7 +102,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof)
* Precondition: $(D_INLINECODE length > 0). * Precondition: $(D_INLINECODE length > 0).
*/ */
@property ubyte front() const @property ubyte front() const
in (this.length > 0) in
{
assert(this.length > 0);
}
do
{ {
return (this.value >> ((this.length - 1) * 8)) & 0xff; return (this.value >> ((this.length - 1) * 8)) & 0xff;
} }
@ -105,7 +117,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof)
* Precondition: $(D_INLINECODE length > 0). * Precondition: $(D_INLINECODE length > 0).
*/ */
void popBack() void popBack()
in (this.length > 0) in
{
assert(this.length > 0);
}
do
{ {
this.value >>= 8; this.value >>= 8;
--this.size; --this.size;
@ -117,7 +133,11 @@ if (L > ubyte.sizeof && L <= ulong.sizeof)
* Precondition: $(D_INLINECODE length > 0). * Precondition: $(D_INLINECODE length > 0).
*/ */
void popFront() void popFront()
in (this.length > 0) in
{
assert(this.length > 0);
}
do
{ {
this.value &= StorageType.max >> ((StorageType.sizeof - this.length) * 8); this.value &= StorageType.max >> ((StorageType.sizeof - this.length) * 8);
--this.size; --this.size;

View File

@ -755,7 +755,11 @@ private void read2Bytes(R)(ref R range, ubyte[] address)
} }
private char toHexDigit(ubyte digit) @nogc nothrow pure @safe 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')); return cast(char) (digit >= 10 ? (digit - 10 + 'a') : (digit + '0'));
} }
@ -763,7 +767,11 @@ in (digit < 16)
private bool writeHexDigit(OR)(ref OR output, private bool writeHexDigit(OR)(ref OR output,
ubyte digit, ubyte digit,
bool groupStarted = false) bool groupStarted = false)
in (digit < 16) in
{
assert(digit < 16);
}
do
{ {
if (digit != 0 || groupStarted) if (digit != 0 || groupStarted)
{ {
@ -1124,7 +1132,11 @@ struct Address
* Precondition: This is an IPv4 address. * Precondition: This is an IPv4 address.
*/ */
ref inout(Address4) toV4() inout @nogc nothrow pure @safe 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; return this.address.get!Address4;
} }
@ -1147,7 +1159,11 @@ struct Address
* Precondition: This is an IPv6 address. * Precondition: This is an IPv6 address.
*/ */
ref inout(Address6) toV6() inout @nogc nothrow pure @safe 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; return this.address.get!Address6;
} }
@ -1169,7 +1185,11 @@ struct Address
* $(D_PSYMBOL Address6.loopback). * $(D_PSYMBOL Address6.loopback).
*/ */
bool isLoopback() const @nogc nothrow pure @safe bool isLoopback() const @nogc nothrow pure @safe
in (this.address.hasValue) in
{
assert(this.address.hasValue);
}
do
{ {
if (this.address.peek!Address4) if (this.address.peek!Address4)
{ {
@ -1195,7 +1215,11 @@ struct Address
* $(D_PSYMBOL Address6.isMulticast). * $(D_PSYMBOL Address6.isMulticast).
*/ */
bool isMulticast() const @nogc nothrow pure @safe bool isMulticast() const @nogc nothrow pure @safe
in (this.address.hasValue) in
{
assert(this.address.hasValue);
}
do
{ {
if (this.address.peek!Address4) if (this.address.peek!Address4)
{ {
@ -1220,7 +1244,11 @@ struct Address
* See_Also: $(D_PSYMBOL Address4.isAny), $(D_PSYMBOL Address6.isAny). * See_Also: $(D_PSYMBOL Address4.isAny), $(D_PSYMBOL Address6.isAny).
*/ */
bool isAny() const @nogc nothrow pure @safe bool isAny() const @nogc nothrow pure @safe
in (this.address.hasValue) in
{
assert(this.address.hasValue);
}
do
{ {
if (this.address.peek!Address4) if (this.address.peek!Address4)
{ {

View File

@ -170,7 +170,11 @@ if (isArray!Array)
void opCall(T)(auto ref T data) void opCall(T)(auto ref T data)
if (is(T : E)) if (is(T : E))
in (!this.data.empty) in
{
assert(!this.data.empty);
}
do
{ {
put(this.data, data); put(this.data, data);
} }

View File

@ -55,7 +55,11 @@ module tanya.range.array;
* Precondition: $(D_INLINECODE array.length > 0). * Precondition: $(D_INLINECODE array.length > 0).
*/ */
@property ref inout(T) front(T)(return scope inout(T)[] array) @property ref inout(T) front(T)(return scope inout(T)[] array)
in (array.length > 0) in
{
assert(array.length > 0);
}
do
{ {
return array[0]; return array[0];
} }
@ -91,7 +95,11 @@ in (array.length > 0)
* Precondition: $(D_INLINECODE array.length > 0). * Precondition: $(D_INLINECODE array.length > 0).
*/ */
@property ref inout(T) back(T)(return scope inout(T)[] array) @property ref inout(T) back(T)(return scope inout(T)[] array)
in (array.length > 0) in
{
assert(array.length > 0);
}
do
{ {
return array[$ - 1]; return array[$ - 1];
} }
@ -126,14 +134,22 @@ in (array.length > 0)
* Precondition: $(D_INLINECODE array.length > 0). * Precondition: $(D_INLINECODE array.length > 0).
*/ */
void popFront(T)(scope ref inout(T)[] array) void popFront(T)(scope ref inout(T)[] array)
in (array.length > 0) in
{
assert(array.length > 0);
}
do
{ {
array = array[1 .. $]; array = array[1 .. $];
} }
/// ditto /// ditto
void popBack(T)(scope ref inout(T)[] array) void popBack(T)(scope ref inout(T)[] array)
in (array.length > 0) in
{
assert(array.length > 0);
}
do
{ {
array = array[0 .. $ - 1]; array = array[0 .. $ - 1];
} }

View File

@ -1556,7 +1556,11 @@ if (isInputRange!Range && hasLvalueElements!Range)
*/ */
ElementType!R getAndPopFront(R)(ref R range) ElementType!R getAndPopFront(R)(ref R range)
if (isInputRange!R) if (isInputRange!R)
in (!range.empty) in
{
assert(!range.empty);
}
do
{ {
static if (hasLvalueElements!R) static if (hasLvalueElements!R)
{ {
@ -1609,7 +1613,11 @@ in (!range.empty)
*/ */
auto ref getAndPopBack(R)(ref R range) auto ref getAndPopBack(R)(ref R range)
if (isBidirectionalRange!R) if (isBidirectionalRange!R)
in (!range.empty) in
{
assert(!range.empty);
}
do
{ {
static if (hasLvalueElements!R) static if (hasLvalueElements!R)
{ {

View File

@ -291,7 +291,11 @@ if (isTypeTuple!Specs && NoDuplicates!Specs.length == Specs.length)
*/ */
ref inout(T) get(T)() inout ref inout(T) get(T)() inout
if (canFind!(T, Types)) 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 ~ ";"); mixin("return " ~ accessor!(T, AlignedUnion!Types).accessor ~ ";");
} }