| 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
Permalink
Reply