summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2021-05-16 07:52:46 +0200
committerEugen Wissner <belka@caraus.de>2021-05-16 07:52:46 +0200
commitb62cbb0647550ce54dc04ce6dc3a136fdb172bd7 (patch)
tree8f7731d6a05d2f96ac143d6d19ed557a0661f728
parent2c21dc34296ad9eeadae45b96a1e07853dbae84f (diff)
downloadtanya-b62cbb0647550ce54dc04ce6dc3a136fdb172bd7.tar.gz
Use std searching and iteration
-rw-r--r--source/tanya/algorithm/iteration.d602
-rw-r--r--source/tanya/algorithm/package.d3
-rw-r--r--source/tanya/algorithm/searching.d53
-rw-r--r--source/tanya/container/array.d6
-rw-r--r--source/tanya/container/hashtable.d6
-rw-r--r--source/tanya/container/list.d6
-rw-r--r--source/tanya/container/string.d2
-rw-r--r--tests/tanya/algorithm/tests/iteration.d74
-rw-r--r--tests/tanya/algorithm/tests/searching.d17
9 files changed, 16 insertions, 753 deletions
diff --git a/source/tanya/algorithm/iteration.d b/source/tanya/algorithm/iteration.d
index 76356a4..14b50fd 100644
--- a/source/tanya/algorithm/iteration.d
+++ b/source/tanya/algorithm/iteration.d
@@ -11,7 +11,7 @@
* All algorithms in this module are lazy, they request the next element of the
* original range on demand.
*
- * Copyright: Eugene Wissner 2018-2020.
+ * Copyright: Eugene Wissner 2018-2021.
* 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)
@@ -20,554 +20,12 @@
*/
module tanya.algorithm.iteration;
-import std.algorithm.comparison;
import std.typecons;
import tanya.memory.lifetime;
import tanya.meta.trait;
import tanya.meta.transform;
import tanya.range;
-// These predicates are used to help preserve `const` and `inout` for
-// ranges built on other ranges.
-
-private enum hasInoutFront(T) = is(typeof((inout ref T a) => a.front));
-private enum hasInoutBack(T) = is(typeof((inout ref T a) => a.back));
-private enum hasInoutIndex(T) = is(typeof((inout ref T a, size_t i) => a[i]));
-
-private enum hasConstEmpty(T) = is(typeof(((const T* a) => (*a).empty)(null)) : bool);
-private enum hasConstLength(T) = is(typeof(((const T* a) => (*a).length)(null)) : size_t);
-private enum hasConstSave(T) = is(typeof(((const T* a) => (*a).save())(null)) : T);
-private enum hasConstSlice(T) = is(typeof(((const T* a) => (*a)[0 .. $])(null)) : T);
-
-@nogc nothrow pure @safe unittest
-{
- // Test the definitions.
- static assert(hasInoutFront!string);
- static assert(hasInoutBack!string);
- static assert(hasInoutIndex!string);
- static assert(hasConstEmpty!string);
- static assert(hasConstLength!string);
- static assert(hasConstSave!string);
- static assert(hasConstSlice!string);
-
- // Test that Take propagates const/inout correctly.
- alias TakeString = Take!(string, false);
- static assert(hasInoutFront!TakeString);
- static assert(hasInoutBack!TakeString);
- static assert(hasInoutIndex!TakeString);
- static assert(hasConstEmpty!TakeString);
- static assert(hasConstLength!TakeString);
- static assert(hasConstSave!TakeString);
- static assert(hasConstSlice!TakeString);
-
- // Test that Retro propagates const/inout correctly.
- alias RetroString = Retro!string;
- static assert(hasInoutFront!RetroString);
- static assert(hasInoutBack!RetroString);
- static assert(hasInoutIndex!RetroString);
- static assert(hasConstEmpty!RetroString);
- static assert(hasConstLength!RetroString);
- static assert(hasConstSave!RetroString);
- static assert(hasConstSlice!RetroString);
-}
-
-private struct Take(R, bool exactly)
-{
- private R source;
- size_t length_;
-
- @disable this();
-
- private this(R source, size_t length)
- {
- this.source = source;
- static if (!exactly && hasLength!R)
- {
- this.length_ = min(source.length, length);
- }
- else
- {
- this.length_ = length;
- }
- }
-
- mixin(`@property auto ref front() ` ~ (hasInoutFront!R ? `inout ` : ``) ~
- `in (!empty)
- {
- return this.source.front;
- }`);
-
- void popFront()
- in (!empty)
- {
- this.source.popFront();
- --this.length_;
- }
-
- mixin(`@property bool empty() ` ~ (exactly || isInfinite!R || hasConstEmpty!R ? `const ` : ``) ~
- `{
- static if (exactly || isInfinite!R)
- {
- return length == 0;
- }
- else
- {
- return this.length_ == 0 || this.source.empty;
- }
- }`);
-
- static if (exactly || hasLength!R)
- {
- @property size_t length() const
- {
- return this.length_;
- }
- }
-
- static if (hasAssignableElements!R)
- {
- @property void front(ref ElementType!R value)
- in (!empty)
- {
- this.source.front = value;
- }
-
- @property void front(ElementType!R value)
- in (!empty)
- {
- this.source.front = move(value);
- }
- }
-
- static if (isForwardRange!R)
- {
- mixin(`typeof(this) save() ` ~ (hasConstSave!R ? `const ` : ``) ~
- `{
- return typeof(this)(this.source.save(), length);
- }`);
- }
- static if (isRandomAccessRange!R)
- {
- mixin(`@property auto ref back() ` ~ (hasInoutBack!R ? `inout ` : ``) ~
- `in (!empty)
- {
- return this.source[this.length - 1];
- }`);
-
- void popBack()
- in (!empty)
- {
- --this.length_;
- }
-
- mixin(`auto ref opIndex(size_t i) ` ~ (hasInoutIndex!R ? `inout ` : ``) ~
- `in (i < length)
- {
- return this.source[i];
- }`);
-
- static if (hasAssignableElements!R)
- {
- @property void back(ref ElementType!R value)
- in (!empty)
- {
- this.source[length - 1] = value;
- }
-
- @property void back(ElementType!R value)
- in (!empty)
- {
- this.source[length - 1] = move(value);
- }
-
- void opIndexAssign(ref ElementType!R value, size_t i)
- in (i < length)
- {
- this.source[i] = value;
- }
-
- void opIndexAssign(ElementType!R value, size_t i)
- in (i < length)
- {
- this.source[i] = move(value);
- }
- }
- }
-
- static if (!exactly && hasSlicing!R)
- {
- static if (is(typeof(length))) alias opDollar = length;
-
- mixin(`auto opSlice(size_t i, size_t j) ` ~ (hasConstSlice!R ? `const ` : ``) ~
- `in (i <= j)
- in (j <= length)
- {
- return typeof(this)(this.source[i .. j], length);
- }`);
- }
-
- version (unittest) static assert(isInputRange!Take);
-}
-
-/**
- * Takes $(D_PARAM n) elements from $(D_PARAM range).
- *
- * If $(D_PARAM range) doesn't have $(D_PARAM n) elements, the resulting range
- * spans all elements of $(D_PARAM range).
- *
- * $(D_PSYMBOL take) is particulary useful with infinite ranges. You can take
- ` $(B n) elements from such range and pass the result to an algorithm which
- * expects a finit range.
- *
- * Params:
- * R = Type of the adapted range.
- * range = The range to take the elements from.
- * n = The number of elements to take.
- *
- * Returns: A range containing maximum $(D_PARAM n) first elements of
- * $(D_PARAM range).
- *
- * See_Also: $(D_PSYMBOL takeExactly).
- */
-auto take(R)(R range, size_t n)
-if (isInputRange!R)
-{
- static if (hasSlicing!R && hasLength!R)
- {
- if (range.length <= n)
- return range;
- else
- return range[0 .. n];
- }
- // Special case: take(take(...), n)
- else static if (is(Range == Take!(RRange, exact), RRange, bool exact))
- {
- if (n > range.length_)
- n = range.length_;
- static if (exact)
- // `take(takeExactly(r, n0), n)` is rewritten `takeExactly(r, min(n0, n))`.
- return Take!(RRange, true)(range.source, n);
- else
- // `take(take(r, n0), n)` is rewritten `take(r, min(n0, n))`.
- return Take!(RRange, false)(range.source, n);
- }
- else static if (isInfinite!R)
- {
- // If the range is infinite then `take` is the same as `takeExactly`.
- return Take!(R, true)(range, n);
- }
- else
- {
- return Take!(R, false)(range, n);
- }
-}
-
-///
-@nogc nothrow pure @safe unittest
-{
- static struct InfiniteRange
- {
- private size_t front_ = 1;
-
- enum bool empty = false;
-
- @property size_t front() @nogc nothrow pure @safe
- {
- return this.front_;
- }
-
- @property void front(size_t i) @nogc nothrow pure @safe
- {
- this.front_ = i;
- }
-
- void popFront() @nogc nothrow pure @safe
- {
- ++this.front_;
- }
-
- size_t opIndex(size_t i) @nogc nothrow pure @safe
- {
- return this.front_ + i;
- }
-
- void opIndexAssign(size_t value, size_t i) @nogc nothrow pure @safe
- {
- this.front = i + value;
- }
-
- InfiniteRange save() @nogc nothrow pure @safe
- {
- return this;
- }
- }
-
- auto t = InfiniteRange().take(3);
- assert(t.length == 3);
- assert(t.front == 1);
- assert(t.back == 3);
-
- t.popFront();
- assert(t.front == 2);
- assert(t.back == 3);
-
- t.popBack();
- assert(t.front == 2);
- assert(t.back == 2);
-
- t.popFront();
- assert(t.empty);
-}
-
-/**
- * Takes exactly $(D_PARAM n) elements from $(D_PARAM range).
- *
- * $(D_PARAM range) must have at least $(D_PARAM n) elements.
- *
- * $(D_PSYMBOL takeExactly) is particulary useful with infinite ranges. You can
- ` take $(B n) elements from such range and pass the result to an algorithm
- * which expects a finit range.
- *
- * Params:
- * R = Type of the adapted range.
- * range = The range to take the elements from.
- * n = The number of elements to take.
- *
- * Returns: A range containing $(D_PARAM n) first elements of $(D_PARAM range).
- *
- * See_Also: $(D_PSYMBOL take).
- */
-auto takeExactly(R)(R range, size_t n)
-if (isInputRange!R)
-{
- static if (hasSlicing!R)
- {
- return range[0 .. n];
- }
- // Special case: takeExactly(take(range, ...), n) is takeExactly(range, n)
- else static if (is(Range == Take!(RRange, exact), RRange, bool exact))
- {
- assert(n <= range.length_);
- return Take!(RRange, true)(range.source, n);
- }
- else
- {
- return Take!(R, true)(range, n);
- }
-}
-
-///
-@nogc nothrow pure @safe unittest
-{
- static struct InfiniteRange
- {
- private size_t front_ = 1;
-
- enum bool empty = false;
-
- @property size_t front() @nogc nothrow pure @safe
- {
- return this.front_;
- }
-
- @property void front(size_t i) @nogc nothrow pure @safe
- {
- this.front_ = i;
- }
-
- void popFront() @nogc nothrow pure @safe
- {
- ++this.front_;
- }
-
- size_t opIndex(size_t i) @nogc nothrow pure @safe
- {
- return this.front_ + i;
- }
-
- void opIndexAssign(size_t value, size_t i) @nogc nothrow pure @safe
- {
- this.front = i + value;
- }
-
- InfiniteRange save() @nogc nothrow pure @safe
- {
- return this;
- }
- }
-
- auto t = InfiniteRange().takeExactly(3);
- assert(t.length == 3);
- assert(t.front == 1);
- assert(t.back == 3);
-
- t.popFront();
- assert(t.front == 2);
- assert(t.back == 3);
-
- t.popBack();
- assert(t.front == 2);
- assert(t.back == 2);
-
- t.popFront();
- assert(t.empty);
-}
-
-// Reverse-access-order range returned by `retro`.
-private struct Retro(Range)
-{
- Range source;
-
- @disable this();
-
- private this(Range source) @safe
- {
- this.source = source;
- }
-
- mixin(`Retro save() ` ~ (hasConstSave!Range ? `const ` : ``) ~
- `{
- return Retro(source.save());
- }`);
-
- mixin(`@property auto ref front() ` ~ (hasInoutBack!Range ? `inout ` : ``) ~
- `in (!empty)
- {
- return this.source.back;
- }`);
-
- void popFront()
- in (!empty)
- {
- this.source.popBack();
- }
-
- mixin(`@property auto ref back() ` ~ (hasInoutFront!Range ? `inout ` : ``) ~
- `in (!empty)
- {
- return this.source.front;
- }`);
-
- void popBack()
- in (!empty)
- {
- this.source.popFront();
- }
-
- mixin(`@property bool empty() ` ~ (hasConstEmpty!Range ? `const ` : ``) ~
- `{
- return this.source.empty;
- }`);
-
- static if (hasLength!Range)
- {
- mixin(`@property size_t length() ` ~ (hasConstLength!Range ? `const ` : ``) ~
- `{
- return this.source.length;
- }`);
- }
-
- static if (isRandomAccessRange!Range && hasLength!Range)
- {
- mixin(`auto ref opIndex(size_t i) ` ~ (hasInoutIndex!Range ? `inout ` : ``) ~
- `in (i < length)
- {
- return this.source[$ - ++i];
- }`);
- }
-
- static if (hasLength!Range && hasSlicing!Range)
- {
- alias opDollar = length;
-
- mixin(`auto opSlice(size_t i, size_t j) ` ~ (hasConstSlice!Range ? `const ` : ``) ~
- `in (i <= j)
- in (j <= length)
- {
- return typeof(this)(this.source[$-j .. $-i]);
- }`);
- }
-
- static if (hasAssignableElements!Range)
- {
- @property void front(ref ElementType!Range value)
- in (!empty)
- {
- this.source.back = value;
- }
-
- @property void front(ElementType!Range value)
- in (!empty)
- {
- this.source.back = move(value);
- }
-
- @property void back(ref ElementType!Range value)
- in (!empty)
- {
- this.source.front = value;
- }
-
- @property void back(ElementType!Range value)
- in (!empty)
- {
- this.source.front = move(value);
- }
-
- static if (isRandomAccessRange!Range && hasLength!Range)
- {
- void opIndexAssign(ref ElementType!Range value, size_t i)
- in (i < length)
- {
- this.source[$ - ++i] = value;
- }
-
- void opIndexAssign(ElementType!Range value, size_t i)
- in (i < length)
- {
- this.source[$ - ++i] = move(value);
- }
- }
- }
-
- version (unittest) static assert(isBidirectionalRange!Retro);
-}
-
-/**
- * Iterates a bidirectional range backwards.
- *
- * If $(D_PARAM Range) is a random-access range as well, the resulting range
- * is a random-access range too.
- *
- * Params:
- * Range = Bidirectional range type.
- * range = Bidirectional range.
- *
- * Returns: Bidirectional range with the elements order reversed.
- */
-auto retro(Range)(Range range)
-if (isBidirectionalRange!Range)
-{
- // Special case: retro(retro(range)) is range
- static if (is(Range == Retro!RRange, RRange))
- return range.source;
- else
- return Retro!Range(range);
-}
-
-///
-@nogc nothrow pure @safe unittest
-{
- const int[3] given = [1, 2, 3];
- const int[3] expected = [3, 2, 1];
-
- auto actual = retro(given[]);
-
- assert(actual.length == expected.length);
- assert(!actual.empty);
- assert(equal(actual, expected[]));
-}
-
private struct SingletonByValue(E)
{
private Nullable!E element;
@@ -719,61 +177,9 @@ auto singleton(E)(return ref E element)
/**
* Accumulates all elements of a range using a function.
*
- * $(D_PSYMBOL foldl) takes a function, an input range and the initial value.
- * The function takes this initial value and the first element of the range (in
- * this order), puts them together and returns the result. The return
- * type of the function should be the same as the type of the initial value.
- * This is than repeated for all the remaining elements of the range, whereby
- * the value returned by the passed function is used at the place of the
- * initial value.
- *
- * $(D_PSYMBOL foldl) accumulates from left to right.
- *
- * Params:
- * F = Callable accepting the accumulator and a range element.
- */
-template foldl(F...)
-if (F.length == 1)
-{
- /**
- * Params:
- * R = Input range type.
- * T = Type of the accumulated value.
- * range = Input range.
- * init = Initial value.
- *
- * Returns: Accumulated value.
- */
- auto foldl(R, T)(R range, auto ref T init)
- if (isInputRange!R && !isInfinite!R)
- {
- if (range.empty)
- {
- return init;
- }
- else
- {
- auto acc = F[0](init, getAndPopFront(range));
- return foldl(range, acc);
- }
- }
-}
-
-///
-@nogc nothrow pure @safe unittest
-{
- int[3] range = [1, 2, 3];
- const actual = foldl!((acc, x) => acc + x)(range[], 0);
-
- assert(actual == 6);
-}
-
-/**
- * Accumulates all elements of a range using a function.
- *
- * $(D_PSYMBOL foldr) takes a function, an input range and the initial value.
- * The function takes this initial value and the first element of the range (in
- * this order), puts them together and returns the result. The return
+ * $(D_PSYMBOL foldr) takes a function, a bidirectional range and the initial
+ * value. The function takes this initial value and the first element of the
+ * range (in this order), puts them together and returns the result. The return
* type of the function should be the same as the type of the initial value.
* This is than repeated for all the remaining elements of the range, whereby
* the value returned by the passed function is used at the place of the
diff --git a/source/tanya/algorithm/package.d b/source/tanya/algorithm/package.d
index 1aee863..90e9a8a 100644
--- a/source/tanya/algorithm/package.d
+++ b/source/tanya/algorithm/package.d
@@ -5,7 +5,7 @@
/**
* Collection of generic algorithms.
*
- * Copyright: Eugene Wissner 2017-2020.
+ * Copyright: Eugene Wissner 2017-2021.
* 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)
@@ -16,4 +16,3 @@ module tanya.algorithm;
public import tanya.algorithm.iteration;
public import tanya.algorithm.mutation;
-public import tanya.algorithm.searching;
diff --git a/source/tanya/algorithm/searching.d b/source/tanya/algorithm/searching.d
deleted file mode 100644
index 63e870f..0000000
--- a/source/tanya/algorithm/searching.d
+++ /dev/null
@@ -1,53 +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/. */
-
-/**
- * Searching algorithms.
- *
- * Copyright: Eugene Wissner 2018-2020.
- * 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)
- * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/algorithm/searching.d,
- * tanya/algorithm/searching.d)
- */
-module tanya.algorithm.searching;
-
-import tanya.range;
-
-/**
- * Counts the elements in an input range.
- *
- * If $(D_PARAM R) has length, $(D_PSYMBOL count) returns it, otherwise it
- * iterates over the range and counts the elements.
- *
- * Params:
- * R = Input range type.
- * range = Input range.
- *
- * Returns: $(D_PARAM range) length.
- */
-size_t count(R)(R range)
-if (isInputRange!R)
-{
- static if (hasLength!R)
- {
- return range.length;
- }
- else
- {
- size_t counter;
- for (; !range.empty; range.popFront(), ++counter)
- {
- }
- return counter;
- }
-}
-
-///
-@nogc nothrow pure @safe unittest
-{
- int[3] array;
- assert(count(array) == 3);
-}
diff --git a/source/tanya/container/array.d b/source/tanya/container/array.d
index dcd2074..d2e0d09 100644
--- a/source/tanya/container/array.d
+++ b/source/tanya/container/array.d
@@ -5,7 +5,7 @@
/**
* Single-dimensioned array.
*
- * Copyright: Eugene Wissner 2016-2020.
+ * Copyright: Eugene Wissner 2016-2021.
* 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)
@@ -16,7 +16,7 @@ module tanya.container.array;
import core.checkedint;
import std.algorithm.comparison;
-import tanya.algorithm.iteration;
+import std.algorithm.iteration;
import tanya.algorithm.mutation;
import tanya.memory.allocator;
import tanya.memory.lifetime;
@@ -676,7 +676,7 @@ struct Array(T)
{
reserve(length + el.length);
}
- return foldl!((acc, e) => acc + insertBack(e))(el, 0U);
+ return fold!((acc, e) => acc + insertBack(e))(el, size_t.init);
}
/// ditto
diff --git a/source/tanya/container/hashtable.d b/source/tanya/container/hashtable.d
index 15bb82d..4dc80c8 100644
--- a/source/tanya/container/hashtable.d
+++ b/source/tanya/container/hashtable.d
@@ -5,7 +5,7 @@
/**
* Hash table.
*
- * Copyright: Eugene Wissner 2018-2020.
+ * Copyright: Eugene Wissner 2018-2021.
* 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)
@@ -14,7 +14,7 @@
*/
module tanya.container.hashtable;
-import tanya.algorithm.iteration;
+import std.algorithm.iteration;
import tanya.algorithm.mutation;
import tanya.container.array;
import tanya.container.entry;
@@ -719,7 +719,7 @@ if (isHashFunction!(hasher, Key))
size_t insert(R)(scope R range)
if (isForwardRange!R && is(ElementType!R == KeyValue) && !isInfinite!R)
{
- return foldl!((acc, x) => acc + insert(x))(range, 0U);
+ return fold!((acc, x) => acc + insert(x))(range, size_t.init);
}
///
diff --git a/source/tanya/container/list.d b/source/tanya/container/list.d
index 0d8fc3d..56c8d22 100644
--- a/source/tanya/container/list.d
+++ b/source/tanya/container/list.d
@@ -6,7 +6,7 @@
* This module contains singly-linked ($(D_PSYMBOL SList)) and doubly-linked
* ($(D_PSYMBOL DList)) lists.
*
- * Copyright: Eugene Wissner 2016-2020.
+ * Copyright: Eugene Wissner 2016-2021.
* 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)
@@ -16,7 +16,7 @@
module tanya.container.list;
import std.algorithm.comparison;
-import tanya.algorithm.iteration;
+import std.algorithm.iteration;
import tanya.container.entry;
import tanya.memory.allocator;
import tanya.memory.lifetime;
@@ -1693,7 +1693,7 @@ struct DList(T)
&& isImplicitlyConvertible!(ElementType!R, T))
in (checkRangeBelonging(r))
{
- return foldl!((acc, x) => acc + insertAfter(r, x))(el, 0U);
+ return fold!((acc, x) => acc + insertAfter(r, x))(el, size_t.init);
}
///
diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d
index 6fad9bb..bd8f817 100644
--- a/source/tanya/container/string.d
+++ b/source/tanya/container/string.d
@@ -1342,7 +1342,7 @@ struct String
///
@nogc pure @safe unittest
{
- import tanya.algorithm.searching : count;
+ import std.algorithm.searching : count;
auto s = String("Из пословицы слова не выкинешь.");
diff --git a/tests/tanya/algorithm/tests/iteration.d b/tests/tanya/algorithm/tests/iteration.d
index 52e99b3..9594d5e 100644
--- a/tests/tanya/algorithm/tests/iteration.d
+++ b/tests/tanya/algorithm/tests/iteration.d
@@ -1,85 +1,13 @@
/* 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/. */
+
module tanya.algorithm.tests.iteration;
import tanya.algorithm.iteration;
import tanya.range;
import tanya.test.stub;
-// length is unknown when taking from a range without length
-@nogc nothrow pure @safe unittest
-{
- static struct R
- {
- mixin InputRangeStub;
- }
- auto actual = take(R(), 100);
-
- static assert(!hasLength!(typeof(actual)));
-}
-
-// Takes minimum length if the range length > n
-@nogc nothrow pure @safe unittest
-{
- auto range = take(cast(int[]) null, 8);
- assert(range.length == 0);
-}
-
-@nogc nothrow pure @safe unittest
-{
- const int[9] range = [1, 2, 3, 4, 5, 6, 7, 8, 9];
- {
- auto slice = take(range[], 8)[1 .. 3];
-
- assert(slice.length == 2);
- assert(slice.front == 2);
- assert(slice.back == 3);
- }
- {
- auto slice = takeExactly(range[], 8)[1 .. 3];
-
- assert(slice.length == 2);
- assert(slice.front == 2);
- assert(slice.back == 3);
- }
-}
-
-// Elements are accessible in reverse order
-@nogc nothrow pure @safe unittest
-{
- const int[3] given = [1, 2, 3];
- auto actual = retro(given[]);
-
- assert(actual.back == given[].front);
- assert(actual[0] == 3);
- assert(actual[2] == 1);
-
- actual.popBack();
- assert(actual.back == 2);
- assert(actual[1] == 2);
-
- // Check slicing.
- auto slice = retro(given[])[1 .. $];
- assert(slice.length == 2 && slice.front == 2 && slice.back == 1);
-}
-
-// Elements can be assigned
-@nogc nothrow pure @safe unittest
-{
- int[4] given = [1, 2, 3, 4];
- auto actual = retro(given[]);
-
- actual.front = 5;
- assert(given[].back == 5);
-
- actual.back = 8;
- assert(given[].front == 8);
-
- actual[2] = 10;
- assert(given[1] == 10);
-}
-
// Singleton range is bidirectional and random-access
@nogc nothrow pure @safe unittest
{
diff --git a/tests/tanya/algorithm/tests/searching.d b/tests/tanya/algorithm/tests/searching.d
deleted file mode 100644
index ca8fdb0..0000000
--- a/tests/tanya/algorithm/tests/searching.d
+++ /dev/null
@@ -1,17 +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/. */
-module tanya.algorithm.tests.searching;
-
-import tanya.algorithm.searching;
-import tanya.test.stub;
-
-@nogc nothrow pure @safe unittest
-{
- @Count(3)
- static struct Range
- {
- mixin InputRangeStub!int;
- }
- assert(count(Range()) == 3);
-}