Skip to content

Commit

Permalink
Add algorithm.iteration.foldr
Browse files Browse the repository at this point in the history
  • Loading branch information
belka-ew committed Apr 24, 2019
1 parent 7353556 commit 0a973b4
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 12 deletions.
60 changes: 60 additions & 0 deletions source/tanya/algorithm/iteration.d
Expand Up @@ -779,3 +779,63 @@ if (F.length == 1)

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[]);
}
8 changes: 2 additions & 6 deletions source/tanya/container/hashtable.d
Expand Up @@ -14,6 +14,7 @@
*/
module tanya.container.hashtable;

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

///
Expand Down
8 changes: 2 additions & 6 deletions source/tanya/container/list.d
Expand Up @@ -16,6 +16,7 @@
module tanya.container.list;

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

///
Expand Down

0 comments on commit 0a973b4

Please sign in to comment.