www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Question about opSlice

reply "Ilya Ivanov" <dieselmachine mail.ru> writes:
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);
}
Mar 17 2015
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
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=20
easier to answer.=
Mar 17 2015
prev sibling next sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
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?
Mar 17 2015
parent reply "Ilya Ivanov" <dieselmachine mail.ru> writes:
Tried with 2.067.0-rc1 - doesn't work. Did you compile with 
-unittest option?
Mar 17 2015
parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
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...
Mar 17 2015
prev sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
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)
Mar 17 2015
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
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.
Mar 17 2015
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Mar 17 2015
parent "Ilya Ivanov" <dieselmachine mail.ru> writes:
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
Mar 17 2015