Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
July 27, 2016 Array of const objects with indirections and std.algorithm.copy | ||||
---|---|---|---|---|
| ||||
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 |
July 27, 2016 Re: Array of const objects with indirections and std.algorithm.copy | ||||
---|---|---|---|---|
| ||||
Posted in reply to drug | 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 > // see That 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 |
July 28, 2016 Re: Array of const objects with indirections and std.algorithm.copy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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? |
July 28, 2016 Re: Array of const objects with indirections and std.algorithm.copy | ||||
---|---|---|---|---|
| ||||
Posted in reply to drug | 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, Ali |
July 28, 2016 Re: Array of const objects with indirections and std.algorithm.copy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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, > Ali > Thank you too. done https://issues.dlang.org/show_bug.cgi?id=16332 |
Copyright © 1999-2021 by the D Language Foundation