mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
170 lines
4.0 KiB
Plaintext
170 lines
4.0 KiB
Plaintext
module std::core::array;
|
||
|
||
<*
|
||
A slice2d allows slicing an array like int[10][10] into an arbitrary "int[][]"-like counterpart
|
||
Typically you'd use array::slice2d(...) to create one.
|
||
*>
|
||
struct Slice2d <Type>
|
||
{
|
||
Type* ptr;
|
||
usz inner_len;
|
||
usz ystart;
|
||
usz ylen;
|
||
usz xstart;
|
||
usz xlen;
|
||
}
|
||
|
||
<*
|
||
@return `The length of the "outer" slice`
|
||
*>
|
||
fn usz Slice2d.len(&self) @operator(len)
|
||
{
|
||
return self.ylen;
|
||
}
|
||
|
||
<*
|
||
@return `The total number of elements.`
|
||
*>
|
||
fn usz Slice2d.count(&self)
|
||
{
|
||
return self.ylen * self.xlen;
|
||
}
|
||
|
||
<*
|
||
Step through each element of the slice.
|
||
*>
|
||
macro void Slice2d.@each(&self; @body(usz[<2>], Type))
|
||
{
|
||
foreach (y, line : *self)
|
||
{
|
||
foreach (x, val : line)
|
||
{
|
||
@body({ x, y }, val);
|
||
}
|
||
}
|
||
}
|
||
|
||
<*
|
||
Step through each element of the slice *by reference*
|
||
*>
|
||
macro void Slice2d.@each_ref(&self; @body(usz[<2>], Type*))
|
||
{
|
||
foreach (y, line : *self)
|
||
{
|
||
foreach (x, &val : line)
|
||
{
|
||
@body({ x, y }, val);
|
||
}
|
||
}
|
||
}
|
||
|
||
<*
|
||
Return a row as a slice.
|
||
|
||
@param idy : "The row to return"
|
||
@return "The slice for the particular row"
|
||
@require idy >= 0 && idy < self.ylen
|
||
*>
|
||
macro Type[] Slice2d.get_row(self, usz idy) @operator([])
|
||
{
|
||
return (self.ptr + self.inner_len * (idy + self.ystart))[self.xstart:self.xlen];
|
||
}
|
||
|
||
<*
|
||
Get the value at a particular x/y position in the slice.
|
||
|
||
@param coord : "The xy coordinate"
|
||
@return "The value at that coordinate"
|
||
@require coord.y >= 0 && coord.y < self.ylen : "y value out of range"
|
||
@require coord.x >= 0 && coord.x < self.xlen : "x value out of range"
|
||
*>
|
||
macro Type Slice2d.get_coord(self, usz[<2>] coord)
|
||
{
|
||
return *self.get_coord_ref(coord);
|
||
}
|
||
|
||
<*
|
||
Get a pointer to the value at a particular x/y position in the slice.
|
||
|
||
@param coord : "The xy coordinate"
|
||
@return "A pointer to the value at that coordinate"
|
||
@require coord.y >= 0 && coord.y < self.ylen : "y value out of range"
|
||
@require coord.x >= 0 && coord.x < self.xlen : "x value out of range"
|
||
*>
|
||
macro Type* Slice2d.get_coord_ref(self, usz[<2>] coord)
|
||
{
|
||
return self.get_xy_ref(coord.x, coord.y);
|
||
}
|
||
|
||
<*
|
||
Get the value at a particular x/y position in the slice.
|
||
|
||
@param x : "The x coordinate"
|
||
@param y : "The x coordinate"
|
||
@return "The value at that coordinate"
|
||
@require y >= 0 && y < self.ylen : "y value out of range"
|
||
@require x >= 0 && x < self.xlen : "x value out of range"
|
||
*>
|
||
macro Type Slice2d.get_xy(self, x, y)
|
||
{
|
||
return *self.get_xy_ref(x, y);
|
||
}
|
||
|
||
<*
|
||
Get the value at a particular x/y position in the slice by reference.
|
||
|
||
@param x : "The x coordinate"
|
||
@param y : "The y coordinate"
|
||
@return "A pointer to the value at that coordinate"
|
||
@require y >= 0 && y < self.ylen : "y value out of range"
|
||
@require x >= 0 && x < self.xlen : "x value out of range"
|
||
*>
|
||
macro Type* Slice2d.get_xy_ref(self, x, y)
|
||
{
|
||
return self.ptr + self.inner_len * (y + self.ystart) + self.xstart + x;
|
||
}
|
||
|
||
<*
|
||
Set the ´value at a particular x/y position in the slice.
|
||
|
||
@param coord : "The xy coordinate"
|
||
@param value : "The new value"
|
||
@require coord.y >= 0 && coord.y < self.ylen : "y value out of range"
|
||
@require coord.x >= 0 && coord.x < self.xlen : "x value out of range"
|
||
*>
|
||
macro void Slice2d.set_coord(self, usz[<2>] coord, Type value)
|
||
{
|
||
*self.get_coord_ref(coord) = value;
|
||
}
|
||
|
||
<*
|
||
Set the value at a particular x/y position in the slice.
|
||
|
||
@param x : "The x coordinate"
|
||
@param y : "The y coordinate"
|
||
@param value : "The new value"
|
||
@require y >= 0 && y < self.ylen : "y value out of range"
|
||
@require x >= 0 && x < self.xlen : "x value out of range"
|
||
*>
|
||
macro void Slice2d.set_xy(self, x, y, Type value)
|
||
{
|
||
*self.get_xy_ref(x, y) = value;
|
||
}
|
||
|
||
<*
|
||
Reslice a slice2d returning a new slice.
|
||
|
||
@param x : "The starting x"
|
||
@param xlen : "The length along x"
|
||
@param y : "The starting y"
|
||
@param ylen : "The length along y"
|
||
@require y >= 0 && y < self.ylen
|
||
@require x >= 0 && x < self.xlen
|
||
*>
|
||
fn Slice2d Slice2d.slice(&self, isz x = 0, isz xlen = 0, isz y = 0, isz ylen = 0)
|
||
{
|
||
if (xlen < 1) xlen = self.xlen + xlen;
|
||
if (ylen < 1) ylen = self.ylen + ylen;
|
||
return { self.ptr, self.inner_len, y + self.ystart, ylen, x + self.xstart, xlen };
|
||
}
|