More alias usages
Inside static if blocks do you feel the need of more kinds of alias, like this? void main() { int[] array; int index; alias array.length A; alias 0B; alias index-1 C; // hard to do } Bye, bearophile
speed of low-level C funcs: example of memmove
Hello, To insert of delete an array slice, I tried to use C's memmove, thinking it would be far faster than manually copying bit per bit (by any kind of magic). But I still wrote a D versions just to check what the actual speed gain is. To my great surprise, the C-memmove and D-manual versions perform *exactly* at the same speed (considering measure imprecision). Note: this remains true when elements are bigger; speed slows down slowly (eg dchar's take only 1/3 more time). Any comment or explanation welcome. Below the code. Denis = code = import std.date : getUTCtime, d_time; import std.c.string : memmove; // C interface: void *memmove(void *dest, const void *src, size_t n); void shiftEndPartC (E) (ref E[] array, size_t source, size_t dest) { // Record length before possible extension. auto length = array.length; int offset = dest - source; // If move up, extend array to make place. if (offset 0) array.length += offset; // Shift slice. auto pDest = cast(void*)((array[dest])); auto pSource= cast(void*)((array[source])); size_t size = (length - source) * E.sizeof; memmove(pDest, pSource, size); // If move down, compress array. if (offset 0) array.length += offset; } void shiftEndPartD (E) (ref E[] array, size_t source, size_t dest) { // Record length before possible extension. auto length = array.length; int offset = dest - source; // If move up, extend array shift backwards. if (offset 0) { array.length += offset; for (size_t i=length-1 ; i=source ; i--) array[i+offset] = array[i]; } // If move down, shift forwards compress array. if (offset 0) { for (size_t i=source ; ilength ; i++) array[i+offset] = array[i]; array.length += offset; } } void testFuncs () { char[] s; // C memmove s = 0123456789.dup; writeln(s); // Insert slice. s.shiftEndPartC(3,5); s[3..5] = --; writeln(s); // Delete slice. s.shiftEndPartC(5,3); writeln(s); writeln(); // D manual s = 0123456789.dup; writeln(s); // Insert slice. s.shiftEndPartD(3,5); s[3..5] = --; writeln(s); // Delete slice. s.shiftEndPartD(5,3); writeln(s); writeln(); } void chrono () { char[] s; d_time t; enum N = 1_000_000; // C memmove s = 0123456789.dup; t = getUTCtime(); foreach (_ ; 0..N) { s.shiftEndPartC(3,5); s[3..5] = --; s.shiftEndPartC(5,3); } t = getUTCtime() - t; writefln(C time: %s, t); // D manual s = 0123456789.dup; t = getUTCtime(); foreach (_ ; 0..N) { s.shiftEndPartD(3,5); s[3..5] = --; s.shiftEndPartD(5,3); } t = getUTCtime() - t; writefln(D time: %s, t); } unittest { //~ testFuncs(); chrono(); } void main () {} -- _ vita es estrany spir.wikidot.com
Anyone have a function to print out the field name and its value?
Let's say I have this structure: struct PAINTSTRUCT { bool state; } And somewhere in my main code I want to print out the value of state. But I also want to know what I'm printing out. So usually I'd do this: void main() { PAINTSTRUCT ps; writefln(ps.state = %s, ps.state); } Has anyone written a function which will automatically print out both the variable name and any object it might be part of, and then the value? E.g. I'd like to use a function like this: writeField(ps.state); And if state is false it would print out to the console: ps.state = false I can't really touch PRINTSTRUCT because it's already defined as a WinAPI structure and messing with that would be bad, so I can't implement toString() or any helper functions within the struct. I need an outside function which could do this automatically for any object/struct type.
Re: Anyone have a function to print out the field name and its value?
Andrej Mitrovic Wrote: Actually I couldn't really just use ps.fErase, because that just passes a bool to the function. Hmm.. this doesn't look possible to do without introducing complexity at the calling site.
Re: speed of low-level C funcs: example of memmove
On 04/09/2011 07:08 PM, spir wrote: Hello, To insert of delete an array slice, I tried to use C's memmove, thinking it would be far faster than manually copying bit per bit (by any kind of magic). But I still wrote a D versions just to check what the actual speed gain is. To my great surprise, the C-memmove and D-manual versions perform *exactly* at the same speed (considering measure imprecision). Note: this remains true when elements are bigger; speed slows down slowly (eg dchar's take only 1/3 more time). Correction: memmove can be from 5 to 10 times faster on big arrays. For instance, with 1_000_000 char array: void chrono () { char[] s; d_time t; enum N = 100; // C memmove s = (0.mult(1_000_000)).dup; t = getUTCtime(); foreach (_ ; 0..N) { s.shiftEndPartC(3,5); s[3..5] = --; s.shiftEndPartC(5,3); } t = getUTCtime() - t; writefln(C time: %s, t); // D manual s = (0.mult(1_000_000)).dup; t = getUTCtime(); foreach (_ ; 0..N) { s.shiftEndPartD(3,5); s[3..5] = --; s.shiftEndPartD(5,3); } t = getUTCtime() - t; writefln(D time: %s, t); } -- _ vita es estrany spir.wikidot.com
Re: Anyone have a function to print out the field name and its value?
On 09/04/2011 18:13, Andrej Mitrovic wrote: Let's say I have this structure: struct PAINTSTRUCT { bool state; } And somewhere in my main code I want to print out the value of state. But I also want to know what I'm printing out. So usually I'd do this: void main() { PAINTSTRUCT ps; writefln(ps.state = %s, ps.state); } Has anyone written a function which will automatically print out both the variable name and any object it might be part of, and then the value? E.g. I'd like to use a function like this: writeField(ps.state); And if state is false it would print out to the console: ps.state = false I can't really touch PRINTSTRUCT because it's already defined as a WinAPI structure and messing with that would be bad, so I can't implement toString() or any helper functions within the struct. I need an outside function which could do this automatically for any object/struct type. Off the top of my head (untested): void print(T)(T t) if (is(T == struct) || is(T == class)) { foreach (i, field; t.tupleof) { writefln(T.tupleof[i].stringof ~ = %s, field); } } -- Robert http://octarineparrot.com/
Re: Anyone have a function to print out the field name and its value?
On 09/04/2011 18:23, Robert Clipsham wrote: Off the top of my head (untested): void print(T)(T t) if (is(T == struct) || is(T == class)) { foreach (i, field; t.tupleof) { writefln(T.tupleof[i].stringof ~ = %s, field); } } -- Robert http://octarineparrot.com/ I forgot to mention... Usage: --- print(myStruct); It's also simple enough to adapt to just print a given field etc. -- Robert http://octarineparrot.com/
Re: Anyone have a function to print out the field name and its value?
Wow, I figured out a trick. Check it out, two modules: 1. fieldwrite.d: module fieldwrite; import std.string; import std.stdio; import std.conv; mixin template field(string T) { struct FieldTemp { this(string str) { writefln(str ~ = %s, mixin(T)); } } FieldTemp fieldTemp = FieldTemp(T); } 2. driver.d: import std.stdio; import fieldwrite; struct S { int x; int y; } void main() { S s; s.x = 1; s.y = 2; mixin field!s.x; mixin field!s.y; }
Re: Anyone have a function to print out the field name and its value?
On 4/9/11, Robert Clipsham rob...@octarineparrot.com wrote: On 09/04/2011 18:23, Robert Clipsham wrote: Off the top of my head (untested): void print(T)(T t) if (is(T == struct) || is(T == class)) { foreach (i, field; t.tupleof) { writefln(T.tupleof[i].stringof ~ = %s, field); } } -- Robert http://octarineparrot.com/ I forgot to mention... Usage: --- print(myStruct); It's also simple enough to adapt to just print a given field etc. -- Robert http://octarineparrot.com/ That's great, I can use it to print out all the fields. Thanks!
Re: Anyone have a function to print out the field name and its value?
On 4/9/11, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: That's great, I can use it to print out all the fields. Thanks! Some error checking should be done, or maybe there's a bug. If a field has a type that is a typedef to say a void*: typedef void* HANDLE struct S { HANDLE hnd; } Printing hnd will fail with an error: D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1599): Error: function std.format.formatValue!(LockingTextWriter,HANDLE,immutable(char)).formatValue is deprecated D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(308): Error: template instance std.format.formatGeneric!(LockingTextWriter,HANDLE,immutable(char)) error instantiating D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(701): instantiated from here: formattedWrite!(LockingTextWriter,immutable(char),HANDLE) D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(1598):instantiated from here: writefln!(string,HANDLE) hello_msg.d(35):instantiated from here: writefln!(string,HANDLE) hello_msg.d(129):instantiated from here: print!(PAINTSTRUCT) Btw, why are we not allowed to have mixin templates that have statements? Why only declarations?
Re: Anyone have a function to print out the field name and its value?
On 09/04/2011 18:44, Andrej Mitrovic wrote: On 4/9/11, Andrej Mitrovicandrej.mitrov...@gmail.com wrote: That's great, I can use it to print out all the fields. Thanks! Some error checking should be done, or maybe there's a bug. If a field has a type that is a typedef to say a void*: typedef void* HANDLE struct S { HANDLE hnd; } Printing hnd will fail with an error: D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1599): Error: function std.format.formatValue!(LockingTextWriter,HANDLE,immutable(char)).formatValue is deprecated D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(308): Error: template instance std.format.formatGeneric!(LockingTextWriter,HANDLE,immutable(char)) error instantiating D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(701): instantiated from here: formattedWrite!(LockingTextWriter,immutable(char),HANDLE) D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(1598):instantiated from here: writefln!(string,HANDLE) hello_msg.d(35):instantiated from here: writefln!(string,HANDLE) hello_msg.d(129):instantiated from here: print!(PAINTSTRUCT) For now you can compile with -d, this should be reported as a bug though. Btw, why are we not allowed to have mixin templates that have statements? Why only declarations? Dunno, never made sense to me... Could be a question for d.D. -- Robert http://octarineparrot.com/
Re: Anyone have a function to print out the field name and its value?
On 4/9/11, Robert Clipsham rob...@octarineparrot.com wrote: For now you can compile with -d, this should be reported as a bug though. Ok, reported. http://d.puremagic.com/issues/show_bug.cgi?id=5825 Dunno, never made sense to me... Could be a question for d.D. Yup. :)
Re: speed of low-level C funcs: example of memmove
If you take a look at the implementation of memmove (grab the std C lib source) you'll see a rather optimized assembly loop which is very smart about doing machine-word aligned moves, and using processor block-copy instructions. I suspect that is the reason you see the difference. For smaller data sets, you won't see as much gain, if any, because it can't take advantage of those other semantics to the same degree. - Cliff On Sat, Apr 9, 2011 at 10:17 AM, spir denis.s...@gmail.com wrote: On 04/09/2011 07:08 PM, spir wrote: Hello, To insert of delete an array slice, I tried to use C's memmove, thinking it would be far faster than manually copying bit per bit (by any kind of magic). But I still wrote a D versions just to check what the actual speed gain is. To my great surprise, the C-memmove and D-manual versions perform *exactly* at the same speed (considering measure imprecision). Note: this remains true when elements are bigger; speed slows down slowly (eg dchar's take only 1/3 more time). Correction: memmove can be from 5 to 10 times faster on big arrays. For instance, with 1_000_000 char array: void chrono () { char[] s; d_time t; enum N = 100; // C memmove s = (0.mult(1_000_000)).dup; t = getUTCtime(); foreach (_ ; 0..N) { s.shiftEndPartC(3,5); s[3..5] = --; s.shiftEndPartC(5,3); } t = getUTCtime() - t; writefln(C time: %s, t); // D manual s = (0.mult(1_000_000)).dup; t = getUTCtime(); foreach (_ ; 0..N) { s.shiftEndPartD(3,5); s[3..5] = --; s.shiftEndPartD(5,3); } t = getUTCtime() - t; writefln(D time: %s, t); } -- _ vita es estrany spir.wikidot.com
How do I iterate over enum members at runtime?
E.g.: enum Metrics : int { SM_CXSCREEN = 0, SM_CYSCREEN, SM_CXVSCROLL, SM_CYHSCROLL, SM_CYCAPTION, SM_CXBORDER, } void foo(int m) { } void main() { foreach (m; Metrics) { foo(m); } } This won't work. I know there's traits to get strings at compile time, e.g.: auto b = [ __traits(allMembers, Metrics) ]; but this doesn't help me try out those enum values at runtime. It could almost work if I could use a mixin() in a foreach loop, but that's lucid dreaming. Another alternative might be to create an array out of the enum, but I don't know of any way of doing this.
Re: How do I iterate over enum members at runtime?
On Sat, 09 Apr 2011 16:20:06 -0400, Andrej Mitrovic wrote: I know there's traits to get strings at compile time, e.g.: auto b = [ __traits(allMembers, Metrics) ]; but this doesn't help me try out those enum values at runtime. It could almost work if I could use a mixin() in a foreach loop, but that's lucid dreaming. Another alternative might be to create an array out of the enum, but I don't know of any way of doing this. You have everything you need, just put them all together: enum Metrics : int { SM_CXSCREEN = 0, SM_CYSCREEN, SM_CXVSCROLL, SM_CYHSCROLL, SM_CYCAPTION, SM_CXBORDER, } void foo(int m) { } void main() { foreach (m; __traits(allMembers, Metrics)) { foo(mixin(Metrics. ~ m)); } }
Re: How do I iterate over enum members at runtime?
What the.. I was sure mixin wouldn't work in a foreach loop. Thanks, Jesse!
Re: How do I iterate over enum members at runtime?
What the.. I was sure mixin wouldn't work in a foreach loop. Whyever not? mixins work in most places. I believe that the problem is that they have to be a whole expression or statement rather than just a piece of one, so sometimes you can't use a mixin for something small and have to put more of the code in a mixin, but string mixins do work in most places. - Jonathan M Davis
Re: How do I iterate over enum members at runtime?
On 4/10/11, Jonathan M Davis jmdavisp...@gmx.com wrote: What the.. I was sure mixin wouldn't work in a foreach loop. Whyever not? mixins work in most places. I believe that the problem is that they have to be a whole expression or statement rather than just a piece of one, so sometimes you can't use a mixin for something small and have to put more of the code in a mixin, but string mixins do work in most places. - Jonathan M Davis Well in this case it works, but it's not always so easy. For example: import std.conv; enum Metrics : int { val0, val1, val2 } void foo(int m) { } void main() { foreach (index; 0..3) { foo(mixin(Metrics.val ~ to!string(index))); } } So even though you might think hey, it's obvious index in this case can never be anything other than 0, 1, or 2, you still won't be able to compile this. CTFE is a tricky thing.
Re: How do I iterate over enum members at runtime?
You could probably make a template out of the ugly __traits invocation as well? On Sat, Apr 9, 2011 at 3:37 PM, Andrej Mitrovic andrej.mitrov...@gmail.comwrote: On 4/10/11, Jonathan M Davis jmdavisp...@gmx.com wrote: What the.. I was sure mixin wouldn't work in a foreach loop. Whyever not? mixins work in most places. I believe that the problem is that they have to be a whole expression or statement rather than just a piece of one, so sometimes you can't use a mixin for something small and have to put more of the code in a mixin, but string mixins do work in most places. - Jonathan M Davis Well in this case it works, but it's not always so easy. For example: import std.conv; enum Metrics : int { val0, val1, val2 } void foo(int m) { } void main() { foreach (index; 0..3) { foo(mixin(Metrics.val ~ to!string(index))); } } So even though you might think hey, it's obvious index in this case can never be anything other than 0, 1, or 2, you still won't be able to compile this. CTFE is a tricky thing.
Re: How do I iterate over enum members at runtime?
Well, the C code I was translating had something like this: struct SysMetrics { int iIndex; char* szLabel; char* szDesc; } And then it used an array of these structures. So for all existing enums that started with SM_, those fields were populated with the enum value and a name and description. A 200 line header file was filled by hand. I really hope the author had some help from an editor for that, lol!. I've managed to do the same in about a dozen lines of code, although I didn't fill the description field (I don't need it anyway): http://codepad.org/EJEuc6qA It's a shame that an enum with a tag doesn't have a .length property. I've had to use __traits to build an array just to get the length.
Re: How do I iterate over enum members at runtime?
Andrej Mitrovic Wrote: It's a shame that an enum with a tag doesn't have a .length property. I've had to use __traits to build an array just to get the length. It has .max http://www.digitalmars.com/d/2.0/enum.html
Re: How do I iterate over enum members at runtime?
You must iterate a compile time only construct. So yes it would be nice to be able to say: static foreach and have the compiler tell you, no I can't do that (and force it if it can). Andrej Mitrovic Wrote: Well in this case it works, but it's not always so easy. For example: import std.conv; enum Metrics : int { val0, val1, val2 } void foo(int m) { } void main() { foreach (index; 0..3) { foo(mixin(Metrics.val ~ to!string(index))); } } So even though you might think hey, it's obvious index in this case can never be anything other than 0, 1, or 2, you still won't be able to compile this. CTFE is a tricky thing.
Re: How do I iterate over enum members at runtime?
On 4/10/11, Jesse Phillips jessekphillip...@gmail.com wrote: Andrej Mitrovic Wrote: It's a shame that an enum with a tag doesn't have a .length property. I've had to use __traits to build an array just to get the length. It has .max http://www.digitalmars.com/d/2.0/enum.html That doesn't show me the number of values an enum tag has, only its largest value. void main() { writeln(foo.max); // 101, not 4 } enum foo : int { a, b, c = 100, d }