Re: std.conv - custom string to struct conversion ?
On Friday, 2 August 2013 at 05:09:14 UTC, Jonathan M Davis wrote: On Friday, August 02, 2013 06:50:01 Douglas Petterson wrote: Is there a way to convert a string to a struct, similarly to the conversion of a struct to a custom string representation ? The following code works fine when using format("%s",C) or to!string(C): struct sCustomConv { string toString() { return "My custom representation"; } } sCustomConv C; string MyBackup = to!string(C); But I can't find which class operator must be overloaded (or more simply how-to) to make this possible: C = to!sCustomConv(MyBackup); http://stackoverflow.com/questions/8351245/override-tot-for-used-defined-t-in-d - Jonathan M Davis There was a request for enhancement to provide a "fromString" for arbitrary types. The idea is that once we have that, then functions such as parse or to!S(string) will be generic, and work on mostly anything. Unfortunatly, (AFAIK), nobody is working on this. Here is a discussion I opened: http://forum.dlang.org/thread/gzodptjyzpqnhxctb...@forum.dlang.org ...and I just noticed it ends with me saying "I'll try to write a DIP then :)" and then not doing it :/
Re: std.conv - custom string to struct conversion ?
On Friday, August 02, 2013 06:50:01 Douglas Petterson wrote: > Is there a way to convert a string to a struct, similarly to the > conversion of a struct to a custom string representation ? > > The following code works fine when using format("%s",C) or > to!string(C): > > struct sCustomConv > { > string toString() > { > return "My custom representation"; > } > } > > sCustomConv C; > string MyBackup = to!string(C); > > But I can't find which class operator must be overloaded (or more > simply how-to) to make this possible: > > C = to!sCustomConv(MyBackup); http://stackoverflow.com/questions/8351245/override-tot-for-used-defined-t-in-d - Jonathan M Davis
std.conv - custom string to struct conversion ?
Is there a way to convert a string to a struct, similarly to the conversion of a struct to a custom string representation ? The following code works fine when using format("%s",C) or to!string(C): struct sCustomConv { string toString() { return "My custom representation"; } } sCustomConv C; string MyBackup = to!string(C); But I can't find which class operator must be overloaded (or more simply how-to) to make this possible: C = to!sCustomConv(MyBackup); Thx.
Re: casts / wildcards for parametrized types
On 08/01/2013 05:40 PM, tx wrote: > Thanks for the reply Ali. Everything you wrote makes sense, but I > think I may have oversimplified the problem in my original email. In > general I don't care about what T is when working with Box (or > ConcreteBox as it were), but I do care that Box contains a T. Consider > this rather contrived example (I'm aware that it's a poorly written > function, it just captures my issue.): > > bool truthy(Item a, Item b){ >if(cast(LongBox) a && cast(LongBox) b){ > return (cast(LongBox) a).value && (cast(LongBox) a).value; >} else if(cast(CharBox) a && cast(CharBox) b){ > return (cast(CharBox) a).value && (cast(CharBox) a).value; >} else { > return !(a is null || b is null); >} > } > > I would much rather write something like: > > bool truthy(Item a, Item b){ >if(cast(Box) a && cast(Box) b){ > return (cast(Box) a).value && (cast(Box) a).value; >} else { > return !(a is null || b is null); >} > } > > To be more explicit: By the time I'm writing these if-else/cast > statements I already know that my objects are both instances of some > type of Box and I also know that the operation(s) I plan to perform on > them are valid for any T that box can contain. Pretty complicated semantics. Something must be wrong there. ;) Here is a solution that shares the solution between a member function and a non-member function. The member returns a three-value enum: class Item{} enum Truthy { nonzero_values, has_zero_value, mismatched_type } class Box(T) : Item { T value; // ... this(T value) { this.value = value; } Truthy truthy_(U)(Box!U b) { auto rhs = cast(Box!T)b; if (!rhs) { return Truthy.mismatched_type; } return value && rhs.value ? Truthy.nonzero_values : Truthy.has_zero_value; } } alias Box!(long) LongBox; alias Box!(char) CharBox; //etc. bool truthy(T0, T1)(Box!T0 lhs, Box!T1 rhs) { if (lhs !is null) { final switch (lhs.truthy_(rhs)) with (Truthy) { case mismatched_type: return rhs !is null; case has_zero_value: return false; case nonzero_values: return true; } } return false; } unittest { auto l0 = new LongBox(0); auto l1 = new LongBox(1); LongBox ln = null; auto c0 = new CharBox(0); auto c1 = new CharBox('a'); CharBox cn = null; // Same types assert(!truthy(l0, l0)); assert(!truthy(l0, l1)); assert( truthy(l1, l1)); assert(!truthy(ln, l0)); assert(!truthy(l1, ln)); assert(!truthy(ln, ln)); assert(!truthy(c0, c0)); assert(!truthy(c0, c1)); assert( truthy(c1, c1)); assert(!truthy(cn, c0)); assert(!truthy(c1, cn)); assert(!truthy(cn, cn)); // Mixed types assert( truthy(c0, l1));// mismatched but both are non-null assert( truthy(l0, c1)); assert( truthy(c1, l1)); assert( truthy(l1, c1)); assert(!truthy(cn, l0));// mismatched but one is null assert(!truthy(c1, ln)); } void main() {} Ali
Re: casts / wildcards for parametrized types
Thanks for the reply Ali. Everything you wrote makes sense, but I think I may have oversimplified the problem in my original email. In general I don't care about what T is when working with Box (or ConcreteBox as it were), but I do care that Box contains a T. Consider this rather contrived example (I'm aware that it's a poorly written function, it just captures my issue.): bool truthy(Item a, Item b){ if(cast(LongBox) a && cast(LongBox) b){ return (cast(LongBox) a).value && (cast(LongBox) a).value; } else if(cast(CharBox) a && cast(CharBox) b){ return (cast(CharBox) a).value && (cast(CharBox) a).value; } else { return !(a is null || b is null); } } I would much rather write something like: bool truthy(Item a, Item b){ if(cast(Box) a && cast(Box) b){ return (cast(Box) a).value && (cast(Box) a).value; } else { return !(a is null || b is null); } } To be more explicit: By the time I'm writing these if-else/cast statements I already know that my objects are both instances of some type of Box and I also know that the operation(s) I plan to perform on them are valid for any T that box can contain. -tx -- tx.lowtech-labs.org / t...@lowtech-labs.org On Thu, Aug 1, 2013 at 5:06 PM, Ali Çehreli wrote: > On 08/01/2013 04:28 PM, tx wrote: > >> Hi All, >> Hoping somebody can provide some help here, I have a set of classes >> that are similar to the following >> >> class Item{} >> >> class Box(T) : Item { >>T value; >>// ... >> } >> >> //Along with some aliases: >> >> alias Box!(long) LongBox; >> alias Box!(char) CharBox; >> //etc. >> >> >> >> I'd like to have a function that operates on instances of Item, but I >> want to specialize the behavior to handle instances of Box >> differently. Is there anyway I can upcast Item to Box without >> specifying the type parameter? In my case I don't really care about >> what T is, just that I'm working with a Box of something. Currently I >> have a whole if-else ladder checking to see if I'm working with an >> instance of each of the aliases and casting appropriately, but I would >> prefer to just write that once. I guess I'm looking for something like >> cast(Box). Is this possible? >> >> To put it another way, is there a D equivalent to the Java syntax of >> Box > > Inserting another layer to the hierarchy is a solution. ConcreteBox is the > same as your Box and the new Box in a non-template intermediate class: > > class Item{} > > class Box : Item{} > > class ConcreteBox(T) : Box { > T value; > // ... > } > > alias ConcreteBox!(long) LongBox; > alias ConcreteBox!(char) CharBox; > //etc. > > // Explicit check > int foo(Item item) > { > if (cast(Box)item) { > return 1; > } > > return 0; > } > > unittest > { > assert(foo(new Item()) == 0); > assert(foo(new LongBox()) == 1); > assert(foo(new CharBox()) == 1); > } > > // Automatic dispatch for compile-time binding > class Foo > { > int foo(Item item) > { > return 0; > } > > int foo(Box box) > { > return 1; > } > } > > unittest > { > auto f = new Foo(); > assert(f.foo(new Item()) == 0); > assert(f.foo(new LongBox()) == 1); > assert(foo(new CharBox()) == 1); > } > > void main() > {} > > Ali >
Get attributes of type by string name
how can I get the UDA's of a type that I only know by name and only in a CTFE. I would like to loop over an array of names passed to a me(I don't know their contents beforehand) and get the attributes. I've tried to use a mixin but I can't get the mixin to work on the string name... e.g., mixin("alias a = __traits(getAttributes, "~type~");");
Re: casts / wildcards for parametrized types
On Friday, 2 August 2013 at 00:44:21 UTC, Meta wrote: One more way, not necessarily a workaround but a little trick that doesn't require you to know the exact type of box, is to use typeof(box). auto box = Box!int(); auto item = cast(Item)box; auto box2 = cast(typeof(box)); Whoops, make that last line: auto box2 = cast(typeof(box))item;
Re: casts / wildcards for parametrized types
One more way, not necessarily a workaround but a little trick that doesn't require you to know the exact type of box, is to use typeof(box). auto box = Box!int(); auto item = cast(Item)box; auto box2 = cast(typeof(box));
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 23:15:47 UTC, Dicebot wrote: On Thursday, 1 August 2013 at 22:59:14 UTC, Dicebot wrote: ... To further clarify this, I have used your simplified example: And in case someone thinks template functions are treated any differently, "string generator(T)(T a)" acts exactly the same.
Re: casts / wildcards for parametrized types
On 08/01/2013 04:28 PM, tx wrote: > Hi All, > Hoping somebody can provide some help here, I have a set of classes > that are similar to the following > > class Item{} > > class Box(T) : Item { >T value; >// ... > } > > //Along with some aliases: > > alias Box!(long) LongBox; > alias Box!(char) CharBox; > //etc. > > > > I'd like to have a function that operates on instances of Item, but I > want to specialize the behavior to handle instances of Box > differently. Is there anyway I can upcast Item to Box without > specifying the type parameter? In my case I don't really care about > what T is, just that I'm working with a Box of something. Currently I > have a whole if-else ladder checking to see if I'm working with an > instance of each of the aliases and casting appropriately, but I would > prefer to just write that once. I guess I'm looking for something like > cast(Box). Is this possible? > > To put it another way, is there a D equivalent to the Java syntax of Box Inserting another layer to the hierarchy is a solution. ConcreteBox is the same as your Box and the new Box in a non-template intermediate class: class Item{} class Box : Item{} class ConcreteBox(T) : Box { T value; // ... } alias ConcreteBox!(long) LongBox; alias ConcreteBox!(char) CharBox; //etc. // Explicit check int foo(Item item) { if (cast(Box)item) { return 1; } return 0; } unittest { assert(foo(new Item()) == 0); assert(foo(new LongBox()) == 1); assert(foo(new CharBox()) == 1); } // Automatic dispatch for compile-time binding class Foo { int foo(Item item) { return 0; } int foo(Box box) { return 1; } } unittest { auto f = new Foo(); assert(f.foo(new Item()) == 0); assert(f.foo(new LongBox()) == 1); assert(foo(new CharBox()) == 1); } void main() {} Ali
Re: Homework help, guys!
On Thursday, 1 August 2013 at 23:48:33 UTC, Timon Gehr wrote: On 08/02/2013 01:34 AM, hunt wrote: Hello, guys. It is weird to ask about my homework here, but I haven't gotten a proper answer yet. It's about D feature...maybe.. http://dpaste.dzfl.pl/905d6ad7 Question is that "Investigate how D allows you to defend your definition of Map so that it may be used only with a type of key that is comparable, and place this defense in your solution." Please leave your comments here. Thank you so much. This should get you started: http://dlang.org/concepts.html http://dlang.org/traits.html#compiles Also, say hello to the most esoteric expression I can think of: D's "is" expression http://dlang.org/expression.html#IsExpression
Re: Homework help, guys!
On 08/02/2013 01:34 AM, hunt wrote: Hello, guys. It is weird to ask about my homework here, but I haven't gotten a proper answer yet. It's about D feature...maybe.. http://dpaste.dzfl.pl/905d6ad7 Question is that "Investigate how D allows you to defend your definition of Map so that it may be used only with a type of key that is comparable, and place this defense in your solution." Please leave your comments here. Thank you so much. This should get you started: http://dlang.org/concepts.html http://dlang.org/traits.html#compiles
casts / wildcards for parametrized types
Hi All, Hoping somebody can provide some help here, I have a set of classes that are similar to the following class Item{} class Box(T) : Item { T value; // ... } //Along with some aliases: alias Box!(long) LongBox; alias Box!(char) CharBox; //etc. I'd like to have a function that operates on instances of Item, but I want to specialize the behavior to handle instances of Box differently. Is there anyway I can upcast Item to Box without specifying the type parameter? In my case I don't really care about what T is, just that I'm working with a Box of something. Currently I have a whole if-else ladder checking to see if I'm working with an instance of each of the aliases and casting appropriately, but I would prefer to just write that once. I guess I'm looking for something like cast(Box). Is this possible? To put it another way, is there a D equivalent to the Java syntax of Box -tx -- tx.lowtech-labs.org / t...@lowtech-labs.org
Homework help, guys!
Hello, guys. It is weird to ask about my homework here, but I haven't gotten a proper answer yet. It's about D feature...maybe.. http://dpaste.dzfl.pl/905d6ad7 Question is that "Investigate how D allows you to defend your definition of Map so that it may be used only with a type of key that is comparable, and place this defense in your solution." Please leave your comments here. Thank you so much.
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 22:59:14 UTC, Dicebot wrote: ... To further clarify this, I have used your simplified example: - // test.d string generator(int x) { if (x > 0) { asm { mov EAX, 0xDEAD; } } return "return 42;"; } int main() { mixin(generator(0)); } - $ dmd -release -inline -O test.d - $ objdump -d test | grep dead 417705: b8 ad de 00 00 mov$0xdead,%eax
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 22:42:11 UTC, JS wrote: I don't know why it is so damn confusing... I didn't say templates, I SAID string mixins of templates. Symbol emitting does not go that way. Object files are old school entities from C times. They have function symbol and type symbols. Templates, mixins - does not matter. If function is used - it goes to object file. If struct definition gets generated - same story. In the world of linker there are no things such as templates or anything like that.
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 22:26:06 UTC, Dicebot wrote: On Thursday, 1 August 2013 at 22:04:57 UTC, JS wrote: IS A GOING TO BE IN THE BINARY?!?!?! Yes, I'm yelling... just to get the point across about the question I'm trying to get answered. HOW MANY TIMES I NEED TO ANSWER YOUR QUESTION FOR YOU TO NOTICE? Yes. UM, NO, BECAUSE YOU ARE NOT ANSWERING MY QUESTION! I don't know why it is so damn confusing... I didn't say templates, I SAID string mixins of templates. I did a test http://dpaste.dzfl.pl/d8e6ca2a http://dpaste.dzfl.pl/a43b923c What is weird, on my comp, the file sizes are exactly the same, searching for the string only shows up in the one with the template call. So It seems the dmd does not add code for string mixins(even though the function is called, it is smart enough not to add it to the binary)... unless it is somehow encrypting the template(again, I would expect the file size to be smaller... unless it does some type of alignment/padding).
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 22:13:25 UTC, John Colvin wrote: On Thursday, 1 August 2013 at 22:04:57 UTC, JS wrote: IS A GOING TO BE IN THE BINARY?!?!?! Why don't you try it and see? Disassemble the object file or get your linker of choice to print out some info. I don't have any of the tools to do so at the moment. The point was to see if anyone actually knew this specifically or was just guessing on what should be... I guess I have my answer(e.g., find out yourself = I don't know).
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 22:04:57 UTC, JS wrote: IS A GOING TO BE IN THE BINARY?!?!?! Yes, I'm yelling... just to get the point across about the question I'm trying to get answered. HOW MANY TIMES I NEED TO ANSWER YOUR QUESTION FOR YOU TO NOTICE? Yes.
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 22:04:57 UTC, JS wrote: IS A GOING TO BE IN THE BINARY?!?!?! Why don't you try it and see? Disassemble the object file or get your linker of choice to print out some info.
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 21:17:34 UTC, H. S. Teoh wrote: On Thu, Aug 01, 2013 at 10:06:54PM +0200, JS wrote: [...] Now are you telling me that template A() { void foo() { writeln("asdf"); } } void main() { A!().foo(); } does not create a function foo in the binary? That it is equivalent to just calling writeln("asdf"); directly? (exact same code) [...] I said that every instantiation of a template creates a copy of everything inside. Therefore, A!().foo() will create a copy of A.foo() in the binary. The template itself has no binary representation, in the sense that if you write: template A(int x) { void foo() { writeln(x); } } there is nothing in the binary corresponding with the template A, or the uninstantiated function foo. But if you instantiate A with some value of x, then you will get a copy of A.foo for every value of x that you instantiate the template with. So if you write: A!1.foo(); A!2.foo(); A!3.foo(); Then you will get 3 copies of foo() in your executable, one for each value of x. yes, I understand that... now use a template for a string mixin! template A() { string A() { ... } } ... mixin(A()); IS A GOING TO BE IN THE BINARY?!?!?! Yes, I'm yelling... just to get the point across about the question I'm trying to get answered. the function A is never used at runtime SO it should technically not be in the binary UNLESS dmd treats it as a normal template function then it will(but shouldn't)! e.g., if the compiler smart enough to realize that A(); is different from mixin(A()); (one being compile time and the other not)
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 21:38:15 UTC, Tofu Ninja wrote: This scares me, it seems to me that the unused import should not be compiled in. And I frequently hear people talk about the linker removing unused code, but this proves that it doesn't or at least not all. It does not. People talk about this because it seems reasonable. But reality differs a lot. No need to ask - just go an check.
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 20:06:56 UTC, JS wrote: the binary file is is 150kB. If I add import std.stdio; It jumps to 300kB. This scares me, it seems to me that the unused import should not be compiled in. And I frequently hear people talk about the linker removing unused code, but this proves that it doesn't or at least not all. I wonder if this is a matter of something that is possible but just not implemented properly(or at all, i don't know) in the linker, or if their is some reason that makes this not possible.
Re: are mixin string templates with functions removed?
On Thu, Aug 01, 2013 at 10:06:54PM +0200, JS wrote: [...] > Now are you telling me that > > template A() > { > void foo() { writeln("asdf"); } > } > void main() > { > A!().foo(); > } > > does not create a function foo in the binary? That it is equivalent > to just calling writeln("asdf"); directly? (exact same code) [...] I said that every instantiation of a template creates a copy of everything inside. Therefore, A!().foo() will create a copy of A.foo() in the binary. The template itself has no binary representation, in the sense that if you write: template A(int x) { void foo() { writeln(x); } } there is nothing in the binary corresponding with the template A, or the uninstantiated function foo. But if you instantiate A with some value of x, then you will get a copy of A.foo for every value of x that you instantiate the template with. So if you write: A!1.foo(); A!2.foo(); A!3.foo(); Then you will get 3 copies of foo() in your executable, one for each value of x. T -- What do you get if you drop a piano down a mineshaft? A flat minor.
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 18:09:54 UTC, H. S. Teoh wrote: On Thu, Aug 01, 2013 at 07:52:28PM +0200, JS wrote: On Thursday, 1 August 2013 at 17:47:00 UTC, H. S. Teoh wrote: >On Thu, Aug 01, 2013 at 07:12:51PM +0200, John Colvin wrote: >>On Thursday, 1 August 2013 at 17:09:07 UTC, JS wrote: >>>If I have a bunch of templates that are only used for code >>>generation, are they removed in the binary(since they are >>>not >>>needed)? >> >>templates don't exist in binaries. > >Templates are like cookie molds, you use them to generate >lots of >(almost) identical cookies, but you never serve the mold to >the >customer. ;-) > > >T But what about the functions that exist in them? Like I said, cookie molds. You use the mold to press cookies, but only the cookies are served, not the mold. The mold may be very complicated, containing subcookies attached to bigger cookies, but whatever is pressed (i.e., instantiated) is what's served on the dinner plate. The mold always remains in the kitchen. template A() { void A() { B(); } void B() { } } is everything in the template removed 100% or is there junk that the compiler doesn't remove? There is nothing to remove. If you instantiated the template, then you get a copy of everything in it. The number of copies equals the number of distinct instantiations. The template itself is just a mold, an abstract entity that doesn't exist in binary form. What it does is to serve as a mold (hence, "template") to make code. So if you use to make 10 copies of the code, that's what you'll get in your executable. If your template contains 5 functions, then each instantiation produces 5 copies of those functions. Simple as that. Of course, not all code produces binary data -- enum and alias definitions don't produce any binary code, for example -- they're just logical entities that only exist at compile time. So if you have an enum inside a template, it will get copied however many times you instantiate the template, but none of those copies end up in the executable because they're just declarations, not actual code or data. Ok, I'm not talking about the template itself but what is contained in the template. It is obvious that templates can "insert" stuff into the binary. a mixin template can easily do that. Now are you telling me that template A() { void foo() { writeln("asdf"); } } void main() { A!().foo(); } does not create a function foo in the binary? That it is equivalent to just calling writeln("asdf"); directly? (exact same code) e.g., it is the same as void main() { A!().foo(); } cause when I actually debug I see a function call to foo. So, saying that templates are like cookie cutter doesn't prove anything. If I have void main() { } the binary file is is 150kB. If I add import std.stdio; It jumps to 300kB. So the linker and compiler are not removing all untouched code.
Re: What would be the best way to compile a project with GDC?
On Thursday, 1 August 2013 at 17:46:07 UTC, Gary Willoughby wrote: There must be a simpler way to pass these files to dmd in the right order? rdmd does it somehow. You do know that you can use GDC with rdmd? `rdmd --compiler=gdmd` afair. Anyway, rdmd does it my checking dmd verbose output that lists all imports, as well as most other D build systems I am aware of.
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 18:09:54 UTC, H. S. Teoh wrote: See for yourself: run a disassembler on the result (preferably filtered through ddemangle so the symbols are actually readable) and see what's included and what's not. On Posix, you can use objdump or nm (if you use nm, though, keep in mind that not all symbols correspond with actual code/data, but they do take up a little space in the executable -- at least enough to store their names). Done it, see my previous comment here. I do have an idea how to fix it, but wasn't able to get though dmd code so far :(
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 17:53:38 UTC, Ali Çehreli wrote: I think the question is whether the instantiations of such templates are removed. If the instance is used only to initialize an enum, the function shouldn't stay in the binary. Even if the function remains, I think the linker takes care of removing unused functions. Ali Unfortunately, you are wrong. No symbol optimization is done by DMD is linker can't figure this out on its own, it requires specific object file layout to do reference counting for symbols. It is really easy to check - make template function with some anchor value inside (OXDEADBEEF) and compile it with this template used exclusively in constraints or CTFE. Then strip and objdump - you'll find anchors in resulting binary for every instantiation.
Re: What would be the best way to compile a project with GDC?
Am Thu, 01 Aug 2013 19:46:05 +0200 schrieb "Gary Willoughby" : > I've just finished a project in D and have been using rdmd to > compile during testing. While this is nice, i now want to try > other compilers to see if i get any speed gains. > > Because i use rdmd it takes care of passing everything to dmd. > Now i want to try GDC and i need to pass the files in the correct > order for compilation. I've first tried to write a bash script > with all the files listed correctly and passed all the necessary > flags to dmd but i can never get the order of the files correct. > > There must be a simpler way to pass these files to dmd in the > right order? rdmd does it somehow. > > Any ideas? How do you handle compiling projects with 50+ source > files? Doesn't rdmd have a verbose flag or something to dump the executed commands? Then you could just copy and paste it from there. You could also try to make rdmd work with gdc but I think there was some problem with rdmd and gdc.
Re: are mixin string templates with functions removed?
On Thu, Aug 01, 2013 at 07:52:28PM +0200, JS wrote: > On Thursday, 1 August 2013 at 17:47:00 UTC, H. S. Teoh wrote: > >On Thu, Aug 01, 2013 at 07:12:51PM +0200, John Colvin wrote: > >>On Thursday, 1 August 2013 at 17:09:07 UTC, JS wrote: > >>>If I have a bunch of templates that are only used for code > >>>generation, are they removed in the binary(since they are not > >>>needed)? > >> > >>templates don't exist in binaries. > > > >Templates are like cookie molds, you use them to generate lots of > >(almost) identical cookies, but you never serve the mold to the > >customer. ;-) > > > > > >T > > But what about the functions that exist in them? Like I said, cookie molds. You use the mold to press cookies, but only the cookies are served, not the mold. The mold may be very complicated, containing subcookies attached to bigger cookies, but whatever is pressed (i.e., instantiated) is what's served on the dinner plate. The mold always remains in the kitchen. > template A() > { > void A() > { > B(); > } > void B() { } > } > > is everything in the template removed 100% or is there junk that the > compiler doesn't remove? There is nothing to remove. If you instantiated the template, then you get a copy of everything in it. The number of copies equals the number of distinct instantiations. The template itself is just a mold, an abstract entity that doesn't exist in binary form. What it does is to serve as a mold (hence, "template") to make code. So if you use to make 10 copies of the code, that's what you'll get in your executable. If your template contains 5 functions, then each instantiation produces 5 copies of those functions. Simple as that. Of course, not all code produces binary data -- enum and alias definitions don't produce any binary code, for example -- they're just logical entities that only exist at compile time. So if you have an enum inside a template, it will get copied however many times you instantiate the template, but none of those copies end up in the executable because they're just declarations, not actual code or data. > Oh... and I'm not talking about theoretical... I'm talking about > what dmd actually does. See for yourself: run a disassembler on the result (preferably filtered through ddemangle so the symbols are actually readable) and see what's included and what's not. On Posix, you can use objdump or nm (if you use nm, though, keep in mind that not all symbols correspond with actual code/data, but they do take up a little space in the executable -- at least enough to store their names). T -- MACINTOSH: Most Applications Crash, If Not, The Operating System Hangs
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 17:57:28 UTC, JS wrote: On Thursday, 1 August 2013 at 17:53:38 UTC, Ali Çehreli wrote: On 08/01/2013 10:45 AM, H. S. Teoh wrote: On Thu, Aug 01, 2013 at 07:12:51PM +0200, John Colvin wrote: On Thursday, 1 August 2013 at 17:09:07 UTC, JS wrote: If I have a bunch of templates that are only used for code generation, are they removed in the binary(since they are not needed)? templates don't exist in binaries. Templates are like cookie molds, you use them to generate lots of (almost) identical cookies, but you never serve the mold to the customer. ;-) T I think the question is whether the instantiations of such templates are removed. If the instance is used only to initialize an enum, the function shouldn't stay in the binary. Even if the function remains, I think the linker takes care of removing unused functions. Ali I have a lot of code generation templates(only for code). I want to make sure they don't hang around in the binary(even strings they use) as there is no point and it is potentially dangerous(security issues). The linker will get rid of anything not needed. Marking things as package (or more restrictive) will make sure they don't stay in librarys when not used. Ultimately, if you're worried about it, get the linker to print a list of all functions, or check the assembly.
Re: Emulating enums
On Thursday, 1 August 2013 at 16:36:34 UTC, Ali Çehreli wrote: On 08/01/2013 03:29 AM, JS wrote: > On Thursday, 1 August 2013 at 05:22:46 UTC, Ali Çehreli wrote: >> On 07/31/2013 06:10 PM, JS wrote: >>> http://dpaste.dzfl.pl/dbb40dbc >>> >>> The code was pared down from a lot of string mixin code generation. I >>> nest the structs because I want a nested enums. I don't want have to >>> have eState and eStateType but eState and eState.Type. >>> >>> Having the ability to nest enums would solve my problem. >>> >>> Regardless, I can almost achieve the effect with nested structs but not >>> quite. >>> >>> In the code, I cannot assign to the struct for some reason even with >>> alias this on iB, which should make State act like the int Value. >>> >>> i.e., >>> >>> b.State.Value = Enums.State.A; >>> >>> works but >>> >>> b.State = Enums.State.A; >>> >>> doesn't >>> >>> It maybe some stupid error on my part but I can't keep my eyes open >>> enough to figure it out... >>> >>> >>> >> >> For that assignment to work, the left-hand side must be assignable. >> However, the property function State() returns Enums.eState by-value. >> >> The following has the same issue: >> >> struct S >> { >> int i_; >> >> @property int i() { >> return i_; >> } >> >> alias i this; >> } >> >> void main() >> { >> auto s = S(); >> s = 42; >> assert(s.i == 42); >> } >> >> Error: cannot implicitly convert expression (42) of type int to S >> >> To compile, i() must return an lvalue: >> >> @property ref int i() { Although, what I said seems more like a workaround because you already had a setter @property. You shouldn't need to make the getter return a reference as well... I guess... I think what is at play here is the current implementation limitation of "a single 'alias this' per type." I think 'alias this' happens to pick the getter perhaps because the getter function is defined first in the class. I don't know... Ali So, a ref'ed getter is the same as a setter? Also, it would see, I'm guessing, that using alias this on a property and having to ref will bypass the setter?
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 17:53:38 UTC, Ali Çehreli wrote: On 08/01/2013 10:45 AM, H. S. Teoh wrote: On Thu, Aug 01, 2013 at 07:12:51PM +0200, John Colvin wrote: On Thursday, 1 August 2013 at 17:09:07 UTC, JS wrote: If I have a bunch of templates that are only used for code generation, are they removed in the binary(since they are not needed)? templates don't exist in binaries. Templates are like cookie molds, you use them to generate lots of (almost) identical cookies, but you never serve the mold to the customer. ;-) T I think the question is whether the instantiations of such templates are removed. If the instance is used only to initialize an enum, the function shouldn't stay in the binary. Even if the function remains, I think the linker takes care of removing unused functions. Ali I have a lot of code generation templates(only for code). I want to make sure they don't hang around in the binary(even strings they use) as there is no point and it is potentially dangerous(security issues).
Re: What would be the best way to compile a project with GDC?
On Thu, Aug 01, 2013 at 07:46:05PM +0200, Gary Willoughby wrote: > I've just finished a project in D and have been using rdmd to > compile during testing. While this is nice, i now want to try other > compilers to see if i get any speed gains. Based on my experience, you will, with gdc / ldc. The optimizers in gdc/ldc are much more mature than in dmd; I've compared the disassembly and measured running times with gdc -O3 vs. dmd -O, and gdc consistently produces code that performs 20-30% faster. YMMV, of course, since the exact amount of speed gain depends on what your code does. > Because i use rdmd it takes care of passing everything to dmd. Now i > want to try GDC and i need to pass the files in the correct order for > compilation. I've first tried to write a bash script with all the > files listed correctly and passed all the necessary flags to dmd > but i can never get the order of the files correct. Huh? It shouldn't matter what order the files are. If it does, it sounds like a bug! > There must be a simpler way to pass these files to dmd in the right > order? rdmd does it somehow. > > Any ideas? How do you handle compiling projects with 50+ source > files? Use a real build system. ;-) I recommend SCons (http://scons.org/) or tup (http://gittup.org/tup/). Both require some amount of learning to use effectively, though. If all else fails there's always makefiles, but I rather use them only as a last resort. T -- Life is unfair. Ask too much from it, and it may decide you don't deserve what you have now either.
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 17:47:00 UTC, H. S. Teoh wrote: On Thu, Aug 01, 2013 at 07:12:51PM +0200, John Colvin wrote: On Thursday, 1 August 2013 at 17:09:07 UTC, JS wrote: >If I have a bunch of templates that are only used for code >generation, are they removed in the binary(since they are not >needed)? templates don't exist in binaries. Templates are like cookie molds, you use them to generate lots of (almost) identical cookies, but you never serve the mold to the customer. ;-) T But what about the functions that exist in them? e.g., template A() { void A() { B(); } void B() { } } is everything in the template removed 100% or is there junk that the compiler doesn't remove? Oh... and I'm not talking about theoretical... I'm talking about what dmd actually does.
Re: are mixin string templates with functions removed?
On 08/01/2013 10:45 AM, H. S. Teoh wrote: On Thu, Aug 01, 2013 at 07:12:51PM +0200, John Colvin wrote: On Thursday, 1 August 2013 at 17:09:07 UTC, JS wrote: If I have a bunch of templates that are only used for code generation, are they removed in the binary(since they are not needed)? templates don't exist in binaries. Templates are like cookie molds, you use them to generate lots of (almost) identical cookies, but you never serve the mold to the customer. ;-) T I think the question is whether the instantiations of such templates are removed. If the instance is used only to initialize an enum, the function shouldn't stay in the binary. Even if the function remains, I think the linker takes care of removing unused functions. Ali
What would be the best way to compile a project with GDC?
I've just finished a project in D and have been using rdmd to compile during testing. While this is nice, i now want to try other compilers to see if i get any speed gains. Because i use rdmd it takes care of passing everything to dmd. Now i want to try GDC and i need to pass the files in the correct order for compilation. I've first tried to write a bash script with all the files listed correctly and passed all the necessary flags to dmd but i can never get the order of the files correct. There must be a simpler way to pass these files to dmd in the right order? rdmd does it somehow. Any ideas? How do you handle compiling projects with 50+ source files?
Re: are mixin string templates with functions removed?
On Thu, Aug 01, 2013 at 07:12:51PM +0200, John Colvin wrote: > On Thursday, 1 August 2013 at 17:09:07 UTC, JS wrote: > >If I have a bunch of templates that are only used for code > >generation, are they removed in the binary(since they are not > >needed)? > > templates don't exist in binaries. Templates are like cookie molds, you use them to generate lots of (almost) identical cookies, but you never serve the mold to the customer. ;-) T -- He who does not appreciate the beauty of language is not worthy to bemoan its flaws.
Re: are mixin string templates with functions removed?
On Thursday, 1 August 2013 at 17:09:07 UTC, JS wrote: If I have a bunch of templates that are only used for code generation, are they removed in the binary(since they are not needed)? templates don't exist in binaries.
are mixin string templates with functions removed?
If I have a bunch of templates that are only used for code generation, are they removed in the binary(since they are not needed)?
Re: Emulating enums
On Thursday, 1 August 2013 at 16:36:34 UTC, Ali Çehreli wrote: On 08/01/2013 03:29 AM, JS wrote: > On Thursday, 1 August 2013 at 05:22:46 UTC, Ali Çehreli wrote: >> On 07/31/2013 06:10 PM, JS wrote: >>> http://dpaste.dzfl.pl/dbb40dbc >>> >>> The code was pared down from a lot of string mixin code generation. I >>> nest the structs because I want a nested enums. I don't want have to >>> have eState and eStateType but eState and eState.Type. >>> >>> Having the ability to nest enums would solve my problem. >>> >>> Regardless, I can almost achieve the effect with nested structs but not >>> quite. >>> >>> In the code, I cannot assign to the struct for some reason even with >>> alias this on iB, which should make State act like the int Value. >>> >>> i.e., >>> >>> b.State.Value = Enums.State.A; >>> >>> works but >>> >>> b.State = Enums.State.A; >>> >>> doesn't >>> >>> It maybe some stupid error on my part but I can't keep my eyes open >>> enough to figure it out... >>> >>> >>> >> >> For that assignment to work, the left-hand side must be assignable. >> However, the property function State() returns Enums.eState by-value. >> >> The following has the same issue: >> >> struct S >> { >> int i_; >> >> @property int i() { >> return i_; >> } >> >> alias i this; >> } >> >> void main() >> { >> auto s = S(); >> s = 42; >> assert(s.i == 42); >> } >> >> Error: cannot implicitly convert expression (42) of type int to S >> >> To compile, i() must return an lvalue: >> >> @property ref int i() { Although, what I said seems more like a workaround because you already had a setter @property. You shouldn't need to make the getter return a reference as well... I guess... I think what is at play here is the current implementation limitation of "a single 'alias this' per type." I think 'alias this' happens to pick the getter perhaps because the getter function is defined first in the class. I don't know... Ali Yeah, I think I remember that being an issue before which kinda sucks as one doesn't want to have to necessarily return references. alias this should also alias all the overloads. In any case, how long has the multiple alias issue been going on? 10 years?
Re: Emulating enums
On 08/01/2013 03:29 AM, JS wrote: > On Thursday, 1 August 2013 at 05:22:46 UTC, Ali Çehreli wrote: >> On 07/31/2013 06:10 PM, JS wrote: >>> http://dpaste.dzfl.pl/dbb40dbc >>> >>> The code was pared down from a lot of string mixin code generation. I >>> nest the structs because I want a nested enums. I don't want have to >>> have eState and eStateType but eState and eState.Type. >>> >>> Having the ability to nest enums would solve my problem. >>> >>> Regardless, I can almost achieve the effect with nested structs but not >>> quite. >>> >>> In the code, I cannot assign to the struct for some reason even with >>> alias this on iB, which should make State act like the int Value. >>> >>> i.e., >>> >>> b.State.Value = Enums.State.A; >>> >>> works but >>> >>> b.State = Enums.State.A; >>> >>> doesn't >>> >>> It maybe some stupid error on my part but I can't keep my eyes open >>> enough to figure it out... >>> >>> >>> >> >> For that assignment to work, the left-hand side must be assignable. >> However, the property function State() returns Enums.eState by-value. >> >> The following has the same issue: >> >> struct S >> { >> int i_; >> >> @property int i() { >> return i_; >> } >> >> alias i this; >> } >> >> void main() >> { >> auto s = S(); >> s = 42; >> assert(s.i == 42); >> } >> >> Error: cannot implicitly convert expression (42) of type int to S >> >> To compile, i() must return an lvalue: >> >> @property ref int i() { Although, what I said seems more like a workaround because you already had a setter @property. You shouldn't need to make the getter return a reference as well... I guess... I think what is at play here is the current implementation limitation of "a single 'alias this' per type." I think 'alias this' happens to pick the getter perhaps because the getter function is defined first in the class. I don't know... Ali
Re: instantiate each of a tuple of templates (Take 2)
On Thursday, 1 August 2013 at 15:06:50 UTC, Artur Skawina wrote: On 08/01/13 14:50, John Colvin wrote: template a(T ...) { void a(R r) { //want to get a tuple of //the members of T, each //instantiated with R. //do some RT stuff } } Is this possible? Whatever I try, I keep running in to "cannot use local as parameter to non-global template" errors, which I understand is to do with context pointers However, this is all compile-time work based entirely on types, there should be no need for any context pointers. Always post real and complete (even if not working) code, as figuring out what the problem is can be harder than giving the solution... template RealTuple(A...) { alias RealTuple = A; } template a(T ...) { auto a(R)(R r) { //want to get a tuple of //the members of T, each //instantiated with R. mixin({ string m; foreach (I, _; T) m ~= "alias UGH"~I.stringof~" = T["~I.stringof~"];\n"; m ~= "alias TupleofTsBangR = RealTuple!("; foreach (I, _; T) m ~= (I?", ":"") ~ "UGH"~I.stringof~"!R"; return m ~ ");"; }()); // do some RT stuff TupleofTsBangR x; foreach (I, _; typeof(x)) x[I] = r; // etc import std.typecons; return tuple(x); } } (If this is what you were actually looking for then I hope somebody else has another solution; this approach is just too ugly...) artur sorry yeah I didnt think the question through before asking. I'm normally the one nagging for better example code when people ask questions! I did consider wading through everything with string mixins etc. but it seemed like a lot of effort for what (on the surface) is a simple problem. Anyhow, please see my response to monarch_dodra as I've revised my question somewhat
Re: instantiate each of a tuple of templates (Take 2)
On Thursday, 1 August 2013 at 14:57:07 UTC, monarch_dodra wrote: On Thursday, 1 August 2013 at 12:50:42 UTC, John Colvin wrote: template a(T ...) { void a(R r) { //want to get a tuple of //the members of T, each //instantiated with R. //do some RT stuff } } Is this possible? Whatever I try, I keep running in to "cannot use local as parameter to non-global template" errors, which I understand is to do with context pointers However, this is all compile-time work based entirely on types, there should be no need for any context pointers. Still not sure what you want, but you may want to look into adjoin and staticMap. Sorry, now I've thought about it some more it appears I was asking the wrong question completely! Here's the situation (you might recognise the pattern from std.algorithm.map): template a(funs...) { auto a(R)(R r) { alias /*something*/ nonVoidFuns; alias /*something*/ voidFuns; //do stuff with nonVoidFuns and voidFuns applied to r } } so i need to find the return type of each fun, when called with something of type R (bearing in mind that fun!R may not be the same type as fun(r) as fun might be T fun(T)(T[] a), then filter funs to seperate the void functions from the non-void ones. Or something else to that effect. I've tried several things with std.typetuple.Filter but nothing seems to work.
Re: instantiate each of a tuple of templates (Take 2)
On 08/01/13 14:50, John Colvin wrote: > template a(T ...) > { > void a(R r) > { > //want to get a tuple of > //the members of T, each > //instantiated with R. > > //do some RT stuff > } > } > > Is this possible? > > Whatever I try, I keep running in to "cannot use local as parameter to > non-global template" errors, which I understand is to do with context pointers > However, this is all compile-time work based entirely on types, there should > be no need for any context pointers. > Always post real and complete (even if not working) code, as figuring out what the problem is can be harder than giving the solution... template RealTuple(A...) { alias RealTuple = A; } template a(T ...) { auto a(R)(R r) { //want to get a tuple of //the members of T, each //instantiated with R. mixin({ string m; foreach (I, _; T) m ~= "alias UGH"~I.stringof~" = T["~I.stringof~"];\n"; m ~= "alias TupleofTsBangR = RealTuple!("; foreach (I, _; T) m ~= (I?", ":"") ~ "UGH"~I.stringof~"!R"; return m ~ ");"; }()); // do some RT stuff TupleofTsBangR x; foreach (I, _; typeof(x)) x[I] = r; // etc import std.typecons; return tuple(x); } } (If this is what you were actually looking for then I hope somebody else has another solution; this approach is just too ugly...) artur
Re: instantiate each of a tuple of templates (Take 2)
On Thursday, 1 August 2013 at 12:50:42 UTC, John Colvin wrote: template a(T ...) { void a(R r) { //want to get a tuple of //the members of T, each //instantiated with R. //do some RT stuff } } Is this possible? Whatever I try, I keep running in to "cannot use local as parameter to non-global template" errors, which I understand is to do with context pointers However, this is all compile-time work based entirely on types, there should be no need for any context pointers. Still not sure what you want, but you may want to look into adjoin and staticMap.
Re: std.container: RedBlackTree questions
On Thursday, 1 August 2013 at 12:27:51 UTC, Ivan Kazmenko wrote: Hi! The key points of this lengthy letter are: (0) I find RedBlackTree hard to use, and below is one story of trying to get it to work. (1) Perhaps I did something wrong a few times. Please show me a better way to go. (2) Perhaps the library code could be improved as well to make the process more intuitive. - I am trying to use RedBlackTree container to maintain a set of Elems, Elem being a non-trivial struct. The problem is that I find the container hard to use. First, I have to note that, instead of storing Elems directly in the RedBlackTree, I have a dynamic array of Elems and a RedBlackTree of integers pointing to that array to improve performance. In my case, the latter proved to be a few times faster than the former because RedBlackTree moves the values around quite a bit. Please comment if there is a common way to achieve a similar performance gain without decoupling. Anyway, instead of storing say "data[a]" and "data[b]" in the tree, I store their indices "a" and "b" and compare these integers like "data[a] < data[b]". Below is the story of my few steps to making this work. I'll appreciate any comments on how I could improve or take a better direction on any of the steps. The compiler is DMD 2.063.2, no compile options. Struct Elem is replaced by an alias to long for simplicity. 1. The first try is to specify the comparison directly: - import std.container; alias Elem = long; Elem [] data; RedBlackTree !(int, "data[a] < data[b]") tree; void main () { } - This gives the following error: rbt1.d(7): Error: template instance RedBlackTree!(int, "data[a] < data[b]") does not match template declaration RedBlackTree(T, alias less = "a < b", bool allowDuplicates = false) if (is(typeof(binaryFun!(less)(T.init, T.init OK, that was predictable. I never got to getting this to work beyond a simple "a < b" or "a + 1 > b + 1" or the like. Is that even possible? 2. Let us try a lambda: - import std.container; alias Elem = long; Elem [] data; RedBlackTree !(int, (a, b) => data[a] < data[b]) tree; void main () { tree = redBlackTree !((a, b) => data[a] < data[b]) (new int [0]); } - Fine with the declaration, but later, an error again: rbt2.d(11): Error: cannot implicitly convert expression (redBlackTree(new int[](0u))) of type rbt2.main.RedBlackTree!(int, __lambda6).RedBlackTree to rbt2.RedBlackTree!(int, __lambda3).RedBlackTree I see. The compiler cannot tell that the lambdas are the same. Oh well. 3. An ordinary function then: - import std.container; alias Elem = long; Elem [] data; bool less_data (int a, int b) {return data[a] < data[b];} RedBlackTree !(int, less_data) tree; void main () { tree = redBlackTree !(less_data) (new int [0]); } - Aaand: phobos\std\container.d(6553): Error: less_data (int a, int b) is not callable using argument types () phobos\std\range.d(611): Error: static assert "Cannot put a char[] into a Appender!(string)" phobos\std\format.d(1433): instantiated from here: put!(Appender!(string), char[]) phobos\std\format.d(1335): instantiated from here: formatUnsigned!(Appender!(string), char) phobos\std\format.d(1309): instantiated from here: formatIntegral!(Appender!(string), ulong, char) phobos\std\format.d(2950): ... (4 instantiations, -v to show) ... phobos\std\container.d(5541): instantiated from here: Tuple!(bool, "added", RBNode!(int)*, "n") rbt3.d(12): instantiated from here: RedBlackTree!(int, less_data) Ouch. What? That does not look like a user-friendly message at all. Am I doing something very wrong?.. 4. After a bit of guessing, I got this working by adding an empty template argument to the function. Here it goes: - import std.container; alias Elem = long; Elem [] data; bool less_data () (int a, int b) {return data[a] < data[b];} RedBlackTree !(int, less_data) tree; void main () { tree = redBlackTree !(less_data) (new int [0]); data = [4, 3, 5]; tree.insert (0); tree.insert (1); tree.insert (2); } - This compiles and runs fine. Or does it? Adding "-unittest" compiler option produces another bunch of errors: phobos\std\container.d(5672): Error: void has no value phobos\std\container.d(5672): Error: incompatible types for ((less_data()(int a, int b)) == ("a < b")): 'void' and 'string' phobos\std\container.d(5946): Error: void has no value phobos\std\container.d(5946): Error: incompatible types for ((less_data()(int a, int b)) == ("a < b")): 'void' and 'string' phobos\std\container.d(6021): Error: void has no value phobos\std\container.d(6021): Error: incompatible types for ((less_data()(int a, int b)) == ("a < b")): 'void' and 'string' phobos\std\container.d(6067): Error: void has no value phobos\std\container.d(6067): Error: incompatible types for ((less_data()(int a, int b)) == ("a < b")): 'void' and 'string' phobos\std\container
Re: instantiate each of a tuple of templates (Take 2)
On Thursday, 1 August 2013 at 12:50:42 UTC, John Colvin wrote: ... Does this help http://dpaste.dzfl.pl/fe533f7a ?
Re: instantiate each of a tuple of templates (Take 2)
On Thursday, 1 August 2013 at 12:50:42 UTC, John Colvin wrote: template a(T ...) { void a(R r) { //want to get a tuple of //the members of T, each //instantiated with R. //do some RT stuff } } Is this possible? Whatever I try, I keep running in to "cannot use local as parameter to non-global template" errors, which I understand is to do with context pointers However, this is all compile-time work based entirely on types, there should be no need for any context pointers. A static foreach should do the trick. (code not actually tested) void a(R r) //void? Not Tuple!T ? { Tuple!T ret foreach(i, Type; T) { ret[i] = r; } return ret; } Is this what you want? This assumes that every member or T is a type, and not a name.
Re: std.container: RedBlackTree questions
On Thursday, 1 August 2013 at 12:55:30 UTC, John Colvin wrote: On Thursday, 1 August 2013 at 12:27:51 UTC, Ivan Kazmenko wrote: On a relevant note, I find the unittests of RedBlackTree a bit excessive even when they compile successfully. They seem to test the integrity of the whole tree every time a tree operation takes place, and that makes the unittests version of my local code run too slowly. Is there a way to turn unittests on only for user code and turn them off for the standard library? Ivan Kazmenko. Unless you've compiled phobos with -unittest, the unittests in the standard library won't even exist in the binary, let alone take up time to run. Unless... I'm mistaken and actually for some bizarre reason unittests get dragged in from the import files, but that seems very unlikely. There is a version(unittest) version = RBDoChecks; line and the following version(RBDoChecks) check(); calls in the tree implementation. Perhaps the approach is special to RedBlackTree. I agree that RBDoChecks can be useful occasionally, for example, when there is a bug in comparison function. But I would be happy if the aforementioned line is removed from the library, or at least a way to override it is provided.
Re: Profiling graph library
On 08/01/2013 01:56 PM, bearophile wrote: > I have not critiqued linear flow programming its, I love it and perhaps I was > the one that has introduced it in D. In the main D newsgroup I have just said > that in D it still causes some performance loss, even using ldc2. That's what I meant -- your remarks on the (current) performance costs. Wasn't meaning to imply you'd critiqued the idea per se!
Re: std.container: RedBlackTree questions
On Thursday, 1 August 2013 at 12:27:51 UTC, Ivan Kazmenko wrote: On a relevant note, I find the unittests of RedBlackTree a bit excessive even when they compile successfully. They seem to test the integrity of the whole tree every time a tree operation takes place, and that makes the unittests version of my local code run too slowly. Is there a way to turn unittests on only for user code and turn them off for the standard library? Ivan Kazmenko. Unless you've compiled phobos with -unittest, the unittests in the standard library won't even exist in the binary, let alone take up time to run. Unless... I'm mistaken and actually for some bizarre reason unittests get dragged in from the import files, but that seems very unlikely.
instantiate each of a tuple of templates (Take 2)
template a(T ...) { void a(R r) { //want to get a tuple of //the members of T, each //instantiated with R. //do some RT stuff } } Is this possible? Whatever I try, I keep running in to "cannot use local as parameter to non-global template" errors, which I understand is to do with context pointers However, this is all compile-time work based entirely on types, there should be no need for any context pointers.
instantiate a tuple of templates
Say I have a template template A(T ...) { void A }
Re: instantiate a tuple of templates
On Thursday, 1 August 2013 at 12:43:21 UTC, John Colvin wrote: Say I have a template template A(T ...) { void A } woops sorry, partial post. Will finish and post again.
Re: Named UDA's
On Thursday, 1 August 2013 at 11:02:00 UTC, JS wrote: Anyways, Just an idea I had when trying to make attributes more useful. struct Name { string data; } @Name("hello") void foo(); I favor this approach much more because of strong typing.
std.container: RedBlackTree questions
Hi! The key points of this lengthy letter are: (0) I find RedBlackTree hard to use, and below is one story of trying to get it to work. (1) Perhaps I did something wrong a few times. Please show me a better way to go. (2) Perhaps the library code could be improved as well to make the process more intuitive. - I am trying to use RedBlackTree container to maintain a set of Elems, Elem being a non-trivial struct. The problem is that I find the container hard to use. First, I have to note that, instead of storing Elems directly in the RedBlackTree, I have a dynamic array of Elems and a RedBlackTree of integers pointing to that array to improve performance. In my case, the latter proved to be a few times faster than the former because RedBlackTree moves the values around quite a bit. Please comment if there is a common way to achieve a similar performance gain without decoupling. Anyway, instead of storing say "data[a]" and "data[b]" in the tree, I store their indices "a" and "b" and compare these integers like "data[a] < data[b]". Below is the story of my few steps to making this work. I'll appreciate any comments on how I could improve or take a better direction on any of the steps. The compiler is DMD 2.063.2, no compile options. Struct Elem is replaced by an alias to long for simplicity. 1. The first try is to specify the comparison directly: - import std.container; alias Elem = long; Elem [] data; RedBlackTree !(int, "data[a] < data[b]") tree; void main () { } - This gives the following error: rbt1.d(7): Error: template instance RedBlackTree!(int, "data[a] < data[b]") does not match template declaration RedBlackTree(T, alias less = "a < b", bool allowDuplicates = false) if (is(typeof(binaryFun!(less)(T.init, T.init OK, that was predictable. I never got to getting this to work beyond a simple "a < b" or "a + 1 > b + 1" or the like. Is that even possible? 2. Let us try a lambda: - import std.container; alias Elem = long; Elem [] data; RedBlackTree !(int, (a, b) => data[a] < data[b]) tree; void main () { tree = redBlackTree !((a, b) => data[a] < data[b]) (new int [0]); } - Fine with the declaration, but later, an error again: rbt2.d(11): Error: cannot implicitly convert expression (redBlackTree(new int[](0u))) of type rbt2.main.RedBlackTree!(int, __lambda6).RedBlackTree to rbt2.RedBlackTree!(int, __lambda3).RedBlackTree I see. The compiler cannot tell that the lambdas are the same. Oh well. 3. An ordinary function then: - import std.container; alias Elem = long; Elem [] data; bool less_data (int a, int b) {return data[a] < data[b];} RedBlackTree !(int, less_data) tree; void main () { tree = redBlackTree !(less_data) (new int [0]); } - Aaand: phobos\std\container.d(6553): Error: less_data (int a, int b) is not callable using argument types () phobos\std\range.d(611): Error: static assert "Cannot put a char[] into a Appender!(string)" phobos\std\format.d(1433): instantiated from here: put!(Appender!(string), char[]) phobos\std\format.d(1335): instantiated from here: formatUnsigned!(Appender!(string), char) phobos\std\format.d(1309): instantiated from here: formatIntegral!(Appender!(string), ulong, char) phobos\std\format.d(2950): ... (4 instantiations, -v to show) ... phobos\std\container.d(5541): instantiated from here: Tuple!(bool, "added", RBNode!(int)*, "n") rbt3.d(12): instantiated from here: RedBlackTree!(int, less_data) Ouch. What? That does not look like a user-friendly message at all. Am I doing something very wrong?.. 4. After a bit of guessing, I got this working by adding an empty template argument to the function. Here it goes: - import std.container; alias Elem = long; Elem [] data; bool less_data () (int a, int b) {return data[a] < data[b];} RedBlackTree !(int, less_data) tree; void main () { tree = redBlackTree !(less_data) (new int [0]); data = [4, 3, 5]; tree.insert (0); tree.insert (1); tree.insert (2); } - This compiles and runs fine. Or does it? Adding "-unittest" compiler option produces another bunch of errors: phobos\std\container.d(5672): Error: void has no value phobos\std\container.d(5672): Error: incompatible types for ((less_data()(int a, int b)) == ("a < b")): 'void' and 'string' phobos\std\container.d(5946): Error: void has no value phobos\std\container.d(5946): Error: incompatible types for ((less_data()(int a, int b)) == ("a < b")): 'void' and 'string' phobos\std\container.d(6021): Error: void has no value phobos\std\container.d(6021): Error: incompatible types for ((less_data()(int a, int b)) == ("a < b")): 'void' and 'string' phobos\std\container.d(6067): Error: void has no value phobos\std\container.d(6067): Error: incompatible types for ((less_data()(int a, int b)) == ("a < b")): 'void' and 'string' phobos\std\container.d(6108): Error: void has no value phobos\std\container.d(610
Re: Profiling graph library
Joseph Rushton Wakeling: So, your critiques of component programming certainly have merit on the performance side. I have not critiqued linear flow programming its, I love it and perhaps I was the one that has introduced it in D. In the main D newsgroup I have just said that in D it still causes some performance loss, even using ldc2. Bye, bearophile
Named UDA's
I guess D doesn't support named UDA's directly? e.g., @(Name = "My Name", Other = .34) It would be nice to have the ability to have an "attribute" hierarchy where looking up attributes on objects could easily be done. e.g., @(Name = "s", Other = 2) struct s { @(Name = "q", Default_Value = 4) int q = 4; } which would form a hierarchy Attributes[]...[] Which @[s].Attributes = {"Name" = "s", "Other" = 2} (Key/Value pairs) @[s][q].Attributes = {"Name" = "q", "Other" = 2, "Default_Value" = 4 } (attributes are inherited Querying at runtime would be a binary search or O(1) if the object type is known. Anyways, Just an idea I had when trying to make attributes more useful.
Re: Profiling graph library
On 07/31/2013 02:31 PM, bearophile wrote: > If this resulting array is used only for a short period of time: > > return sequence.map!(x => x.func).array; Just to compare, I tried rewriting the cacheing version of the neighbours() function to use this kind of sequence. Here's the original code: https://github.com/WebDrake/Dgraph/blob/cache/dgraph/graph.d#L358-L379 ... and here's the rewritten version: auto neighbours(immutable size_t v) { if (!_cacheNeighbours[v]) { iota(_sumTail[v], _sumTail[v + 1]) .map!(a => _head[_indexTail[a]]) .copy(_neighbours[_sumTail[v] + _sumHead[v] .. _sumHead[v] + _sumTail[v + 1]]); iota(_sumHead[v], _sumHead[v + 1]) .map!(a => _tail[_indexHead[a]]) .copy(_neighbours[_sumHead[v] + _sumTail[v + 1] .. _sumTail[v + 1] + _sumHead[v + 1]]); _cacheNeighbours[v] = true; } return _neighbours[_sumTail[v] + _sumHead[v] .. _sumTail[v + 1] + _sumHead[v + 1]]; } Although it's faster than the non-cached map-based version, there's still a substantial performance hit from a large number of small allocations. So, your critiques of component programming certainly have merit on the performance side. What's weird is that even though the graph is always passed around by ref, meaning that the neighbours are calculated only once, according to callgrind the number of calls to _d_allocmemory still amounts to no. of vertices * no. of trial runs. And yes, I put in some checks to make sure that the loop was only being called the correct number of times.
Re: Emulating enums
On Thursday, 1 August 2013 at 05:22:46 UTC, Ali Çehreli wrote: On 07/31/2013 06:10 PM, JS wrote: http://dpaste.dzfl.pl/dbb40dbc The code was pared down from a lot of string mixin code generation. I nest the structs because I want a nested enums. I don't want have to have eState and eStateType but eState and eState.Type. Having the ability to nest enums would solve my problem. Regardless, I can almost achieve the effect with nested structs but not quite. In the code, I cannot assign to the struct for some reason even with alias this on iB, which should make State act like the int Value. i.e., b.State.Value = Enums.State.A; works but b.State = Enums.State.A; doesn't It maybe some stupid error on my part but I can't keep my eyes open enough to figure it out... For that assignment to work, the left-hand side must be assignable. However, the property function State() returns Enums.eState by-value. The following has the same issue: struct S { int i_; @property int i() { return i_; } alias i this; } void main() { auto s = S(); s = 42; assert(s.i == 42); } Error: cannot implicitly convert expression (42) of type int to S To compile, i() must return an lvalue: @property ref int i() { Ali Thanks...
Re: Mysql - Sql things ?
On Wednesday, 31 July 2013 at 12:09:02 UTC, David wrote: https://github.com/rejectedsoftware/mysql-native Waw ! Many thanks, Completely missed it :) See you