Thread overview
Question about opSlice
Mar 17, 2015
Ilya Ivanov
Mar 17, 2015
ketmar
Mar 17, 2015
Marc Schütz
Mar 17, 2015
Ilya Ivanov
Mar 17, 2015
Marc Schütz
Mar 17, 2015
John Colvin
Mar 17, 2015
John Colvin
Mar 17, 2015
Ali Çehreli
Mar 17, 2015
Ilya Ivanov
March 17, 2015
Can please someone tell me what is wrong with my code or is it a
bug?
The compilation errors are:
D:\DLang\test.d(184): Error: vector[0..2] is not an lvalue
D:\DLang\test.d(186): Error: vector[0..2] is not an lvalue
D:\DLang\test.d(188): Error: vector.opSlice(0u, 2u) is not an
lvalue
D:\DLang\test.d(190): Error: vector.opSlice(0u, 2u) is not an
lvalue

If I use old style opSlice (the commented out code) everything
works fine.

Thanks

import std.stdio;
import std.conv;

class MyVector(T)
{
private:
	struct Slice
	{
		public size_t i, j;
	}
	T[] data;

public:
	this(T[] other)
	{	data = new T[other.length];
		data[] = other.dup;
	}

	Slice opSlice(size_t i, size_t j) {
		Slice slice = Slice(i, j);
		return slice;
	}
	size_t opDollar() {
		return data.length;
	}
	T opIndex(size_t i)
	{
		return data[i];
	}
	T[] opIndex(Slice slice)
	{
		return data[slice.i .. slice.j];
	}
	MyVector opIndexUnary(string op)(size_t i)
	{
		mixin(op ~ "data[i];");
		return this;
	}
	MyVector opIndexUnary(string op)(Slice slice)
	{
		mixin(op ~ "data[slice.i .. slice.j];");
		return this;
	}
	MyVector opIndexUnary(string op)()
	{
		mixin(op ~ "data[];");
		return this;
	}
	void opIndexAssign(T value, size_t i)
	{
		data[i] = value;
	}
	void opIndexAssign(T value, Slice slice)
	{
		data[slice.i .. slice.j] = value;
	}
	void opIndexAssign(T[] value, Slice slice)
	{
		data[slice.i .. slice.j] = value;
	}
	void opIndexAssign(T value)
	{
		data[] = value;
	}
	void opIndexAssign(T[] value)
	{
		data[] = value;
	}
	void opIndexOpAssign(string op)(T value, size_t i)
	{
		mixin("data[i] " ~ op ~ "= value;");
	}
	void opIndexOpAssign(string op)(T value, Slice slice)
	{
		mixin("data[slice.i .. slice.j] " ~ op ~ "= value;");
	}
	void opIndexOpAssign(string op)(T[] value, Slice slice)
	{
		mixin("data[slice.i .. slice.j] " ~ op ~ "= value;");
	}
	void opIndexOpAssign(string op)(T value)
	{
		mixin("data[] " ~ op ~ "= value;");
	}
	void opIndexOpAssign(string op)(T[] value)
	{
		mixin("data[] " ~ op ~ "= value;");
	}

	/*MyVector opSliceUnary(string op)(size_t i, size_t j)
	{
		mixin(op ~ "data[i..j];");
		return this;
	}
	MyVector opSliceUnary(string op)()
	{
		mixin(op ~ "data[];");
		return this;
	}
	void opSliceAssign(T value, size_t i, size_t j)
	{
		data[i..j] = value;
	}
	void opSliceAssign(T[] value, size_t i, size_t j)
	{
		data[i..j] = value[];
	}
	void opSliceAssign(T value)
	{
		data[] = value;
	}
	void opSliceAssign(T[] value)
	{
		data[] = value[];
	}
	void opSliceOpAssign(string op)(T value, size_t i, size_t j)
	{
		mixin("data[i..j] " ~ op ~ "= value;");
	}
	void opSliceOpAssign(string op)(T[] value, size_t i, size_t j)
	{
		mixin("data[i..j] " ~ op ~ "= value[];");
	}
	void opSliceOpAssign(string op)(T value)
	{
		mixin("data[] " ~ op ~ "= value;");
	}
	void opSliceOpAssign(string op)(T[] value)
	{
		mixin("data[] " ~ op ~ "= value[];");
	}*/
}


void main(string[] args)
  {
	writeln("All tests passed!");
}

void assertArray(int[] array, int val0, int val1, int val2) {
	assert(array[0] == val0);
	assert(array[1] == val1);
	assert(array[2] == val2);
}
void assertVector(T)(MyVector!(T) vector, T val0, T val1, T val2)
{
	assert(vector[0] == val0);
	assert(vector[1] == val1);
	assert(vector[2] == val2);
}

unittest
{
	int[] array = new int[3];
	array[] = [1, 2, 3];
	assertArray(array, 1, 2, 3);
	array[0..2] = 5;
	assertArray(array, 5, 5, 3);
	array[0..2] = [6, 7];
	assertArray(array, 6, 7, 3);
	array[0..2] += 3;
	assertArray(array, 9, 10, 3);
	array[0..2] += [4, 5];
	assertArray(array, 13, 15, 3);
	array[1..$] = 6;
	assertArray(array, 13, 6, 6);
	array[] = 7;
	assertArray(array, 7, 7, 7);
	array[] = [8, 9, 10];
	assertArray(array, 8, 9, 10);
	++array[0];
	assertArray(array, 9, 9, 10);
	++array[1..$];
	assertArray(array, 9, 10, 11);
	--array[];
	assertArray(array, 8, 9, 10);
	array[] *= 2;
	assertArray(array, 16, 18, 20);
	array[] += [3, 4, 5];
	assertArray(array, 19, 22, 25);

	array[] = [1, 2, 3];
	auto vector = new MyVector!int(array);
	assertVector(vector, 1, 2, 3);
	vector[0..2] = 5;
	assertVector(vector, 5, 5, 3);
	vector[0..2] = [6, 7];
	assertVector(vector, 6, 7, 3);
	vector[0..2] += 3;
	assertVector(vector, 9, 10, 3);
	vector[0..2] += [4, 5];
	assertVector(vector, 13, 15, 3);
	vector[1..$] = 6;
	assertVector(vector, 13, 6, 6);
	vector[] = 7;
	assertVector(vector, 7, 7, 7);
	vector[] = [8, 9, 10];
	assertVector(vector, 8, 9, 10);
	++vector[0];
	assertVector(vector, 9, 9, 10);
	++vector[1..$];
	assertVector(vector, 9, 10, 11);
	--vector[];
	assertVector(vector, 8, 9, 10);
	vector[] *= 2;
	assertVector(vector, 16, 18, 20);
	vector[] += [3, 4, 5];
	assertVector(vector, 19, 22, 25);
}
March 17, 2015
On Tue, 17 Mar 2015 13:57:16 +0000, Ilya Ivanov wrote:

tl;dr. please, have some mercy! the less unnecessary code you post, the easier to answer.

March 17, 2015
On Tuesday, 17 March 2015 at 13:57:18 UTC, Ilya Ivanov wrote:
> Can please someone tell me what is wrong with my code or is it a
> bug?
> The compilation errors are:
> D:\DLang\test.d(184): Error: vector[0..2] is not an lvalue
> D:\DLang\test.d(186): Error: vector[0..2] is not an lvalue
> D:\DLang\test.d(188): Error: vector.opSlice(0u, 2u) is not an
> lvalue
> D:\DLang\test.d(190): Error: vector.opSlice(0u, 2u) is not an
> lvalue
>
> If I use old style opSlice (the commented out code) everything
> works fine.

Your example compiles fine for me with both DMD 2.067rc1 and master. Which compiler version are you using?
March 17, 2015
Tried with 2.067.0-rc1 - doesn't work. Did you compile with -unittest option?
March 17, 2015
On Tuesday, 17 March 2015 at 15:10:22 UTC, Ilya Ivanov wrote:
> Tried with 2.067.0-rc1 - doesn't work. Did you compile with -unittest option?

I hadn't, and indeed I get the errors now for both compiler versions. Sorry...
March 17, 2015
On Tuesday, 17 March 2015 at 13:57:18 UTC, Ilya Ivanov wrote:
[snip]

I recently did a full Array2D with slicing and non-contiguous views etc and found that it was quite a nightmare getting all this stuff correct.

I think your mistake is that opSlice needs to be a template to trigger the new-style slicing/indexing.
E.g.

opSlice(size_t dim)(size_t i, size_t j)
March 17, 2015
On Tuesday, 17 March 2015 at 16:29:38 UTC, John Colvin wrote:
> On Tuesday, 17 March 2015 at 13:57:18 UTC, Ilya Ivanov wrote:
> [snip]
>
> I recently did a full Array2D with slicing and non-contiguous views etc and found that it was quite a nightmare getting all this stuff correct.
>
> I think your mistake is that opSlice needs to be a template to trigger the new-style slicing/indexing.
> E.g.
>
> opSlice(size_t dim)(size_t i, size_t j)

or maybe that should be uint dim, pretty sure it doesn't matter though.
March 17, 2015
On 03/17/2015 09:29 AM, John Colvin wrote:
> On Tuesday, 17 March 2015 at 13:57:18 UTC, Ilya Ivanov wrote:
> [snip]
>
> I recently did a full Array2D with slicing and non-contiguous views etc
> and found that it was quite a nightmare getting all this stuff correct.
>
> I think your mistake is that opSlice needs to be a template to trigger
> the new-style slicing/indexing.
> E.g.
>
> opSlice(size_t dim)(size_t i, size_t j)

I have simple but working code for both methods at the following links:


http://ddili.org/ders/d.en/operator_overloading.html#ix_operator_overloading.opSlice


http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.multi-dimensional%20operator%20overloading

Ali

March 17, 2015
On Tuesday, 17 March 2015 at 17:36:22 UTC, Ali Çehreli wrote:
> On 03/17/2015 09:29 AM, John Colvin wrote:
>> On Tuesday, 17 March 2015 at 13:57:18 UTC, Ilya Ivanov wrote:
>> [snip]
>>
>> I recently did a full Array2D with slicing and non-contiguous views etc
>> and found that it was quite a nightmare getting all this stuff correct.
>>
>> I think your mistake is that opSlice needs to be a template to trigger
>> the new-style slicing/indexing.
>> E.g.
>>
>> opSlice(size_t dim)(size_t i, size_t j)
>
> I have simple but working code for both methods at the following links:
>
>
> http://ddili.org/ders/d.en/operator_overloading.html#ix_operator_overloading.opSlice
>
>
> http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.multi-dimensional%20operator%20overloading
>
> Ali

Old-style opSlice works in my test too, but new-style doesn't. Filed the bug https://issues.dlang.org/show_bug.cgi?id=14302