digitalmars.D.learn - Shallow copy object when type is know
- Tofu Ninja (4/4) Apr 20 2016 Is there a way to shallow copy an object when the type is known?
- Tofu Ninja (10/14) Apr 20 2016 I feel like
- Alex Parrill (6/10) Apr 20 2016 A generic class copy function would require accessing private
- Tofu Ninja (10/20) Apr 20 2016 To implement a copy/paste/duplicate functionality in a game
- Rene Zwanenburg (30/40) Apr 21 2016 How are you handling loading and saving of your components? Can't
- Marc =?UTF-8?B?U2Now7x0eg==?= (4/6) Apr 21 2016 You could implement a `dup()` method. `dup` is already used for
- rumbu (14/18) Apr 21 2016 extern (C) Object _d_newclass(TypeInfo_Class ci);
- mw (5/23) Aug 27 2020 Is this the established D-idiom of a generic class bit-wise clone
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
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
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
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: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...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
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
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
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
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 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.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; }
Aug 27 2020