diff --git a/source/tanya/container/entry.d b/source/tanya/container/entry.d index 54cedc9..6fec435 100644 --- a/source/tanya/container/entry.d +++ b/source/tanya/container/entry.d @@ -12,29 +12,6 @@ */ module tanya.container.entry; -version (unittest) -{ - package struct ConstEqualsStruct - { - int opEquals(typeof(this) that) const @nogc - { - return true; - } - } - - package struct MutableEqualsStruct - { - int opEquals(typeof(this) that) @nogc - { - return true; - } - } - - package struct NoEqualsStruct - { - } -} - package struct Entry(T) { /// Item content. diff --git a/source/tanya/container/vector.d b/source/tanya/container/vector.d index c5d6d3e..00a9987 100644 --- a/source/tanya/container/vector.d +++ b/source/tanya/container/vector.d @@ -18,18 +18,30 @@ import std.conv; import std.range.primitives; import std.meta; import std.traits; -public import tanya.meta.gen : IL; import tanya.memory; version (unittest) { - import tanya.container.entry; struct SWithDtor { ~this() @nogc { } } + struct ConstEqualsStruct + { + int opEquals(typeof(this) that) const @nogc + { + return true; + } + } + struct MutableEqualsStruct + { + int opEquals(typeof(this) that) @nogc + { + return true; + } + } } // Defines the container's primary range. @@ -43,22 +55,6 @@ private struct Range(E) } private this(E* begin, E* end) - in - { - assert(begin <= end); - } - body - { - this.begin = begin; - this.end = end; - } - - private this(in E* begin, in E* end) const - in - { - assert(begin <= end); - } - body { this.begin = begin; this.end = end; @@ -136,12 +132,12 @@ private struct Range(E) return typeof(return)(begin, end); } - const(Range) opIndex() const + Range!(const E) opIndex() const { return typeof(return)(begin, end); } - Range opSlice(in size_t i, in size_t j) + Range opSlice(in size_t i, in size_t j) @trusted in { assert(i <= j); @@ -152,7 +148,7 @@ private struct Range(E) return typeof(return)(begin + i, begin + j); } - const(Range) opSlice(in size_t i, in size_t j) const + Range!(const E) opSlice(in size_t i, in size_t j) const @trusted in { assert(i <= j); @@ -163,125 +159,10 @@ private struct Range(E) return typeof(return)(begin + i, begin + j); } - bool opEquals()(Range that) const @trusted - { - if (length != that.length) - { - return false; - } - for (const(E)* i = begin; i != end; ++i) - { - if (*i != that.front) - { - return false; - } - that.popFront(); - } - return true; - } - - inout(E[]) get() inout + inout(E[]) get() inout @trusted { return begin[0 .. length]; } - - static if (isMutable!E) - { - bool opEquals(Range that) @trusted - { - if (length != that.length) - { - return false; - } - for (E* i = begin; i != end; ++i) - { - if (*i != that.front) - { - return false; - } - that.popFront(); - } - return true; - } - - ref E opIndexAssign(ref E value, in size_t pos) @trusted - in - { - assert(length > pos); - } - body - { - return *(begin + pos) = value; - } - - /// Ditto. - E opIndexAssign(E value, in size_t pos) - { - return opIndexAssign(value, pos); - } - - Range opIndexAssign(ref E value) @trusted - { - E* begin = this.begin; - for (E* e = this.begin; e != end; ++e) - { - *e = value; - } - return typeof(return)(begin, end); - } - - Range opIndexAssign(E value) - { - return opIndexAssign(value); - } - - Range opSliceAssign(ref E value, in size_t i, in size_t j) @trusted - in - { - assert(i <= j); - assert(j < length); - } - body - { - E* begin = this.begin + i; - E* end = this.begin + j; - for (E* e = begin; e != end; ++e) - { - *e = value; - } - return typeof(return)(begin, end); - } - - Range opSliceAssign(E value) - { - return opSliceAssign(value); - } - - Range opSliceAssign(R)(R value, in size_t i, in size_t j) @trusted - if (!isInfinite!R - && isInputRange!R - && isImplicitlyConvertible!(ElementType!R, T)) - in - { - assert(j - i == walkLength(value)); - } - body - { - T* begin = this.begin + i; - const T* end = this.begin + j; - for (T* v = begin; v != end; ++v, value.popFront()) - { - *v = value.front; - } - return typeof(return)(begin, end); - } - - Range opSliceAssign(R)(R value, in size_t i, in size_t j) - if (isStaticArray!R && isImplicitlyConvertible!(ElementType!R, T)) - { - return opSliceAssign(value[], i, j); - } - } } /** @@ -303,16 +184,16 @@ struct Vector(T) } /** - * Creates a new $(D_PSYMBOL Vector). + * Creates a new $(D_PSYMBOL Vector) with the elements from another input + * range or a static array $(D_PARAM init). * * Params: - * R = Type of the static array with the initial elements. - * init = Values to initialize the array with. Use $(D_PSYMBOL IL). + * R = Type of the initial range or size of the static array. + * init = Values to initialize the array with. * to generate a list. * allocator = Allocator. */ - this(R)(auto in ref R init, shared Allocator allocator = defaultAllocator) - if (isStaticArray!R && isImplicitlyConvertible!(ElementType!R, T)) + this(size_t R)(auto in ref T[R] init, shared Allocator allocator = defaultAllocator) { this(allocator); insertBack(init[]); @@ -344,7 +225,7 @@ struct Vector(T) * init = Source vector. * allocator = Allocator. */ - this(ref Vector init, shared Allocator allocator = defaultAllocator) @trusted + this(ref Vector init, shared Allocator allocator = defaultAllocator) { this(allocator); insertBack(init[]); @@ -353,10 +234,10 @@ struct Vector(T) /// Ditto. this(Vector init, shared Allocator allocator = defaultAllocator) @trusted { + this(allocator); if (allocator is init.allocator) { // Just steal all references and the allocator. - this(init.allocator); vector = init.vector; length_ = init.length_; capacity_ = init.capacity_; @@ -368,7 +249,6 @@ struct Vector(T) else { // Move each element. - this(allocator); reserve(init.length); const T* end = vector + init.length; @@ -382,14 +262,14 @@ struct Vector(T) } /// - @nogc @safe unittest + unittest { - auto v1 = Vector!int(IL(1, 2, 3)); + auto v1 = Vector!int([1, 2, 3]); auto v2 = Vector!int(v1); assert(v1.vector !is v2.vector); assert(v1 == v2); - auto v3 = Vector!int(Vector!int(IL(1, 2, 3))); + auto v3 = Vector!int(Vector!int([1, 2, 3])); assert(v1 == v3); assert(v3.length == 3); assert(v3.capacity == 3); @@ -444,7 +324,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(3, 8, 2)); + auto v = Vector!int([3, 8, 2]); assert(v.capacity == 3); assert(v.length == 3); @@ -497,7 +377,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(18, 20, 15)); + auto v = Vector!int([18, 20, 15]); v.clear(); assert(v.length == 0); assert(v.capacity == 3); @@ -705,7 +585,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(5, 18, 17)); + auto v = Vector!int([5, 18, 17]); assert(v.removeBack(0) == 0); assert(v.removeBack(2) == 2); @@ -750,16 +630,16 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(5, 18, 17, 2, 4, 6, 1)); + auto v = Vector!int([5, 18, 17, 2, 4, 6, 1]); v.remove(v[1..3]); - assert(v == Vector!int(IL(5, 2, 4, 6, 1))); + assert(v == Vector!int([5, 2, 4, 6, 1])); v.remove(v[4..4]); - assert(v == Vector!int(IL(5, 2, 4, 6, 1))); + assert(v == Vector!int([5, 2, 4, 6, 1])); v.remove(v[4..5]); - assert(v == Vector!int(IL(5, 2, 4, 6))); + assert(v == Vector!int([5, 2, 4, 6])); v.remove(v[]); assert(v.empty); @@ -846,7 +726,7 @@ struct Vector(T) assert(v1.capacity == 4); assert(v1[0] == 5 && v1[1] == 6 && v1[2] == 4 && v1[3] == 2); - auto v2 = Vector!int(IL(34, 234)); + auto v2 = Vector!int([34, 234]); assert(v1.insertBack(v2[]) == 2); assert(v1.length == 6); assert(v1.capacity == 6); @@ -864,10 +744,10 @@ struct Vector(T) * * Precondition: $(D_INLINECODE length > pos) */ - ref T opIndexAssign(ref T value, in size_t pos) @trusted + ref T opIndexAssign(ref T value, in size_t pos) in { - assert(length_ > pos); + assert(length > pos); } body { @@ -881,31 +761,44 @@ struct Vector(T) } /// Ditto. - Range!T opIndexAssign(ref T value) @trusted + Range!T opIndexAssign()(auto ref T value) { - const T* end = vector + length_; - for (T* v = vector; v != end; ++v) - { - *v = value; - } - return opIndex(); + return opSliceAssign(value, 0, length); } - /// Ditto. - Range!T opIndexAssign(T value) + /** + * Assigns a range. The range should have the same length as the vector. + * + * Params: + * R = Range type. + * value = Value. + * + * Returns: Assigned value. + * + * Precondition: $(D_INLINECODE length == value.length) + */ + Range!T opIndexAssign(R)(R value) + if ((!isInfinite!R && isInputRange!R + && isImplicitlyConvertible!(ElementType!R, T)) + || isStaticArray!R && is(ElementType!R == T)) { - return opIndexAssign(value); + return opSliceAssign(value, 0, length); } /// unittest { - auto v1 = Vector!int(IL(12, 1, 7)); + auto v1 = Vector!int([12, 1, 7]); v1[] = 3; assert(v1[0] == 3); assert(v1[1] == 3); assert(v1[2] == 3); + + v1[] = [7, 1, 12]; + assert(v1[0] == 7); + assert(v1[1] == 1); + assert(v1[2] == 12); } /** @@ -919,7 +812,7 @@ struct Vector(T) ref inout(T) opIndex(in size_t pos) inout @trusted in { - assert(length_ > pos); + assert(length > pos); } body { @@ -944,7 +837,7 @@ struct Vector(T) /// unittest { - const v1 = Vector!int(IL(6, 123, 34, 5)); + const v1 = Vector!int([6, 123, 34, 5]); assert(v1[0] == 6); assert(v1[1] == 123); @@ -963,9 +856,9 @@ struct Vector(T) * Returns: $(D_KEYWORD true) if the vectors are equal, $(D_KEYWORD false) * otherwise. */ - bool opEquals()(auto ref typeof(this) v) @trusted + bool opEquals()(auto ref typeof(this) v) { - if (length_ != v.length_) + if (length != v.length) { return false; } @@ -981,9 +874,9 @@ struct Vector(T) } /// Ditto. - bool opEquals()(in auto ref typeof(this) v) const @trusted + bool opEquals()(in auto ref typeof(this) v) const { - if (length_ != v.length_) + if (length != v.length) { return false; } @@ -999,9 +892,9 @@ struct Vector(T) } /// Ditto. - bool opEquals(Range!T v) @trusted + bool opEquals(Range!T v) { - if (length_ != v.length) + if (length != v.length) { return false; } @@ -1027,10 +920,10 @@ struct Vector(T) * Returns: $(D_KEYWORD true) if the vectors are equal, $(D_KEYWORD false) * otherwise. */ - bool opEquals(R)(Range!R v) const @trusted + bool opEquals(R)(Range!R v) const if (is(Unqual!R == T)) { - if (length_ != v.length) + if (length != v.length) { return false; } @@ -1141,7 +1034,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(5, 15, 8)); + auto v = Vector!int([5, 15, 8]); size_t i; foreach (j, ref e; v) @@ -1161,7 +1054,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(5, 15, 8)); + auto v = Vector!int([5, 15, 8]); size_t i; foreach_reverse (j, ref e; v) @@ -1196,7 +1089,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(5)); + auto v = Vector!int([5]); assert(v.front == 5); @@ -1223,7 +1116,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(5)); + auto v = Vector!int([5]); assert(v.back == 5); @@ -1242,11 +1135,11 @@ struct Vector(T) * * Precondition: $(D_INLINECODE i <= j && j <= length) */ - Range!T opSlice(in size_t i, in size_t j) + Range!T opSlice(in size_t i, in size_t j) @trusted in { assert(i <= j); - assert(j <= length_); + assert(j <= length); } body { @@ -1254,7 +1147,7 @@ struct Vector(T) } /// Ditto. - Range!(const T) opSlice(in size_t i, in size_t j) const + Range!(const T) opSlice(in size_t i, in size_t j) const @trusted in { assert(i <= j); @@ -1277,7 +1170,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(1, 2, 3)); + auto v = Vector!int([1, 2, 3]); auto r = v[]; assert(r.front == 1); @@ -1295,7 +1188,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(1, 2, 3, 4)); + auto v = Vector!int([1, 2, 3, 4]); auto r = v[1 .. 4]; assert(r.length == 3); assert(r[0] == 2); @@ -1322,7 +1215,7 @@ struct Vector(T) * Precondition: $(D_INLINECODE i <= j && j <= length); * The lenghts of the range and slice match. */ - Range!T opSliceAssign(ref T value, in size_t i, in size_t j) @trusted + Range!T opSliceAssign(ref T value, in size_t i, in size_t j) in { assert(i <= j); @@ -1330,7 +1223,7 @@ struct Vector(T) } body { - vector[i .. j].fill(value); + fill((() @trusted => vector[i .. j])(), value); return opSlice(i, j); } @@ -1342,9 +1235,9 @@ struct Vector(T) /// Ditto. Range!T opSliceAssign(R)(R value, in size_t i, in size_t j) - if (!isInfinite!R - && isInputRange!R + if ((!isInfinite!R && isInputRange!R && isImplicitlyConvertible!(ElementType!R, T)) + || isStaticArray!R && is(ElementType!R == T)) in { assert(i <= j); @@ -1353,26 +1246,15 @@ struct Vector(T) } body { - const T* end = vector + j; - for (T* v = vector + i; v != end; ++v, value.popFront()) - { - *v = value.front; - } + copy(value, (() @trusted => vector[i .. j])()); return opSlice(i, j); } - /// Ditto. - Range!T opSliceAssign(R)(R value, in size_t i, in size_t j) - if (isStaticArray!R && isImplicitlyConvertible!(ElementType!R, T)) - { - return opSliceAssign(value[], i, j); - } - /// - unittest + @safe unittest { - auto v1 = Vector!int(IL(3, 3, 3)); - auto v2 = Vector!int(IL(1, 2)); + auto v1 = Vector!int([3, 3, 3]); + auto v2 = Vector!int([1, 2]); v1[0 .. 2] = 286; assert(v1[0] == 286); @@ -1382,6 +1264,11 @@ struct Vector(T) v2[0 .. $] = v1[1 .. 3]; assert(v2[0] == 286); assert(v2[1] == 3); + + v1[0 .. 2] = [5, 8]; + assert(v1[0] == 5); + assert(v1[1] == 8); + assert(v1[2] == 3); } /** @@ -1392,7 +1279,7 @@ struct Vector(T) * * Returns: The array with elements of this vector. */ - inout(T[]) get() inout + inout(T[]) get() inout @trusted { return vector[0 .. length]; } @@ -1400,7 +1287,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(1, 2, 4)); + auto v = Vector!int([1, 2, 4]); auto data = v.get(); assert(data[0] == 1); @@ -1419,7 +1306,7 @@ struct Vector(T) /// unittest { - auto v = Vector!int(IL(5, 15, 8)); + auto v = Vector!int([5, 15, 8]); assert(v.front == 5); assert(v[1] == 15); @@ -1435,14 +1322,14 @@ unittest { const v1 = Vector!int(); const Vector!int v2; - const v3 = Vector!int(IL(1, 5, 8)); + const v3 = Vector!int([1, 5, 8]); static assert(is(PointerTarget!(typeof(v3.vector)) == const(int))); } @nogc unittest { // Test that const vectors return usable ranges. - auto v = const Vector!int(IL(1, 2, 4)); + auto v = const Vector!int([1, 2, 4]); auto r1 = v[]; assert(r1.back == 4); @@ -1497,18 +1384,12 @@ unittest assert(v3 == v4[]); assert(v3[] == v4[]); - auto v7 = Vector!MutableEqualsStruct(); - auto v8 = Vector!MutableEqualsStruct(); + auto v7 = Vector!MutableEqualsStruct(1, MutableEqualsStruct()); + auto v8 = Vector!MutableEqualsStruct(1, MutableEqualsStruct()); assert(v7 == v8); assert(v7[] == v8); assert(v7 == v8[]); - assert(v7[] == v8[]); -} - -@nogc unittest -{ - // Implicitly convertible works. - auto v = Vector!int(IL(cast(short) 1, cast(short) 2)); + assert(equal(v7[], v8[])); } @nogc unittest diff --git a/source/tanya/meta/gen.d b/source/tanya/meta/gen.d deleted file mode 100644 index a87a90b..0000000 --- a/source/tanya/meta/gen.d +++ /dev/null @@ -1,49 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Templates that generate values. - * - * Copyright: Eugene Wissner 2016. - * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, - * Mozilla Public License, v. 2.0). - * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) - */ -module tanya.meta.gen; - -import std.traits; - -/** - * Initializer list. - * - * Generates a static array with elements from $(D_PARAM args). All elements - * should have the same type. It can be used in constructors which accept a - * list of the elements of the same type in the situations where variadic - * functions and templates can't be used. - * - * Params: - * Args = Argument type. - * args = Arguments. - */ -enum IL(Args...)(Args args) - if (Args.length > 0) -{ - alias BaseType = typeof(args[0]); - - BaseType[args.length] result; - - foreach (i, a; args) - { - static assert(isImplicitlyConvertible!(typeof(a), BaseType)); - result[i] = a; - } - return result; -} - -/// -unittest -{ - static assert(IL(1, 5, 8).length == 3); - static assert(IL(1, 5, 8).sizeof == 3 * int.sizeof); -} diff --git a/source/tanya/meta/package.d b/source/tanya/meta/package.d deleted file mode 100644 index c511220..0000000 --- a/source/tanya/meta/package.d +++ /dev/null @@ -1,15 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Metaprogramming. - * - * Copyright: Eugene Wissner 2016. - * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, - * Mozilla Public License, v. 2.0). - * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) - */ -module tanya.meta; - -public import tanya.meta.gen;