Add getAndPopFront()/getAndPopBack()
This commit is contained in:
		| @@ -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); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user