Re: Array of const objects with indirections and std.algorithm.copy

2016-07-28 Thread drug007 via Digitalmars-d-learn

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


Re: Array of const objects with indirections and std.algorithm.copy

2016-07-28 Thread Ali Çehreli via Digitalmars-d-learn

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



Re: Array of const objects with indirections and std.algorithm.copy

2016-07-28 Thread drug via Digitalmars-d-learn

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?


Re: Array of const objects with indirections and std.algorithm.copy

2016-07-27 Thread Ali Çehreli via Digitalmars-d-learn

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



Array of const objects with indirections and std.algorithm.copy

2016-07-27 Thread drug via Digitalmars-d-learn

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