Associative array and ranges
Hey guys, I have an associative array like this: T[hash_t] myArray; (T means the template type). Is there any chance to cast/convert this array to an indexed array or is it possible to iterate over specific indices? I know that there is something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way. It's for a game and I think every next()-call influences the fps. I hope there is any solution for my problem :) - Thanks!
Re: ASM access to array
As bearophile notet, unittest are always good!! But for the start, I always liked to make some pretty-printing functions ... ... so this is my version import std.stdio; uint rotl_d(uint value,ubyte rotation){ return (valuerotation) | (value(value.sizeof*8 - rotation)); } uint rotl_asm(uint value,ubyte rotation){ asm{ mov EAX, value; // get first argument mov CL , rotation; // how many bits to move rol EAX, CL; }// return with result in EAX } void bin_writeln(string info,uint value, bool nl){ writefln(%1s: %02$32b%3$s,info,value,nl?\n:); } int main(string[] argv){ uint a=0xc0def00d; bin_writeln(value a,a ,false); bin_writeln(value b,rotl_d(a,1),true); // bin_writeln(value a,a ,false); bin_writeln(value b,rotl_asm(a,1),true); return 0; } greets Matthias
higher-order funcs for ranges (with usual interface)
Hello, This bit of code for arrays: Out[] map (In,Out) (In[] input, Out delegate (In) f) { Out[] output = new Out[](input.length); foreach (i,item ; input) output [i] = f(item); return output; } unittest { char character (uint code) {return cast(char)code;} uint[] codes = [0x61,0x62,0x63]; // functional style writeln(map(codes, character));// abc // OO style writeln(codes.map(character)); // abc } How to write this for ranges? I mean, with the same kind of interface to client code (not the interface of std.algo.map). And is there a way to write it so that it works both for ranges and other kinds of sequences (arrays, strings); or even for anything iterable (AA, set, list, tree...). For ranges, I'm looking for something similar to: Range!Out map (In,Out) (Range!In input, Out delegate (In) f) {...} Indeed, the compiler should understand that Range!T is a type id just like T[]. Denis -- _ vita es estrany spir.wikidot.com
Re: higher-order funcs for ranges (with usual interface)
On Wed, 02 Feb 2011 13:26:39 +0100, spir wrote: Hello, This bit of code for arrays: Out[] map (In,Out) (In[] input, Out delegate (In) f) { Out[] output = new Out[](input.length); foreach (i,item ; input) output [i] = f(item); return output; } unittest { char character (uint code) {return cast(char)code;} uint[] codes = [0x61,0x62,0x63]; // functional style writeln(map(codes, character));// abc // OO style writeln(codes.map(character)); // abc } How to write this for ranges? [...] For ranges, I'm looking for something similar to: Range!Out map (In,Out) (Range!In input, Out delegate (In) f) {...} Indeed, the compiler should understand that Range!T is a type id just like T[]. I don't think it's possible to do it exactly as you describe. I mean, Range in that case can be anything, and you can't always return a range of the same kind. Two possibilities are, you can do it eagerly, Out[] map(Range, In, Out)(Range input, Out delegate(In) f) if (isInputRange!Range is(ElementType!Range : In)) { ... } or you can do it lazily by defining your own map range (untested): struct Map(Range, In, Out) if (isInputRange!Range is(ElementType!Range : In) { Range input; Out delegate(In) f; @property bool empty() { return input.empty; } // Inefficient, should cache front... @property Out front() { return f(input.front); } void popFront() { input.popFront(); } } Map!(Range, Out) map(Range, In, Out)(Range input, Out delegate(In) f) if (isInputRange!R is(ElementType!Range : In) { return typeof(return)(input, f); } -Lars
Re: higher-order funcs for ranges (with usual interface)
On Wed, 02 Feb 2011 13:18:07 +, Lars T. Kyllingstad wrote: [...] struct Map(Range, In, Out) if (isInputRange!Range is(ElementType!Range : In) { Range input; Out delegate(In) f; @property bool empty() { return input.empty; } // Inefficient, should cache front... @property Out front() { return f(input.front); } void popFront() { input.popFront(); } } Map!(Range, Out) map(Range, In, Out)(Range input, Out delegate(In) f) if (isInputRange!R is(ElementType!Range : In) { return typeof(return)(input, f); } Oops, seems i missed a few closing parentheses on the template constraints. -Lars
Re: Associative array and ranges
Nrgyzer nrgy...@gmail.com wrote: Hey guys, I have an associative array like this: T[hash_t] myArray; (T means the template type). Is there any chance to cast/convert this array to an indexed array or is it possible to iterate over specific indices? I know that there is something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way. It's for a game and I think every next()-call influences the fps. I hope there is any solution for my problem :) - Thanks! You should probably try aa.byValue: auto o = [a: 1, b: 2]; foreach ( e; o.byValue ) { writeln( e ); } It seems from the (somewhat unreadable) source, that the values are stored in an array of pointers to structs holding these values. If this is not fast enough for your needs, I'm afraid you will have to write an AA implementation yourself. (You can replace the code in druntime/src/rt/aaA.d with your own if you still want the nice syntax sugar) -- Simen
default '==' on structs
Hello, What are the default semantics for '==' on structs? I ask this because I was forced to write opEquals on a struct to get expected behaviour. This struct is basically: struct Lexeme { string tag; string slice; Ordinal index; } Equal Lexeme's compare unequal using default '=='. When I add: const bool opEquals (ref const(Lexeme) l) { return ( this.tag == l.tag this.slice == l.slice this.index == l.index ); } then all works fine. What do I miss? Denis -- _ vita es estrany spir.wikidot.com
Re: default '==' on structs
On Wed, 02 Feb 2011 15:55:53 +0100, spir wrote: Hello, What are the default semantics for '==' on structs? I ask this because I was forced to write opEquals on a struct to get expected behaviour. This struct is basically: struct Lexeme { string tag; string slice; Ordinal index; } Equal Lexeme's compare unequal using default '=='. When I add: const bool opEquals (ref const(Lexeme) l) { return ( this.tag == l.tag this.slice == l.slice this.index == l.index ); } then all works fine. What do I miss? I think the compiler does a bitwise comparison in this case, meaning that it compares the arrays' pointers instead of their data. Related bug report: http://d.puremagic.com/issues/show_bug.cgi?id=3433 -Lars
Re: Associative array and ranges
On Wednesday 02 February 2011 02:11:34 Nrgyzer wrote: Hey guys, I have an associative array like this: T[hash_t] myArray; (T means the template type). Is there any chance to cast/convert this array to an indexed array or is it possible to iterate over specific indices? I know that there is something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way. It's for a game and I think every next()-call influences the fps. I hope there is any solution for my problem :) - Thanks! If you know which keys you want, then just have a list of those and iterate over them, and then use them to grab their corresponding values from the AA on each iteration. As far as iterating over the AA itself goes, either you're iterating over the keys, the values, or both. You can't iterate over just part of it. I haven't a clue how such a thing would be implemented anyway. But there's nothing to stop you from iterating over a list of the keys that you want and then using those keys to grab the values from the AA. - Jonathan M Davis
Re: default '==' on structs
On 02/02/2011 04:20 PM, Lars T. Kyllingstad wrote: On Wed, 02 Feb 2011 15:55:53 +0100, spir wrote: Hello, What are the default semantics for '==' on structs? I ask this because I was forced to write opEquals on a struct to get expected behaviour. This struct is basically: struct Lexeme { string tag; string slice; Ordinal index; } Equal Lexeme's compare unequal using default '=='. When I add: const bool opEquals (ref const(Lexeme) l) { return ( this.tag == l.tag this.slice == l.slice this.index == l.index ); } then all works fine. What do I miss? I think the compiler does a bitwise comparison in this case, meaning that it compares the arrays' pointers instead of their data. Related bug report: http://d.puremagic.com/issues/show_bug.cgi?id=3433 -Lars Thank you, Lars. In fact, I do not really understand what you mean. But it helped me think further :-) Two points: * The issue reported is about '==' on structs not using member opEquals when defined, instead performing bitwise comparison. This is not my case: Lexeme members are plain strings and an uint. They should just be compared as is. Bitwise comparison should just work fine. Also, this issue is marked solved for dmd 2.037 (I use 2.051). * The following works as expected: struct Floats {float f1, f2;} struct Strings {string s1, s2;} struct Lexeme { string tag; string slice; uint index; } unittest { assert ( Floats(1.1,2.2) == Floats(1.1,2.2) ); assert ( Strings(a,b) == Strings(a,b) ); assert ( Lexeme(a,b,1) == Lexeme(a,b,1) ); } This shows, if I'm right: 1. Array (string) members are compared by value, not by ref/pointer. 2. Comparing Lexeme's works in this test case. * Why does my app then need opEquals, just to compare member per member (see code above)? The issue happens in a unittest. Lexemes are generated by a typical use of the module's features, then assert() compares them to expected result: assert ( lexeme == Lexeme(expected_data) ); I'll try to reduce the issue to isolate the key point. Thank you for your help, denis -- _ vita es estrany spir.wikidot.com
Re: default '==' on structs
What is Ordinal defined as? If it's a uint, I get the expected results: alias uint Ordinal; struct Lexeme { string tag; string slice; Ordinal index; } void main() { auto lex1 = Lexeme(a,b,1); auto lex2 = Lexeme(a,b,1); assert(lex1 == lex2); assert(lex1 == Lexeme(a,b,1)); } Can't say much more without knowing what your app does though.
Re: higher-order funcs for ranges (with usual interface)
On 02/02/2011 02:18 PM, Lars T. Kyllingstad wrote: On Wed, 02 Feb 2011 13:26:39 +0100, spir wrote: Hello, This bit of code for arrays: Out[] map (In,Out) (In[] input, Out delegate (In) f) { Out[] output = new Out[](input.length); foreach (i,item ; input) output [i] = f(item); return output; } unittest { char character (uint code) {return cast(char)code;} uint[] codes = [0x61,0x62,0x63]; // functional style writeln(map(codes,character));// abc // OO style writeln(codes.map(character)); // abc } How to write this for ranges? [...] For ranges, I'm looking for something similar to: Range!Out map (In,Out) (Range!In input, Out delegate (In) f) {...} Indeed, the compiler should understand that Range!T is a type id just like T[]. I don't think it's possible to do it exactly as you describe. I mean, Range in that case can be anything, and you can't always return a range of the same kind. Right. The output range's ElementType is given by f's return type. As you say, the kind of range may change. Even if it's the same, how could one express that: range_which-elements-are-of-type-T, syntactically and in the param set, just like array_which-elements-are-of-type- is written T[]? Currently, we must (1) declare the range type as template param, which is a bit redondant because the ElementType must also be given, (2) add some 'is' horror code: if (isInputRange!Range is(ElementType!Range : In)) I guess the only solution would be for the compiler to support a kind of reange type syntax? Two possibilities are, you can do it eagerly, Out[] map(Range, In, Out)(Range input, Out delegate(In) f) if (isInputRange!Range is(ElementType!Range : In)) { ... } OK. or you can do it lazily by defining your own map range (untested): struct Map(Range, In, Out) if (isInputRange!Range is(ElementType!Range : In) { Range input; Out delegate(In) f; @property bool empty() { return input.empty; } // Inefficient, should cache front... @property Out front() { return f(input.front); } void popFront() { input.popFront(); } } That's similar to what I did. Map!(Range, Out) map(Range, In, Out)(Range input, Out delegate(In) f) if (isInputRange!R is(ElementType!Range : In) { return typeof(return)(input, f); } What's the point of map, then? My version initially had a 'MapRange' defined as static struct template inside map, but then map just instanciated it, so I suppressed map alltogether, letting the user write: auto r2 = MapRange!(R1, In, Out)(input, f); which is not more complicated than calling the func, I guess. -Lars Denis -- _ vita es estrany spir.wikidot.com
Re: Associative array and ranges
Nrgyzer: Is there any chance to cast/convert this array to an indexed array or is it possible to iterate over specific indices? I know that there is something like next() for the foreach-statement but when the array contains some thousand instances and I only want iterate over (for example) 5 elements I think that's the wrong way. Show a hypothetical code example of what you desire to do, please. Bye, bearophile
Re: default '==' on structs
spir: * The issue reported is about '==' on structs not using member opEquals when defined, instead performing bitwise comparison. This is not my case: Lexeme members are plain strings and an uint. They should just be compared as is. Bitwise comparison should just work fine. Also, this issue is marked solved for dmd 2.037 (I use 2.051). Lars is right, the == among structs is broken still: struct Foo { string s; } void main() { string s1 = he; string s2 = llo; string s3 = hel; string s4 = lo; auto f1 = Foo(s1 ~ s2); auto f2 = Foo(s3 ~ s4); assert((s1 ~ s2) == (s3 ~ s4)); assert(f1 == f2); } Bye, bearophile
Re: default '==' on structs
On 02/02/2011 05:49 PM, Andrej Mitrovic wrote: What is Ordinal defined as? If it's a uint, I get the expected results: alias uint Ordinal; struct Lexeme { string tag; string slice; Ordinal index; } void main() { auto lex1 = Lexeme(a,b,1); auto lex2 = Lexeme(a,b,1); assert(lex1 == lex2); assert(lex1 == Lexeme(a,b,1)); } Can't say much more without knowing what your app does though. Actually, its size_t. But I also have everything working fine in a test case exactly similar to yours (see other post). Dunno yet why I need to add an opEquals just comparing members individually for my unittests to pass. I take the opportunity to say a few words about the module; case (1) it helps debugging (2) some people are interested in it. The module is a lexing toolkit. It allows creating a lexer from a language's morphology, then use it to scan source. Example for simple arithmetics: Morphology morphology = [ [ SPACING ,`[\ \t]*` ], [ OPEN_GROUP , `(` ], [ CLOSE_GROUP ,`)` ], [ operator , `[+*-/]` ], [ symbol , `[a-zA-A][a-zA-A0-9]*` ], [ number , `[+-]?[0-9]+(\.[0-9]+)?` ], ]; auto lexer = new Lexer(morphology); auto lexemes = lexer.lexemes(source); As you see, each lexeme kind is defined by a string tag and a regex format. The output is an array of lexemes holding the matched slice, wrapped in a class LexemeStream. This class mainly provides a match method: Lexeme* match (tag) Match returns a pointer to the current lexeme if it is of the right kind, else null (same principle as D's builtin 'in' operator). So, one can either ignore the lexeme if all what is needed is testing the match (case of punctuation), or use the lexeme's slice (case of values). The issue I get happens when checking that a result stream of lexemes is as expected: '==' failed. I then checked its first/last lexemes only: ditto. Thus, I started to wonder about the default semantics of '==' for structs, so that I wrote my own opEquals == pass for individual lexemes, pass for whole lexeme streams. Why? dunno. Denis -- _ vita es estrany spir.wikidot.com
Re: default '==' on structs
On 02/02/2011 07:05 PM, bearophile wrote: spir: * The issue reported is about '==' on structs not using member opEquals when defined, instead performing bitwise comparison. This is not my case: Lexeme members are plain strings and an uint. They should just be compared as is. Bitwise comparison should just work fine. Also, this issue is marked solved for dmd 2.037 (I use 2.051). Lars is right, the == among structs is broken still: struct Foo { string s; } void main() { string s1 = he; string s2 = llo; string s3 = hel; string s4 = lo; auto f1 = Foo(s1 ~ s2); auto f2 = Foo(s3 ~ s4); assert((s1 ~ s2) == (s3 ~ s4)); assert(f1 == f2); } Thank you, this helps much. I don't get the details yet, but think some similar issue is playing a role in my case. String members of the compared Lexeme structs are not concatenated, but one of them is sliced from the scanned source. If I dup'ed instead of slicing, this would create brand new strings; thus '==' performing bitwise comp should run fine, don't you think? I'll try in a short while. Do you know more about why/how the above fails? Denis -- _ vita es estrany spir.wikidot.com
Re: default '==' on structs
On 02/02/2011 07:09 PM, bearophile wrote: Lars is right, the == among structs is broken still: If necessary please open a new bug report, this is an important bug. Right, i'll do it when (hopefully) I understand more about the details of why/how '==' fails in my case. Denis -- _ vita es estrany spir.wikidot.com
Re: default '==' on structs
On 02/02/2011 07:09 PM, bearophile wrote: Lars is right, the == among structs is broken still: If necessary please open a new bug report, this is an important bug. Bye, bearophile Right, reduced the bug cases I found to: struct S {string s;} unittest { // concat string s1 = he; string s2 = llo; string s3 = hel; string s4 = lo; assert ( S(s1 ~ s2) != S(s3 ~ s4) ); // slice string s = hello; assert ( S(s[1..$-1]) != S(ell) ); } Same for array members (indeed): struct A {int[] a;} unittest { // concat int[] a1 = [1,2]; int[] a2 = [3]; int[] a3 = [1]; int[] a4 = [2,3]; assert ( A(a1 ~ a2) != A(a3 ~ a4) ); // slice int[] a = [1,2,3]; assert ( A(a[1..$-1]) != A([2]) ); } But this is not very relevant, because plain arrays /members/ (unlike strings) seem to be compared by ref (exactly by array struct): unittest { // string string s1 = hello; string s2 = hello; assert ( S(s1) == S(s2) ); // array (note '!=' assert) int[] a1 = [1,2,3]; int[] a2 = [1,2,3]; assert ( A(a1) != A(a2) ); } I think at opening a new bug report in a short while, with reference to issue #3433 (http://d.puremagic.com/issues/show_bug.cgi?id=3433) which was (unduly?) marked as fixed for dmd 2.037. In the meanwhile, if anyone knows about related cases of bug, or has more info, please tell. On the other hand, the example of arrays let me doubt about correct / desirable semantics. 1. Indeed, I think string members should be compared by value. 2. But arrays are not, so should strings be compared by ref as well, if only to avoid inconsistency? 3. But then, why the already existing difference between strings arrays? 4. Or should arrays be compared by value like string? 5. But strings are not /really/ compared by value as of now... The current behaviour is weird. I don't how it can only happen. Denis -- _ vita es estrany spir.wikidot.com
Foreach type infering only works up to 2 levels?
int[][][][] multiArray; void main() { foreach (one, two; multiArray) // ok { } foreach (one, two, three; multiArray) // fail { } } test.d(13): Error: cannot infer type for two test.d(13): Error: cannot infer type for three Same thing happens with hashes as well. Is this a limitation in the language or a bug?
Re: default '==' on structs
spir: Do you know more about why/how the above fails? It's simple. A string (or array) is a 2-words long struct that contains a pointer to the data and a size_t length. Default struct equality just compares the bits of those two fields. In the above example I have created f1 and f2 using two strings that have the same contents and lengths, but the pointers are different, because they are generated at run-time (normally the compiler uses a pool of shared string literals), so the equality fails. I have asked Walter to fix this problem with strings and arrays probably three years ago or more, it's not a new problem :-) Bye, bearophile
Re: Foreach type infering only works up to 2 levels?
Andrej Mitrovic Wrote: Wow disregard this whole post. I've just realized how stupid that looks. Sorry. :) See, you have material for a tutorial. I know you wouldn't run out.
Re: Foreach type infering only works up to 2 levels?
On 2/2/11, Jesse Phillips jessekphillip...@gmail.com wrote: Andrej Mitrovic Wrote: Wow disregard this whole post. I've just realized how stupid that looks. Sorry. :) See, you have material for a tutorial. I know you wouldn't run out. Actually, yes. TDPL doesn't discuss much about multidimensional data, other than the simple 2-dimensional arrays (IIRC).
Re: default '==' on structs
On 02/02/2011 07:41 PM, spir wrote: On 02/02/2011 07:05 PM, bearophile wrote: spir: * The issue reported is about '==' on structs not using member opEquals when defined, instead performing bitwise comparison. This is not my case: Lexeme members are plain strings and an uint. They should just be compared as is. Bitwise comparison should just work fine. Also, this issue is marked solved for dmd 2.037 (I use 2.051). Lars is right, the == among structs is broken still: struct Foo { string s; } void main() { string s1 = he; string s2 = llo; string s3 = hel; string s4 = lo; auto f1 = Foo(s1 ~ s2); auto f2 = Foo(s3 ~ s4); assert((s1 ~ s2) == (s3 ~ s4)); assert(f1 == f2); } Thank you, this helps much. I don't get the details yet, but think some similar issue is playing a role in my case. String members of the compared Lexeme structs are not concatenated, but one of them is sliced from the scanned source. If I dup'ed instead of slicing, this would create brand new strings; thus '==' performing bitwise comp should run fine, don't you think? I'll try in a short while. No! idup does not help, still need opEquals. See also this example case: struct S {string s;} unittest { // concat string s1 = he; string s2 = llo; string s3 = hel; string s4 = lo; assert ( S(s1 ~ s2) != S(s3 ~ s4) ); // slice string s = hello; assert ( S(s[1..$-1]) != S(ell) ); // idup'ed assert ( S(s[1..$-1].idup) != S(ell) ); s2 = s[1..$-1].idup; assert ( S(s2) != S(ell) ); } Denis -- _ vita es estrany spir.wikidot.com
Re: default '==' on structs
On 02/02/2011 08:20 PM, bearophile wrote: spir: Do you know more about why/how the above fails? It's simple. A string (or array) is a 2-words long struct that contains a pointer to the data and a size_t length. Default struct equality just compares the bits of those two fields. In the above example I have created f1 and f2 using two strings that have the same contents and lengths, but the pointers are different, because they are generated at run-time (normally the compiler uses a pool of shared string literals), so the equality fails. I have asked Walter to fix this problem with strings and arrays probably three years ago or more, it's not a new problem :-) All right, you mean string literals are interned? Explaining why the case below works... struct S {string s;} unittest { // plainly equal members string s01 = hello; string s02 = hello; assert ( S(s01) == S(s02) ); } ... because s01 s02 are actually the same, unique, piece of data in memory (thus pointers are equal indeed)? I'm ok to write another bug report as you asked. But since you've asked for this already, and there is bug#3433 on a very similar topic supposedly closed as well, I fear it's useless, don't you? And if we fix string, then the case of regular arrays becomes inconsistent. The code issue about clear semantics, I guess, is that the case above works *due to* an implementation detail. The rest is just annoying (need to write opequals to get expected semantics in 99% cases, probably), but /not/ inconsistent. Denis -- _ vita es estrany spir.wikidot.com
Re: Foreach type infering only works up to 2 levels?
Am 02.02.2011 20:16, schrieb Andrej Mitrovic: int[][][][] multiArray; void main() { foreach (one, two; multiArray) // ok { } foreach (one, two, three; multiArray) // fail { } } test.d(13): Error: cannot infer type for two test.d(13): Error: cannot infer type for three Same thing happens with hashes as well. Is this a limitation in the language or a bug? I use the following idiom. foreach(x, ref column; array) foreach(y, ref element; column) //maybe more... { //do something } It works because of constructs take one staement one block is one statement. It is really great because it leads to such flexible soultions. You might say it's bad practise bad then you have to say the same about 'else if'. Mafi
Re: Foreach type infering only works up to 2 levels?
On 2/2/11, Mafi m...@example.org wrote: foreach(x, ref column; array) foreach(y, ref element; column) //maybe more... { //do something } Cool, that fixes the indentation issue. Nice.
Re: default '==' on structs
spir: And if we fix string, then the case of regular arrays becomes inconsistent. The bug report is about arrays too, of course. I will write this bug report. Bye, bearophile
Is runtime introspection in a working state?
After exploring object.d/di I've found upon some functions I can use on a type returned by .classinfo. But getMembers which I'm interested in doesn't seem to work: import std.stdio; class Foo { int x; void bar() { } } void main() { Foo foo = new Foo(); auto info = foo.classinfo; auto barField = info.getMembers(bar); writeln(typeid(barField)); // const(const(object.MemberInfo)[]) writeln(barField.length); // 0 auto fields = info.getMembers(null); writeln(typeid(fields));// const(const(object.MemberInfo)[]) writeln(fields.length); // 0 } I can get other methods to work, such as toString and tsize. But no luck with getMembers.
Re: default '==' on structs
The bug report is about arrays too, of course. I will write this bug report. http://d.puremagic.com/issues/show_bug.cgi?id=5519 Bye, bearophile
Re: ASM access to array
What about my edited version: import std.stdio; uint rotl_d(uint value,ubyte rotation){ return (valuerotation) | (value(value.sizeof*8 - rotation)); } uint rotl_asm(uint value,ubyte rotation){ asm{ mov EAX, value; // get first argument mov CL , rotation; // how many bits to move rol EAX, CL; }// return with result in EAX } void bin_writeln(string info,uint value, bool nl){ writefln(%1s: %02$32b%3$s,info,value,nl?\n:); } int main(string[] argv){ uint a=0xc0def00d; bin_writeln(value a,a ,false); bin_writeln(value b,rotl_d(a,1),true); // bin_writeln(value a,a ,false); bin_writeln(value b,rotl_asm(a,1),true); uint b; ubyte c = 0; while ( 1 == 1 ) { // Press Ctrl + C to quit b = rotl_asm(0xc0def00d, c); foreach (rst; 0 .. 5_000 ) writef(%032b %2d\r,b, c ); c = cast(ubyte)( c + 1 == 32 ? 0 : c + 1 ); } return 0; }
Accessing this of containing class
Hi, Is there a method to access this reference of the container class from an inner class. i.e. class A { class B { methodM() { callAnotherM(A::this or A.this); } } } Thanks Mandeep
Re: Accessing this of containing class
On Wednesday 02 February 2011 21:26:00 Mandeep Singh Brar wrote: Hi, Is there a method to access this reference of the container class from an inner class. i.e. class A { class B { methodM() { callAnotherM(A::this or A.this); } } } The outer class is referenced via the property outer. However, if the inner class is static, then it has no such property and is not tied to a specific instance of the outer class. In such a case, it can access the private members of an instance of the outer class, but it's not tied to an particular instance. Non-static inner classes (like yours above), however, _are_ tied to a particular instance of the outer class, and they have the outer property which is the this of the outer class. - Jonathan M Davis
Re: higher-order funcs for ranges (with usual interface)
On Wed, 02 Feb 2011 18:38:02 +0100, spir wrote: On 02/02/2011 02:18 PM, Lars T. Kyllingstad wrote: On Wed, 02 Feb 2011 13:26:39 +0100, spir wrote: Hello, This bit of code for arrays: Out[] map (In,Out) (In[] input, Out delegate (In) f) { Out[] output = new Out[](input.length); foreach (i,item ; input) output [i] = f(item); return output; } unittest { char character (uint code) {return cast(char)code;} uint[] codes = [0x61,0x62,0x63]; // functional style writeln(map(codes,character));// abc // OO style writeln(codes.map(character)); // abc } How to write this for ranges? [...] For ranges, I'm looking for something similar to: Range!Out map (In,Out) (Range!In input, Out delegate (In) f) {...} Indeed, the compiler should understand that Range!T is a type id just like T[]. I don't think it's possible to do it exactly as you describe. I mean, Range in that case can be anything, and you can't always return a range of the same kind. Right. The output range's ElementType is given by f's return type. As you say, the kind of range may change. Even if it's the same, how could one express that: range_which-elements-are-of-type-T, syntactically and in the param set, just like array_which-elements-are-of-type- is written T[]? Currently, we must (1) declare the range type as template param, which is a bit redondant because the ElementType must also be given, (2) add some 'is' horror code: if (isInputRange!Range is(ElementType!Range : In)) I guess the only solution would be for the compiler to support a kind of reange type syntax? I'm not sure I understand what you mean here. Perhaps you're looking for something like concepts, which have been discussed for both D and C++0x but rejected in both languages: http://en.wikipedia.org/wiki/Concept_%28generic_programming%29 Anyway, if the source and target range are of the same (known) kind, something like this should work: struct MyRange(T) { ... } MyRange!Out map(In, Out)(MyRange!In input, Out delegate(In) f) { ... } If they are of different kinds, but still known, this should work: struct MySourceRange(T) { ... } struct MyTargetRange(T) { ... } MyTargetRange!Out map(In, Out) (MySourceRange!In input, Out delegate(In) f) { ... } Note that I am only talking about what the compiler should be able to figure out through IFTI (implicit function template instantiation), and not about actual implementation. Two possibilities are, you can do it eagerly, Out[] map(Range, In, Out)(Range input, Out delegate(In) f) if (isInputRange!Range is(ElementType!Range : In)) { ... } OK. or you can do it lazily by defining your own map range (untested): struct Map(Range, In, Out) if (isInputRange!Range is(ElementType!Range : In) { Range input; Out delegate(In) f; @property bool empty() { return input.empty; } // Inefficient, should cache front... @property Out front() { return f(input.front); } void popFront() { input.popFront(); } } That's similar to what I did. Map!(Range, Out) map(Range, In, Out)(Range input, Out delegate(In) f) if (isInputRange!R is(ElementType!Range : In) { return typeof(return)(input, f); } What's the point of map, then? My version initially had a 'MapRange' defined as static struct template inside map, but then map just instanciated it, so I suppressed map alltogether, letting the user write: auto r2 = MapRange!(R1, In, Out)(input, f); which is not more complicated than calling the func, I guess. map() is just a helper function. Unlike struct literals/constructors, functions can make use of IFTI, which makes for much prettier code: // The range from my example, without map() auto result = Map!(SomeRange!int, int, bool)(someRange, someDelegate); // The range from my example, with map() auto result = map(someInputRange, someDelegate); This has become a quite common idiom in Phobos. std.range, for instance, is littered with helper functions like this: Retro, retro() Stride, stride() Chain, chain() ... The list goes on. -Lars