Re: Simple immutable example doesn't work - why???
On Tuesday, 12 November 2013 at 01:15:02 UTC, Louis Berube wrote: Thanks, I think I understand. Now, how about an array of immutables: immutable class Test { public: this(in uint value) { this.value = value; } unittest { auto t = new immutable Test(4); assert (t.value == 4); } unittest { auto tarray = new immutable(Test)[3]; tarray[0] = new immutable Test(4); // "Error: cannot modify // immutable expression // tarray[0]" } private: uint value; } I thought the parantheses in the array declaration would do the trick, but apparently not. Once you initialize an immutable class reference, you won't be able to rebind it anymore. As far as I know there's two straight methods. immutable class Test { this(in uint value) { this.value = value; } uint value; } void main() { version(Try1) { // 1. concatenate elements immutable(Test)[] tarray; tarray ~= new immutable Test(2); tarray = new immutable Test(1) ~ tarray; } else { // 2. use array literal syntax auto tarray = [ new immutable Test(1), new immutable Test(2), ]; } static assert(is(typeof(tarray[0]) == immutable(Test))); assert(tarray.length == 2) assert(tarray[0].value == 1); assert(tarray[1].value == 2); } In D, you can reserve continuous memory area for array appending by using built-in 'reserve' method. Therefore in most cases, "reserve elements on empty array, then append created elements" would be the efficient way to initialize the array of immutable elements. void main() { immutable(Test)[] tarray; tarray.reserve(2); auto save_ptr = tarray.ptr; assert(save_ptr !is null && tarray.capacity >= 2); // underlying memory is allocated and the appendable number is more than 2. assert(tarray.length == 0); // but array itself is still empty. tarray ~= new immutable Test(1); tarray ~= new immutable Test(2); assert(tarray.length == 2); // array is expectedly filled. assert(tarray.ptr is save_ptr); // But the two concatenations didn't reallocate underlying memory. } And I don't recommend to use std.exception.assumeUnique, because it is just a cosmetic function to make ugly (but necessary for some reason) array cast grep-able and human-readable. Kenji Hara
Re: dchar literals?
On Monday, 11 November 2013 at 13:20:04 UTC, bearophile wrote: Philippe Sigaud: And I agree with you than character literals should default to dchar. It's a perpetual source of friction for me. 99% of my char literals need to be of type char. On the other hand once you have suffixes to specify the char type, most of that problem vanishes, because writing 'x'c or 'x'w, 'x'd is good. Bye, bearophile Or, uniform construction for built-in types would be another better way. auto c = char('a'); auto w = wchar('a'); auto d = dchar('a'); auto x = char('à'); // compile-time error Kenji Hara
Re: dchar literals?
On Tuesday, November 12, 2013 09:14:54 Kenji Hara wrote: > On Monday, 11 November 2013 at 13:20:04 UTC, bearophile wrote: > > Philippe Sigaud: > >> And I agree with you than character literals should default to > >> dchar. It's > >> a perpetual source of friction for me. > > > > 99% of my char literals need to be of type char. > > > > On the other hand once you have suffixes to specify the char > > type, most of that problem vanishes, because writing 'x'c or > > 'x'w, 'x'd is good. > > > > Bye, > > bearophile > > Or, uniform construction for built-in types would be another > better way. > > auto c = char('a'); > auto w = wchar('a'); > auto d = dchar('a'); > > auto x = char('à'); // compile-time error That's more verbose, but it's something that I think we need anyway, and it might be enough to make it not worth adding the suffixes to character literals. - Jonathan M Davis
Re: bidirectional map
On Tuesday, 12 November 2013 at 01:14:47 UTC, bioinfornatics wrote: Dear, I am looking for a bidirectional map i.e http://en.wikipedia.org/wiki/Bidirectional_map My seach into D documentation seem to said to me that this structure is not implemented. Something like (for primary idea): struct BidirectionalMap(T,U){ private: T[U] _forwardHash; U[T] _reverseHash; public: @safe void opIndeyAssign( T k, U v){ // pure? _forwardHash[k] = v; _reverseHash[v] = k; } @property BidirectionalMap!(T,U) dup(){ return BidirectionalMap!(T,U)( this ); } } Maybe we can get a better (faster/lighter) implementation if T==U (using sorted (T,T) tuples?) By the way: map[10] = 5; // => _forwardHash[10] = 5; _reverseHash[5] = 10; map[10] = 3; // => _forwardHash[10] = 3; _reverseHash[3] = 10; So: _reverseHash[5] == 10; // True, it should not, should it?
Re: dchar literals?
Kenji Hara: Or, uniform construction for built-in types would be another better way. auto c = char('a'); auto w = wchar('a'); auto d = dchar('a'); auto x = char('à'); // compile-time error Yes, uniform construction syntax for all types seems a good idea. But the suffixes for chars, as the strings, could be a good idea any way, it's shorter, and it's symmetric with strings. Bye, bearophile
how use lowerBound with just sorting key, not complete values
The following code works for finding the lower bound based on needle. But I have to create a needle which I don't want to do. How can I use lowerBound with just the sortKey, date in this case? So I want to do something like the following - but it won't work. Is there a way to search an array I know is ordered by date by only supplying date? assumeSorted!q{ a.date < b.date }(sarr) .lowerBound(Date(2000,2,1)); Thanks Dan --- import std.stdio; import std.range; import std.datetime; import std.algorithm; import std.array; struct S { Date date; string foo; } void main() { auto sarr = [ S(Date(2000,1,1), "x"), S(Date(2000,2,1), "a"), S(Date(2000,3,1), "foo") ]; assert(sort!q{ a.date < b.date }(sarr).array == sarr); auto needle = S(Date(2000,2,1)); writeln(assumeSorted!q{ a.date < b.date }(sarr) .lowerBound(needle)); writeln(sarr); }
Re: bidirectional map
On Tuesday, 12 November 2013 at 09:10:07 UTC, Andrea Fontana wrote: On Tuesday, 12 November 2013 at 01:14:47 UTC, bioinfornatics wrote: Dear, I am looking for a bidirectional map i.e http://en.wikipedia.org/wiki/Bidirectional_map My seach into D documentation seem to said to me that this structure is not implemented. Something like (for primary idea): struct BidirectionalMap(T,U){ private: T[U] _forwardHash; U[T] _reverseHash; public: @safe void opIndeyAssign( T k, U v){ // pure? _forwardHash[k] = v; _reverseHash[v] = k; } @property BidirectionalMap!(T,U) dup(){ return BidirectionalMap!(T,U)( this ); } } Maybe we can get a better (faster/lighter) implementation if T==U (using sorted (T,T) tuples?) By the way: map[10] = 5; // => _forwardHash[10] = 5; _reverseHash[5] = 10; map[10] = 3; // => _forwardHash[10] = 3; _reverseHash[3] = 10; So: _reverseHash[5] == 10; // True, it should not, should it? Maybe using Variant will allow to use 1 associative array
Re: how use lowerBound with just sorting key, not complete values
Daniel Davidson: Is there a way to search an array I know is ordered by date by only supplying date? You can use a map to perform a projection: import std.stdio, std.range, std.datetime, std.algorithm, std.array; struct S { Date date; string foo; } void main() { auto sarr = [S(Date(2000, 1, 1), "x"), S(Date(2000, 2, 1), "a"), S(Date(2000, 3, 1), "foo")]; assert(sarr.isSorted!q{ a.date < b.date }); auto needle = S(Date(2000, 2, 1)); sarr .assumeSorted!q{ a.date < b.date } .lowerBound(needle) .writeln; sarr.writeln; sarr .map!(s => s.date) .assumeSorted .lowerBound(Date(2000, 2, 1)) .writeln; } Output: [S(2000-Jan-01, "x")] [S(2000-Jan-01, "x"), S(2000-Feb-01, "a"), S(2000-Mar-01, "foo")] [2000-Jan-01] Bye, bearophile
Re: how use lowerBound with just sorting key, not complete values
On Tuesday, 12 November 2013 at 15:51:53 UTC, bearophile wrote: Daniel Davidson: Is there a way to search an array I know is ordered by date by only supplying date? You can use a map to perform a projection: import std.stdio, std.range, std.datetime, std.algorithm, std.array; struct S { Date date; string foo; } void main() { auto sarr = [S(Date(2000, 1, 1), "x"), S(Date(2000, 2, 1), "a"), S(Date(2000, 3, 1), "foo")]; assert(sarr.isSorted!q{ a.date < b.date }); auto needle = S(Date(2000, 2, 1)); sarr .assumeSorted!q{ a.date < b.date } .lowerBound(needle) .writeln; sarr.writeln; sarr .map!(s => s.date) .assumeSorted .lowerBound(Date(2000, 2, 1)) .writeln; } Output: [S(2000-Jan-01, "x")] [S(2000-Jan-01, "x"), S(2000-Feb-01, "a"), S(2000-Mar-01, "foo")] [2000-Jan-01] Bye, bearophile Yes, but that is only giving the dates. I want the actual array elements. Suppose S is a large object with lots of extra fields in addition to `string foo`. There should be a way to pull out the lower bound based on a date without creating a needle (S). Maybe lowerBound is not the right function? Thanks Dan
Re: how use lowerBound with just sorting key, not complete values
Daniel Davidson: Yes, but that is only giving the dates. I want the actual array elements. Suppose S is a large object with lots of extra fields in addition to `string foo`. There should be a way to pull out the lower bound based on a date without creating a needle (S). Maybe lowerBound is not the right function? Second try: import std.stdio, std.range, std.datetime, std.algorithm, std.array, std.typecons; struct S { Date date; string foo; } void main() { auto sarr = [S(Date(2000, 1, 1), "x"), S(Date(2000, 2, 1), "a"), S(Date(2000, 3, 1), "foo")]; assert(sarr.isSorted!q{ a.date < b.date }); sarr.writeln; auto needle = S(Date(2000, 2, 1)); sarr .map!(s => s.date) .zip(sarr.length.iota) .assumeSorted!q{ a[0] < b[0] } .lowerBound(tuple(needle.date, 0)) .map!(p => sarr[p[1]]) .writeln; } Output: [S(2000-Jan-01, "x"), S(2000-Feb-01, "a"), S(2000-Mar-01, "foo")] [S(2000-Jan-01, "x")] Bye, bearophile
Re: how use lowerBound with just sorting key, not complete values
On Tuesday, 12 November 2013 at 16:34:30 UTC, bearophile wrote: Daniel Davidson: Yes, but that is only giving the dates. I want the actual array elements. Suppose S is a large object with lots of extra fields in addition to `string foo`. There should be a way to pull out the lower bound based on a date without creating a needle (S). Maybe lowerBound is not the right function? Second try: import std.stdio, std.range, std.datetime, std.algorithm, std.array, std.typecons; struct S { Date date; string foo; } void main() { auto sarr = [S(Date(2000, 1, 1), "x"), S(Date(2000, 2, 1), "a"), S(Date(2000, 3, 1), "foo")]; assert(sarr.isSorted!q{ a.date < b.date }); sarr.writeln; auto needle = S(Date(2000, 2, 1)); sarr .map!(s => s.date) .zip(sarr.length.iota) .assumeSorted!q{ a[0] < b[0] } .lowerBound(tuple(needle.date, 0)) .map!(p => sarr[p[1]]) .writeln; } Output: [S(2000-Jan-01, "x"), S(2000-Feb-01, "a"), S(2000-Mar-01, "foo")] [S(2000-Jan-01, "x")] Bye, bearophile Well, I think that is it. Thanks, bearophile! Pardon the redirect, but while you are at it, I would appreciate your take on this one (http://forum.dlang.org/post/gofijmqwhfcwgbruz...@forum.dlang.org). I'm sure you'll improve it and teach me a few things on the way ;-) Thanks Dan
Re: Unexpected behavior when misusing inline assembly
Just realized I forgot to delete the 7 and the x from inside the function calls. Question is the same, though. On Tuesday, 12 November 2013 at 18:22:46 UTC, Noah wrote: When running the following code: __gshared void* return_ptr; __gshared void* injected_fn = &fn; void main() { buffer(7); printf("End main\n"); } void buffer() { test(x); printf("End buffer\n"); } void test() { printf("This is a test!\n"); inject(); printf("End of the test!\n"); } void fn() { printf("Hello, world!\n"); asm { mov RAX, return_ptr; mov [RBP+8], RAX; } } void inject() { asm { naked; push RAX; mov RAX, [RBP+8]; mov return_ptr, RAX; mov RAX, injected_fn; mov [RBP+8], RAX; pop RAX; ret; } } The program behaves as expected, that is, the program prints This is a test! End of the test! Hello, world! End buffer End main However, if I call test directly from main, it results in a segfault. If I call inject directly from main, it works. And, oddly, if I add any amount of inline assembler to main, and call test there, it works. Could anyone explain to me what's going on?
Unexpected behavior when misusing inline assembly
When running the following code: __gshared void* return_ptr; __gshared void* injected_fn = &fn; void main() { buffer(7); printf("End main\n"); } void buffer() { test(x); printf("End buffer\n"); } void test() { printf("This is a test!\n"); inject(); printf("End of the test!\n"); } void fn() { printf("Hello, world!\n"); asm { mov RAX, return_ptr; mov [RBP+8], RAX; } } void inject() { asm { naked; push RAX; mov RAX, [RBP+8]; mov return_ptr, RAX; mov RAX, injected_fn; mov [RBP+8], RAX; pop RAX; ret; } } The program behaves as expected, that is, the program prints This is a test! End of the test! Hello, world! End buffer End main However, if I call test directly from main, it results in a segfault. If I call inject directly from main, it works. And, oddly, if I add any amount of inline assembler to main, and call test there, it works. Could anyone explain to me what's going on?
Re: Unexpected behavior when misusing inline assembly
Of course after I post this I realize the answer. The function only works when the surrounding function has at least one argument. Probably has something to do with the way the compiler emits no-argument functions, I'll have to look at some disassembly.
__gshared immutable array of immutable elements
In this declaration (tango.io.Console.d from Tango2): __gshared immutable immutable(char)[] Eol = "\r\n"; Aren't the two `immutable` keywords redundant? Why would `__gshared` be necessary for such an immutable type? Thanks
Re: __gshared immutable array of immutable elements
Dne 12.11.2013 19:49, Nicolas Sicard napsal(a): In this declaration (tango.io.Console.d from Tango2): __gshared immutable immutable(char)[] Eol = "\r\n"; Aren't the two `immutable` keywords redundant? Why would `__gshared` be necessary for such an immutable type? Thanks Hi, this declaration is equal to __gshared immutable string Eol = "\r\n"; Those two immutables are not redundant, because it is an array of immutable chars (string), that is itself immutable. The __gshared should not be necessary, but given some quirks with type system and concurrency, it may be necessary to have it. But this is just a guess from me. Drasha
Object destruction versus finalization
I played around a little and figured out, that destructors in D work quite similarily to destructors in C++. They are invoked, after the members of the instance being destructed have been destroyed themselfes (or at least have been brought into an invalid state). Therefore, these members cannot be accessed savely from inside the destructor. In contrast, Java and C# offer a concept called finalizer. When the finalizer is called, all members of the instance itself are still valid and are guaranteed to be freely accessible. This behaviour can be useful for some cleanup operations. Managed C++ offers both, C#-like finalizers and conventional C++ destructors, where the destructor is called ~className and the finalizer is called !className. Is their a best practice to mimikry this behaviour, i.e. to call a certain block of code when an object is being garbage collected, but before its contents render invalid? Any hints would be greatly appreciated.
Re: __gshared immutable array of immutable elements
On Tuesday, 12 November 2013 at 20:09:57 UTC, Martin Drašar wrote: Those two immutables are not redundant, because it is an array of immutable chars (string), that is itself immutable. It is redundant because "immutable" is transitive. "immutable char[]" is equivalent. But Tango has lot of meaningless and redundant attributes ( "final private" ;) )
Re: Object destruction versus finalization
On Tuesday, 12 November 2013 at 20:15:02 UTC, Florian wrote: I played around a little and figured out, that destructors in D work quite similarily to destructors in C++. They are invoked, after the members of the instance being destructed have been destroyed themselfes (or at least have been brought into an invalid state). Therefore, these members cannot be accessed savely from inside the destructor. What made you think so? It must be other way around. Destructor is expected to release resources held by object, it is necessary that those resources are still valid at destructor call point. It would have been completely against the mode of operations of garbage collector.
opCmp on a struct keyed by an array of bytes
Is there any better way to write the method than: (cmp doesn't seem to work, and byte arrays don't have an opCmp method.) int opCmp(ref const B24 b) const {for(int i = 0;i < 24;i++) {if(bytes[i] < b.bytes[i])return-1; if(bytes[i] > b.bytes[i])return1; } return0; }//opCmp FWIW, the key is a fixed length array of ubyte, but similar structs have differing lengths. If it's not supported by the system I don't want to do something like casting the pieces to ulongs and comparing those rather than the bytes. The added complexity isn't worth it. -- Charles Hixson
Re: opCmp on a struct keyed by an array of bytes
On 11/12/2013 01:06 PM, Charles Hixson wrote: Is there any better way to write the method than: (cmp doesn't seem to work, and byte arrays don't have an opCmp method.) int opCmp(ref const B24 b) const {for(int i = 0;i < 24;i++) {if(bytes[i] < b.bytes[i])return-1; if(bytes[i] > b.bytes[i])return1; } return0; }//opCmp FWIW, the key is a fixed length array of ubyte, but similar structs have differing lengths. If it's not supported by the system I don't want to do something like casting the pieces to ulongs and comparing those rather than the bytes. The added complexity isn't worth it. There is std.algorithm.cmp: import std.algorithm; struct B24 { byte[24] bytes; int opCmp(ref const B24 b) const { return bytes[].cmp(b.bytes[]); } } void main() { auto a = B24(); auto b = B24(); assert(a == b); a.bytes[23] = 1; assert(a > b); b.bytes[22] = 1; assert(b > a); } Ali
Re: [Font] Getting font folder on all platforms
Le 08/11/2013 21:05, Flamaros a écrit : On Tuesday, 15 October 2013 at 23:10:32 UTC, Flamaros wrote: On Friday, 6 September 2013 at 20:54:53 UTC, Flamaros wrote: On Friday, 6 September 2013 at 16:05:43 UTC, Tourist wrote: On Thursday, 5 September 2013 at 19:48:07 UTC, Flamaros wrote: I am searching the right way to find fonts folder for each platforms (Windows, linux, macOS X) On Windows it's generally "C:\Windows\Fonts" but a direct access seems brutal, it's certainly expected to retrieve this path by using some register keys? Is someone know how it works for linux and/or macOS X? I need to be able to retrieve fastest as possible the right file from the font and family name. Windows: call SHGetKnownFolderPath with FOLDERID_Fonts as rfid. http://msdn.microsoft.com/en-us/library/windows/desktop/bb762188%28v=vs.85%29.aspx Nice, thx. Do you know if there is a table of fonts and there family, or need open all font file my self? I need to do some more tests, but scanning the registry seems working under Windows. Here is my test code : stringfontPathFromName(in string name, in Font.Family family = Font.Family.Regular) { version(Windows) { import std.windows.registry; stringfontPath = "C:/Windows/Fonts/"; stringfontFileName; KeyfontKey; fontKey = Registry.localMachine().getKey("Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"); if (family == Font.Family.Regular) fontFileName = fontKey.getValue(name ~ " (TrueType)").value_EXPAND_SZ(); else if (family == Font.Family.Bold) fontFileName = fontKey.getValue(name ~ " Bold (TrueType)").value_EXPAND_SZ(); else if (family == Font.Family.Italic) fontFileName = fontKey.getValue(name ~ " Italic (TrueType)").value_EXPAND_SZ(); else if (family == (Font.Family.Bold | Font.Family.Italic)) fontFileName = fontKey.getValue(name ~ " Bold Italic (TrueType)").value_EXPAND_SZ(); return fontPath ~ fontFileName; } } unittest { assert(fontPathFromName("Arial") == "C:/Windows/Fonts/arial.ttf"); assert(fontPathFromName("arial") == "C:/Windows/Fonts/arial.ttf");// Test with wrong case assert(fontPathFromName("Arial", Font.Family.Bold | Font.Family.Italic) == "C:/Windows/Fonts/arialbi.ttf"); } I did some progress with fontconfig under linux, I'll try to use it for Windows too. I find a way to make it work under Windows. I also bind almost all fontconfig API in a similar way of Derelict. If someone is interested look font.d at : https://github.com/D-Quick/DQuick PS : I took fontconfig dll from GTK packages
Re: Object destruction versus finalization
On Tuesday, 12 November 2013 at 20:29:13 UTC, Dicebot wrote: On Tuesday, 12 November 2013 at 20:15:02 UTC, Florian wrote: I played around a little and figured out, that destructors in D work quite similarily to destructors in C++. They are invoked, after the members of the instance being destructed have been destroyed themselfes (or at least have been brought into an invalid state). Therefore, these members cannot be accessed savely from inside the destructor. What made you think so? It must be other way around. Destructor is expected to release resources held by object, it is necessary that those resources are still valid at destructor call point. It would have been completely against the mode of operations of garbage collector. Let me explain this by discussing the example below. I created method stubs, which write single lines to the console, so it is quite easy to follow the control flow. The main method creates an instance of a type "Session", which itself has a member of type "Connection". Let us assume, that I want to properly shutdown the "Connection" instance by invoking its methods, when the "Session" is torn down. The example below prints the following output: ~Connection ~Session segmentation fault This means, the destructor of "Connection" is invoked *BEFORE* the destructor of "Session" is called. This yields to an invalid reference for the call of the shutdown() method, leading to the segmentation fault. Of course, in a scenario as simple as that, it would be possible to move the shutdown() sequence into the destructor of the "Connection" class. However, doing so is not desirable. Just picture, that we want to set some timeout parameters or the like for the shutdown depending on the state of the "Session". This would become really messy. And be assured, I have a more complex scenario, where I definitely want to invoke methods on memeber instances when an instance is destroyed. I am convinced there is a reason for finalizing objects like Java, C# and managed C++ do. Example: import std.stdio; class Connection { this() { } void shutdown() { writeln("shutdown"); } ~this() { writeln("~Connection"); } } class Session { Connection connection; this() { connection = new Connection(); } ~this() { writeln("~Session"); connection.shutdown(); // -> segmentation fault } } void main() { auto session = new Session(); }
Re: __gshared immutable array of immutable elements
On Tuesday, 12 November 2013 at 20:16:31 UTC, Dicebot wrote: On Tuesday, 12 November 2013 at 20:09:57 UTC, Martin Drašar wrote: Those two immutables are not redundant, because it is an array of immutable chars (string), that is itself immutable. It is redundant because "immutable" is transitive. "immutable char[]" is equivalent. But Tango has lot of meaningless and redundant attributes ( "final private" ;) ) That´s what I thought. So no hidden subtlety here, just hyperprotection :) Thanks
Re: opCmp on a struct keyed by an array of bytes
Ali Çehreli: int opCmp(ref const B24 b) const { return bytes[].cmp(b.bytes[]); Few months ago I have written a small rant about that. That little [] at the end of those arrays is not innocuous, it essentially throws away a very precious compile-time amount of information: the static length of the arrays. So for the compiler it becomes much harder to optimize those loops. In my opinion this is an unacceptable part of the design of Phobos (mostly std.algorithm). Bye, bearophile
Re: Object destruction versus finalization
On Tuesday, November 12, 2013 23:40:24 Florian wrote: > it would be possible to move the shutdown() sequence into the > destructor of the "Connection" class. Classes in D do not have destructors. Only structs to. ~this is a destructor in a struct, but it's a finalizer in a class. Finalizers are not guaranteed to be run, and they can't do anything with GC memory (be it allocating it, deallocating it, or using it) unless they're begging for trouble, because the GC is free to collect any GC-allocated objects before calling any finalizers (which avoids circular reference problems). As such, class finalizers are really only good for managing non-GC resources. - Jonathan M Davis
Re: Object destruction versus finalization
I understood very well, that the garbage collector is not guaranteed to run. However, it does not explain the segmentation fault in my example, does it?
Re: Object destruction versus finalization
On Wednesday, November 13, 2013 00:07:12 Florian wrote: > I understood very well, that the garbage collector is not > guaranteed to run. However, it does not explain the segmentation > fault in my example, does it? You're getting a segfault, because you're using something which is on the GC heap - namely the Connection that you allocated with new. You can't do that in finalizer, because the GC can choose to free it before the finalizer even runs (this avoids issues with circular references). You can only access stuff in the finalizer which is part of the class (and not on the GC heap aside from the fact that the instance of the class is itself on the GC heap) or which is not managed by the GC at all (e.g. it was malloced, or it was some other sort of system resource that the GC doesn't manage). If you want your Connection object to shutdown when it's collected, you're going to need to do that in its own finalizer, not in the finalizer of a class that's using it. - Jonathan M Davis
Re: Object destruction versus finalization
On Tuesday, 12 November 2013 at 23:18:11 UTC, Jonathan M Davis wrote: You can't do that in finalizer, because the GC can choose to free it before the finalizer even runs (this avoids issues with circular references). Ah, damn, have forgotten about it. Disregard previous post.
Re: Object destruction versus finalization
On Tuesday, 12 November 2013 at 22:40:26 UTC, Florian wrote: The example below prints the following output: ~Connection ~Session segmentation fault Same example prints this for me (no segfault): ~Session shutdown ~Connection 2.064.2 @ linux-64 What is your system / compiler? Output does not seem right at all.
Re: Odd compiler complaints with import declarations
See also http://d.puremagic.com/issues/show_bug.cgi?id=11451
Re: opCmp on a struct keyed by an array of bytes
On 11/12/2013 01:38 PM, Ali Çehreli wrote: On 11/12/2013 01:06 PM, Charles Hixson wrote: Is there any better way to write the method than: (cmp doesn't seem to work, and byte arrays don't have an opCmp method.) int opCmp(ref const B24 b) const {for(int i = 0;i < 24;i++) {if(bytes[i] < b.bytes[i])return-1; if(bytes[i] > b.bytes[i])return1; } return0; }//opCmp FWIW, the key is a fixed length array of ubyte, but similar structs have differing lengths. If it's not supported by the system I don't want to do something like casting the pieces to ulongs and comparing those rather than the bytes. The added complexity isn't worth it. There is std.algorithm.cmp: import std.algorithm; struct B24 { byte[24] bytes; int opCmp(ref const B24 b) const { return bytes[].cmp(b.bytes[]); } } void main() { auto a = B24(); auto b = B24(); assert(a == b); a.bytes[23] = 1; assert(a > b); b.bytes[22] = 1; assert(b > a); } Ali Thank you. That's exactly the answer I was looking for. ( I had tried "return bytes.cmp(b.bytes);" , but it didn't occur to me that the error meant I should have used a copy? Does this syntax mean that what's being compared is a dynamic array copy of the original static array? Even if it is, that's the answer I wanted. -- Charles Hixson
Re: opCmp on a struct keyed by an array of bytes
Charles Hixson: I had tried "return bytes.cmp(b.bytes);" , but it didn't occur to me that the error meant I should have used a copy? Does this syntax mean that what's being compared is a dynamic array copy of the original static array? They are not copies, just slices. In case of doubts take a look at the generated assembly. Bye, bearophile
Re: bidirectional map
On 11/11/2013 05:14 PM, bioinfornatics wrote: Dear, I am looking for a bidirectional map i.e http://en.wikipedia.org/wiki/Bidirectional_map My seach into D documentation seem to said to me that this structure is not implemented. Something like (for primary idea): struct BidirectionalMap(T,U){ private: T[U] _forwardHash; U[T] _reverseHash; public: @safe void opIndeyAssign( T k, U v){ // pure? _forwardHash[k] = v; _reverseHash[v] = k; } @property BidirectionalMap!(T,U) dup(){ return BidirectionalMap!(T,U)( this ); } } you could build one using multi_index. https://bitbucket.org/ariovistus/multi_index at least, that is how boost::bimap was done. I always assumed it would be trivial in D, but I haven't tried doing it. Something like alias MultiIndexContainer!(Tuple!(T,"t",U,"u"), IndexedBy!(HashedUnique!("a.t"), HashedUnique!("a.u"))) BiMap; and then wrap as you see fit.
Re: Simple immutable example doesn't work - why???
Thanks to both TFF and Kenji for their excellent explanations. I think my head is going to explode ;). So, as I understand it, there are two sorts of immutable entities in D. The first is probably the one most familiar to the majority of us, which is an entity with immutable contents but with mutable binding. This is what TFF illustrated so well in his post above and what we are all familiar with as "string". The second will take me longer to get used to, which is an entity with immutable contents *and* with immutable binding. This is what I tripped over in my example and what Kenji adroitly showed how to deal with in his post. Does this correctly sum up what I have read? If so, this conversation has cleared up a great deal of my misunderstanding of how "immutable" works. It would be great to see the above examples in a D reference or tutorial (maybe the second edition of Andrei's book?). Many thanks.
cannot infer argument types
Hi, I have this error message ( i.e title ) and i do not see where i am wrong: this( in ubyte wordLength, in string sequence ){ kMer = wordLength; bytePerChar = cast(ubyte)(T.sizeof / kMer); char[ubyte] toCharTmp; ubyte[char] toNumTmp; foreach( ubyte i, const char letter; sequence.dup.sort.uniq() ){ if(i !in toCharTmp) toCharTmp[ i ] = letter; toNumTmp[ letter ] = i; } toChar = toCharTmp.rehash; toNum = toNumTmp.rehash; } Error is given at I have removed explicit type on this line… but I have always same error!
Re: cannot infer argument types
On Wednesday, November 13, 2013 03:43:40 bioinfornatics wrote: > Hi, > > I have this error message ( i.e title ) and i do not see where i > am wrong: > > > this( in ubyte wordLength, in string sequence ){ > kMer = wordLength; > bytePerChar = cast(ubyte)(T.sizeof / kMer); > > char[ubyte] toCharTmp; > ubyte[char] toNumTmp; > foreach( ubyte i, const char letter; > sequence.dup.sort.uniq() ){ > if(i !in toCharTmp) > toCharTmp[ i ] = letter; > toNumTmp[ letter ] = i; > } > toChar = toCharTmp.rehash; > toNum = toNumTmp.rehash; > } > > Error is given at > > I have removed explicit type on this line… but I have always same > error! You have two variables to the left to the ; in the foreach. If you were iterating over an array, then the first one would be the index, and the second one would be the element. However, the result of sequence.dup.sort.uniq() is a range that is _not_ an array, and foreach does not support an index for ranges. You can fake it with lockstep if you want, since it does something with tuples to make it so that you get multiple elements on the left-hand side of the semicolon. http://dlang.org/phobos/std_range.html#lockstep In addition, I would point out that sequence.dup.sort is using the built-in sort for arrays rather than std.algorithm.sort (you have to have the parens when calling sort on array, or it'll use the built-in one), and the built-in sort for arrays is not only buggy, but it's going to be deprecated, so I wouldn't advise using it. And yes, the means that you'll have to have a random-access range, meaning that you'll need to convert your string to dchar[], but at least then you'll get a sort that works and isn't going to be removed from the language (IIRC, the built-in sort doesn't sort Unicode properly anyway). If you know that you only have ASCII characters, then you can use ubyte[] instead, but char[] isn't going to work, since it's not a random-access range. - Jonathan M Davis
ddoc - modules with same name
Let's suppose I have a module structure: - package.module1.core - package.module2.core Building documentation with dmd will generate a sigle core.html file with content related only to package.module2.core, overwriting the first one. Is there any way that dmd can recreate directory structure for documentation, obtaining two files: package\module1\core.html and package\module2\core.html?