How to return range constructs?

Robin robbepop at web.de
Fri Feb 28 09:02:10 PST 2014


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


More information about the Digitalmars-d-learn mailing list