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

Reply via email to