Hiho,
for experimental and learning reasons I am working on a simple
matrix library for D. And since ranges seem to be a cool feature
of the D language I am currently trying to understand them and
use them more in my codes.
So I thought that it would be a nice feature if I could create
methods to return specific ranges for certain matrix instances,
e.g. something like getRowRange(size_t row) or
getColumnRange(size_t col) which returns a range to easily
iterate through a single row- or column vector of a matrix
instance with a simple foreach loop.
I store the matrix data within a single dimensional array for
performance purposes instead of a jagged array:
private
{
T[] data;
Dimension dim;
}
The Dimension 'dim' is an object holding the number of rows and
columns as well as some handy methods and properties such as
isSquare etc.
So my question is: How to define such a method which returns a
range for a single row or column vector? The range should be
modifiable depending on whether the matrix instance is
const/immutable or not. Or isn't that possible at all? I thought
that it could be tricky for row vectors since their data wouldn't
be dense in memory.
I've looked into the std.range documentation but doesn't seem to
get a clue how to get this working. And if it works - what range
type would fit best for my purposes - or do I need to create a
sub-class of a certain range type specially fit for my matrix?
My try so far:
module neoLab.core.ColumnVectorRange;
import std.range;
import neoLab.core.Matrix;
final class ColumnVectorRange(T) : RandomAccessFinite!T {
private
{
T[] data;
size_t cur = 0;
size_t length = 0;
}
this(const ref Matrix m, size_t row)
in
{
assert(row < m.getDimension().rows, "Row index is invalid.");
}
body
{
this.data = m.data;
this.length = m.getDimension().cols;
}
ColumnVectorRange!T save() {
// What does this do?
}
override T opIndex(size_t index) {
return this.data[index]; // this correct?
}
override T moveAt(size_t index) {
return this.data[this.cur]; // this good?
}
override size_t length() {
return this.length;
}
override alias opDollar = this.length; // Is this nessecary?
override ColumnVectorRange!E opSlice(size_t, size_t) {
// What does this do in particular?
}
}
I highly appreciate tips and answers! =)
Thanks in advance.
Robin