summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-01-16 09:02:00 +0100
committerEugen Wissner <belka@caraus.de>2017-01-16 09:02:00 +0100
commit20c8b659d11eeeb1277edc1b7e812cee0624a5be (patch)
tree4d6908f0b15e334daa13feedde8550bda966a5c4
parent4ea9c2b740fce773b8f7ba821700a5a1bdc53f2b (diff)
downloadtanya-20c8b659d11eeeb1277edc1b7e812cee0624a5be.tar.gz
Remove mutation methods from vector range
in favor of std.algorithm.mutation.
-rw-r--r--source/tanya/container/entry.d23
-rw-r--r--source/tanya/container/vector.d323
-rw-r--r--source/tanya/meta/gen.d49
-rw-r--r--source/tanya/meta/package.d15
4 files changed, 102 insertions, 308 deletions
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;