digitalmars.D.learn - Really in need of help with std.container.array.d
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (20/20) Oct 12 2014 I'm trying to figure out how to add complete support for
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (17/17) Oct 12 2014 On Sunday, 12 October 2014 at 20:17:38 UTC, Nordlöw wrote:
- Robert burner Schadek (9/9) Oct 13 2014 hm, the problems seams to be that "inout Array" is not becoming
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (55/56) Oct 14 2014 I tried replace inout with a C++-style member duplication at
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (5/11) Oct 14 2014 Do you mean a mutable array containing references to inout data?
- Robert burner Schadek (15/17) Oct 14 2014 struct Range(T) {
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (56/74) Oct 15 2014 I tried that at
- Robert burner Schadek (2/4) Oct 16 2014 I will give it a try
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (3/5) Oct 16 2014 Thank you.
- anonymous (56/64) Oct 19 2014 [...]
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (3/7) Oct 19 2014 What do these comments containing Error messages mean? Doesn't
- anonymous (10/17) Oct 19 2014 Yes, they don't compile. It's three slightly different versions
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (3/14) Oct 19 2014 So there's currently no complete solution to this problem yet,
- anonymous (4/20) Oct 19 2014 The last variant works: `_outer_ = data;`.
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (47/70) Oct 19 2014 Used your ideas here
- anonymous (11/17) Oct 19 2014 You didn't make the change we just discussed.
- anonymous (2/3) Oct 19 2014 Should be `typeof(return)`.
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (10/25) Oct 19 2014 New response at
- anonymous (52/60) Oct 20 2014 The error is because of this (lines 470 through 483):
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (3/7) Oct 20 2014 Yes, please! That would be very kind of you.
- anonymous (3/9) Oct 20 2014 Forgot to mention it here, not sure if you noticed it:
- =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= (2/4) Oct 20 2014 Superb.
- anonymous (3/18) Oct 19 2014 Has already been filed:
I'm trying to figure out how to add complete support for constness in std.container.array.Array at https://github.com/D-Programming-Language/phobos/commit/703305f0bfb1cc22eff3e44e351cc3db3e03f94f#commitcomment-8114056 My current solution (which currently fails) at https://github.com/nordlow/phobos/commit/5c57cb18c2b9d340a19d19207deca5af0339cf7e#diff-0 tries to solve the problem by making wrapper struct Range a template that captures the constness of parenting Array. My current implementation of array.d at https://github.com/nordlow/phobos/blob/inout-array-range/std/container/array.d#L221 however fails its unittests as array.d(223,19): Error: variable std.container.array.Array!int.Array.Range!(inout(Array!int)).Range._outer only parameters or stack based variables can be inout array.d(430,5): Error: template instance std.container.array.Array!int.Array.Range!(inout(Array!int)) error instantiating array.d(833,5): instantiated from here: Array!int array.d(862,5): Error: static assert (!true) is false and I have no clue how to proceed with this. Please help, me and at least one other D developer is hindered by this.
Oct 12 2014
On Sunday, 12 October 2014 at 20:17:38 UTC, Nordlöw wrote: https://github.com/nordlow/phobos/commit/5c57cb18c2b9d340a19d19207deca5af0339cf7e#diff-0Made some corrections https://github.com/nordlow/phobos/compare/inout-array-range but gives a similar error array.d(223,19): Error: variable std.container.array.Array!int.Array.Range!(inout(Array!int)).Range._outer only parameters or stack based variables can be inout array.d(430,5): Error: template instance std.container.array.Array!int.Array.Range!(inout(Array!int)) error instantiating array.d(833,5): instantiated from here: Array!int array.d(816,5): Error: template instance std.container.array.Array!int.Array.Range!(Array!int) error instantiating array.d(833,5): instantiated from here: Array!int array.d(862,5): Error: static assert (!true) is false
Oct 12 2014
hm, the problems seams to be that "inout Array" is not becoming "const Array" and friends. A blunt force solution would be to create a range as Range!(ReturnType!Array...)(cast(Array!T)this, low, high); and then do the correct casts in Range. The ReturnType would be the ReturnType of opIndex of the Range type and the Array would be stored as plain array without any qualifier. other than that I'm not sure how to go about this.
Oct 13 2014
On Monday, 13 October 2014 at 13:46:56 UTC, Robert burner Schadek wrote:other than that I'm not sure how to go about this.I tried replace inout with a C++-style member duplication at https://github.com/nordlow/phobos/commit/b2a4ca28bf25bf7c6149566d066cbb54118b36b4 Now it instead errors as Error: mutable method std.container.array.Array!int.Array.__fieldPostBlit is not callable using a const object array.d(252,26): Error: cast(inout(int))this._outer.opIndex(this._a) is not an lvalue array.d(258,26): Error: cast(inout(int))this._outer.opIndex(this._b - 1LU) is not an lvalue ../../std/algorithm.d(2364,9): Error: cannot modify const expression result array.d(276,24): Error: template instance std.algorithm.move!(const(int)) error instantiating array.d(439,5): instantiated from here: Range!(const(Array!int)) array.d(851,5): instantiated from here: Array!int array.d(294,26): Error: cast(inout(int))this._outer.opIndex(this._a + i) is not an lvalue Error: mutable method std.container.array.Array!int.Array.~this is not callable using a const object array.d(320,30): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(507,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(514,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(326,38): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(507,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(514,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(299,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(309,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(443,5): Error: template instance std.container.array.Array!int.Array.Range!(Array!int) error instantiating array.d(851,5): instantiated from here: Array!int ../../std/typecons.d(3889,17): Error: template instance object.destroy!(Payload) error instantiating array.d(169,26): instantiated from here: RefCounted!(Payload, cast(RefCountedAutoInitialize)0) array.d(851,5): instantiated from here: Array!int array.d(880,5): Error: static assert (!true) is false Ideas?
Oct 14 2014
On Monday, 13 October 2014 at 13:46:56 UTC, Robert burner Schadek wrote:A blunt force solution would be to create a range as Range!(ReturnType!Array...)(cast(Array!T)this, low, high); and then do the correct casts in Range. The ReturnType would be the ReturnType of opIndex of the Range type and the Array would be stored as plain array without anyDo you mean a mutable array containing references to inout data?qualifier.Could you please give me a code example? I'm not skilled enough in D to follow this description.
Oct 14 2014
On Tuesday, 14 October 2014 at 12:51:29 UTC, Nordlöw wrote:Could you please give me a code example? I'm not skilled enough in D to follow this description.struct Range(T) { Array!S array; T opIndex(size_t i) { return cast(T)array[i]; } } struct Array(T) { Range!(const(T)) opSlice() const { return Range!(const(T))(cast(Array!T)array, 0, length); } Range!(T) opSlice() const { return Range!(T)(cast(Array!T)array, 0, length); } }
Oct 14 2014
On Tuesday, 14 October 2014 at 16:08:31 UTC, Robert burner Schadek wrote:On Tuesday, 14 October 2014 at 12:51:29 UTC, Nordlöw wrote:I tried that at https://github.com/nordlow/phobos/commit/9daf235d7091f76cd941e29e3c167d559bf56a94 but that triggers a new interesting suite of errors Error: mutable method std.container.array.Array!int.Array.__fieldPostBlit is not callable using a const object array.d(252,26): Error: cast(inout(int))this._outer.opIndex(this._a) is not an lvalue array.d(258,26): Error: cast(inout(int))this._outer.opIndex(this._b - 1LU) is not an lvalue ../../std/algorithm.d(2364,9): Error: cannot modify const expression result array.d(276,24): Error: template instance std.algorithm.move!(const(int)) error instantiating array.d(444,5): instantiated from here: Range!(const(Array!int)) array.d(856,5): instantiated from here: Array!int array.d(299,26): Error: cast(int)this._outer.opIndex(this._a + i) is not an lvalue Error: mutable method std.container.array.Array!int.Array.~this is not callable using a const object array.d(325,30): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(512,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(519,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(331,38): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(512,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(519,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(304,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(314,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(448,5): Error: template instance std.container.array.Array!int.Array.Range!(Array!int) error instantiating array.d(856,5): instantiated from here: Array!int ../../std/typecons.d(3889,17): Error: template instance object.destroy!(Payload) error instantiating array.d(169,26): instantiated from here: RefCounted!(Payload, cast(RefCountedAutoInitialize)0) array.d(856,5): instantiated from here: Array!int array.d(885,5): Error: static assert (!true) is false Comint exited abnormally with code 1 at Wed Oct 15 23:14:37 I'm stuck. Need help.Could you please give me a code example? I'm not skilled enough in D to follow this description.struct Range(T) { Array!S array; T opIndex(size_t i) { return cast(T)array[i]; } } struct Array(T) { Range!(const(T)) opSlice() const { return Range!(const(T))(cast(Array!T)array, 0, length); } Range!(T) opSlice() const { return Range!(T)(cast(Array!T)array, 0, length); } }
Oct 15 2014
On Wednesday, 15 October 2014 at 21:15:14 UTC, Nordlöw wrote:Comint exited abnormally with code 1 at Wed Oct 15 23:14:37 I'm stuck. Need help.I will give it a try
Oct 16 2014
On Thursday, 16 October 2014 at 13:56:18 UTC, Robert burner Schadek wrote:Thank you.I'm stuck. Need help.I will give it a try
Oct 16 2014
On Wednesday, 15 October 2014 at 21:15:14 UTC, Nordlöw wrote:https://github.com/nordlow/phobos/commit/9daf235d7091f76cd941e29e3c167d559bf56a94 but that triggers a new interesting suite of errors Error: mutable method std.container.array.Array!int.Array.__fieldPostBlit is not callable using a const object[...]Error: mutable method std.container.array.Array!int.Array.~this is not callable using a const object[...]I'm stuck. Need help.I reduced it to this: ---- struct RefCounted { this(this) /* const doesn't help */ {} ~this() /* const doesn't help */ {} } struct Array { RefCounted _data; } void main() {const Array a; const copy = a;} /* works */ struct RangeM {Array a;} /* works */ struct RangeC {const Array a;} /* error */ ---- Looks like a compiler bug to me. And here's a workaround: ---- struct RangeC { const Array[1] a_; property ref const(Array) a() {return a_[0];} } ---- Using it in std.container.array: ---- static struct Range(A) { private A[1] _outer_; private property ref const(A) _outer() const {return _outer_[0];} private property ref A _outer() {return _outer_[0];} /* ... */ private this(ref A data, size_t a, size_t b) { version(none) _outer = data; /* "Error: mutable method [...].Array.opAssign is not callable using a const object" */ else version(none) _outer_[0] = data; /* Errors about postblit. */ else _outer_ = data; /* works */ /* ... */ } ---- Then you also have to disable any methods/overloads that would return mutable data when A isn't mutable, e.g.: ---- static if (isMutable!A) property ref T front() {/* ... */} ---- Related: `front` and `back` cannot be inout, because the constness depends not on Range's constness, but on Array's.
Oct 19 2014
On Sunday, 19 October 2014 at 15:21:02 UTC, anonymous wrote:version(none) _outer = data; /* "Error: mutable method [...].Array.opAssign is not callable using a const object" */What do these comments containing Error messages mean? Doesn't this code compile?
Oct 19 2014
On Sunday, 19 October 2014 at 18:58:50 UTC, Nordlöw wrote:On Sunday, 19 October 2014 at 15:21:02 UTC, anonymous wrote:Yes, they don't compile. It's three slightly different versions of initializing _outer. The first one, `_outer = data;`, is the original one. It's understandable that it doesn't work anymore with the workaround in place. I don't know why the second one, `_outer_[0] = data;`, doesn't work. Maybe it triggers the same (or a related) postblit compiler bug again. It's essentially the same as the third one, `_outer_ = data;`, which happens to work.version(none) _outer = data; /* "Error: mutable method [...].Array.opAssign is not callable using a const object" */What do these comments containing Error messages mean? Doesn't this code compile?
Oct 19 2014
On Sunday, 19 October 2014 at 19:13:33 UTC, anonymous wrote:Yes, they don't compile. It's three slightly different versions of initializing _outer. The first one, `_outer = data;`, is the original one. It's understandable that it doesn't work anymore with the workaround in place. I don't know why the second one, `_outer_[0] = data;`, doesn't work. Maybe it triggers the same (or a related) postblit compiler bug again. It's essentially the same as the third one, `_outer_ = data;`, which happens to work.So there's currently no complete solution to this problem yet, then?
Oct 19 2014
On Sunday, 19 October 2014 at 19:30:40 UTC, Nordlöw wrote:On Sunday, 19 October 2014 at 19:13:33 UTC, anonymous wrote:The last variant works: `_outer_ = data;`. And that one is enabled in my code, while the other two are `version(none)`-ed away.Yes, they don't compile. It's three slightly different versions of initializing _outer. The first one, `_outer = data;`, is the original one. It's understandable that it doesn't work anymore with the workaround in place. I don't know why the second one, `_outer_[0] = data;`, doesn't work. Maybe it triggers the same (or a related) postblit compiler bug again. It's essentially the same as the third one, `_outer_ = data;`, which happens to work.So there's currently no complete solution to this problem yet, then?
Oct 19 2014
On Sunday, 19 October 2014 at 19:36:46 UTC, anonymous wrote:On Sunday, 19 October 2014 at 19:30:40 UTC, Nordlöw wrote:Used your ideas here https://github.com/nordlow/phobos/commit/be6b5f8c4d428a9708a52757a3f31aab6878d379 but unittests now fails as array.d(234,13): Error: mutable method std.container.array.Array!int.Array.opAssign is not callable using a const object ../../std/algorithm.d(2364,9): Error: cannot modify const expression result array.d(297,24): Error: template instance std.algorithm.move!(const(int)) error instantiating array.d(465,5): instantiated from here: Range!(const(Array!int)) array.d(877,5): instantiated from here: Array!int array.d(320,26): Error: cast(int)__dop1738.opIndex(this._a + i) is not an lvalue array.d(346,30): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(533,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(540,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(352,38): Error: None of the overloads of 'opSliceAssign' are callable using a const object, candidates are: array.d(533,10): std.container.array.Array!int.Array.opSliceAssign(int value) array.d(540,10): std.container.array.Array!int.Array.opSliceAssign(int value, ulong i, ulong j) array.d(325,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(335,32): Error: mutable method std.container.array.Array!int.Array.Range!(Array!int).Range.this is not callable using a const object array.d(469,5): Error: template instance std.container.array.Array!int.Array.Range!(Array!int) error instantiating array.d(877,5): instantiated from here: Array!int ../../std/typecons.d(3889,17): Error: template instance object.destroy!(Payload) error instantiating array.d(169,26): instantiated from here: RefCounted!(Payload, cast(RefCountedAutoInitialize)0) array.d(877,5): instantiated from here: Array!int array.d(906,5): Error: static assert (!true) is false Comint exited abnormally with code 1 at Sun Oct 19 22:06:48On Sunday, 19 October 2014 at 19:13:33 UTC, anonymous wrote:The last variant works: `_outer_ = data;`. And that one is enabled in my code, while the other two are `version(none)`-ed away.Yes, they don't compile. It's three slightly different versions of initializing _outer. The first one, `_outer = data;`, is the original one. It's understandable that it doesn't work anymore with the workaround in place. I don't know why the second one, `_outer_[0] = data;`, doesn't work. Maybe it triggers the same (or a related) postblit compiler bug again. It's essentially the same as the third one, `_outer_ = data;`, which happens to work.So there's currently no complete solution to this problem yet, then?
Oct 19 2014
On Sunday, 19 October 2014 at 20:10:33 UTC, Nordlöw wrote:Used your ideas here https://github.com/nordlow/phobos/commit/be6b5f8c4d428a9708a52757a3f31aab6878d379 but unittests now fails as array.d(234,13): Error: mutable method std.container.array.Array!int.Array.opAssign is not callable using a const objectYou didn't make the change we just discussed. Change line 234 from `_outer = data;` to `_outer_ = data;`. You also need to guard much more with `static if (isMutable!A)`: * everything that returns (non-const) T, * everything that returns Range!A, * everything that mutates elements (e.g. opSliceAssign). And you can't do `return typeof(this)(...);` when the return type is `Range!(const(A))`, because `typeof(this)` can be `const(Range!A)` which is not the same. Spell the type out or use `typeof(result)`.
Oct 19 2014
On Sunday, 19 October 2014 at 20:39:18 UTC, anonymous wrote:Spell the type out or use `typeof(result)`.Should be `typeof(return)`.
Oct 19 2014
On Sunday, 19 October 2014 at 20:39:18 UTC, anonymous wrote:New response at https://github.com/nordlow/phobos/commit/ce6b9e9ae600b7c28ecddd1e3af7b1516247fb33 now errors as array.d(927,15): Error: None of the overloads of 'opSlice' are callable using a const object, candidates are: array.d(472,25): std.container.array.Array!int.Array.opSlice() array.d(495,25): std.container.array.Array!int.Array.opSlice(ulong i, ulong j)array.d(234,13): Error: mutable method std.container.array.Array!int.Array.opAssign is not callable using a const objectYou didn't make the change we just discussed. Change line 234 from `_outer = data;` to `_outer_ = data;`. You also need to guard much more with `static if (isMutable!A)`: * everything that returns (non-const) T, * everything that returns Range!A, * everything that mutates elements (e.g. opSliceAssign). And you can't do `return typeof(this)(...);` when the return type is `Range!(const(A))`, because `typeof(this)` can be `const(Range!A)` which is not the same. Spell the type out or use `typeof(result)`.
Oct 19 2014
On Sunday, 19 October 2014 at 22:19:05 UTC, Nordlöw wrote:https://github.com/nordlow/phobos/commit/ce6b9e9ae600b7c28ecddd1e3af7b1516247fb33 now errors as array.d(927,15): Error: None of the overloads of 'opSlice' are callable using a const object, candidates are: array.d(472,25): std.container.array.Array!int.Array.opSlice() array.d(495,25): std.container.array.Array!int.Array.opSlice(ulong i, ulong j)The error is because of this (lines 470 through 483): ---- static if (isMutable!T) { Range!(Array!T) opSlice() { return typeof(return)(this, 0, length); } } else { Range!(const(Array!T)) opSlice() const { return typeof(return)(this, 0, length); } } ---- You're disabling the const version when T is mutable. Consider const(Array!int): T is int is mutable, so there is no const opSlice. But the Array itself is const, so the non-const version can't be used. Do not disable the const versions of the methods. Only ever disable the non-const ones. Also, the opSlice we're looking at here is Array's, not Array.Range's. You don't need to touch Array's methods at all. Only Array.Range's non-const methods need special treatment, because you need to catch the special case when the Range is mutable, but the referenced Array is not. And it's really `isMutableA!`, not `isMutable!T`. I guess you went for that because `A` is only defined in Array.Range, not in Array itself. But T's mutability isn't of interest. For example, Array.Range.opSlice should look like this: ---- static if (isMutable!A) /* !A, not !T */ { Range!(A) opSlice() {/* ... */} Range!(A) opSlice(size_t i, size_t j) {/* ... */} } /* No `else`, the const versions should always be available. */ Range!(const(A)) opSlice() const {/* ... */} Range!(const(A)) opSlice(size_t i, size_t j) const {/* ... */} ---- Then there are still various methods of Array.Range left to be `static if(isMutable!A)` guarded: * move* * opIndex * opSlice* By the way, since we're in D.learn, I'm assuming you want to do this yourself. But if you'd like, I could make a pull request with my suggestions to your branch.
Oct 20 2014
On Monday, 20 October 2014 at 10:56:43 UTC, anonymous wrote:On Sunday, 19 October 2014 at 22:19:05 UTC, Nordlöw wrote: By the way, since we're in D.learn, I'm assuming you want to do this yourself. But if you'd like, I could make a pull request with my suggestions to your branch.Yes, please! That would be very kind of you. /Thx
Oct 20 2014
On Monday, 20 October 2014 at 11:20:30 UTC, Nordlöw wrote:On Monday, 20 October 2014 at 10:56:43 UTC, anonymous wrote:Forgot to mention it here, not sure if you noticed it: https://github.com/nordlow/phobos/pull/1On Sunday, 19 October 2014 at 22:19:05 UTC, Nordlöw wrote: By the way, since we're in D.learn, I'm assuming you want to do this yourself. But if you'd like, I could make a pull request with my suggestions to your branch.Yes, please! That would be very kind of you.
Oct 20 2014
On Monday, 20 October 2014 at 18:01:11 UTC, anonymous wrote:Forgot to mention it here, not sure if you noticed it: https://github.com/nordlow/phobos/pull/1Superb.
Oct 20 2014
Speaking of this module, since I cannot currently login to bugtracker, I'd like to note here that there are two major bugs in one little function: Array.Payload.length setter. One is this https://issues.dlang.org/show_bug.cgi?id=13619 and the other is reallocating without notifying GC of the pointers, which leads to having dangling pointers in the array after a GC cycle.
Oct 20 2014
On Tuesday, 21 October 2014 at 04:22:37 UTC, thedeemon wrote:Speaking of this module, since I cannot currently login to bugtracker, I'd like to note here that there are two major bugs in one little function: Array.Payload.length setter. One is this https://issues.dlang.org/show_bug.cgi?id=13619 and the other is reallocating without notifying GC of the pointers, which leads to having dangling pointers in the array after a GC cycle.Submitted the second one here: https://issues.dlang.org/show_bug.cgi?id=13642
Oct 20 2014
On Sunday, 19 October 2014 at 15:21:02 UTC, anonymous wrote:---- struct RefCounted { this(this) /* const doesn't help */ {} ~this() /* const doesn't help */ {} } struct Array { RefCounted _data; } void main() {const Array a; const copy = a;} /* works */ struct RangeM {Array a;} /* works */ struct RangeC {const Array a;} /* error */ ---- Looks like a compiler bug to me.Has already been filed: https://issues.dlang.org/show_bug.cgi?id=13629
Oct 19 2014