On 1/19/22 21:24, Salih Dincer wrote:
> ```d
> size_t length() inout {
> //return last_ - first_ + 1 - empty_;/*
> auto len = 1 + last_ - first_;
> return cast(size_t)len;//*/
> }
> ```
Good catch but we can't ignore '- empty_'. Otherwise an empty range will
return 1.
> But it only works on integers.
After fixing the size_t issue, it should work on user-defined types as
well. In fact, it is better to leave the return type as auto so that it
works with user-defined types that support the length expression but is
a different type like e.g. MyDiffType.
Having said that, floating point types don't make sense with the
semantics of a *bidirectional and inclusive* range. :) Let's see how it
looks for ranges where the step size is 0.3:
import std.stdio;
void main() {
float beg = 0.0;
float end = 1.0;
float step = 0.3;
writeln("\nIncrementing:");
for (float f = beg; f <= end; f += step) {
report(f);
}
writeln("\nDecrementing:");
for (float f = end; f >= beg; f -= step) {
report(f);
}
}
void report(float f) {
writefln!"%.16f"(f);
}
Here is the output:
Incrementing:
0.0000000000000000
0.3000000119209290
0.6000000238418579
0.9000000357627869
<-- Where is 1.0?
Decrementing:
1.0000000000000000
0.6999999880790710
0.3999999761581421
0.0999999642372131
<-- Where is 0.0?
So if we add the 1.0 value after 0.9000000357627869 to be *inclusive*,
then that last step would not be 0.3 anymore. (Thinking about it, step
would mess up things for integral types as well; so, it must be checked
during construction.)
The other obvious issue in the output is that a floating point iota
cannot be bidirectional because the element values would be different.
Ali