takeBack() implementation in std.range for OutputRanges
Salih Dincer
salihdb at hotmail.com
Sat Aug 31 17:55:17 UTC 2024
Why have a function called dropBack() but not takeBack()?
---
**Rationale:** It uses the drop() function in the module and is
compatible with the name dropBack().
Let's say we have a range (called STS for short) that returns odd
numbers:
```d
alias STS = SonsuzTekSayı;
struct SonsuzTekSayı { // InfinityNumbers
import std.traits;
import std.bigint;
BigInt numara;
size_t length;
this(T)(T ilk) { // Initialize
static if (isIntegral!T)
numara = BigInt(ilk % 2 ? ilk : ++ilk);
else {
import std.string : isNumeric;
if (ilk.isNumeric) {
auto birler = cast(char)ilk.back;
if (birler % 2 == 0) ++birler;
ilk.length--;
numara = BigInt(ilk ~ birler);
}
}
}
bool empty;
auto front() => numara;
auto popFront() => numara += 2;
}
```
Let's add a convenience function to increase efficiency:
```d
alias adetSayıVer = startingFrom;
auto startingFrom(T)(size_t Length, T First)
{
import std.range : take;
auto range = STS(First);
range.length = Length;
return range.take(Length);
}
```
Since our range is not Bidirectional, we get an error with
```dropBack()```. Also, we cannot pop 4 elements from the end
like we do in an array (```arr[$ - 4..$]```), my solution is (if
it gives the range length) the following:
```d
auto takeBack(R)(R range, size_t n)
{
import std.range : drop;
auto diff = range.length - n;
return range.drop(diff);
}
void main()
{
import std.stdio : writeln;
auto r = 1000.startingFrom("9000");
r.takeBack(4).writeln; /* PRINTS:
[10993, 10995, 10997, 10999]
*/
}
```
**FN:** Although it is not needed at all, takeBack() already
works with an array. Perhaps the slicing method for arrays could
be adapted with or without a convenience function.
SDB at 79
More information about the dip.ideas
mailing list