www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Use dup on Containers with const Elements

reply Q. Schroll <qs.il.paperinik gmail.com> writes:
Cases to consider: Arrays and AAs with const(T) Elements, where T 
is a value or a reference type respectively.

     class C { }
     struct S { }

     const(S)[]  varr;
     const(C)[]  carr;
     const(S)[S] vaav;
     const(C)[S] caav;
     const(S)[C] vaac;
     const(C)[C] caac;

     pragma(msg, typeof(varr.dup));
     pragma(msg, typeof(carr.dup!(const C))); // (1)
     pragma(msg, typeof(vaav.dup));
     pragma(msg, typeof(caav.dup));
     pragma(msg, typeof(vaac.dup));
     pragma(msg, typeof(caac.dup));

yields

S[]         // ok
const(C)[]  // ok
const(S)[S] // (2)
const(C)[S] // ok
const(S)[C] // ok
const(C)[C] // ok

Questions:
(1) Why do I have to specify the type here? Why does inference 
fail?
(2) Why not just S[S]?
The copy of a const S is a S so why is the copy of a (const S, 
const S)-pair not just (S, S)?
Jul 29 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/29/16 3:00 PM, Q. Schroll wrote:
 Cases to consider: Arrays and AAs with const(T) Elements, where T is a
 value or a reference type respectively.
[snip]
 Questions:
 (1) Why do I have to specify the type here? Why does inference fail?
 (2) Why not just S[S]?
 The copy of a const S is a S so why is the copy of a (const S, const
 S)-pair not just (S, S)?
array.dup has the meaning to copy the original but make the elements mutable. At least, that's what it was when it was handled by the compiler/runtime. So the reason for 1 is that you can't convert const(C) to just C without a cast, so you must specify the type. I'm not certain about AA, as I don't remember how dup was defined on them. -Steve
Jul 29 2016
parent reply Q. Schroll <qs.il.paperinik gmail.com> writes:
On Friday, 29 July 2016 at 19:24:59 UTC, Steven Schveighoffer 
wrote:
 On 7/29/16 3:00 PM, Q. Schroll wrote:
 Cases to consider: Arrays and AAs with const(T) Elements, 
 where T is a
 value or a reference type respectively.
[snip]
 Questions:
 (1) Why do I have to specify the type here? Why does inference 
 fail?
 (2) Why not just S[S]?
 The copy of a const S is a S so why is the copy of a (const S, 
 const
 S)-pair not just (S, S)?
array.dup has the meaning to copy the original but make the elements mutable. At least, that's what it was when it was handled by the compiler/runtime.
I do understand the reasons why I can't simply copy const reference type objects to mutable. It just makes sense as the referred object is still const. I thought of dup being there for convenience and performance reasons. The spec says about dup: "Create a dynamic array of the same size and copy the contents of the array into it." It has not been clear to me it intends to make the elements mutable. For my intention, I thought of dup making a shallow copy--which is a deep copy on value types so it can drop the const then.
 So the reason for 1 is that you can't convert const(C) to just 
 C without a cast, so you must specify the type.
The implementation is made so that I have to. This one is obvious then.
 I'm not certain about AA, as I don't remember how dup was 
 defined on them.

 -Steve
I just wonder if it is a bug. If it is true, then it's a misfeature or badly specified function.
Jul 30 2016
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/30/16 5:21 PM, Q. Schroll wrote:
 On Friday, 29 July 2016 at 19:24:59 UTC, Steven Schveighoffer wrote:
 On 7/29/16 3:00 PM, Q. Schroll wrote:
 Cases to consider: Arrays and AAs with const(T) Elements, where T is a
 value or a reference type respectively.
[snip]
 Questions:
 (1) Why do I have to specify the type here? Why does inference fail?
 (2) Why not just S[S]?
 The copy of a const S is a S so why is the copy of a (const S, const
 S)-pair not just (S, S)?
array.dup has the meaning to copy the original but make the elements mutable. At least, that's what it was when it was handled by the compiler/runtime.
I do understand the reasons why I can't simply copy const reference type objects to mutable. It just makes sense as the referred object is still const. I thought of dup being there for convenience and performance reasons. The spec says about dup: "Create a dynamic array of the same size and copy the contents of the array into it." It has not been clear to me it intends to make the elements mutable. For my intention, I thought of dup making a shallow copy--which is a deep copy on value types so it can drop the const then.
If that intention is not in the docs, then that is an omission. It definitely always intends to make the result mutable, and should be an error if you can't do that. Much code out there expects it to be this way, and would break if it simply copied the const tag. I went ahead and submitted a PR: https://github.com/dlang/dlang.org/pull/1435 -Steve
Jul 31 2016