wmemchar for unix
For performance reasons, I need a w version of memchr. C defines wmemchr as: wchar_t * wmemchr ( const wchar_t *, wchar_t, size_t ); Unfortunatly, on unix, wchar_t is defined a *4* bytes long, making wmemchr, effectivelly, dmemchr. Are there any 2 byte alternatives for wmemchr on unix?
Re: Test
On 8/27/2013 4:56 PM, Mike Parker wrote: Sorry for the noise. Having some difficulty with my newsreader. Last one.
Test
Sorry for the noise. Having some difficulty with my newsreader.
Re: How to cleanup after Socket.bind on Linux?
On Tue, 27 Aug 2013 04:30:10 +0100, Ali Çehreli acehr...@yahoo.com wrote: The following simple socket example is trying to cleanup after itself, except the bind() call. As I repeat in the QUESTION comment below, I have read the man page of bind and I know that I need to unlink a path. How can I get that path? That example is for AF_UNIX domain sockets. TcpSocket is an AF_INET domain socket. In AF_INET there is no 'path' and there is nothing you need to do to cleanup after bind - other than close the socket. I do not believe a shutdown is required for a listening socket - tho don't quote me on that. The problem is, currently the program apparently leakes some resources. It cannot be started a second time for 8080 still being in use, unless you wait for several seconds, presumably until the OS does the cleanup. Correct. And this time varies by platform, as dnewbie mentions on Windows you can re-use immediately. You could set the REUSE option on the socket prior to 'bind', this would allow you to bind again while the previous socket was in cleanup. The other thing which might be affecting things is.. Take a look at: http://linux.die.net/man/7/socket Specifically SO_LINGER. This socket option controls whether and how long a socket will linger after it is closed. I am not sure what the linux defaults are for that, but it may be set to linger intentionally. You could use getsockopt to obtain the LINGER default values and see. Also.. the sentence When the socket is closed as part of exit(2), it always lingers in the background. made me think, when does scope(exit) fire? Does it occur as part of exit in your example? Does manually calling shutdown/close on the listening socket resolve the issue. Regan -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: template definitions spanning modules.
On Monday, 26 August 2013 at 00:46:50 UTC, Jason den Dulk wrote: Hi Consider the following code module A; void xx(T:int)(T t) { .. } void xx(T:float)(T t) { .. } module B; import A; void xx(T:string)(T t) { .. } void main() { xx!(int)(4); xx(4.5); xx(abc); } The compiler won't let me do this. It will complain that xx!(int)(4) cannot be instantiated with xx(T:string). If I move xx(T:string) into its own module, the compiler complains about ambiguity. If I put them all in the same module, it works fine. I read about overload sets in the docs and tried the alias A.xx xx suggestion, but the compiler didn't like that either. Is there any way I can make this work without having to put them all in the same module? Thanks in advance. Jason. It's a known bug: http://d.puremagic.com/issues/show_bug.cgi?id=10658
Re: Variant[Variant]
Hi Ali, thanks for helping me out. On Tuesday, 27 August 2013 at 01:38:54 UTC, Ali Çehreli wrote: I spent 15 minutes trying to complete the code but failed. Could you please provide a minimal program that almost compiles. I uploaded a new version with a main routine. So you know, I am using DMD 2.063.2 on Fedora 15. The code should compile with dmd serialize.d. I since realized that I was not dealing with a Variant[Variant] but a Variant(Variant[Variant]). It didn't seem to like having [Variant] called upon it. After extracting it to a V[V] (called tcd1_vn), I noticed something else. Doing a foreach on it, foreach (_a_, _b_;tcd1_vn) { writeln(_a_.type(),,,_b_.type()); writeln(_a_.get!(string),,,_b_.get!(long)); } gives this: immutable(char)[],long a,1 immutable(char)[],long b,2 immutable(char)[],long c,3 So it appears that Variant(a) is a key, but assert(Variant(a) in tcd1_vn); fails. Any ideas? Thanks again for helping. I have been reading your online book. I have found it quite helpful. Regards Jason
Re: ElementType!string
On Sunday, 25 August 2013 at 19:38:52 UTC, Paolo Invernizzi wrote: Thanks, somewhat unintuitive. It is a trap for the unwary, but in this case the benefits outweigh the costs. On Sunday, 25 August 2013 at 19:56:34 UTC, Jakob Ovrum wrote: To get a range of UTF-8 or UTF-16 code units, the code units have to be represented as something other than `char` and `wchar`. For example, you can cast your string to immutable(ubyte)[] to operate on that, then cast it back at a later point. To have to use ubyte would seem to defeat the purpose of having char. If I were to have this: auto no_convert(C)(C[] s) if (isSomeChar!C) { struct No { private C[] s; this(C[] _s) { s = _s; } @property bool empty() { return s.length == 0; } @property C front() in{ assert(s.length != 0); } body{ return s[0]; } void popFront() in{ assert(s.length != 0); } body{ s = s[1..$]; } } return No(s); } it's element type would be char for strings. Would this still result in conversions if I used it with other algorithms?
Re: ElementType!string
On Tuesday, 27 August 2013 at 11:43:29 UTC, Jason den Dulk wrote: On Sunday, 25 August 2013 at 19:38:52 UTC, Paolo Invernizzi wrote: Thanks, somewhat unintuitive. It is a trap for the unwary, but in this case the benefits outweigh the costs. On Sunday, 25 August 2013 at 19:56:34 UTC, Jakob Ovrum wrote: To get a range of UTF-8 or UTF-16 code units, the code units have to be represented as something other than `char` and `wchar`. For example, you can cast your string to immutable(ubyte)[] to operate on that, then cast it back at a later point. To have to use ubyte would seem to defeat the purpose of having char. If I were to have this: auto no_convert(C)(C[] s) if (isSomeChar!C) { struct No { private C[] s; this(C[] _s) { s = _s; } @property bool empty() { return s.length == 0; } @property C front() in{ assert(s.length != 0); } body{ return s[0]; } void popFront() in{ assert(s.length != 0); } body{ s = s[1..$]; } } return No(s); } it's element type would be char for strings. Would this still result in conversions if I used it with other algorithms? That should work. It's the functions in std.array that make ranges out of arrays by provideng empty, front and popFront. As long as you don't use these, everything is fine. Actually I think that your wrapper should do the conversion and std.array should not, but that train is long gone.
Re: Freshly Compiled DMD + Visual Studio
27-Aug-2013 08:46, Meta пишет: I decided to compile D from Github for the first time, and everything seemed to be working. I can build and run stuff fine from the command line. However, then I tried to make Visual Studio use my newly compiled DMD, and things blew up. I'm using VisualD 0.3.37. When I try to compile a small project (which compiles correctly when doing it from the command line) it gets as far as linking, and then spits out a bunch of errors: Linker errors are typically solve by doing clean, then rebuilding from source. There is a decent chance that you (or VisualD) do separate compilation and old object files can't find matching symbols in the new runtime library. From what I can tell, it looks like it cannot link in druntime correctly... But I'm not really an expert. -- Dmitry Olshansky
Re: ElementType!string
On Tuesday, 27 August 2013 at 11:43:29 UTC, Jason den Dulk wrote: On Sunday, 25 August 2013 at 19:38:52 UTC, Paolo Invernizzi wrote: Thanks, somewhat unintuitive. It is a trap for the unwary, but in this case the benefits outweigh the costs. On Sunday, 25 August 2013 at 19:56:34 UTC, Jakob Ovrum wrote: To get a range of UTF-8 or UTF-16 code units, the code units have to be represented as something other than `char` and `wchar`. For example, you can cast your string to immutable(ubyte)[] to operate on that, then cast it back at a later point. To have to use ubyte would seem to defeat the purpose of having char. If I were to have this: auto no_convert(C)(C[] s) if (isSomeChar!C) { struct No { private C[] s; this(C[] _s) { s = _s; } @property bool empty() { return s.length == 0; } @property C front() in{ assert(s.length != 0); } body{ return s[0]; } void popFront() in{ assert(s.length != 0); } body{ s = s[1..$]; } } return No(s); } it's element type would be char for strings. Would this still result in conversions if I used it with other algorithms? It might, but that range of yours is underwhelming: no indexing, no length, no nothing. Why would you want to do *that* though? Is it because you have an ASCII string? In that case, you should be interested in std.encoding.AsciiChar and std.encoding.AsciiString.
repeating random number sequences.
Hi This code foreach (j; 0..5) writeln(rndGen().take(5)); writeln(uniform(0, 1024)); foreach (j; 0..5) writeln(rndGen().take(5)); produces this output [3410716173, 2484862302, 280352965, 1820347603, 850366086] [3410716173, 2484862302, 280352965, 1820347603, 850366086] [3410716173, 2484862302, 280352965, 1820347603, 850366086] [3410716173, 2484862302, 280352965, 1820347603, 850366086] [3410716173, 2484862302, 280352965, 1820347603, 850366086] 813 [2484862302, 280352965, 1820347603, 850366086, 604192828] [2484862302, 280352965, 1820347603, 850366086, 604192828] [2484862302, 280352965, 1820347603, 850366086, 604192828] [2484862302, 280352965, 1820347603, 850366086, 604192828] [2484862302, 280352965, 1820347603, 850366086, 604192828] Is this correct behaviour? It appears a little inconsistant to me. Regards Jason
Re: repeating random number sequences.
On Tuesday, 27 August 2013 at 12:59:19 UTC, Jason den Dulk wrote: Hi This code foreach (j; 0..5) writeln(rndGen().take(5)); writeln(uniform(0, 1024)); foreach (j; 0..5) writeln(rndGen().take(5)); produces this output [3410716173, 2484862302, 280352965, 1820347603, 850366086] [3410716173, 2484862302, 280352965, 1820347603, 850366086] [3410716173, 2484862302, 280352965, 1820347603, 850366086] [3410716173, 2484862302, 280352965, 1820347603, 850366086] [3410716173, 2484862302, 280352965, 1820347603, 850366086] 813 [2484862302, 280352965, 1820347603, 850366086, 604192828] [2484862302, 280352965, 1820347603, 850366086, 604192828] [2484862302, 280352965, 1820347603, 850366086, 604192828] [2484862302, 280352965, 1820347603, 850366086, 604192828] [2484862302, 280352965, 1820347603, 850366086, 604192828] Is this correct behaviour? It appears a little inconsistant to me. Regards Jason No. It is incorrect behavior. It is a *very* big problem we know about, and are trying to fix. The problem (arguably) is so big, it warrants making a brand new random2 module. Long story short: The current PRNG's a value types. This means that when you pass them around (by value) you are duplicating them. The fix (for us) is to make them all reference types, so that passign them around doesn't duplicate them. In the meantime, workarounds include: Generating a new PRGN every time you need a new sequence, or creating your own wrapper around rndGen(); struct GoodPrng { enum empty = false; void popFront() { rndGen().popFront(); } auto front() @property { return rndGen().front; } } GoodPrng goodPrng() { return GoodPrng(); } This should work: void main() { foreach (j; 0..5) writeln(GoodPrng().take(5)); writeln(uniform(0, 1024)); foreach (j; 0..5) writeln(GoodPrng().take(5)); } [47855835, 916983782, 2006604655, 2074198403, 772414269] [2220086136, 3393309461, 3644080841, 1053550911, 2595436893] [3782843356, 2688374946, 3181159978, 628742771, 1672837671] [192566424, 3205182805, 521392827, 1528745543, 2713259487] [1188847012, 820882915, 1616362385, 837154982, 553045938] 400 [2350166972, 951558946, 1940218749, 1245693761, 315407] [4184834298, 2262977512, 3554532516, 3345988025, 1171565042] [3698692802, 538668063, 4044473111, 666762521, 865383943] [3357865623, 3653338316, 276404459, 1764534280, 1999822962] [1118055308, 3030179246, 3422085781, 4056620356, 201644357] We apologize for the inconvenience.
Re: Freshly Compiled DMD + Visual Studio
On Tuesday, 27 August 2013 at 12:09:22 UTC, Dmitry Olshansky wrote: Linker errors are typically solve by doing clean, then rebuilding from source. There is a decent chance that you (or VisualD) do separate compilation and old object files can't find matching symbols in the new runtime library. I rebuilt it, but I am still getting the same linker errors. Both times I built DMD following the directions on this page: http://wiki.dlang.org/Building_DMD. Are they perhaps out of date?
Re: Freshly Compiled DMD + Visual Studio
On Tuesday, 27 August 2013 at 13:32:06 UTC, Meta wrote: On Tuesday, 27 August 2013 at 12:09:22 UTC, Dmitry Olshansky wrote: Linker errors are typically solve by doing clean, then rebuilding from source. There is a decent chance that you (or VisualD) do separate compilation and old object files can't find matching symbols in the new runtime library. I rebuilt it, but I am still getting the same linker errors. Both times I built DMD following the directions on this page: http://wiki.dlang.org/Building_DMD. Are they perhaps out of date? Check that your library paths are all set to the path for of the newly built Phobos. It may be that it's trying to link in the old library.
Re: wmemchar for unix
On Aug 26, 2013, at 11:57 PM, monarch_dodra monarchdo...@gmail.com wrote: For performance reasons, I need a w version of memchr. C defines wmemchr as: wchar_t * wmemchr ( const wchar_t *, wchar_t, size_t ); Unfortunatly, on unix, wchar_t is defined a *4* bytes long, making wmemchr, effectivelly, dmemchr. Are there any 2 byte alternatives for wmemchr on unix? Why not cast the array to ushort[] and do a find()? Or is that too slow as well?
Re: wmemchar for unix
On Tue, Aug 27, 2013 at 07:37:02AM -0700, Sean Kelly wrote: On Aug 26, 2013, at 11:57 PM, monarch_dodra monarchdo...@gmail.com wrote: For performance reasons, I need a w version of memchr. C defines wmemchr as: wchar_t * wmemchr ( const wchar_t *, wchar_t, size_t ); Unfortunatly, on unix, wchar_t is defined a *4* bytes long, making wmemchr, effectivelly, dmemchr. Are there any 2 byte alternatives for wmemchr on unix? Why not cast the array to ushort[] and do a find()? Or is that too slow as well? Optimized searches of this kind ideally translate to the various rep* instructions on x86. I'm not sure if dmd does that optimization. If you really feel inclined, you could do static if (X86) and throw in an asm block (but that would break purity, @safety, etc., so probably not a good idea). You *might* be able to coax GDC (or LDC) to do loop unrolling and/or substitution with rep* instructions with just plain D code, though. Can't really say without trying it out. T -- They pretend to pay us, and we pretend to work. -- Russian saying
Re: Freshly Compiled DMD + Visual Studio
On Tuesday, 27 August 2013 at 14:04:09 UTC, Meta wrote: On Tuesday, 27 August 2013 at 13:55:55 UTC, Andre Artus wrote: Check that your library paths are all set to the path for of the newly built Phobos. It may be that it's trying to link in the old library. Of course it was something as simple as that. Thank you Andre. No problem.
Strange behavior of read file
module main; import std.stdio, std.file, std.string, std.algorithm, std.range, std.datetime, std.conv, std.typetuple; int f(string fileName = rC:\Euler\data\e67.txt) { auto text = read(fileName); return text.length; } void main() { try { string fileName = rC:\Euler\data\e67.txt; auto text = read(fileName); writeln(text.length); writeln(f); // EXCEPTION HERE } catch (Exception e) { writeln(e); } writeln(f); } I'm running this test code compiled with DMD 2.063.2 on Windows 7 and I'm getting an exception The system cannot find the file specified. The same code runs fine on Linux. The file in question exists of course. When I remove the default parameter value from f(), exceptions stop. Is there a problem of having two strings rC:\Euler\data\e67.txt with the same content?
Re: wmemchar for unix
On Tuesday, 27 August 2013 at 14:37:14 UTC, Sean Kelly wrote: On Aug 26, 2013, at 11:57 PM, monarch_dodra monarchdo...@gmail.com wrote: For performance reasons, I need a w version of memchr. C defines wmemchr as: wchar_t * wmemchr ( const wchar_t *, wchar_t, size_t ); Unfortunatly, on unix, wchar_t is defined a *4* bytes long, making wmemchr, effectivelly, dmemchr. Are there any 2 byte alternatives for wmemchr on unix? Why not cast the array to ushort[] and do a find()? Or is that too slow as well? Because it's specifically to speed up find's implementation ^^
Re: wmemchar for unix
On Tuesday, 27 August 2013 at 14:43:10 UTC, H. S. Teoh wrote: On Tue, Aug 27, 2013 at 07:37:02AM -0700, Sean Kelly wrote: On Aug 26, 2013, at 11:57 PM, monarch_dodra monarchdo...@gmail.com wrote: For performance reasons, I need a w version of memchr. C defines wmemchr as: wchar_t * wmemchr ( const wchar_t *, wchar_t, size_t ); Unfortunatly, on unix, wchar_t is defined a *4* bytes long, making wmemchr, effectivelly, dmemchr. Are there any 2 byte alternatives for wmemchr on unix? Why not cast the array to ushort[] and do a find()? Or is that too slow as well? Optimized searches of this kind ideally translate to the various rep* instructions on x86. I'm not sure if dmd does that optimization. If you really feel inclined, you could do static if (X86) and throw in an asm block (but that would break purity, @safety, etc., so probably not a good idea). You *might* be able to coax GDC (or LDC) to do loop unrolling and/or substitution with rep* instructions with just plain D code, though. Can't really say without trying it out. T Hum... I think that is too complicated for what I'm trying to do. I don't know assembly enough. Ideally, I was hoping for a pre-existing C function to do the work for me :) For now, I can settle for a simple: version (windows) //use fast wmemchr else //use standard code But It feels weird, in the sense that there is no reason for 2byte search to be more specific to windows than for unix...
Re: Strange behavior of read file
Correction to my initial post: I oversimplified the code example by snipping too much of context. Here is an example, which fails both on Windows and Linux: module main; import std.stdio, std.file, std.string, std.algorithm, std.range, std.datetime, std.conv, std.typetuple; int e67_1(string fileName = r67.txt) { // Read triangle numbers from file. int[][] cell; foreach (y, line; splitLines(cast(char[]) read(fileName))) { auto row = new int[y+1]; foreach (x, token; split(line)) row[x] = to!int(token); cell ~= row; } // Compute maximum value partial paths ending at each cell. foreach (y; 1..cell.length) { cell[y][0] += cell[y-1][0]; foreach (x; 1..y) cell[y][x] += max(cell[y-1][x-1], cell[y-1][x]); cell[y][y] += cell[y-1][y-1]; } // Return the maximum value terminal path. return cell[$-1].reduce!max; } void main() { try { writeln(e67_1); } catch (Exception e) { writeln(e); } } Here is the message on Linux: std.file.FileException@std/file.d(219): 67.txt: No such file or directory ./main(void[] std.file.read(const(char[]), ulong)+0x87) [0x4c5b2b] ./main(int main.e67_1(immutable(char)[])+0x41) [0x4805a9] ./main(_Dmain+0x56) [0x4807de] ./main(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runMain()+0x18) [0x4b8e60] ./main(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x4b8992] ./main(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runAll()+0x40) [0x4b8eb0] ./main(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate())+0x2a) [0x4b8992] ./main(_d_run_main+0x1ae) [0x4b894e] ./main(main+0x17) [0x4b879b] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7ff2929ccea5] Again, the file requested exists. I test that by adding other functions (from my initial post) to the code above.
Re: Strange behavior of read file
On Tuesday, 27 August 2013 at 15:45:06 UTC, Paul Jurczak wrote: module main; import std.stdio, std.file, std.string, std.algorithm, std.range, std.datetime, std.conv, std.typetuple; int f(string fileName = rC:\Euler\data\e67.txt) { auto text = read(fileName); return text.length; } void main() { try { string fileName = rC:\Euler\data\e67.txt; auto text = read(fileName); writeln(text.length); writeln(f); // EXCEPTION HERE } catch (Exception e) { writeln(e); } writeln(f); } I'm running this test code compiled with DMD 2.063.2 on Windows 7 and I'm getting an exception The system cannot find the file specified. The same code runs fine on Linux. The file in question exists of course. When I remove the default parameter value from f(), exceptions stop. Is there a problem of having two strings rC:\Euler\data\e67.txt with the same content? Works for me on my own win7 with 2.063.2 (replaced file with rC:\D\test.txt). Not sure what else is going on. Did you copy paste the *exact* code that was failing? Please try inserting this trace: int f(string fileName = rC:\D\test.txt) { writeln(fileName: , fileName); //HERE auto text = read(fileName); return text.length; } And report what happens. Off topic, text might be a poor choice for a variable name, as it shadows the pretty common function std.conv.text
Re: Strange behavior of read file
On Tue, Aug 27, 2013 at 07:14:22PM +0200, Paul Jurczak wrote: Correction to my initial post: I oversimplified the code example by snipping too much of context. Here is an example, which fails both on Windows and Linux: module main; import std.stdio, std.file, std.string, std.algorithm, std.range, std.datetime, std.conv, std.typetuple; int e67_1(string fileName = r67.txt) { // Read triangle numbers from file. int[][] cell; foreach (y, line; splitLines(cast(char[]) read(fileName))) { Maybe try inserting a writeln just before the foreach to print out what filename it's actually trying to read? Or try using File to open it and see if you get the same error? auto f = File(fileName, r); T -- Ignorance is bliss... until you suffer the consequences!
Re: Strange behavior of read file
On Tuesday, 27 August 2013 at 17:14:23 UTC, Paul Jurczak wrote: Correction to my initial post: I'll investigate later then.
Re: improve concurrent queue
On Monday, 26 August 2013 at 19:35:28 UTC, luminousone wrote: I have been working on a project and needed a good concurrent queue What does good mean? Concurrent queues have so many design parameters (single reader? single writer? blocking? bounded? etc) and there is no queue, which performs optimal for every case. I can recommand this paper (paywalled though): http://dl.acm.org/citation.cfm?id=248106 Nevertheless, I believe you rather wanted some comments on your specific code. I wonder why you implemented spinlocks yourself? If you write a blocking algorithm, you should probably use the phobos locks.
Re: Strange behavior of read file
On Tuesday, 27 August 2013 at 17:19:08 UTC, monarch_dodra wrote: On Tuesday, 27 August 2013 at 17:14:23 UTC, Paul Jurczak wrote: Correction to my initial post: I'll investigate later then. I am unable to reproduce.
Re: Variant[Variant]
On 08/27/2013 03:53 AM, Jason den Dulk wrote: I uploaded a new version with a main routine. So you know, I am using DMD 2.063.2 on Fedora 15. The code should compile with dmd serialize.d. And it's here: http://jaypha.com.au/serialize.d I since realized that I was not dealing with a Variant[Variant] but a Variant(Variant[Variant]). It didn't seem to like having [Variant] called upon it. After extracting it to a V[V] (called tcd1_vn), I noticed something else. Doing a foreach on it, foreach (_a_, _b_;tcd1_vn) { writeln(_a_.type(),,,_b_.type()); writeln(_a_.get!(string),,,_b_.get!(long)); } gives this: immutable(char)[],long a,1 immutable(char)[],long b,2 immutable(char)[],long c,3 So it appears that Variant(a) is a key, but assert(Variant(a) in tcd1_vn); fails. Any ideas? It is definitely a bug. I spent a lot of time on this and figured it out just before giving up. :) (Actually I figured it out *after* giving up. :p) The signature of VariantN.toHash() does not match D's expectation so it is not considered at all. As a result, the default toHash for structs gets called, which happens to hash by the members of the struct. The problem is, being a variant type, the members of VariantN are a function pointer and the storage: struct VariantN(size_t maxDataSize, AllowedTypesX...) { // ... ptrdiff_t function(OpID selector, ubyte[size]* store, void* data) fptr = handler!(void); union { ubyte[size] store; // conservatively mark the region as pointers static if (size = (void*).sizeof) void* p[size / (void*).sizeof]; } // ... } Since 'store' is just a ubyte[] array, the default toHash for structs cannot hash it as strings. VariantN.toHash's signature must be changed accordingly and Phobos must be recompiled: // WARNING: Unnecessarily slow because type.getHash() is not nothrow. size_t toHash() const nothrow @safe { try { return type.getHash(store); } catch (Exception) { return 0; } } The original toHash was this: size_t toHash() { return type.getHash(store); } The other issue is, the compiler did not warn me until I added a const to the signature. Try to compile this: size_t toHash() const { return type.getHash(store); } ./phobos/std/variant.d(822): Warning: toHash() must be declared as extern (D) size_t toHash() const nothrow @safe, not const @trusted ulong() The same warning should be given to the naked signature 'size_t toHash()' as well. (I remember bearophile warning about such problems.) So, VariantN is broken. It cannot be used as an AA key correctly, at least when it stores a string. To make matters worse, testing with Variants that are initialized by literal strings works because the compiler optimizes the same literal strings. Thanks again for helping. I have been reading your online book. I have found it quite helpful. You are very kind. :) However, as this issue proves, the book is outdated in some parts. At least there is a note for me to update the toHash signatures in the book: :) https://code.google.com/p/ddili/source/browse/trunk/src/ders/d.en/object.d#681 So, I will get to this issue eventually. :-/ May I ask you or somebody else to create a bug about VariantN.toHash not being considered at all. Thank you! :) Ali
Re: wmemchar for unix
27-Aug-2013 18:41, H. S. Teoh пишет: On Tue, Aug 27, 2013 at 07:37:02AM -0700, Sean Kelly wrote: On Aug 26, 2013, at 11:57 PM, monarch_dodra monarchdo...@gmail.com wrote: For performance reasons, I need a w version of memchr. C defines wmemchr as: wchar_t * wmemchr ( const wchar_t *, wchar_t, size_t ); Unfortunatly, on unix, wchar_t is defined a *4* bytes long, making wmemchr, effectivelly, dmemchr. Are there any 2 byte alternatives for wmemchr on unix? Why not cast the array to ushort[] and do a find()? Or is that too slow as well? Optimized searches of this kind ideally translate to the various rep* instructions on x86. Rather a loop with XMM moves. What's best though is always a moving target. I'm not sure if dmd does that optimization. If you really feel inclined, you could do static if (X86) and throw in an asm block (but that would break purity, @safety, etc., so probably not a good idea). It would be awesome to have pure D analogs for memchr, memcpy and its ilk that won't be so limiting (as in types used) but would guarantee top performance. -- Dmitry Olshansky
Re: wmemchar for unix
On Tue, Aug 27, 2013 at 11:18:50PM +0400, Dmitry Olshansky wrote: 27-Aug-2013 18:41, H. S. Teoh пишет: On Tue, Aug 27, 2013 at 07:37:02AM -0700, Sean Kelly wrote: On Aug 26, 2013, at 11:57 PM, monarch_dodra monarchdo...@gmail.com wrote: For performance reasons, I need a w version of memchr. C defines wmemchr as: wchar_t * wmemchr ( const wchar_t *, wchar_t, size_t ); Unfortunatly, on unix, wchar_t is defined a *4* bytes long, making wmemchr, effectivelly, dmemchr. Are there any 2 byte alternatives for wmemchr on unix? Why not cast the array to ushort[] and do a find()? Or is that too slow as well? Optimized searches of this kind ideally translate to the various rep* instructions on x86. Rather a loop with XMM moves. What's best though is always a moving target. I'm not sure if dmd does that optimization. If you really feel inclined, you could do static if (X86) and throw in an asm block (but that would break purity, @safety, etc., so probably not a good idea). It would be awesome to have pure D analogs for memchr, memcpy and its ilk that won't be so limiting (as in types used) but would guarantee top performance. [...] Those would have to be compiler intrinsics, since they are CPU-dependent optimizations. Plus they could improve dmd code generation. :) T -- The only difference between male factor and malefactor is just a little emptiness inside.
Re: improve concurrent queue
On Tuesday, 27 August 2013 at 17:35:13 UTC, qznc wrote: On Monday, 26 August 2013 at 19:35:28 UTC, luminousone wrote: I have been working on a project and needed a good concurrent queue What does good mean? Concurrent queues have so many design parameters (single reader? single writer? blocking? bounded? etc) and there is no queue, which performs optimal for every case. Generally, multiple writers and a single reader, but multiple writers and multiple readers may also occur. I can recommand this paper (paywalled though): http://dl.acm.org/citation.cfm?id=248106 Nevertheless, I believe you rather wanted some comments on your specific code. I wonder why you implemented spinlocks yourself? If you write a blocking algorithm, you should probably use the phobos locks. I was under the impression that the atomic spinlock has a lower latency for any waiters, then a mutex when its unlocked? I am using this for a temporary or depending on performance, a perminate replacement for std.concurrency send/receive until such time as bugs in std.variant are fixed. I have a thread with an opengl context, and I am using the queue to send messages to this thread containing interface Drawable objects, that have any needed preprocessing on them done such that only opengl calls have to be made to the video card to render it.
Re: wmemchar for unix
27-Aug-2013 23:31, H. S. Teoh пишет: On Tue, Aug 27, 2013 at 11:18:50PM +0400, Dmitry Olshansky wrote: 27-Aug-2013 18:41, H. S. Teoh пишет: [snip] I'm not sure if dmd does that optimization. If you really feel inclined, you could do static if (X86) and throw in an asm block (but that would break purity, @safety, etc., so probably not a good idea). It would be awesome to have pure D analogs for memchr, memcpy and its ilk that won't be so limiting (as in types used) but would guarantee top performance. [...] Those would have to be compiler intrinsics, since they are CPU-dependent optimizations. Plus they could improve dmd code generation. :) It would be golden to finally see a time where compilers have D-specific intrinsics! :) -- Dmitry Olshansky
Re: Strange behavior of read file
I played a little with it int f(string fileName = rsomeExistingPath) { auto text = read(fileName); return text.length; } void main() { try { string fileName = rsomeExistingPath; if(exists(fileName)) writeln(File ', fileName, ' does exist.); auto text = read(fileName); writeln(text.length); writeln(f); // EXCEPTION HERE } catch (Exception e) { writeln(e); } writeln(f); } As you see, I mistrustingly inserted a dumb exist test before attempting to read. Here's what I came up with (on linux): - trying with filename r~/text.txt (i.e. an existing file in my home dir) it FAILED. - trying with the same filename but this time home dir explicitely written out fully (r/home/me/test.txt) it WORKED. - your code did NOT throw where you say it does (writeln(f)) but actually in the read call. Conclusion: I assume D's OS path related mechanisms to be somewhat dumb. Anyway the code throws where it's supposed to, i.e. when confronted with a non existing (or not recognized?) path.
Re: Strange behavior of read file
On Wed, 28 Aug 2013 00:51:12 +0200, Ramon wrote: - trying with filename r~/text.txt (i.e. an existing file in my home dir) it FAILED. - trying with the same filename but this time home dir explicitely written out fully (r/home/me/test.txt) it WORKED. Conclusion: I assume D's OS path related mechanisms to be somewhat dumb. Anyway the code throws where it's supposed to, i.e. when confronted with a non existing (or not recognized?) path. You need to use the expandTilde function: http://dlang.org/phobos/ std_path.html#.expandTilde
Re: Strange behavior of read file
On Wed, Aug 28, 2013 at 12:51:12AM +0200, Ramon wrote: [...] Here's what I came up with (on linux): - trying with filename r~/text.txt (i.e. an existing file in my home dir) it FAILED. - trying with the same filename but this time home dir explicitely written out fully (r/home/me/test.txt) it WORKED. [...] That's because '~' is expanded not by the OS but by the shell. The OS treats it as a directory with the literal name '~', which doesn't exist. D's file I/O functions don't go through the shell. std.path.expandTilde is your friend. :) T -- This sentence is false.
Re: Strange behavior of read file
On Tuesday, 27 August 2013 at 17:14:23 UTC, Paul Jurczak wrote: Correction to my initial post: I oversimplified the code example by snipping too much of context. Here is an example, which fails both on Windows and Linux: I get a range violation in Linux, but that is to be expected since my file is empty. Removing the file gives the file not found exception.
Re: Strange behavior of read file
Justin Whear H.S. Teoh Yep, that's what I assumed, too. But that's so C Style. Wouldn't it befit phobos to have sth. like normalizePath? Like: On Unix/linux rep ' ' with '\ ' replace ~ with $HOME etc. so as to have normalizePath return a path equal to what the shell would do? Well, whatever, I hope the OP (Paul Jurczak) could solve the problem. A+ - R
Regarding std.collection.Array
Is it a good idea to add to std.collection.Array a method similar to: T[] unsafeRelease() pure nothrow { return this._data._payload; } It's meant to be used as an unsafe hack to call some some functions that require a built-in array as input. Bye, bearophile
Re: Limited Semi-PolyMorphic (LSP) structs?
It just came to mind that what I want is almost more a unioned struct. Perhaps this will come up with something closer to what I am really looking for. assuming we could use a union, it would be closer to: //type is the identifier of which one it's going to be using union AB { iA ia; iB ib; void A(){} void B(){} void C(){} } struct iA { char type; void A(); void C(); } struct iB { char type; void A(); void B(); } Now last i checked putting functions calls in unions wasn't really a good idea or supported, however we have a problem where iA and iB don't know about the union AB, and they will still try to call the local struct's data first (or the namespace) before anything else. This means if C() get's called, and the type is suppose to use iB, then when C() calls A(), it gets iA's A() and not iB's A(). If however we try to do inner structs, then: struct AB { char type; iA ia; iB ib; struct iA { void real_A() { //regardless what we call, the outer struct gets the calls A(); //line 9 B(); C(); } void real_C() { A(); B(); C(); } } struct iB { void real_A() { A(); B(); C(); } void real_B() { A(); B(); C(); } } void A() { //calls real_A or real_B switch (type) { case 'A': ia.real_A(); case 'B': ib.real_A(); default: throw new Exception(); } } void B() { switch (type) { case 'B': ib.real_B(); default: throw new Exception(); } } void C() { ia.real_C(); } } So far this does seem to want to work, but last I checked I thought this was illegal, the reason being the inner structs needed a pointer to their outer parent which wasn't a class, at which point there was something just difficult about it. test.d(9): Error: this for A needs to be type AB not type iA test.d(10): Error: this for B needs to be type AB not type iA test.d(11): Error: this for C needs to be type AB not type iA test.d(14): Error: this for A needs to be type AB not type iA test.d(15): Error: this for B needs to be type AB not type iA test.d(16): Error: this for C needs to be type AB not type iA test.d(22): Error: this for A needs to be type AB not type iB test.d(23): Error: this for B needs to be type AB not type iB test.d(24): Error: this for C needs to be type AB not type iB test.d(27): Error: this for A needs to be type AB not type iB test.d(28): Error: this for B needs to be type AB not type iB test.d(29): Error: this for C needs to be type AB not type iB I recall there being something to help get around this, but a delegate didn't seem quite like the right answer... I really really don't want to rely on classes, passing a reference to the caller may work but adds unnecessary stuff (plus you have to explicitly call the referenced rather than having it feel like what it should). 'alias this' might help (as with my template attempt), but it quickly becomes a chore to keep up things and gets ugly fast. Mmm..
Re: Limited Semi-PolyMorphic (LSP) structs?
Era, I haven't had time to go through your everything you wrote here but are you looking to create some form of discriminated union (AKA tagged union) using D structs? Do you have a specific problem you need to solve, or are you just exploring the language?
Re: Strange behavior of read file
On Tuesday, 27 August 2013 at 17:19:08 UTC, monarch_dodra wrote: On Tuesday, 27 August 2013 at 17:14:23 UTC, Paul Jurczak wrote: Correction to my initial post: I'll investigate later then. monarch_dodra, H. S. Teoh, Ramon, Justin Whear, Jesse Phillips: Sorry for the delay in responding - I had to take a nap and it helped to find the error I made. I noticed that the file path name was misspelled by one character in one of the test cases. Now everything works fine with both relative and absolute paths. Thank you for your help and I'm sorry for this wild goose chase.
Re: How to cleanup after Socket.bind on Linux?
On 08/27/2013 02:02 AM, Regan Heath wrote: You could set the REUSE option on the socket prior to 'bind', this would allow you to bind again while the previous socket was in cleanup. That worked. I copied the following line from std/socket.d: listener.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true); Ali
Re: Limited Semi-PolyMorphic (LSP) structs?
On Wed, Aug 28, 2013 at 06:45:11AM +0200, Era Scarecrow wrote: On Wednesday, 28 August 2013 at 03:45:06 UTC, Andre Artus wrote: Era, I haven't had time to go through your everything you wrote here but are you looking to create some form of discriminated union (AKA tagged union) using D structs? Do you have a specific problem you need to solve, or are you just exploring the language? The tagged union struct does sorta match the basic idea. What i have is a structure that basically is just a single struct, however it's semi-polymorphic. (I guess that's obvious by the subject). What changes is only really behavior and rarely would it actually add more data, so inheriting and OOP fits it fairly well, however since structs can't inherit it becomes an issue. I can either inherit, or i can make the function(s) large and clunky and basically do it as C. [...] One trick that you may find helpful, is to use alias this to simulate struct inheritance: struct Base { int x; } struct Derived1 { Base __base; alias __base this; int y; } struct Derived2 { Base __base; alias __base this; int z; } void baseFunc(Base b) { ... } void derivFunc1(Derived1 d) { auto tmp = d.y; auto tmp2 = d.x; // note: base struct member directly accessible } void derivFunc2(Derived2 d) { auto tmp = d.z; auto tmp2 = d.x; } Derived1 d1; Derived2 d2; baseFunc(d1); // OK baseFunc(d2); // OK derivFunc1(d1); // OK //derivFunc2(d1); // Error: Derived1 can't convert to Derived2 derivFunc2(d2); // OK This won't help you if you need a single variable to store both structs derived this way, though, 'cos you wouldn't know what size the structs should be. You *could* get away with using Base* (Base pointers) in a semi-polymorphic way as long as you're sure the derived structs don't go out of scope before the Base*, but it gets a bit tricky at that point, and you start to need real classes instead. T -- Once bitten, twice cry...