Define methods using templates
Hello, I'm trying to use templates to define several methods (property setters) within a class to avoid some code duplication. Here is an attempt: class Camera { private: Vector4 m_pos; float m_fov, m_ratio, m_near, m_far; bool m_matrixCalculated; public: void SetProperty(Tin, alias Field)(ref Tin param) @property pure @safe { Field = param; m_matrixCalculated = false; } alias pos = SetProperty!(float[], m_pos); alias pos = SetProperty!(Vector4, m_pos); alias ratio = SetProperty!(float, m_ratio); alias near = SetProperty!(float, m_near); alias far = SetProperty!(float, m_far); } I get this kind of compilation error: Error: template instance SetProperty!(float[], m_pos) cannot use local 'm_pos' as parameter to non-global template SetProperty(Tin, alias Field)(ref Tin param) I don't understand why that error occurs. And I cannot find any elegant solutions (even with mixin's) to declare a template and then instantiate it in a single line to define the methods I want. Does any of you have an idea? Thanks
Re: Define methods using templates
On 12/30/14 8:17 AM, Claude wrote: Hello, I'm trying to use templates to define several methods (property setters) within a class to avoid some code duplication. Here is an attempt: class Camera { private: Vector4 m_pos; float m_fov, m_ratio, m_near, m_far; bool m_matrixCalculated; public: void SetProperty(Tin, alias Field)(ref Tin param) @property pure @safe { Field = param; m_matrixCalculated = false; } alias pos = SetProperty!(float[], m_pos); alias pos = SetProperty!(Vector4, m_pos); alias ratio = SetProperty!(float, m_ratio); alias near = SetProperty!(float, m_near); alias far = SetProperty!(float, m_far); } I get this kind of compilation error: Error: template instance SetProperty!(float[], m_pos) cannot use local 'm_pos' as parameter to non-global template SetProperty(Tin, alias Field)(ref Tin param) I don't understand why that error occurs. I think it has to do with the fact that when you are defining the aliases, m_pos for example, is an *instance* member so requires an instance to get an alias. What you are probably better off doing is: void SetProperty(Tin, string Field)(ref Tin param) @property pure @safe { mixin(Field ~ = param;); m_matrixCalculated = false; } alias pos = SetProperty!(float[], m_pos); I would also put some strict template constraints on the Field string too, because one abuse SetProperty pretty easily there. -Steve
Re: Define methods using templates
On 12/30/14 8:48 AM, Steven Schveighoffer wrote: I think it has to do with the fact that when you are defining the aliases, m_pos for example, is an *instance* member so requires an instance to get an alias. What you are probably better off doing is: void SetProperty(Tin, string Field)(ref Tin param) @property pure @safe { mixin(Field ~ = param;); m_matrixCalculated = false; } alias pos = SetProperty!(float[], m_pos); I would also put some strict template constraints on the Field string too, because one abuse SetProperty pretty easily there. A possibly more elegant solution, use opDispatch: void opDispatch(string Field, Tin)(ref Tin param) @property pure @safe if(Field == pos || Field == ratio || ...) { mixin(m_ ~ Field ~ = param;); m_matrixCalculated = false; } Not sure if opDispatch works as a @property this way... -Steve
Re: Define methods using templates
V Tue, 30 Dec 2014 13:17:08 + Claude via Digitalmars-d-learn digitalmars-d-learn@puremagic.com napsáno: Hello, I'm trying to use templates to define several methods (property setters) within a class to avoid some code duplication. Here is an attempt: class Camera { private: Vector4 m_pos; float m_fov, m_ratio, m_near, m_far; bool m_matrixCalculated; public: void SetProperty(Tin, alias Field)(ref Tin param) @property pure @safe { Field = param; m_matrixCalculated = false; } alias pos = SetProperty!(float[], m_pos); alias pos = SetProperty!(Vector4, m_pos); alias ratio = SetProperty!(float, m_ratio); alias near = SetProperty!(float, m_near); alias far = SetProperty!(float, m_far); } I get this kind of compilation error: Error: template instance SetProperty!(float[], m_pos) cannot use local 'm_pos' as parameter to non-global template SetProperty(Tin, alias Field)(ref Tin param) I don't understand why that error occurs. And I cannot find any elegant solutions (even with mixin's) to declare a template and then instantiate it in a single line to define the methods I want. Does any of you have an idea? Thanks class Camera { private: int m_pos; float m_fov, m_ratio, m_near, m_far; bool m_matrixCalculated; public: mixin template opAssign(alias Field) { void opAssign(Tin)(auto ref Tin param) @property pure @safe { Field = param; m_matrixCalculated = false; } } mixin opAssign!(m_pos) pos; mixin opAssign!(m_fov) fov; mixin opAssign!(m_ratio) ratio; mixin opAssign!(m_near) near; mixin opAssign!(m_far) far; } void main() { Camera cam = new Camera(); cam.fov = 1.0; stdin.readln; }
Do you have any idea about deleting exe's symbol table on windows building by DMD or LDC2 64 bit?
Do you have any idea about deleting exe's symbol table on windows? I know mingw for win32 is ok. do you have any other idea about building by DMD or or LDC2 64 bit? Thank you.
Re: Define methods using templates
Thanks Steven and Daniel for your explanations. mixin template opAssign(alias Field) { void opAssign(Tin)(auto ref Tin param) @property pure @safe { Field = param; m_matrixCalculated = false; } } mixin opAssign!(m_pos) pos; I tested both the string mixin and opAssign implementations, and they work like a charm. I would have never thought of using both @property and opAssign, but it looks like a secure way of doing it for the compilation fails nicely if I type a wrong field in. src/camera.d(58): Error: undefined identifier m_os, did you mean variable m_pos?
Is it possible to use an UDA to generate a struct inside a class ?
I have a struct used to describe a property[1]. Its standard usage is represented in this simple example: |class Bar { |private uint fField0; |private izPropDescriptor!uint descrField0; |this() { |descrField0.define(field0, field0, field0); |} |public void field0(uint aValue) {fField0 = aValue;} |public uint field0(){return fField0;} |} The descriptor is used by a property binding system or a serializer. The problem is that declaring a property descriptor is **very** repetitive. I've always wanted to find a way to generate a descriptor automatically, and finally today, while reading some random things on GH, I've found that the annotation system used in HibernateD[2] could be used. So far I didnt get the point of UDA and never used them. So I've created a basic UDA but, and then ? Can a descriptor be created using my attribute ? How ? |struct Setter { |const char[] propertyName; |} |struct Getter { |const char[] propertyName; |} |class Foo { |private uint fField0; |public @Setter(field0) void field0(uint aValue) { |fField0 = aValue; |} |public @Getter(field0) uint field0(){ |return fField0; |} |} [1]:https://github.com/BBasile/Iz/blob/master/import/iz/properties.d#L27 [2]:https://github.com/buggins/hibernated/blob/master/source/hibernated/annotations.d#L15
Re: Is it possible to use an UDA to generate a struct inside a class ?
On 12/30/2014 09:42 AM, Basile Burg wrote: Can a descriptor be created using my attribute ? How ? Here is a quick and dirty solution: import std.string; struct PropertyDescriptor { string type; string name; string memberName() @property const { return name ~ _; } string definition() @property const { return format(%s %s;, type, memberName); } string getter() @property const { return format(%s %s() @property const { return %s; }, type, name, memberName); } string setter() @property const { return format(void %s(%s value) @property { %s = value; }, name, type, memberName); } } unittest { const descr = PropertyDescriptor(int, foo); assert(descr.memberName == foo_); assert(descr.definition == q{int foo_;}); assert(descr.getter == q{int foo() @property const { return foo_; }}); assert(descr.setter == q{void foo(int value) @property { foo_ = value; }}); } struct Property { PropertyDescriptor[] properties; string propertyCode() @property const { string result; foreach (property; properties) { result ~= property.definition ~ property.getter ~ property.setter; } return result; } } string propertyInjections(T)() { string result; foreach (attr; __traits(getAttributes, T)) { static if (is (typeof(attr) == Property)) { result ~= attr.propertyCode; } } return result; } @Property([ PropertyDescriptor(int, i), PropertyDescriptor(double, d) ]) class C { mixin (propertyInjections!C); } void main() { auto c = new C(); c.i = 42; assert(c.i == 42); } Ali
Re: Define methods using templates
On 12/30/2014 05:17 AM, Claude wrote: use templates to define several methods (property setters) within a class to avoid some code duplication. I just saw this post, which is essentially the same question as Basile Burg's. I hope that a college (in France?) is teaching D and that this is a homework assignment. Cool stuff! :) Ali
Re: Is it possible to use an UDA to generate a struct inside a class ?
On Tuesday, 30 December 2014 at 19:05:23 UTC, Ali Çehreli wrote: On 12/30/2014 09:42 AM, Basile Burg wrote: Can a descriptor be created using my attribute ? How ? Here is a quick and dirty solution: import std.string; struct PropertyDescriptor { string type; string name; string memberName() @property const { return name ~ _; } string definition() @property const { return format(%s %s;, type, memberName); } string getter() @property const { return format(%s %s() @property const { return %s; }, type, name, memberName); } string setter() @property const { return format(void %s(%s value) @property { %s = value; }, name, type, memberName); } } unittest { const descr = PropertyDescriptor(int, foo); assert(descr.memberName == foo_); assert(descr.definition == q{int foo_;}); assert(descr.getter == q{int foo() @property const { return foo_; }}); assert(descr.setter == q{void foo(int value) @property { foo_ = value; }}); } struct Property { PropertyDescriptor[] properties; string propertyCode() @property const { string result; foreach (property; properties) { result ~= property.definition ~ property.getter ~ property.setter; } return result; } } string propertyInjections(T)() { string result; foreach (attr; __traits(getAttributes, T)) { static if (is (typeof(attr) == Property)) { result ~= attr.propertyCode; } } return result; } @Property([ PropertyDescriptor(int, i), PropertyDescriptor(double, d) ]) class C { mixin (propertyInjections!C); } void main() { auto c = new C(); c.i = 42; assert(c.i == 42); } Ali Ok, thx. I see the trick: mixin (propertyInjections!C); Introspection inside each class. I don't find this solution ugly btw. I think there is no other way to do this.
Idea/request: If you have a DUB project, add a code.dlang.org badge to README
A few weeks/months ago someone here mentioned that it'd be good if DUB projects linked to code.dlang.org to help anyone who runs into such a project quickly discover other D projects. MAny GitHub projects have badges/shields on top of their READMEs - little image strips showing things like continuous integration status, code coverage, etc. There's also a service generating these: shields.io I generated a simple listed at| code.dlang.org shield, and added it to my project READMEs as a link pointing to code.dlang.org for example, see D:YAML README: https://github.com/kiith-sa/D-YAML You can do the same by either linking to or downloading the shield: https://img.shields.io/badge/listed%20at-code.dlang.org-red.png (used red... because mars) and putting the image (whether as a link to shields.io or your own copy) into your README. It's not likely to be a huge improvement, but I expect it *can* help people notice more D projects and it's trivial to do.
Re: Idea/request: If you have a DUB project, add a code.dlang.org badge to README
On Tuesday, 30 December 2014 at 21:12:38 UTC, Kiith-Sa wrote: A few weeks/months ago someone here mentioned that it'd be good if DUB projects linked to code.dlang.org to help anyone who runs into such a project quickly discover other D projects. MAny GitHub projects have badges/shields on top of their READMEs - little image strips showing things like continuous integration status, code coverage, etc. There's also a service generating these: shields.io I generated a simple listed at| code.dlang.org shield, and added it to my project READMEs as a link pointing to code.dlang.org for example, see D:YAML README: https://github.com/kiith-sa/D-YAML You can do the same by either linking to or downloading the shield: https://img.shields.io/badge/listed%20at-code.dlang.org-red.png (used red... because mars) and putting the image (whether as a link to shields.io or your own copy) into your README. It's not likely to be a huge improvement, but I expect it *can* help people notice more D projects and it's trivial to do. red is connoted negative/agressive, I think blue would be better. Or maybe yellow-mustard for those who have doubtful tastes...
Re: Idea/request: If you have a DUB project, add a code.dlang.org badge to README
On Tuesday, 30 December 2014 at 21:19:52 UTC, jklp wrote: On Tuesday, 30 December 2014 at 21:12:38 UTC, Kiith-Sa wrote: A few weeks/months ago someone here mentioned that it'd be good if DUB projects linked to code.dlang.org to help anyone who runs into such a project quickly discover other D projects. MAny GitHub projects have badges/shields on top of their READMEs - little image strips showing things like continuous integration status, code coverage, etc. There's also a service generating these: shields.io I generated a simple listed at| code.dlang.org shield, and added it to my project READMEs as a link pointing to code.dlang.org for example, see D:YAML README: https://github.com/kiith-sa/D-YAML You can do the same by either linking to or downloading the shield: https://img.shields.io/badge/listed%20at-code.dlang.org-red.png (used red... because mars) and putting the image (whether as a link to shields.io or your own copy) into your README. It's not likely to be a huge improvement, but I expect it *can* help people notice more D projects and it's trivial to do. red is connoted negative/agressive, I think blue would be better. Or maybe yellow-mustard for those who have doubtful tastes... If you want blue, just replace red with blue. I used red because it's the color of the D logo, site and the color of Mars (as D was originally called Mars and lot of D things are named after Mars, e.g. Phobos/Deimos etc.)
Re: Idea/request: If you have a DUB project, add a code.dlang.org badge to README
On Tuesday, 30 December 2014 at 21:19:52 UTC, jklp wrote: On Tuesday, 30 December 2014 at 21:12:38 UTC, Kiith-Sa wrote: A few weeks/months ago someone here mentioned that it'd be good if DUB projects linked to code.dlang.org to help anyone who runs into such a project quickly discover other D projects. MAny GitHub projects have badges/shields on top of their READMEs - little image strips showing things like continuous integration status, code coverage, etc. There's also a service generating these: shields.io I generated a simple listed at| code.dlang.org shield, and added it to my project READMEs as a link pointing to code.dlang.org for example, see D:YAML README: https://github.com/kiith-sa/D-YAML You can do the same by either linking to or downloading the shield: https://img.shields.io/badge/listed%20at-code.dlang.org-red.png (used red... because mars) and putting the image (whether as a link to shields.io or your own copy) into your README. It's not likely to be a huge improvement, but I expect it *can* help people notice more D projects and it's trivial to do. red is connoted negative/agressive, I think blue would be better. Or maybe yellow-mustard for those who have doubtful tastes... aand what I was supposed to post (I didn't itend to put this in D.learn): http://forum.dlang.org/thread/tbspahcinalabopfb...@forum.dlang.org#post-tbspahcinalabopfbxey:40forum.dlang.org
Re: Idea/request: If you have a DUB project, add a code.dlang.org badge to README
On Tuesday, 30 December 2014 at 21:23:53 UTC, Kiith-Sa wrote: On Tuesday, 30 December 2014 at 21:19:52 UTC, jklp wrote: On Tuesday, 30 December 2014 at 21:12:38 UTC, Kiith-Sa wrote: A few weeks/months ago someone here mentioned that it'd be good if DUB projects linked to code.dlang.org to help anyone who runs into such a project quickly discover other D projects. MAny GitHub projects have badges/shields on top of their READMEs - little image strips showing things like continuous integration status, code coverage, etc. There's also a service generating these: shields.io I generated a simple listed at| code.dlang.org shield, and added it to my project READMEs as a link pointing to code.dlang.org for example, see D:YAML README: https://github.com/kiith-sa/D-YAML You can do the same by either linking to or downloading the shield: https://img.shields.io/badge/listed%20at-code.dlang.org-red.png (used red... because mars) and putting the image (whether as a link to shields.io or your own copy) into your README. It's not likely to be a huge improvement, but I expect it *can* help people notice more D projects and it's trivial to do. red is connoted negative/agressive, I think blue would be better. Or maybe yellow-mustard for those who have doubtful tastes... If you want blue, just replace red with blue. I used red because it's the color of the D logo, site and the color of Mars (as D was originally called Mars and lot of D things are named after Mars, e.g. Phobos/Deimos etc.) Sorry it was a trivial and useless answer. forgot that this board is excusively serious.
Re: Fastest Way to Append Multiple Elements to an Array
On Saturday, 27 December 2014 at 07:34:43 UTC, Tobias Pankrath wrote: On Friday, 26 December 2014 at 16:31:48 UTC, Nordlöw wrote: On Friday, 26 December 2014 at 16:29:56 UTC, Nordlöw wrote: See my update at https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L1602 which tries to merge all the ideas into one adapting algorithm :) Destroy! BTW: writeln(estimateLength([1,2,3],[1,2,3])); If appending to an int[] this must print 6, if appending to an int[][] it should print 2. Do you have a suitable proposal for a CT-expression that checks if an argument of type E to estimateLength() will be treated as T[] in the append? My current suggestion is isArray!A is(T == ElementType!(A)) hasLength!A in use at https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L1602 with the hope of being compatible with static arrays. However uncommenting https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L1680 gives compilation error as algorithm_ex.d(1658,20): Error: template std.array.Appender!(int[]).Appender.put cannot deduce function from argument types !()(int[3]), candidates are: /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/array.d(2518,10): std.array.Appender!(int[]).Appender.put(U)(U item) if (canPutItem!U) /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/array.d(2554,10): std.array.Appender!(int[]).Appender.put(Range)(Range items) if (canPutConstRange!Range) /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/array.d(2563,10): std.array.Appender!(int[]).Appender.put(Range)(Range items) if (canPutRange!Range) algorithm_ex.d(1658,20): Error: template std.array.Appender!(int[]).Appender.put cannot deduce function from argument types !()(int[3]), candidates are: /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/array.d(2518,10): std.array.Appender!(int[]).Appender.put(U)(U item) if (canPutItem!U) /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/array.d(2554,10): std.array.Appender!(int[]).Appender.put(Range)(Range items) if (canPutConstRange!Range) /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/array.d(2563,10): std.array.Appender!(int[]).Appender.put(Range)(Range items) if (canPutRange!Range) algorithm_ex.d(1681,16): Error: template instance algorithm_ex.append!(int, int[3], int[3]) error instantiating Comint exited abnormally with code 1 at Tue Dec 30 23:55:33 Isn't appender compatible with static arrays?
Re: Fastest Way to Append Multiple Elements to an Array
On Friday, 26 December 2014 at 16:31:48 UTC, Nordlöw wrote: On Friday, 26 December 2014 at 16:29:56 UTC, Nordlöw wrote: See my update at https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L1602 which tries to merge all the ideas into one adapting algorithm :) Destroy! BTW: 1. Is is relevant to extend `append` to data being a non-Random-Access range? 2. I guess a corresponding `prepend` is motivated aswell, right? Append and Prepend would be very useful additions to Phobos it's quite surprising there not already there? In any case would love to see some pull requests :)
getting current DateTime
How do you get the current DateTime? Why doesn't DateTime have DateTime.now?
Re: getting current DateTime
On Wednesday, 31 December 2014 at 06:03:06 UTC, bitwise wrote: How do you get the current DateTime? Why doesn't DateTime have DateTime.now? import std.stdio; import std.datetime; void main() { writeln(Clock.currTime); } Frank
Re: getting current DateTime
On Wed, 31 Dec 2014 06:03:04 + bitwise via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: How do you get the current DateTime? Why doesn't DateTime have DateTime.now? but it has! ;-) auto now = cast(DateTime)Clock.currTime; signature.asc Description: PGP signature
Re: getting current DateTime
On Wednesday, 31 December 2014 at 06:31:13 UTC, ketmar via Digitalmars-d-learn wrote: On Wed, 31 Dec 2014 06:03:04 + bitwise via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: How do you get the current DateTime? Why doesn't DateTime have DateTime.now? but it has! ;-) auto now = cast(DateTime)Clock.currTime; Ah! indeed it does. It would be nice if that cast was made implicit though. Thanks =D
Re: getting current DateTime
It would be nice if that cast was made implicit though. Just realizing now that DateTime doesn't have sub-second accuracy =/