digitalmars.D.learn - Array of const objects with indirections and std.algorithm.copy
- drug (48/48) Jul 27 2016 I have the following:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (20/52) Jul 27 2016 You're defining the assignment from const to non-const. It could have
- drug (26/26) Jul 28 2016 I see. I'll try to rephrase my question to be clear. We have:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (9/13) Jul 28 2016 https://github.com/dlang/phobos/blob/v2.071.1/std/algorithm/mutation.d#L...
- drug007 (3/16) Jul 28 2016 Thank you too.
I have the following: ``` struct Foo { int[] i; this(int[] i) { this.i = i.dup; } ref Foo opAssign(ref const(this) other) { i = other.i.dup; return this; } } const(Foo)[] cfoo; ``` I need to copy it: ``` Foo[] foo; cfoo.copy(foo); // fails to compile because phobos in case of array uses // array specialization and this specialization fails // see https://github.com/dlang/phobos/blob/v2.071.1/std/algorithm/mutation.d#L333 ``` but it works: ``` foreach(ref src, ref dest; lockstep(cfoo, foo)) dest = src; ``` In my opinion the possible decision is disabling the array specialization if the arrays can't be low-level copied. And the question raises here - why `areCopyCompatibleArrays` doesn't work in this case? I found that ``` // return true pragma(msg, __traits(compiles, { typeof(foo).init[] = typeof(cfoo).init[]; } )) // return false pragma(msg, __traits(compiles, { foo[] = cfoo[]; } )) ``` The question is - shouldn't `areCopyCompatibleArrays` be modified according code above to use array specialization where it is appropriate and allow to copy arrays by elements when it is needed? The full code is here https://dpaste.dzfl.pl/5e13e183a006
Jul 27 2016
On 07/27/2016 04:51 AM, drug wrote:I have the following: ``` struct Foo { int[] i; this(int[] i) { this.i = i.dup; } ref Foo opAssign(ref const(this) other) { i = other.i.dup; return this; } }You're defining the assignment from const to non-const. It could have relied on .dup or something else. The compiler cannot know the equivalent for the copy operation.const(Foo)[] cfoo; ``` I need to copy it: ``` Foo[] foo; cfoo.copy(foo); // fails to compile because phobos in case of array uses // array specialization and this specialization fails // seeThat makes sense to me. Otherwise we wouldn't be observing const-ness of the elements: Mutate the original through the copy...https://github.com/dlang/phobos/blob/v2.071.1/std/algorithm/mutation.d#L333``` but it works: ``` foreach(ref src, ref dest; lockstep(cfoo, foo)) dest = src;Because the programmer said it's safe to do so. :)// return true pragma(msg, __traits(compiles, { typeof(foo).init[] = typeof(cfoo).init[]; } ))(Unrelated, I've just learned that pragma() does not require a semicolon. Ok... :) ) Well, that's interesting. I guess it means null = null, which does not compile. I think it's a bug that the above produces true. However, I would write that __traits(compiles) in a more straightforward way. (You're creating a lambda there, which does not have anything to do with the core of the problem here.) So, the following produces false, false: pragma(msg, __traits(compiles, [ typeof(foo)() ] = [ typeof(cfoo)() ])); pragma(msg, __traits(compiles, foo = cfoo)); Yeah, those look more straightforward to me at least for this problem. Ali
Jul 27 2016
I see. I'll try to rephrase my question to be clear. We have: ``` struct Foo { int i; float f; } int main() { const(Foo)[] cfoo = [Foo(1, 0.5), Foo(2, 0.75)]; Foo[] foo; cfoo.copy(foo); // it works, constness no matter here because Foo is value type } ``` but if Foo contains indirections it won't be a value type anymore and `copy` doesn't work. It's right and expected. Then I define `opAssign` to accept a const instance of `Foo` and I expect that `copy` should work because `Foo` (with indirections) now can be safely copied using `opAssign`. But it doesn't work just because current implementaion of `copy` assumes that if its arguments are array then it can be low-level copied. But `cfoo` is array of element that can't be bitblt-ed and should be copied by element. `copy` does by element copying for ranges, but not for arrays. Am I wrong or copy array specialization should be extended to support arrays that require by element copying?
Jul 28 2016
On 07/27/2016 04:51 AM, drug wrote:cfoo.copy(foo); // fails to compile because phobos in case of array uses // array specialization and this specialization fails // seehttps://github.com/dlang/phobos/blob/v2.071.1/std/algorithm/mutation.d#L333 Thanks for explaining further. Yes, this is a bug. Although areCopyCompatibleArrays!(const(Foo)[], Foo[]) is true, std.algorithm.copy of that specialization fails. Please create a bug report at https://issues.dlang.org/ Thank you, Ali
Jul 28 2016
On 28.07.2016 21:45, Ali Çehreli wrote:On 07/27/2016 04:51 AM, drug wrote: > cfoo.copy(foo); // fails to compile because phobos in case of array uses > // array specialization and this specialization fails > // see > https://github.com/dlang/phobos/blob/v2.071.1/std/algorithm/mutation.d#L333 Thanks for explaining further. Yes, this is a bug. Although areCopyCompatibleArrays!(const(Foo)[], Foo[]) is true, std.algorithm.copy of that specialization fails. Please create a bug report at https://issues.dlang.org/ Thank you, AliThank you too. done https://issues.dlang.org/show_bug.cgi?id=16332
Jul 28 2016