Re: Tuple fields/types
On Thursday, 30 June 2016 at 21:53:42 UTC, Jordan Wilson wrote: Hello, For tuples, does the fieldNames property have a 1-1 correspondence with the Types property? It appears that way in my testing: alias MyData = Tuple!(string,"a",int,"b"); foreach (i, type; MyData.Types){ writeln (MyData.fieldNames[i]," ",type.stringof); // a string // b int } But I can't figure out for sure from the documentation: alias fieldNames = staticMap!(extractName, fieldSpecs); alias Types = staticMap!(extractType, fieldSpecs); Thanks, Jordan It's an implementation detail but I wouldn't expect the order to ever change.
Re: Tuple fields/types
On Thursday, 30 June 2016 at 21:53:42 UTC, Jordan Wilson wrote: Hello, For tuples, does the fieldNames property have a 1-1 correspondence with the Types property? It appears that way in my testing: alias MyData = Tuple!(string,"a",int,"b"); foreach (i, type; MyData.Types){ writeln (MyData.fieldNames[i]," ",type.stringof); // a string // b int } But I can't figure out for sure from the documentation: alias fieldNames = staticMap!(extractName, fieldSpecs); alias Types = staticMap!(extractType, fieldSpecs); Thanks, Jordan static map (and map in general) is a 1:1 correspondence, so yes.
Re: GTKD - CSS class color "flash" delay
On Thursday, 30 June 2016 at 20:11:17 UTC, Mike Wey wrote: Is the complete source available some ware? Yes, here: http://pastebin.com/h0Nx1mL6
Get program stats at run time
How can I get the program stats at run time such as minimum and maximum amount of memory and cpu used, cpu architecture, os, etc?
Tuple fields/types
Hello, For tuples, does the fieldNames property have a 1-1 correspondence with the Types property? It appears that way in my testing: alias MyData = Tuple!(string,"a",int,"b"); foreach (i, type; MyData.Types){ writeln (MyData.fieldNames[i]," ",type.stringof); // a string // b int } But I can't figure out for sure from the documentation: alias fieldNames = staticMap!(extractName, fieldSpecs); alias Types = staticMap!(extractType, fieldSpecs); Thanks, Jordan
Re: Associative array of const items
On Thursday, 30 June 2016 at 17:08:45 UTC, Jonathan Marler wrote: Is there a way to have an associative array of const values? I thought it would have been: const(T)[K] map; map[x] = y; but the second line gives Error: cannot modify const expression. I would think that the const(T)[K] would behave similarly to const(T)[], where you can modify the array, just not the individual elements, but associative arrays don't seem to have the same semantics. Is there a way to achieve these semantics with an associative array? It is possible to initialize the array with a AA literal as const(int)[string] aa = [ "1": 1, "2": 2 ]; but AAs don't have opIndexAssign etc. The reasonable things you do to const(T)[] is shorten it or reassign it completely. For an AA, this is removing elements or adding new ones. While the first is without problems, the problem is how to determine if aa["1"] = 1 is a (legal) initialization or (illegal) reassignment of a const(T). Unfortunately, there is no function to add key-value-pairs that throws an Error if the key is already there or else reinitializes the value.
Re: Get current date and time with std.datetime
On Monday, 24 October 2011 at 15:29:41 UTC, Jonathan M Davis wrote: On Friday, October 07, 2011 19:58:12 Joel Christensen wrote: > http://d-programming-language.org/intro-to-datetime.html Thanks Jonathan, that helped I think, (haven't read it all, though). But I've got errors with some of the date times not being able to change them with int's values. task.d(44): Error: function std.datetime.DateTime.month () const is not callable using argument types (int) task.d(44): Error: cannot implicitly convert expression (month0) of type int to Month Month is an enum. So, any function taking a month must take an enum value, not an integer. e.g. Month.jan, Month.feb, Month.mar, etc. If you want to pass it an integral value, you have to cast. e.g. cast(Month)1, cast(Month)2, cast(Month)3, etc. - Jonathan M Davis Why is it so hard to simply get the current date and time formatted properly in a string? There are no examples of this in your documentation yet this is probably one of the most used cases.
Re: GTKD - CSS class color "flash" delay
On 06/30/2016 08:53 AM, TheDGuy wrote: On Wednesday, 29 June 2016 at 10:41:21 UTC, TheDGuy wrote: I tried to debug a little and what i don't understand is, that i get two times 'blue' on the console, even though yellow and blue lit up but yellow stayed at the flash color: private void letButtonsFlash(){ foreach(Button btn;bArr){ btn.setSensitive(false); } for(int i = 0; i < level; i++){ index = i; Button currentButton = bArr[rndButtonBlink[i]]; //Array holds randomized Buttons ListG list = currentButton.getStyleContext().listClasses(); string CSSClassName = to!string(cast(char*)list.next().data); currentButton.getStyleContext().addClass(CSSClassName ~ "-flash"); Timeout t = new Timeout(() => this.timeout_delay(currentButton),1,false); } foreach(Button btn;bArr){ btn.setSensitive(true); } } bool timeout_delay(Button currentButton){ ListG list = currentButton.getStyleContext().listClasses(); string CSSClassName = to!string(cast(char*)list.next().data); writeln(CSSClassName); //try to debug currentButton.getStyleContext().removeClass(CSSClassName ~ "-flash"); return false; } The reason for the problem that buttons are flashing simultaneously might be, that the Timeout is running in an extra thread and therefore another Timeout is created by the mainthread in the for-loop even though the last one hasn't finished yet. But what i don't understand is why the last button doesn't go back to the normal CSSClass and that the first button has two timeouts (according to my console debug text)? It would be very much appreciated if someone who has GTKD installed can try my code: http://pastebin.com/h0Nx1mL6 Okay, i am quite sure now that this is some kind of bug: https://picload.org/image/rrrgwpgi/gtkd_timeout.png private void letButtonsFlash(){ foreach(Button btn;bArr){ btn.setSensitive(false); } for(int i = 0; i < level; i++){ index = i; Button currentButton = bArr[rndButtonBlink[i]]; //Array holds randomized Buttons ListG list = currentButton.getStyleContext().listClasses(); string CSSClassName = to!string(cast(char*)list.next().data); currentButton.getStyleContext().addClass(CSSClassName ~ "-flash"); writeln("Creating Timeout for : " ~ CSSClassName); Timeout t = new Timeout(() => this.timeout_delay(currentButton),1,false); } foreach(Button btn;bArr){ btn.setSensitive(true); } } bool timeout_delay(Button currentButton){ ListG list = currentButton.getStyleContext().listClasses(); string CSSClassName = to!string(cast(char*)list.next().data); currentButton.getStyleContext().removeClass(CSSClassName ~ "-flash"); writeln("Removing flash CSS color for: " ~ CSSClassName); return false; } Is the complete source available some ware? -- Mike Wey
Associative array of const items
Is there a way to have an associative array of const values? I thought it would have been: const(T)[K] map; map[x] = y; but the second line gives Error: cannot modify const expression. I would think that the const(T)[K] would behave similarly to const(T)[], where you can modify the array, just not the individual elements, but associative arrays don't seem to have the same semantics. Is there a way to achieve these semantics with an associative array?
Re: Cast vs Virtual Method vs TypeId?
On Thursday, 30 June 2016 at 00:25:53 UTC, Jonathan Marler wrote: I'd like to hear peoples thoughts on the various solutions for the following problem. Say you have some hierarchy of classes like: class GameObject { // ... } class Entity : GameObject { // ... } class Player : Entity { // ... } class Enemy : Entity { // ... } // ... Assume you have a function that accepts a GameObject but does something special if that GameObject happens to be an instance of the Player class. How would you go about determining this? (Note: assume you need to make the distinction at runtime, so you can't use a static if with an 'is' expression inside a template.) I'd like to hear what people think in 2 cases 1) Only need to know if it's an instance of the Player class. 2) Need to know if it's an instance of the Player class AND need an instance of the Player class. The potential solutions I thought of were: 1) typeid (Only handles case 1) if(typeid(obj) == typeid(Player) { // treat as player object } If you don't need an instance of the Player class, maybe this one is good? I don't know in terms of efficiency if this is better, or casting is better. Maybe cast uses the typeid under the hood to determine if the cast can be performed? 2) Custom Type Enum (Only handles case 1) enum GameObjectType { gameObject, player, ... } class GameObject { GameObjectType type; } if(obj.type == GameObjectType.player) { // treat it as a player object // Note: if you need to use Player class specific fields // then you'll need to use the cast or virtual function // design which kinda defeats the purpose of this design in the // case where it is actually a Player object. } This method may be similar to the typeid method, not sure since I don't know how typeid works under the hood. If it's similar then this would just be a waste of memory and should not be used in favor of the typeid method. 3) Cast (Handles case 1 and 2) auto player = cast(Player)obj; if(player) { // treat it as a player object } I don't know how cast works under the hood so it's hard to compare it to other methods. Any information on how cast works under the hood would be great. 4) Virtual Method (Handles case 1 and 2) class GameObject { Player asPlayer() { return null; } } class Player { override Player asPlayer() { return this; } } auto player = obj.asPlayer; if(player) { // treat it as a player object } else { // treat it as any other game object } This solution handles the same cases as regular casting, but I can't compare them since I don't know how casting works under the hood. One thing to consider is that this method scales linearly since you need to add a new virtual method for every type you want to support, so the vtable gets larger as you add more types. Any other solutions? Thoughts? Thanks in advance for the feedback. This problem is not D specific, there are lots of different approaches. If you're not going to add new types to the hierarchy very often the visitor pattern is a good choice, see[1]. You can also use composition instead of inheritance to share code by using mixins + templates. Or you can try more traditional entity-component-systems. Take a look at game engines written in D, they may have some good D specific ideas already. http://www.deadalnix.me/2012/08/25/visitor-pattern-revisited-in-d/
Re: Cast vs Virtual Method vs TypeId?
On Thursday, 30 June 2016 at 00:27:57 UTC, rikki cattermole wrote: On 30/06/2016 12:25 PM, Jonathan Marler wrote: Assume you have a function that accepts a GameObject but does something special if that GameObject happens to be an instance of the Player class. How would you go about determining this? (Note: assume you need to make the distinction at runtime, so you can't use a static if with an 'is' expression inside a template.) void func(GameObject o) { if (Player player = cast(Player)o) { // something special } } Thanks for the response. Do you also have any information on how cast works under the hood?
Re: What's the secret to static class members
On Thursday, 30 June 2016 at 01:11:09 UTC, Mike Parker wrote: I think it's safe to say this guy is just trolling and we can ignore him. I was about to say the same, Mike. He is either trolling, or genuinely did not even bother to learn some language basics...
Re: thread-safe shared field access
On 6/30/16 10:10 AM, jj75607 wrote: For example I have a shared from different threads variable. What piece of code is correctly thread-safe? First: shared class A { shared(int) x; Note, no need to mark x shared. 'A' implicitly shares everything. void test1() { x = 10; x += 5 writeln(x); } } Or second: import core.atomic; shared class A { shared(int) x; void test1() { atomicStore(x, 10); atomicOp!("+=")(x, 5); writeln(atomicLoad(x)); } } I don't believe the first will compile. This is probably the only thing that D adds for shared data (it enforces that you use atomics to read or modify shared primitives). And yes, the second is correct while the first is not. Note that writeln is still writing a copy of the atomically loaded x. you could as easily done: auto xcopy = atomicOp!("+=")(x, 5); writeln(xcopy); To avoid the atomic load. -Steve
thread-safe shared field access
For example I have a shared from different threads variable. What piece of code is correctly thread-safe? First: shared class A { shared(int) x; void test1() { x = 10; x += 5 writeln(x); } } Or second: import core.atomic; shared class A { shared(int) x; void test1() { atomicStore(x, 10); atomicOp!("+=")(x, 5); writeln(atomicLoad(x)); } }
Re: compilation error with shared ReadWriteMutex
On 6/30/16 8:41 AM, jj75607 wrote: On Thursday, 30 June 2016 at 12:25:54 UTC, Steven Schveighoffer wrote: On 6/30/16 8:18 AM, jj75607 wrote: [...] You don't need to mark this shared, because the entire class is shared, all members are implicitly marked shared. [...] Thanks! Is this a compilation only 'cast' with no runtime works? Yes. cast() just removes the any qualifiers. -Steve
Re: compilation error with shared ReadWriteMutex
On Thursday, 30 June 2016 at 12:25:54 UTC, Steven Schveighoffer wrote: On 6/30/16 8:18 AM, jj75607 wrote: [...] You don't need to mark this shared, because the entire class is shared, all members are implicitly marked shared. [...] Thanks! Is this a compilation only 'cast' with no runtime works?
Re: opEquals on shared object
On 6/30/16 8:30 AM, jj75607 wrote: On Thursday, 30 June 2016 at 12:21:03 UTC, Steven Schveighoffer wrote: On 6/30/16 6:26 AM, jj75607 wrote: Hello! I need to overload opEquals on shared class C shared class C { override bool opEquals(Object o) { return false; } } But compilation fails with the message: Error: function f700.C.opEquals does not override any function, did you mean to override 'object.Object.opEquals'? What am I doing wrong? Object.opEquals is not marked shared. You can't override a non-shared method with a shared one. You need to remove override. But... unfortunately, this may not work in practice. The opEquals handling for objects is pretty much screwed unless you have unshared mutable objects. I think it may work for const objects, but not in a good way. -Steve Thanks! But what should I do to fix that code? shared class C { bool opEquals(Object o) { return false; } } class A(T) { void f(T a, T b) { if(a == b) writeln("equals"); else writeln("non equals"); } } int main(string[] argv) { auto a1 = new A!int; a1.f(1,2); auto a2 = new A!(shared(C)); shared C c = new shared(C); a2.f(c,c); return 0; } It fails with Error: none of the overloads of 'opEquals' are callable using argument types (shared(C), shared(C)) This is an artifact of the object.opEquals entry point function. It handles calling your object's opEquals properly. Try changing C.opEquals to accept a shared(Object). If that doesn't work, you may be out of luck until the druntime team figures this out. Please file an issue if you can't get it to work. -Steve
Re: opEquals on shared object
On Thursday, 30 June 2016 at 12:21:03 UTC, Steven Schveighoffer wrote: On 6/30/16 6:26 AM, jj75607 wrote: Hello! I need to overload opEquals on shared class C shared class C { override bool opEquals(Object o) { return false; } } But compilation fails with the message: Error: function f700.C.opEquals does not override any function, did you mean to override 'object.Object.opEquals'? What am I doing wrong? Object.opEquals is not marked shared. You can't override a non-shared method with a shared one. You need to remove override. But... unfortunately, this may not work in practice. The opEquals handling for objects is pretty much screwed unless you have unshared mutable objects. I think it may work for const objects, but not in a good way. -Steve Thanks! But what should I do to fix that code? shared class C { bool opEquals(Object o) { return false; } } class A(T) { void f(T a, T b) { if(a == b) writeln("equals"); else writeln("non equals"); } } int main(string[] argv) { auto a1 = new A!int; a1.f(1,2); auto a2 = new A!(shared(C)); shared C c = new shared(C); a2.f(c,c); return 0; } It fails with Error: none of the overloads of 'opEquals' are callable using argument types (shared(C), shared(C))
Re: compilation error with shared ReadWriteMutex
On 6/30/16 8:18 AM, jj75607 wrote: I wrote shared class with rwmutex import core.sync.rwmutex; shared class Shared { ReadWriteMutex rwmutex; int[] items; this() { rwmutex = new ReadWriteMutex(); } } But it fails with: Error: cannot implicitly convert expression (new ReadWriteMutex(cast(Policy)1)) of type core.sync.rwmutex.ReadWriteMutex to shared(ReadWriteMutex) I add `shared' keyword to the `rwmutex' variable shared class Shared { shared(ReadWriteMutex) rwmutex; You don't need to mark this shared, because the entire class is shared, all members are implicitly marked shared. int[] items; this() { rwmutex = new shared(ReadWriteMutex)(); This is what fixes the original compilation error. You are constructing a shared object, so it can be correctly assigned to the shared member. } } And got another compilation error: Error: non-shared method core.sync.rwmutex.ReadWriteMutex.this is not callable using a shared object Yep. Nothing in core.sync can be marked shared. Ironic, isn't it? In seriousness, someone need to work on getting core.sync shareable. The library was written way before shared was a thing (it's actually from D1 days). It makes no sense that Mutexes and the like cannot be shared. That is their core purpose. How can I use shared class with mutex correctly? casting: rwmutex = cast(shared) new ReadWriteMutex(); ... (cast()rwmutex).lock(); // casts away all attributes. Note, beware of removing const/immutable attributes (i.e. don't do this in functions marked const or immutable). -Steve
Re: opEquals on shared object
On 6/30/16 6:26 AM, jj75607 wrote: Hello! I need to overload opEquals on shared class C shared class C { override bool opEquals(Object o) { return false; } } But compilation fails with the message: Error: function f700.C.opEquals does not override any function, did you mean to override 'object.Object.opEquals'? What am I doing wrong? Object.opEquals is not marked shared. You can't override a non-shared method with a shared one. You need to remove override. But... unfortunately, this may not work in practice. The opEquals handling for objects is pretty much screwed unless you have unshared mutable objects. I think it may work for const objects, but not in a good way. -Steve
compilation error with shared ReadWriteMutex
I wrote shared class with rwmutex import core.sync.rwmutex; shared class Shared { ReadWriteMutex rwmutex; int[] items; this() { rwmutex = new ReadWriteMutex(); } } But it fails with: Error: cannot implicitly convert expression (new ReadWriteMutex(cast(Policy)1)) of type core.sync.rwmutex.ReadWriteMutex to shared(ReadWriteMutex) I add `shared' keyword to the `rwmutex' variable shared class Shared { shared(ReadWriteMutex) rwmutex; int[] items; this() { rwmutex = new shared(ReadWriteMutex)(); } } And got another compilation error: Error: non-shared method core.sync.rwmutex.ReadWriteMutex.this is not callable using a shared object How can I use shared class with mutex correctly?
Re: EnumToFlags
On Thursday, 30 June 2016 at 02:39:22 UTC, JS wrote: I created a type that makes working with flags much easier. Please review for issues and enhancements. It would be nice to simplify the value size code. [...] You can look at this, it's more or less the same concept: https://github.com/BBasile/iz/blob/master/import/iz/enumset.d#L226 Two things that important: - enum members are not always integer numbers. - enum used as flags is only fast when members values are consecutives. I've recently discovered that it can even be used to make UDAs, what a "yeah" ;)
opEquals on shared object
Hello! I need to overload opEquals on shared class C shared class C { override bool opEquals(Object o) { return false; } } But compilation fails with the message: Error: function f700.C.opEquals does not override any function, did you mean to override 'object.Object.opEquals'? What am I doing wrong?
Re: EnumToFlags
On 06/30/2016 04:39 AM, JS wrote: struct EnumToFlags(alias E) { import std.traits, std.conv, std.string, std.algorithm, std.array; static if (E.max < 8) alias vtype = ubyte; Convention says: Capitalize user-defined type names. So it should be "Vtype" or maybe "VType" instead of "vtype". else static if (E.max < 16) alias vtype = ushort; else static if (E.max < 32) alias vtype = uint; else static if (E.max < 64) alias vtype = ulong; else static if (E.max < 128) alias vtype = ucent; There is no ucent type. The keyword is reserved, but there is no actual type. else static assert("Cannot store more than 128 flags in an enum."); vtype value; template opDispatch(string Name) { enum opDispatch = 1 << __traits(getMember, E, Name); `1` needs to be `1L` here, or maybe `1UL`. Can't shift more than 31 bits otherwise, because `1` is an int. Same throughout. Note that you're shifting by the enum member's value here. } auto opAssign(vtype e) { value = e; } In my opinion, a void return type would be clearer here. bool opEquals(typeof(this) e) { if (e is this) return true; return (value == e.value); } opEquals should be const. The parentheses around the return value are pointless. Does this opEquals do anything different from the default one? As far as I see, `e is this` does the same as `value == e.value` and the default equality would do the same, too. auto opBinary(string op)(typeof(this) e) { auto x = typeof(this)(); mixin("x.value = this.value "~op~" e.value;"); return x; } auto opUnary(string op)() { auto x = typeof(this)(); mixin("x.value = "~op~"this.value;"); return x; } auto opCast() { return value; } When is this opCast going to be called? auto toString() { string s; foreach(i, e; EnumMembers!E) { if (((1 << i) & value) == 1 << i) s ~= to!string(e) ~ " | "; } if (s.length > 0) s = s[0..$-3]; return s; } this(string from) { char uOp = ' '; char Op = '='; Convention says: Don't capitalize variable names. So it should be "op" instead of "Op". char nOp = '='; int previdx = 0; value = 0; for(int i = 0; i < from.length; i++) There's a subtle problem here with i's type. from.length is a size_t, i.e. ulong in a 64 bit program. So it may be larger than int.max. When that happens, you've an infinite loop here, as i can never reach from.length. Solution: use size_t for i and previdx. Also, foreach is nicer: foreach (i; 0 .. from.length) { nOp = from[i]; if (nOp == '!' || nOp == '~') { uOp = nOp; previdx = i + 1; continue; } if (nOp == '&' || nOp == '^' || nOp == '|' || nOp == '+' || nOp == '-' || i == from.length-1) { auto v = from[previdx..(i + ((i == from.length-1) ? 1 : 0))].strip(); vtype x = 0; foreach(j, e; EnumMembers!E) if (to!string(e) == v) x = cast(vtype)(1 << j); Here you're shifting by the enum member's index. In opDispatch you shift by its value. That difference leads to this: enum E {a = 0, b = 2} alias F = EnumToFlags!E; assert(F("a") is F.a); /* passes */ assert(F("b") is F.b); /* fails */ if (uOp == '!') x = !x; if (uOp == '~') x = ~x; switch(Op) { case '&': value = cast(vtype)(value & x); break; case '|': value = cast(vtype)(value | x); break; case '+': value = cast(vtype)(value + x); break; case '-': value = cast(vtype)(value - x); break; case '^': value = cast(vtype)(value ^ x); break; case '=': value = cast(vtype)(x); break; default: assert("Invalid EnumFlags operation `"~Op~"`."); } previdx = i + 1; Op = nOp; uOp = ' '; } } } alias value this; }; No semicolon after struct declarations in D. You forgot to include some tests or a usage example. It's not obvious to me what EnumToFlags is supposed to accomplish or how to use it. Possibly the to and from string stuff can be improved? Simply apply to a pre-existing enum. I'm not sure what the purpose of all this is, but it seems a bit convoluted to me. Conversion from string seems pointless. In my opinion, this: ali
Re: Local fixed sized arrays
On Monday, 27 June 2016 at 21:58:04 UTC, "Smoke" Adams wrote: I'm in need of a way to create a local array that isn't GC'ed. It must be dynamic in the sense of setting the size at compile time but it will be used only in scope and only on structs. `alloca` is made for that purpose. https://dlang.org/library/core/stdc/stdlib/alloca.html Search for it online to read-up on proper usage so you can avoid the caveats. cheers, Johan