diff options
| author | Eugen Wissner <belka@caraus.de> | 2019-04-17 06:27:18 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2019-04-17 06:27:18 +0200 |
| commit | 76bda0ac8df2f9e5d49e126d16d785f5c63c4430 (patch) | |
| tree | 9fef4f9163c92eadc854501b76587924cdd62179 /source | |
| parent | f214f3baa2f3b613f39ded5ac615a887603aa05c (diff) | |
| download | tanya-76bda0ac8df2f9e5d49e126d16d785f5c63c4430.tar.gz | |
Add getAndPopFront()/getAndPopBack()
Diffstat (limited to 'source')
| -rw-r--r-- | source/tanya/algorithm/iteration.d | 5 | ||||
| -rw-r--r-- | source/tanya/container/array.d | 8 | ||||
| -rw-r--r-- | source/tanya/range/primitive.d | 94 |
3 files changed, 98 insertions, 9 deletions
diff --git a/source/tanya/algorithm/iteration.d b/source/tanya/algorithm/iteration.d index 0e91c5d..e71d581 100644 --- a/source/tanya/algorithm/iteration.d +++ b/source/tanya/algorithm/iteration.d @@ -756,7 +756,7 @@ if (F.length == 1) * * Returns: Accumulated value. */ - T foldl(R, T)(R range, auto ref T init) + auto foldl(R, T)(R range, auto ref T init) if (isInputRange!R && !isInfinite!R) { if (range.empty) @@ -765,8 +765,7 @@ if (F.length == 1) } else { - auto acc = F[0](init, range.front); - range.popFront; + auto acc = F[0](init, getAndPopFront(range)); return foldl(range, acc); } } diff --git a/source/tanya/container/array.d b/source/tanya/container/array.d index 5b3f522..872d55e 100644 --- a/source/tanya/container/array.d +++ b/source/tanya/container/array.d @@ -16,6 +16,7 @@ module tanya.container.array; import core.checkedint; import tanya.algorithm.comparison; +import tanya.algorithm.iteration; import tanya.algorithm.mutation; import tanya.memory.allocator; import tanya.memory.lifetime; @@ -670,12 +671,7 @@ struct Array(T) { reserve(length + el.length); } - size_t retLength; - foreach (e; el) - { - retLength += insertBack(e); - } - return retLength; + return foldl!((acc, e) => acc + insertBack(e))(el, 0U); } /// ditto diff --git a/source/tanya/range/primitive.d b/source/tanya/range/primitive.d index 82950ac..258d5d5 100644 --- a/source/tanya/range/primitive.d +++ b/source/tanya/range/primitive.d @@ -1545,3 +1545,97 @@ if (isInputRange!Range && hasLvalueElements!Range) assert(!sameHead(r1, r2)); } + +/** + * Returns the first element and advances the range. + * + * If $(D_PARAM range) has lvalue elements, then $(D_PSYMBOL getAndPopFront) + * returns by reference, otherwise the returned element is copied. + * + * Params: + * R = Input range type. + * range = Input range. + * + * Returns: Front range element. + * + * See_Also: $(D_PSYMBOL getAndPopBack). + */ +ElementType!R getAndPopFront(R)(ref R range) +if (isInputRange!R) +in (!range.empty) +{ + static if (hasLvalueElements!R) + { + auto el = (() @trusted => &range.front())(); + } + else + { + auto el = range.front; + } + range.popFront(); + static if (hasLvalueElements!R) + { + return *el; + } + else + { + return el; + } +} + +/// +@nogc nothrow pure @safe unittest +{ + int[3] array = [1, 2, 3]; + auto slice = array[]; + + assert(getAndPopFront(slice) == 1); + assert(slice.length == 2); +} + +/** + * Returns the last element and removes it from the range. + * + * If $(D_PARAM range) has lvalue elements, then $(D_PSYMBOL getAndPopBack) + * returns by reference, otherwise the returned element is copied. + * + * Params: + * R = Bidirectional range type. + * range = Bidirectional range. + * + * Returns: Last range element. + * + * See_Also: $(D_PSYMBOL getAndPopFront). + */ +auto ref getAndPopBack(R)(ref R range) +if (isBidirectionalRange!R) +in (!range.empty) +{ + static if (hasLvalueElements!R) + { + auto el = (() @trusted => &range.back())(); + } + else + { + auto el = range.back; + } + range.popBack(); + static if (hasLvalueElements!R) + { + return *el; + } + else + { + return el; + } +} + +/// +@nogc nothrow pure @trusted unittest +{ + int[3] array = [1, 2, 3]; + auto slice = array[]; + + assert(getAndPopBack(slice) == 3); + assert(slice.length == 2); +} |
