summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2018-11-06 16:45:40 +0100
committerEugen Wissner <belka@caraus.de>2018-11-06 16:59:57 +0100
commitee8b7ef719521562d5b6ab04d94848483461456d (patch)
treedbf051ded4757d2afd7cff7b97934bd86eab6220
parent65e2e344dfa0f676ac5a84d74b03b46e74b76eaa (diff)
parentc290c850884ef27d978e82f4ee1864e1428d2644 (diff)
downloadtanya-ee8b7ef719521562d5b6ab04d94848483461456d.tar.gz
Merge remote-tracking branch 'retro-retro'
-rw-r--r--source/tanya/algorithm/iteration.d175
1 files changed, 91 insertions, 84 deletions
diff --git a/source/tanya/algorithm/iteration.d b/source/tanya/algorithm/iteration.d
index 27fce71..57f78e5 100644
--- a/source/tanya/algorithm/iteration.d
+++ b/source/tanya/algorithm/iteration.d
@@ -408,127 +408,134 @@ if (isInputRange!R)
}
}
-/**
- * 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)
+// Reverse-access-order range returned by `retro`.
+private struct Retro(Range)
{
- static struct Retro
+ Range source;
+
+ @disable this();
+
+ private this(Range source)
{
- Range source;
+ this.source = source;
+ }
- @disable this();
+ Retro save()
+ {
+ return this;
+ }
- private this(Range source)
- {
- this.source = source;
- }
+ @property auto ref front()
+ in (!empty)
+ {
+ return this.source.back;
+ }
- Retro save()
- {
- return this;
- }
+ void popFront()
+ in (!empty)
+ {
+ this.source.popBack();
+ }
- @property auto ref front()
- in (!empty)
+ @property auto ref back()
+ in (!empty)
+ {
+ return this.source.front;
+ }
+
+ void popBack()
+ in (!empty)
+ {
+ this.source.popFront();
+ }
+
+ @property bool empty()
+ {
+ return this.source.empty;
+ }
+
+ static if (hasLength!Range)
+ {
+ @property size_t length()
{
- return this.source.back;
+ return this.source.length;
}
+ }
- void popFront()
- in (!empty)
+ static if (isRandomAccessRange!Range && hasLength!Range)
+ {
+ auto ref opIndex(size_t i)
+ in (i < length)
{
- this.source.popBack();
+ return this.source[$ - ++i];
}
+ }
- @property auto ref back()
+ static if (hasAssignableElements!Range)
+ {
+ @property void front(ref ElementType!Range value)
in (!empty)
{
- return this.source.front;
+ this.source.back = value;
}
- void popBack()
+ @property void front(ElementType!Range value)
in (!empty)
{
- this.source.popFront();
+ this.source.back = move(value);
}
- @property bool empty()
+ @property void back(ref ElementType!Range value)
+ in (!empty)
{
- return this.source.empty;
+ this.source.front = value;
}
- static if (hasLength!Range)
+ @property void back(ElementType!Range value)
+ in (!empty)
{
- @property size_t length()
- {
- return this.source.length;
- }
+ this.source.front = move(value);
}
static if (isRandomAccessRange!Range && hasLength!Range)
{
- auto ref opIndex(size_t i)
+ void opIndexAssign(ref ElementType!Range value, size_t i)
in (i < length)
{
- return this.source[$ - ++i];
- }
- }
-
- static if (hasAssignableElements!Range)
- {
- @property void front(ref ElementType!Range value)
- in (!empty)
- {
- this.source.back = value;
+ this.source[$ - ++i] = 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(ElementType!Range value, size_t i)
+ in (i < length)
{
- 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);
- }
+ this.source[$ - ++i] = move(value);
}
}
}
- return Retro(range);
+ 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)(return 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);
}
///