proposal for general dup function

Dan dbdavidson at yahoo.com
Sun Dec 9 06:45:45 PST 2012


Phobos can and should have a general dup function, capable of 
duping (i.e. recursive deep copy) structs without requiring any 
effort from struct developers. This can be done to cover the vast 
majority of object copy issues for structs and would have these 
benefits:

- no need to write (and potentially mess up) a dup function for 
your own structs
- ability to dup structs that others have written for which you 
don't have direct read access to all the fields
- as your structs grow less chance of bugs (the general dup would 
recognize and incorporate new fields)
- it addresses the inability to copy const and immutable 
reference structs (which Walter and Andrei may be looking to 
address with copy constructor feature)
- it would add more formality to the dup convention

Issues not covered:

- custom memory management by struct, some structs want to do low 
level stuff themselves. This is ok, though, as the struct 
developer can write his own dup and that will be honored by the 
general dup when composition requires it
- some resources are based on handles that can lead to 
indirection. For example, deep copy of file handles could cause 
unintended sharing. In these cases the back door is for the 
developer to write a custom dup or disable dup.
- classes not covered. Maybe the approach could be extended to 
support classes - but it is much more complicated.

Sample implementation:

I've written one called gdup just to distinguish it from dup. It 
is a function and a property, so the usage should feel natural. 
An example usage is shown below. Implementation and tests are 
located at:

https://github.com/patefacio/d-help/blob/master/d-help/opmix/mix.d
https://github.com/patefacio/d-help/blob/master/d-help/opmix/d_test/gdup_suite.d

A pdf writeup exists in section "dup and Global Dup" at:
https://github.com/patefacio/d-help/blob/master/doc/canonical.pdf?raw=true

The specific functions related to gdup are:

@property auto gdup(T)(const ref T t)
void gdup(T1, T2)(ref T1 t1, const ref T2 t2)
ref T opDupPreferred(T, F)(ref T target, const ref F src)

Some sample questions to the news group where this feature in the 
standard library would solve a user problem:

http://forum.dlang.org/thread/mailman.1946.1352987649.5162.digitalmars-d-learn@puremagic.com?page=3
http://forum.dlang.org/thread/pzuparprsetydynbcuce@forum.dlang.org
http://forum.dlang.org/thread/urvdcpflzajhpackmxyz@forum.dlang.org


Thanks
Dan

   static struct A {
     char[] c;
   }
   static struct B {
     A a;
   }
   static struct C {
     B b;
   }
   void main() {
     const(C) c = C(B(A(['a'])));
     C c2 = c.gdup;
   }


More information about the Digitalmars-d mailing list