Add algorithm.iteration.foldr

This commit is contained in:
Eugen Wissner 2019-04-24 06:53:08 +02:00
parent 73535568b7
commit 0a973b46ba
3 changed files with 64 additions and 12 deletions

View File

@ -779,3 +779,63 @@ if (F.length == 1)
assert(actual == 6); 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
* 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 foldr) accumulates from right to left.
*
* Params:
* F = Callable accepting the accumulator and a range element.
*/
template foldr(F...)
if (F.length == 1)
{
/**
* Params:
* R = Bidirectional range type.
* T = Type of the accumulated value.
* range = Bidirectional range.
* init = Initial value.
*
* Returns: Accumulated value.
*/
auto foldr(R, T)(R range, auto ref T init)
if (isBidirectionalRange!R)
{
if (range.empty)
{
return init;
}
else
{
auto acc = F[0](init, getAndPopBack(range));
return foldr(range, acc);
}
}
}
///
@nogc nothrow pure @safe unittest
{
int[3] range = [1, 2, 3];
int[3] output;
const int[3] expected = [3, 2, 1];
alias f = (acc, x) {
acc.front = x;
acc.popFront;
return acc;
};
const actual = foldr!f(range[], output[]);
assert(output[] == expected[]);
}

View File

@ -14,6 +14,7 @@
*/ */
module tanya.container.hashtable; module tanya.container.hashtable;
import tanya.algorithm.iteration;
import tanya.algorithm.mutation; import tanya.algorithm.mutation;
import tanya.container.array; import tanya.container.array;
import tanya.container.entry; import tanya.container.entry;
@ -718,12 +719,7 @@ if (isHashFunction!(hasher, Key))
size_t insert(R)(scope R range) size_t insert(R)(scope R range)
if (isForwardRange!R && is(ElementType!R == KeyValue) && !isInfinite!R) if (isForwardRange!R && is(ElementType!R == KeyValue) && !isInfinite!R)
{ {
size_t count; return foldl!((acc, x) => acc + insert(x))(range, 0U);
foreach (e; range)
{
count += insert(e);
}
return count;
} }
/// ///

View File

@ -16,6 +16,7 @@
module tanya.container.list; module tanya.container.list;
import tanya.algorithm.comparison; import tanya.algorithm.comparison;
import tanya.algorithm.iteration;
import tanya.container.entry; import tanya.container.entry;
import tanya.memory.allocator; import tanya.memory.allocator;
import tanya.memory.lifetime; import tanya.memory.lifetime;
@ -1690,12 +1691,7 @@ struct DList(T)
&& isImplicitlyConvertible!(ElementType!R, T)) && isImplicitlyConvertible!(ElementType!R, T))
in (checkRangeBelonging(r)) in (checkRangeBelonging(r))
{ {
size_t inserted; return foldl!((acc, x) => acc + insertAfter(r, x))(el, 0U);
foreach (e; el)
{
inserted += insertAfter(r, e);
}
return inserted;
} }
/// ///