diff options
| author | Eugen Wissner <belka@caraus.de> | 2018-11-06 16:45:40 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2018-11-06 16:59:57 +0100 |
| commit | ee8b7ef719521562d5b6ab04d94848483461456d (patch) | |
| tree | dbf051ded4757d2afd7cff7b97934bd86eab6220 /source | |
| parent | 65e2e344dfa0f676ac5a84d74b03b46e74b76eaa (diff) | |
| parent | c290c850884ef27d978e82f4ee1864e1428d2644 (diff) | |
| download | tanya-ee8b7ef719521562d5b6ab04d94848483461456d.tar.gz | |
Merge remote-tracking branch 'retro-retro'
Diffstat (limited to 'source')
| -rw-r--r-- | source/tanya/algorithm/iteration.d | 175 |
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); } /// |
