digitalmars.D.learn - How to copy object of class A to another object of class B?
- zhmt (58/58) Jan 28 2015 I have a struct created by thrift:
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (8/20) Jan 28 2015 Haven't tested it, but the `auto name = ...` part is likely to be
- zhmt (12/12) Jan 28 2015 void getT(SRC,DEST)(SRC src,DEST dest)
- zhmt (1/1) Jan 28 2015 Anybody help?
- zhmt (9/9) Jan 28 2015 The final version works well:
- Baz (11/12) Jan 28 2015 __Traits functions are evaluated at compile time so it's not as
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/14) Jan 28 2015 enum name = SRC.tupleof[i].stringof;
- aldanor (9/30) Jan 28 2015 And if the alias doesn't work directly, you can always use a
- Artur Skawina via Digitalmars-d-learn (10/67) Jan 28 2015 You could just add a method to the db class:
- Chris Williams (27/46) Jan 28 2015 Assuming that the hibernated class isn't auto-generated and you
- zhmt (4/55) Jan 28 2015 The hibernated class is not auto-generated yet. I think this is a
I have a struct created by thrift: struct Card { long id; string pwd; long agentId; bool valid; long rmb; long createDate; long soldDate; long chargeDate; mixin TStructHelpers!([ TFieldMeta(`id`, 1, TReq.OPTIONAL), TFieldMeta(`pwd`, 2, TReq.OPTIONAL), TFieldMeta(`agentId`, 3, TReq.OPTIONAL), TFieldMeta(`valid`, 4, TReq.OPTIONAL), TFieldMeta(`rmb`, 5, TReq.OPTIONAL), TFieldMeta(`createDate`, 6, TReq.OPTIONAL), TFieldMeta(`soldDate`, 7, TReq.OPTIONAL), TFieldMeta(`chargeDate`, 8, TReq.OPTIONAL) ]); } and another class created for hibernated: class Card { import hibernated.core; Id Generated long id; UniqueKey string pwd; //index long agentId; bool valid; long rmb; long createDate; long soldDate; long chargeDate; } Sometime , I need to copy them: thrift.Card tc; .... db.Card dc; dc.id = tc.id; dc.pwd = tc.pwd; ... It is boring coding, I want a solution to copy them automatically: void copyObj(SRC,DEST)(SRC src,DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { auto name = SRC.tupleof[i].stringof; __traits(getMember, dest, name) = __traits(getMember, src, name); writeln(name); } } Unfortunitely, it doesnt work, how to improve it? Any suggestions is welcome. Thx ahead!!!
Jan 28 2015
On Wednesday, 28 January 2015 at 09:44:29 UTC, zhmt wrote:It is boring coding, I want a solution to copy them automatically: void copyObj(SRC,DEST)(SRC src,DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { auto name = SRC.tupleof[i].stringof; __traits(getMember, dest, name) = __traits(getMember, src, name); writeln(name); } } Unfortunitely, it doesnt work, how to improve it?Haven't tested it, but the `auto name = ...` part is likely to be the problem. By using `auto`, your declaring a runtime variable, which you then later try to use with `__traits(getMember, ...)`, which expects a value known at compile time. Try using `alias name = ...`, or if that fails, just repeat the expression `SRC.tupleof[i].stringof` wherever `name` occurs (though I'm sure there is a nicer way).
Jan 28 2015
void getT(SRC,DEST)(SRC src,DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { string name = SRC.tupleof[i].stringof; __traits(getMember, dest, name) = __traits(getMember, src, name); writeln(name); } } when I write the code above, the compile complains that: source/app.d(14): Error: variable name cannot be read at compile time.
Jan 28 2015
The final version works well: void copyObj(SRC,DEST)(ref SRC src,ref DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { __traits(getMember, dest, SRC.tupleof[i].stringof) = __traits(getMember, src, SRC.tupleof[i].stringof); } } thank u , Marc Schütz .
Jan 28 2015
On Wednesday, 28 January 2015 at 14:35:58 UTC, zhmt wrote:Anybody help?__Traits functions are evaluated at compile time so it's not as simple. The best you can do is to generate a string to mixin based on the aggragate members. here i have an example of how you can iterate through the members: https://github.com/BBasile/Iz/blob/master/import/iz/traits.d#L18 Writing an opAssign() operator will be as fast, you just need to remember to keep it in sync with the classe members. You could also generate the struct programmatically, based on the classes declaration.
Jan 28 2015
name must be 'enum': On 01/28/2015 06:34 AM, zhmt wrote:void getT(SRC,DEST)(SRC src,DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { string name = SRC.tupleof[i].stringof;enum name = SRC.tupleof[i].stringof;__traits(getMember, dest, name) = __traits(getMember, src, name); writeln(name); } } when I write the code above, the compile complains that: source/app.d(14): Error: variable name cannot be read at compile time.Ali
Jan 28 2015
On Wednesday, 28 January 2015 at 14:59:52 UTC, Ali Çehreli wrote:name must be 'enum': On 01/28/2015 06:34 AM, zhmt wrote:Ali, I have test the enum name declaration, it works well, Thx for your help.void getT(SRC,DEST)(SRC src,DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { string name = SRC.tupleof[i].stringof;enum name = SRC.tupleof[i].stringof;__traits(getMember, dest, name) = __traits(getMember, src, name); writeln(name); } } when I write the code above, the compile complains that: source/app.d(14): Error: variable name cannot be read at compile time.Ali
Jan 28 2015
On Wednesday, 28 January 2015 at 11:30:13 UTC, Marc Schütz wrote:On Wednesday, 28 January 2015 at 09:44:29 UTC, zhmt wrote:And if the alias doesn't work directly, you can always use a well-known hack: alias Alias(T) = T; alias Alias(alias T) = T; so then this works: alias member = Alias!(__traits(getMember, Parent, "child")); Idk if it's a feature or a bug of how getMember works but I had to use this numerous times.It is boring coding, I want a solution to copy them automatically: void copyObj(SRC,DEST)(SRC src,DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { auto name = SRC.tupleof[i].stringof; __traits(getMember, dest, name) = __traits(getMember, src, name); writeln(name); } } Unfortunitely, it doesnt work, how to improve it?Haven't tested it, but the `auto name = ...` part is likely to be the problem. By using `auto`, your declaring a runtime variable, which you then later try to use with `__traits(getMember, ...)`, which expects a value known at compile time. Try using `alias name = ...`, or if that fails, just repeat the expression `SRC.tupleof[i].stringof` wherever `name` occurs (though I'm sure there is a nicer way).
Jan 28 2015
On 01/28/15 10:44, zhmt via Digitalmars-d-learn wrote:I have a struct created by thrift: struct Card { long id; string pwd; long agentId; bool valid; long rmb; long createDate; long soldDate; long chargeDate; mixin TStructHelpers!([ TFieldMeta(`id`, 1, TReq.OPTIONAL), TFieldMeta(`pwd`, 2, TReq.OPTIONAL), TFieldMeta(`agentId`, 3, TReq.OPTIONAL), TFieldMeta(`valid`, 4, TReq.OPTIONAL), TFieldMeta(`rmb`, 5, TReq.OPTIONAL), TFieldMeta(`createDate`, 6, TReq.OPTIONAL), TFieldMeta(`soldDate`, 7, TReq.OPTIONAL), TFieldMeta(`chargeDate`, 8, TReq.OPTIONAL) ]); } and another class created for hibernated: class Card { import hibernated.core; Id Generated long id; UniqueKey string pwd; //index long agentId; bool valid; long rmb; long createDate; long soldDate; long chargeDate; } Sometime , I need to copy them: thrift.Card tc; .... db.Card dc; dc.id = tc.id; dc.pwd = tc.pwd; ... It is boring coding, I want a solution to copy them automatically:You could just add a method to the db class: void fields(B)(auto ref B b) property { foreach (I, _; typeof(this.tupleof)) this.tupleof[I] = mixin(`b.`~__traits(identifier, this.tupleof[I])); } then dc.fields = tc; will work. artur
Jan 28 2015
On Wednesday, 28 January 2015 at 09:44:29 UTC, zhmt wrote:Sometime , I need to copy them: thrift.Card tc; .... db.Card dc; dc.id = tc.id; dc.pwd = tc.pwd; ... It is boring coding, I want a solution to copy them automatically: void copyObj(SRC,DEST)(SRC src,DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { auto name = SRC.tupleof[i].stringof; __traits(getMember, dest, name) = __traits(getMember, src, name); writeln(name); } } Unfortunitely, it doesnt work, how to improve it?Assuming that the hibernated class isn't auto-generated and you can redefine its contents freely, the following style may be an alternative that works for you: struct Foo { public: string a; int b; } class FooClass { public: union { struct { string a; int b; }; Foo foo; } } void main() { Foo f = Foo("a", 10); FooClass c = new FooClass(); c.foo = f; writefln("%s %s", c.a, c.b); } Probably the anonymous struct will break the UDAs, but it should be worth testing.
Jan 28 2015
On Wednesday, 28 January 2015 at 23:34:10 UTC, Chris Williams wrote:On Wednesday, 28 January 2015 at 09:44:29 UTC, zhmt wrote:The hibernated class is not auto-generated yet. I think this is a good idea too.Sometime , I need to copy them: thrift.Card tc; .... db.Card dc; dc.id = tc.id; dc.pwd = tc.pwd; ... It is boring coding, I want a solution to copy them automatically: void copyObj(SRC,DEST)(SRC src,DEST dest) { foreach (i, type; typeof(SRC.tupleof)) { auto name = SRC.tupleof[i].stringof; __traits(getMember, dest, name) = __traits(getMember, src, name); writeln(name); } } Unfortunitely, it doesnt work, how to improve it?Assuming that the hibernated class isn't auto-generated and you can redefine its contents freely, the following style may be an alternative that works for you: struct Foo { public: string a; int b; } class FooClass { public: union { struct { string a; int b; }; Foo foo; } } void main() { Foo f = Foo("a", 10); FooClass c = new FooClass(); c.foo = f; writefln("%s %s", c.a, c.b); } Probably the anonymous struct will break the UDAs, but it should be worth testing.
Jan 28 2015