www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Shallow copy object when type is know

reply Tofu Ninja <emmons0 purdue.edu> writes:
Is there a way to shallow copy an object when the type is known? 
I cant seem to figure out if there is a standard way. I can't 
just implement a copy function for the class, I need a generic 
solution.
Apr 20 2016
next sibling parent Tofu Ninja <emmons0 purdue.edu> writes:
On Wednesday, 20 April 2016 at 12:32:48 UTC, Tofu Ninja wrote:
 Is there a way to shallow copy an object when the type is 
 known? I cant seem to figure out if there is a standard way. I 
 can't just implement a copy function for the class, I need a 
 generic solution.
I feel like void shallow_copy(T)(T s, T d) if(is(T == class)) { ubyte[] sp = (cast(ubyte*)s)[0..T.classinfo.m_init.length]; ubyte[] dp = (cast(ubyte*)d)[0..T.classinfo.m_init.length]; dp[] = sp[]; } would be really unsafe but I dont see any other way to do it... I dont know what kind of hidden members I might be messing up when doing that.
Apr 20 2016
prev sibling next sibling parent reply Alex Parrill <initrd.gz gmail.com> writes:
On Wednesday, 20 April 2016 at 12:32:48 UTC, Tofu Ninja wrote:
 Is there a way to shallow copy an object when the type is 
 known? I cant seem to figure out if there is a standard way. I 
 can't just implement a copy function for the class, I need a 
 generic solution.
A generic class copy function would require accessing private fields, so a clean per-attribute class copy is impossible. Doing a bitwise copy might work except for the synchronization mutex pointer. Can you elaborate on why you need this?
Apr 20 2016
parent reply Tofu Ninja <emmons0 purdue.edu> writes:
On Wednesday, 20 April 2016 at 18:48:58 UTC, Alex Parrill wrote:
 On Wednesday, 20 April 2016 at 12:32:48 UTC, Tofu Ninja wrote:
 Is there a way to shallow copy an object when the type is 
 known? I cant seem to figure out if there is a standard way. I 
 can't just implement a copy function for the class, I need a 
 generic solution.
A generic class copy function would require accessing private fields, so a clean per-attribute class copy is impossible. Doing a bitwise copy might work except for the synchronization mutex pointer. Can you elaborate on why you need this?
To implement a copy/paste/duplicate functionality in a game editor. I have an entity-component system, to duplicate an entity, all it's components need to be duplicated. I have many many components, I don't want to rely on manually writing copy methods for each, it is too error prone. There are only a very few that need special copies, almost all can get by with a simple shallow copy. I would like a generic way to do that shallow copy. How does D not have shallow copy? Seems like a very basic functionality...
Apr 20 2016
next sibling parent Rene Zwanenburg <renezwanenburg gmail.com> writes:
On Wednesday, 20 April 2016 at 19:58:15 UTC, Tofu Ninja wrote:
 To implement a copy/paste/duplicate functionality in a game 
 editor. I have an entity-component system, to duplicate an 
 entity, all it's components need to be duplicated. I have many 
 many components, I don't want to rely on manually writing copy 
 methods for each, it is too error prone. There are only a very 
 few that need special copies, almost all can get by with a 
 simple shallow copy. I would like a generic way to do that 
 shallow copy.
How are you handling loading and saving of your components? Can't you use the same mechanism, without going through the storage format? Anyway, to answer your question, perhaps something like this: (untested, it probably needs some minor modifications to compile) T shallowCopy(T)(T source) { assert(source.classinfo == T.typeinfo); auto rv = new T; shallowCopy(source, rv); return rv; } void shallowCopy(T)(T source, T target) { foreach(i; 0 .. T.tupleof.length) { target.tupleof[i] = source.tupleof[i]; } import std.traits : BaseClassesTuple; alias baseClasses = BaseClassesTuple!T; static if(baseClasses.length > 0) { shallowCopy!(baseClasses[0])(source, target); } }
 How does D not have shallow copy? Seems like a very basic 
 functionality...
Generally speaking copying class instances is a very bad idea. That's one of the things structs are for.
Apr 21 2016
prev sibling parent Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Wednesday, 20 April 2016 at 19:58:15 UTC, Tofu Ninja wrote:
 How does D not have shallow copy? Seems like a very basic 
 functionality...
You could implement a `dup()` method. `dup` is already used for shallow copying of arrays, why not reuse it for classes (as a convention)?
Apr 21 2016
prev sibling parent reply rumbu <rumbu rumbu.ro> writes:
On Wednesday, 20 April 2016 at 12:32:48 UTC, Tofu Ninja wrote:
 Is there a way to shallow copy an object when the type is 
 known? I cant seem to figure out if there is a standard way. I 
 can't just implement a copy function for the class, I need a 
 generic solution.
extern (C) Object _d_newclass(TypeInfo_Class ci); Object dup(Object obj) { if (obj is null) return null; ClassInfo ci = obj.classinfo; size_t start = Object.classinfo.init.length; size_t end = ci.init.length; Object clone = _d_newclass(ci); (cast(void*)clone)[start .. end] = (cast(void*)obj)[start .. end]; return clone; }
Apr 21 2016
parent mw <mingwu gmail.com> writes:
On Thursday, 21 April 2016 at 11:53:13 UTC, rumbu wrote:
 On Wednesday, 20 April 2016 at 12:32:48 UTC, Tofu Ninja wrote:
 Is there a way to shallow copy an object when the type is 
 known? I cant seem to figure out if there is a standard way. I 
 can't just implement a copy function for the class, I need a 
 generic solution.
extern (C) Object _d_newclass(TypeInfo_Class ci); Object dup(Object obj) { if (obj is null) return null; ClassInfo ci = obj.classinfo; size_t start = Object.classinfo.init.length; size_t end = ci.init.length; Object clone = _d_newclass(ci); (cast(void*)clone)[start .. end] = (cast(void*)obj)[start .. end]; return clone; }
Is this the established D-idiom of a generic class bit-wise clone function (as of 2020)? Any risk of using this implementation I should be aware of? Thanks.
Aug 27 2020