Add algorithm.iteration.foldr
This commit is contained in:
		| @@ -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[]); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// |     /// | ||||||
|   | |||||||
| @@ -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; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// |     /// | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user