Re: A module comprehensive template-specialization
On Sun, 27 Jun 2010 18:51:35 +0200, Matthias Walter xa...@xammy.homelinux.net wrote: Hi list, I tried to write a traits class comparable to iterator_traits in C++ STL or graph_traits in Boost Graph Library in D 2.0, but failed to do so via template specialization which is put into different modules. Putting everything into one module interferes with extensibility. I tried the following: == Module a == | module a; | | template Base (T) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T: T*) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } The error message is: bug.d(8): Error: template instance ambiguous template declaration b.Base(T : T*) and a.Base(T) Can I handle this in another way (like making the template a conditional one)? best regards Matthias Walter I believe this is intended behavior, as it prevents template hijacking and the like. Using alias to import the two templates into the same scope might help, though I'm not sure exactly how it should be done. On another note, though, have you looked at __traits() and std.traits?
Re: A module comprehensive template-specialization
On 06/28/2010 05:32 AM, Simen kjaeraas wrote: Matthias Walter xa...@xammy.homelinux.net wrote: Can I handle this in another way (like making the template a conditional one)? Template constraints[1] sounds like what you want. Basically, you want the following: == Module a == | module a; | | template Base (T) if (!is(T t : t*)) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T) if (is(T t : t*)) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } Not tested, ymmv. [1]: http://digitalmars.com/d/2.0/template.html#Constraint The problem with constraints arises when I want to make an existing class (who's code I cannot modify) match a Concept, in which case I would just add another template specialization for this class. Here I would have to add further conditions to the template constraints, which would also mean to modify a library. A prominent example for Boost Graph Library is the LEDA graph class, which can be enabled to be used by BGL by more or less just specializing the graph_traits template. Any further ideas?
Re: Why doesn't this work in D2?
On 2010-06-28 02:28, BCS wrote: Hello Jacob, That's annoying, specially since char is a value type. I would preferably have a solution for both D1 and D2. Can I use a template to cast/alias away the immutable part? One solution would be to have templates strip off const/immutable from the top level of args. void F1(T)(T t) { pragam(msg,typeof(t).stringof); } string s1; immutable(char[]) s2 char[] s3 F1(s1); // immutable(char)[] // all as normal F1(s2); // immutable(char)[] // making a mutable copy of a immutable value is OK F1(s3); // char[] // all as normal void F2(T)(immutable T t) { pragam(msg,typeof(t).stringof); } F2(s1); // immutable(char[]) // making an immutable copy of a mutable reference to immutable data is ok F2(s2); // immutable(char[]) // all as normal F2(s3); // error, invalid conversion This solution would match the proposal that popped up a while ago to allow value assignment from const/immutable to mutable. I don't think I understand what you're showing here. How would I strip off the const/immutable with a template ? -- /Jacob Carlborg
Re: A module comprehensive template-specialization
On 06/28/2010 09:49 AM, Justin Spahr-Summers wrote: On Sun, 27 Jun 2010 18:51:35 +0200, Matthias Walter xa...@xammy.homelinux.net wrote: Hi list, I tried to write a traits class comparable to iterator_traits in C++ STL or graph_traits in Boost Graph Library in D 2.0, but failed to do so via template specialization which is put into different modules. Putting everything into one module interferes with extensibility. I tried the following: == Module a == | module a; | | template Base (T) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T: T*) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } The error message is: bug.d(8): Error: template instance ambiguous template declaration b.Base(T : T*) and a.Base(T) Can I handle this in another way (like making the template a conditional one)? best regards Matthias Walter I believe this is intended behavior, as it prevents template hijacking and the like. Using alias to import the two templates into the same scope might help, though I'm not sure exactly how it should be done. I tried to do so in some variants but did not succeed unfortunately. If you have a precise idea, please let me know! On another note, though, have you looked at __traits() and std.traits? I looked at them but didn't find them helpful for this precise problem. The whole reason for doing this is to make it possible to make another existing class model the concept (i.e. have some aliases / typedefs done) of my library class without editing any of them. As I mentioned in my other response, a prominent example for Boost Graph Library is the LEDA graph class, which can be enabled to be used by BGL by more or less just specializing the graph_traits template. I'd like to have this kind of technique available, too. Any further suggestions?
Re: A module comprehensive template-specialization
On Mon, 28 Jun 2010 11:09:13 +0200, Matthias Walter xa...@xammy.homelinux.net wrote: On 06/28/2010 09:49 AM, Justin Spahr-Summers wrote: On Sun, 27 Jun 2010 18:51:35 +0200, Matthias Walter xa...@xammy.homelinux.net wrote: Hi list, I tried to write a traits class comparable to iterator_traits in C++ STL or graph_traits in Boost Graph Library in D 2.0, but failed to do so via template specialization which is put into different modules. Putting everything into one module interferes with extensibility. I tried the following: == Module a == | module a; | | template Base (T) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T: T*) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } The error message is: bug.d(8): Error: template instance ambiguous template declaration b.Base(T : T*) and a.Base(T) Can I handle this in another way (like making the template a conditional one)? best regards Matthias Walter I believe this is intended behavior, as it prevents template hijacking and the like. Using alias to import the two templates into the same scope might help, though I'm not sure exactly how it should be done. I tried to do so in some variants but did not succeed unfortunately. If you have a precise idea, please let me know! On another note, though, have you looked at __traits() and std.traits? I looked at them but didn't find them helpful for this precise problem. The whole reason for doing this is to make it possible to make another existing class model the concept (i.e. have some aliases / typedefs done) of my library class without editing any of them. As I mentioned in my other response, a prominent example for Boost Graph Library is the LEDA graph class, which can be enabled to be used by BGL by more or less just specializing the graph_traits template. I'd like to have this kind of technique available, too. Any further suggestions? I haven't looked at the boost stuff you mention but is it possible that using alias this, solves a similar or the same problem? TDPL addresses the use of aliasing to bring multiple declarations into the same scope/module but it only uses actual functions not templates.
Re: Why doesn't this work in D2?
On Mon, Jun 28, 2010 at 10:56, Jacob Carlborg d...@me.com wrote: Something to keep in mind: as of 2.04x (.045? maybe), the way UTF-8 / UTF-32 is managed was changed. asd is an array of immutable(dchar), not imutable(char). At least DMD tells me that its element type is 'dchar'. So your function can be done this way in D2: void foo(T,U)(in T[] a, U b) if (is(U : Unqual!T)) // that compiles only if b can be cast to A { writeln(a,b); } asd.foo('s'); // prints asds. is(U == Unqual!T) does not work, for U is 'char' while Unqual!T is 'dchar'. More generally, using ranges and not arrays, the template becomes a bit more heavy: void foo(Range,Elem)(in Range range, Elem elem) if (isInputRange!Range is(Elem : Unqual!(ElementType!Range))) { ... } I don't think I understand what you're showing here. How would I strip off the const/immutable with a template ? Hmmm... * plays with is expressions * This seems to work: template UnConst(T) { static if (is(T t == const U, U)) // that is: 'if T is a 'const U', for some U' alias U UnConst; // then give me the U, (ie, T without a const) else alias T UnConst; // else give me the (original) T } template UnImmutable(T) { static if (is(T t == immutable U, U)) // 'if T is an 'immutable U', for some U' alias U UnImmutable; else alias T UnImmutable; } test: void main() { alias const int Int; writeln(UnConst!Int.stringof); writeln(Int.stringof); writeln(UnConst!int.stringof); writeln(UnConst!(const int).stringof); writeln(UnConst!(immutable int).stringof); alias immutable int IInt; writeln(UnConst!IInt.stringof); writeln(IInt.stringof); writeln(UnImmutable!int.stringof); writeln(UnImmutable!(const int).stringof); writeln(UnImmutable!(immutable int).stringof); } Philippe
Re: Why doesn't this work in D2?
On Mon, 28 Jun 2010 08:14:12 -0400, Philippe Sigaud philippe.sig...@gmail.com wrote: On Mon, Jun 28, 2010 at 10:56, Jacob Carlborg d...@me.com wrote: Something to keep in mind: as of 2.04x (.045? maybe), the way UTF-8 / UTF-32 is managed was changed. asd is an array of immutable(dchar), not imutable(char). At least DMD tells me that its element type is 'dchar'. No, that is not true. It's still an array of immutable(char). The compiler still sees it as an array of immutable(char). However, std.range forces the element type of char[] and wchar[] to be bidirectional ranges of dchar. The tests such as isRandomAccessRange and ElementType are fudged to say string is *not* a random access range, and its element type is dchar. This was one of Andrei's changes because without such shoehorning, std.algorithm could possible start shearing off strings that weren't valid. Whether that was the right decision remains to be seen. I personally would rather have special ranges that do those things. If I have a string that's always in English, why do I need to generate the dchars based on the characters in that array? -Steve
Re: Why doesn't this work in D2?
On 2010-06-28 14:14, Philippe Sigaud wrote: On Mon, Jun 28, 2010 at 10:56, Jacob Carlborg d...@me.com mailto:d...@me.com wrote: Something to keep in mind: as of 2.04x (.045? maybe), the way UTF-8 / UTF-32 is managed was changed. asd is an array of immutable(dchar), not imutable(char). At least DMD tells me that its element type is 'dchar'. So your function can be done this way in D2: void foo(T,U)(in T[] a, U b) if (is(U : Unqual!T)) // that compiles only if b can be cast to A { writeln(a,b); } asd.foo('s'); // prints asds. is(U == Unqual!T) does not work, for U is 'char' while Unqual!T is 'dchar'. More generally, using ranges and not arrays, the template becomes a bit more heavy: void foo(Range,Elem)(in Range range, Elem elem) if (isInputRange!Range is(Elem : Unqual!(ElementType!Range))) { ... } I don't think I understand what you're showing here. How would I strip off the const/immutable with a template ? Hmmm... * plays with is expressions * This seems to work: template UnConst(T) { static if (is(T t == const U, U)) // that is: 'if T is a 'const U', for some U' alias U UnConst; // then give me the U, (ie, T without a const) else alias T UnConst; // else give me the (original) T } template UnImmutable(T) { static if (is(T t == immutable U, U)) // 'if T is an 'immutable U', for some U' alias U UnImmutable; else alias T UnImmutable; } test: void main() { alias const int Int; writeln(UnConst!Int.stringof); writeln(Int.stringof); writeln(UnConst!int.stringof); writeln(UnConst!(const int).stringof); writeln(UnConst!(immutable int).stringof); alias immutable int IInt; writeln(UnConst!IInt.stringof); writeln(IInt.stringof); writeln(UnImmutable!int.stringof); writeln(UnImmutable!(const int).stringof); writeln(UnImmutable!(immutable int).stringof); } Philippe Hmm, now I don't know what I'm doing, I thought you could do something like this: template Char (T) { alias T Char; } void foo (T) (Char!(T) b) { } void main () { foo('s'); } -- /Jacob Carlborg
Re: auto functions not authorized inside main?
On Sun, 27 Jun 2010 17:17:25 +0200, Philippe Sigaud philippe.sig...@gmail.com wrote: Is it defined somewhere that auto functions are not authorized inside main? void main() { auto fun(string s) { return s;} // this does not compile } error: main.d|6|found 's' when expecting ')'| main.d|6|semicolon expected, not ')'| main.d|6|found ')' instead of statement| main.d|7|unrecognized declaration| ||=== Build finished: 4 errors, 0 warnings ===| So it's not even parsed? I couldn't find a bugzilla entry for this and I cannot believe no one ever tried to put an auto fun inside main! Is that part of the spec? Philippe Hope this isn't a stupid question, but how would you access this function if it did work? Would it be fun(asdf)? Is this just shorthand for: auto fun = function(string s) {return s;}; -Rory
Re: Why doesn't this work in D2?
Hello Jacob, On 2010-06-28 02:28, BCS wrote: One solution would be to have templates strip off const/immutable from the top level of args. [...] This solution would match the proposal that popped up a while ago to allow value assignment from const/immutable to mutable. I don't think I understand what you're showing here. How would I strip off the const/immutable with a template ? I was proposing a language change Sorry for any confusion. The idea is that unless the user ask for it explicitly, there is no particular reason to preserve const/immutable for the value portion (true value types and the first level of references/pointers) of arguments. -- ... IXOYE
Re: Why doesn't this work in D2?
On Mon, Jun 28, 2010 at 14:35, Steven Schveighoffer schvei...@yahoo.comwrote: On Mon, 28 Jun 2010 08:14:12 -0400, Philippe Sigaud philippe.sig...@gmail.com wrote: On Mon, Jun 28, 2010 at 10:56, Jacob Carlborg d...@me.com wrote: Something to keep in mind: as of 2.04x (.045? maybe), the way UTF-8 / UTF-32 is managed was changed. asd is an array of immutable(dchar), not imutable(char). At least DMD tells me that its element type is 'dchar'. No, that is not true. It's still an array of immutable(char). The compiler still sees it as an array of immutable(char). However, std.range forces the element type of char[] and wchar[] to be bidirectional ranges of dchar. The tests such as isRandomAccessRange and ElementType are fudged to say string is *not* a random access range, and its element type is dchar. This was one of Andrei's changes because without such shoehorning, std.algorithm could possible start shearing off strings that weren't valid. Ah yes, indeed, you're right. Whether that was the right decision remains to be seen. I personally would rather have special ranges that do those things. If I have a string that's always in English, why do I need to generate the dchars based on the characters in that array? All that I can say is that it instantly broke dozens of unit tests in my projects, which were using strings a simple random-access ranges. It took me 2 DMD releases to work my way uout of it. Maybe I should have a look at byCodeUnit or somesuch. But for clueless users like me, strings suddenly became much more complicated to use. Maybe I was using them in unsafe ways, I don't know. I just hope for a way to get my simple strings back.
Re: auto functions not authorized inside main?
Hello Rory, On Sun, 27 Jun 2010 17:17:25 +0200, Philippe Sigaud philippe.sig...@gmail.com wrote: void main() { auto fun(string s) { return s;} // this does not compile } Hope this isn't a stupid question, but how would you access this function if it did work? Would it be fun(asdf)? Is this just shorthand for: auto fun = function(string s) {return s;}; I would look almost the same to the user but should in fact be a normal local function. -- ... IXOYE
scope keyword within template mixins
Hi D users, I created/tested a little logging class under DMD 1.062: //- // // helper class for debugging/logging // import std.string; import std.stdio; scope class LogEnter { static int mIndent; static char[] doindent() { return \n ~ repeat( , mIndent); } this(char[] text) { mText = text; writef(doindent() ~ ~ mText ~ ); mIndent += 2; } ~this() { mIndent -= 2; writef(doindent() ~ / ~ mText ~ ); } char[] mText; } //- // // logging with scope keyword // void C() { scope auto log = new LogEnter(C); D(); } void D() { scope auto log = new LogEnter(D); } void main() { // C(); } //- Together with the scope keyword this works as expected. The output looks like: C D /D /C After that I tried to move the LogEnter instantiation into a template mixin, as follows: //- // // logging via template mixin // template Log(char[] msg) { scope auto log = new LogEnter(msg); } void A() { mixin Log!(A); B(); } void B() { mixin Log!(B); } void main() { A(); } //- I get the following output: A B IMO the template mixin variant should behave the same. Did I miss something or is this a bug ? I already searched bugzilla for similar bugs, but I found none. Thanks in advance for your help KlausO
Re: auto functions not authorized inside main?
On Mon, 28 Jun 2010 16:07:43 +0200, Philippe Sigaud philippe.sig...@gmail.com wrote:On Mon, Jun 28, 2010 at 15:40, Rory McGuire rmcgu...@neonova.co.za wrote: void main() { auto fun(string s) { return s;} // this does not compile } Hope this isn't a stupid question, but how would you access this function if it did work? Would it be fun("asdf")?Yes, that's what I had in mind. Basically, just using it as any other auto inner function. void main(){auto fun(string s) { return s;}auto s = fun("abc"); auto t = fun("def");} Is this just shorthand for: auto fun = function(string s) {return s;};That'd be about the same, yes. Fact is, I don't really _need_ this, I was just astonished to be bitten by this.Why can I do void main(){ string foo(string s) { return s;}}and notvoid main(){ auto foo(string s) { return s;}} ?***OK, I tested it some more, and it seems you cannot define auto function inside any other function. So auto function cannot be inner functions. I'm quite astonished I never did that when using D, but OK. I filed a bug report, at least to update the docs. It's bug #4401.Philippe Right! I get what you're saying, didn't realise because it was formatted more how I would format a anon delegate.You're saying "surely the compiler can infer the return type for a inner function just as much as it can infer the return type of a normal function..Must be a compiler bug.-Rory
Re: auto functions not authorized inside main?
On Mon, 28 Jun 2010 16:01:46 +0200, BCS n...@anon.com wrote: Hello Rory, On Sun, 27 Jun 2010 17:17:25 +0200, Philippe Sigaud philippe.sig...@gmail.com wrote: void main() { auto fun(string s) { return s;} // this does not compile } Hope this isn't a stupid question, but how would you access this function if it did work? Would it be fun(asdf)? Is this just shorthand for: auto fun = function(string s) {return s;}; I would look almost the same to the user but should in fact be a normal local function. Ye I got it now. My brain was interpreting it as a delegate that wasn't being assigned to anything for some reason. Now I get that it is just return type inferance doesn't work for inner functions. -Rory
@porperty problem..
Hi I have a forward reference pb in conjunction with @property. Err msg is : forward refrence to inferred return type of function call s1.servername. any ideas ? beside, where are the @property docs ? thanks, bjoern final class LoadBalancer { private static LoadBalancer lb; private Server[] servers; static this() { synchronized lb = new LoadBalancer; } private this() { Server s1 = new Server(); s1.servername = Server 1; // ERROR servers ~= s1; } public static LoadBalancer getLoadBalancer() { return lb; } @property nextServer() { return servers[0]; } class Server { private string _name, _id; @property servername(string name) { _name = name; } @property servername() { return _name; } } }
Re: @porperty problem..
On Mon, 28 Jun 2010 16:37:06 -0400, BLS windev...@hotmail.de wrote: Hi I have a forward reference pb in conjunction with @property. Err msg is : forward refrence to inferred return type of function call s1.servername. any ideas ? beside, where are the @property docs ? thanks, bjoern final class LoadBalancer { private static LoadBalancer lb; private Server[] servers; static this() { synchronized lb = new LoadBalancer; } private this() { Server s1 = new Server(); s1.servername = Server 1; // ERROR servers ~= s1; } public static LoadBalancer getLoadBalancer() { return lb; } @property nextServer() { Shouldn't this be @property Server nextServer() { ??? return servers[0]; } class Server { private string _name, _id; @property servername(string name) { _name = name; } @property servername() { return _name; } } } -Steve
Re: @prorperty problem..
On 28/06/2010 22:37, BLS wrote: forward refrence to inferred return type of function call s1.servername. any ideas ? beside, where are the @property docs ? thanks, bjoern ok moving the inner Server class (see prev. msg) in front of LoadBalancer works.. seems to be a forward reference bug. class Server { private string _name, _id; @property servername(string name) { _name = name; } @property servername() { return _name; } } final class LoadBalancer { private static LoadBalancer lb; private Server[] servers; static this() { synchronized lb = new LoadBalancer; } private this() { Server s1 = new Server(); s1.servername = Server 1; // NO PROBLEM } ... }
Re: Why doesn't this work in D2?
On 2010-06-28 15:48, BCS wrote: Hello Jacob, On 2010-06-28 02:28, BCS wrote: One solution would be to have templates strip off const/immutable from the top level of args. [...] This solution would match the proposal that popped up a while ago to allow value assignment from const/immutable to mutable. I don't think I understand what you're showing here. How would I strip off the const/immutable with a template ? I was proposing a language change Sorry for any confusion. The idea is that unless the user ask for it explicitly, there is no particular reason to preserve const/immutable for the value portion (true value types and the first level of references/pointers) of arguments. Ok, now I understand. -- /Jacob Carlborg
Re: @porperty problem..
On Mon, 28 Jun 2010 22:37:06 +0200, BLS windev...@hotmail.de wrote: Hi I have a forward reference pb in conjunction with @property. Err msg is : forward refrence to inferred return type of function call s1.servername. any ideas ? beside, where are the @property docs ? thanks, bjoern final class LoadBalancer { private static LoadBalancer lb; private Server[] servers; static this() { synchronized lb = new LoadBalancer; } private this() { Server s1 = new Server(); s1.servername = Server 1; // ERROR servers ~= s1; } public static LoadBalancer getLoadBalancer() { return lb; } @property nextServer() { return servers[0]; } class Server { private string _name, _id; @property servername(string name) { _name = name; } @property servername() { return _name; } } } Only place I've seen @property docs is in TDPL
Re: @porperty problem..
On 06/28/2010 03:47 PM, Steven Schveighoffer wrote: On Mon, 28 Jun 2010 16:37:06 -0400, BLS windev...@hotmail.de wrote: @property nextServer() { Shouldn't this be @property Server nextServer() { ??? auto functions?
Re: @porperty problem..
On Mon, 28 Jun 2010 16:55:01 -0400, Ellery Newcomer ellery-newco...@utulsa.edu wrote: On 06/28/2010 03:47 PM, Steven Schveighoffer wrote: On Mon, 28 Jun 2010 16:37:06 -0400, BLS windev...@hotmail.de wrote: @property nextServer() { Shouldn't this be @property Server nextServer() { ??? auto functions? I wasn't aware that @property implies auto. I guess that makes sense, but I didn't consider it anything but a hint to the compiler about how it could be called, not that did anything with the type. But I guess it's similar to static... -Steve
Re: @porperty problem..
On 28/06/2010 22:47, Steven Schveighoffer wrote: houldn't this be @property Server nextServer() { Ouch, you are right.. Interesting enough that @property nextServer() { return ...} compiles without giving any error message.. Anyway it seems to be a forward reference bug. moving the inner Server() class in front of LoadBalancer eliminates the error msg. bjoern
Re: @porperty problem..
On Mon, 28 Jun 2010 16:55:44 -0400, Rory McGuire rmcgu...@neonova.co.za wrote: On Mon, 28 Jun 2010 22:37:06 +0200, BLS windev...@hotmail.de wrote: beside, where are the @property docs ? Only place I've seen @property docs is in TDPL http://www.digitalmars.com/d/2.0/function.html#property-functions -Steve
Re: @porperty problem..
On 06/28/2010 03:58 PM, Steven Schveighoffer wrote: On Mon, 28 Jun 2010 16:55:01 -0400, Ellery Newcomer ellery-newco...@utulsa.edu wrote: On 06/28/2010 03:47 PM, Steven Schveighoffer wrote: On Mon, 28 Jun 2010 16:37:06 -0400, BLS windev...@hotmail.de wrote: @property nextServer() { Shouldn't this be @property Server nextServer() { ??? auto functions? I wasn't aware that @property implies auto. I guess that makes sense, but I didn't consider it anything but a hint to the compiler about how it could be called, not that did anything with the type. But I guess it's similar to static... -Steve There are a bunch of modifiers that do. protection modifiers and maybe align and a few others don't, but pretty much everything else does
Re: @porperty problem..
On 28/06/2010 22:58, Steven Schveighoffer wrote: I wasn't aware that @property implies auto. I guess that makes sense, but I didn't consider it anything but a hint to the compiler about how it could be called, not that did anything with the type. Hm, this snippet does not compile : class Server { private string _name, _id; @property servername(string name) { _name = name; } @property string servername() { return _name; } } remove string from @property and it works. On the other hand .. @property Server nextServer() { return servers[0]; } compiles fine ! Guess we need the official documents... Bjoern
Re: @porperty problem..
On 28/06/2010 23:00, Steven Schveighoffer wrote: http://www.digitalmars.com/d/2.0/function.html#property-functions -Steve Makes sense :) thanks
Re: @porperty problem..
BLS windev...@hotmail.de wrote: Hm, this snippet does not compile : class Server { private string _name, _id; @property servername(string name) { _name = name; } @property string servername() { return _name; } } remove string from @property and it works. Maybe it's because you haven't added string to the setter? Just grasping at straws here. -- Simen
Re: @porperty problem..
On 29/06/2010 00:07, Simen kjaeraas wrote: Maybe it's because you haven't added string to the setter? Just grasping at straws here. -- Simen Hi Simen, yes, thats the prob. I just have not found the @property docs.. thanks for all the help.. This snippet works now as expected.. D properties are just fine. Bjoern import std.stdio; import std.random; void main(string[] args) { LoadBalancer b1 = LoadBalancer.getLoadBalancer(); LoadBalancer b2 = LoadBalancer.getLoadBalancer(); LoadBalancer b3 = LoadBalancer.getLoadBalancer(); // Confirm these are the same instance if (b1 == b2 b2 == b3 ) { writeln(Same instance\n); } // Next, load 15 requests for a server for (int i = 0; i 15; i++) { string serverName = b1.nextServer.servername; writeln(Dispatch request to: ~ serverName); } } // D2 thread safe ?? singleton final class LoadBalancer { private static LoadBalancer lb; private Server[] servers; static this() { synchronized lb = new LoadBalancer; } private this() { Server s1 = new Server(); s1.servername = Server 1; s1.id = ; Server s2 = new Server(); s2.servername = Server 2; servers ~= s1; servers ~= s2; } public static LoadBalancer getLoadBalancer() { return lb; } @property { Server nextServer() { return servers[ uniform(0, servers.length) ]; } } // inner class class Server { private string _name, _id; @property { string servername(string sn) { return _name = sn; } string servername() { return _name; } string id(string id) { return _id = id; } string id() { return _id; } } } }
Re: What are delimited string, heredoc and D token strings?
On 27/06/10 1:03 PM, bearophile wrote: Pierre Rouleau: In what sense? This is valid D1 code: import std.stdio; void main() { string s = this is just a test; writefln(s); } Bye, bearophile Thanks! -- Pierre
How do I make an extern function?
module a; extern void foo( ); void bar( ) { foo( ); } module b; import std.stdio; void foo( ) { writeln( Hi! ); } The above does not work (Error 42: Symbol Undefined _D1a3fooFZv). Adding extern to foo in module b changes nothing. extern( C ) works, but seems like a hack. Better ideas? -- Simen
Re: How do I make an extern function?
On Monday, June 28, 2010 17:51:09 Simen kjaeraas wrote: module a; extern void foo( ); void bar( ) { foo( ); } module b; import std.stdio; void foo( ) { writeln( Hi! ); } The above does not work (Error 42: Symbol Undefined _D1a3fooFZv). Adding extern to foo in module b changes nothing. extern( C ) works, but seems like a hack. Better ideas? Um, extern isn't needed in D. All you need to do is make the function public and then import the module. I would expect this to work: module a; import b; void bar( ) { foo( ); } module b; import std.stdio; void foo( ) { writeln( Hi! ); } - Jonathan M Davis
Re: How do I make an extern function?
Hello Simen, module a; extern void foo( ); void bar( ) { foo( ); } module b; import std.stdio; void foo( ) { writeln( Hi! ); } The above does not work (Error 42: Symbol Undefined _D1a3fooFZv). Adding extern to foo in module b changes nothing. extern( C ) works, but seems like a hack. Better ideas? The issue is that the function called from module a is _D1a3fooFZv where the function defined in module b is _D1b3fooFZv ('a' - 'b') so they aren't the same function. extern(C) works because C doesn't mangle names so the function is foo in both cases. You can resolve this by having a a.di file with the extern foo(); in it (DMD has a flag to generate such a file for you). OTOH without knowing what you are doing, I can't tell if this is the correct solution. -- ... IXOYE
Grokking std.container and Ranges
I thought I understood ranges until I actually started trying to use them. Now I'm having difficulties with the new range-based containers. So I've got two issues right now, grokking ranges and understanding the container interfaces. Given an SList, I want to do the following: foreach(obj; list) { if(obj.pleaseKillMe) somehow_remove_the_object_from_the_list(); } Part of my problem is I'm not entirely clear what's going on with the foreach. I know it's iterating a range, but is it the SList itself being iterated, or is it a range returned by SList.opSlice? I assume the latter, which at one point led me to try this (thinking of Java's iterator.remove()): auto r = list[]; foreach(obj; r) { if(obj.pleaseKillMe) r.popFront(); } Which, of course, didn't work. I see that popFront doesn't actually 'pop' anything off of, or out of, the range as it would in a traditional stack or a queue. The foreach doc says about range.popFront: move the left edge of the range right one Meaning, it's more like a next() than the pop() I'm familiar with (recalibrating all those years of C and Java terminology is not easy). And even if it did, changes to the range do not propagate to the underlying container. I understand that, at least (now). So apparently I want something like the list.stableRemove*() variants, which the docs say remove an item from a container without invalidating any ranges currently iterating the container. Great! Only, there's no variant that accepts a single item. SList has removeFront and removeAny, and ranges can be removed via linearRemove. I can insert individual items fine. But how do I remove them?
Re: Grokking std.container and Ranges
Hello Mike, I want to do the following: foreach(obj; list) { if(obj.pleaseKillMe) somehow_remove_the_object_from_the_list(); } That isn't legal for normal arrays or AAs. IIRC the docs even say that you can't change what a foreach is iterating over during the foreach. I think you will have to convert to a manual for loop to make it work. That said, I've not worked with range at all. -- ... IXOYE