The difference between T[] opIndex() and T[] opSlice()
Salih Dincer
salihdb at hotmail.com
Mon Oct 2 06:23:47 UTC 2023
On Monday, 2 October 2023 at 02:01:34 UTC, Jonathan M Davis wrote:
>
> For most code, you'd just write an opIndex with a single
> parameter for indexing an element, opSlice with two parameters
> for slicing the range or container, and then either opIndex or
> opSlice with no parameters to return a slice of the entire
> container (in which case, personally, I'd use opSlice, because
> semantically, that's what you're doing, but either should work
> IIRC).
Overloading has nothing to do with indexing, so I'll use opSlice.
```d
import std.stdio;
import std.range;
struct Matrix(T)
{
private T[][] elements;
size_t length;
T* ptr;
this(size_t length)
{
this.length = length * length;
size_t m = T.sizeof * this.length;
ubyte[] arr = new ubyte[](m);
ptr = cast(T*)arr.ptr;
m /= length;
foreach(i; 0 .. length)
{
size_t n = i * m;
elements ~= cast(T[])arr[n .. n + m];
}
}
ref T opIndex(size_t i)
in(i < length)
=> ptr[i];
auto opDollar() => length;
auto opSliceAssign(T value, size_t a, size_t b)
in(a <= length && b <= length)
=> ptr[a..b] = value;
auto opSlice() => elements;
auto opSliceAssign(T value)
{
foreach(i; 0 .. length)
{
ptr[i] = value;
}
}
}
void main()
{
auto arr = Matrix!double(3);
size_t n;
foreach(value; iota(0.1, 1, 0.1))
arr[n++] = value;
arr[].writefln!"%-(%-(%s %)\n%)\n";
arr[0..$/2] = 0; // reset a slice
arr[].writefln!"%-(%-(%s %)\n%)\n";
arr[] = 0; // reset all
arr[].writefln!"%-(%-(%s %)\n%)\n";
arr[6..9] = 1; // set a slice
arr[].writefln!"%-(%-(%s %)\n%)\n";
}
```
SDB at 79
More information about the Digitalmars-d-learn
mailing list