| Thread overview | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 17, 2015 Question about opSlice | ||||
|---|---|---|---|---|
| ||||
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 Re: Question about opSlice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ilya Ivanov Attachments: | 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 Re: Question about opSlice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ilya Ivanov | 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 Re: Question about opSlice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | Tried with 2.067.0-rc1 - doesn't work. Did you compile with -unittest option? | |||
March 17, 2015 Re: Question about opSlice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ilya Ivanov | 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 Re: Question about opSlice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ilya Ivanov | 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 Re: Question about opSlice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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 Re: Question about opSlice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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 Re: Question about opSlice | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply