digitalmars.D.learn - Convert this C macro kroundup32 to D mixin?
- biocyberman (10/10) Apr 08 2017 What is the D mixin version equivalent to this macro:
- Mike Parker (5/15) Apr 08 2017 I would expect if you implement it as a function the compiler
- Mike Parker (12/16) Apr 08 2017 This gives me no error, so it does inline it.
- biocyberman (32/42) Apr 08 2017 I also came up with this:
- Nicholas Wilson (34/76) Apr 08 2017 The ':' means that it applies to everything that follows it, so
- biocyberman (4/37) Apr 08 2017 This thing now is clear and settled while I try to navigate my
- biocyberman (3/7) Apr 08 2017 Thanks for mentioning pragma. However, anyway to do it with
- =?UTF-8?Q?Ali_=c3=87ehreli?= (30/39) Apr 08 2017 You can mixin declarations with a template but I don't see how it can
- biocyberman (9/40) Apr 09 2017 You made the point, it looks really ugly :). However, sometimes
What is the D mixin version equivalent to this macro: #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) The macro looks cryptic. What the macro does has been explained here: http://stackoverflow.com/questions/3384852/could-someone-help-explain-what-this-c-one-liner-does But I still don't know how to convert that to D mixin. I would like 'mixin' instead of a function is to avoid function call overhead. Also because it is short, so I think a mixin is enough, not a 'template mixin'.
Apr 08 2017
On Saturday, 8 April 2017 at 09:53:47 UTC, biocyberman wrote:What is the D mixin version equivalent to this macro: #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) The macro looks cryptic. What the macro does has been explained here: http://stackoverflow.com/questions/3384852/could-someone-help-explain-what-this-c-one-liner-does But I still don't know how to convert that to D mixin. I would like 'mixin' instead of a function is to avoid function call overhead. Also because it is short, so I think a mixin is enough, not a 'template mixin'.I would expect if you implement it as a function the compiler will inline it. You can always use the pragma(inline, true) [1] with -inline to verify. [1] https://dlang.org/spec/pragma.html#inline
Apr 08 2017
On Saturday, 8 April 2017 at 10:02:01 UTC, Mike Parker wrote:I would expect if you implement it as a function the compiler will inline it. You can always use the pragma(inline, true) [1] with -inline to verify. [1] https://dlang.org/spec/pragma.html#inlineThis gives me no error, so it does inline it. T kroundup32(T)(T x) { pragma(inline, true); --(x); (x)|=(x)>>1; (x)|=(x)>>2; (x)|=(x)>>4; (x)|=(x)>>8; (x)|=(x)>>16; return ++(x); }
Apr 08 2017
On Saturday, 8 April 2017 at 10:09:47 UTC, Mike Parker wrote:T kroundup32(T)(T x) { pragma(inline, true); --(x); (x)|=(x)>>1; (x)|=(x)>>2; (x)|=(x)>>4; (x)|=(x)>>8; (x)|=(x)>>16; return ++(x); }I also came up with this: import std.stdio; pragma( inline, true ): static int kroundup32( int x){ --(x); writeln("X: ",x); (x)|=(x)>>1; writeln("X: ",x); (x)|=(x)>>2; writeln("X: ",x); (x)|=(x)>>4; writeln("X: ",x); (x)|=(x)>>8; writeln("X: ",x); (x)|=(x)>>16; writeln("X: ",x); ++(x); writeln("X: ",x); return x; } int main(){ int num = 31; num = kroundup32(num); writeln("Num:", num); return 0; } Is this way of using pragma the same as your way? I am still new to this so I want to understand more. And is it a good idea to do manipulate 'num' directly so I can omit 'return' and avoid re-assigning statement? That's what C version does.
Apr 08 2017
On Saturday, 8 April 2017 at 11:01:34 UTC, biocyberman wrote:On Saturday, 8 April 2017 at 10:09:47 UTC, Mike Parker wrote:The ':' means that it applies to everything that follows it, so while it doesn't matters in this example if you had pragma( inline, true ): int kroundup32( int x) { ... } auto someVeryLargeFunction( Args args) { // ... } and then you used someVeryLargeFunction in a bunch of places then that would cause a lot of binary bloat.T kroundup32(T)(T x) { pragma(inline, true); --(x); (x)|=(x)>>1; (x)|=(x)>>2; (x)|=(x)>>4; (x)|=(x)>>8; (x)|=(x)>>16; return ++(x); }I also came up with this: import std.stdio; pragma( inline, true ): static int kroundup32( int x){ --(x); writeln("X: ",x); (x)|=(x)>>1; writeln("X: ",x); (x)|=(x)>>2; writeln("X: ",x); (x)|=(x)>>4; writeln("X: ",x); (x)|=(x)>>8; writeln("X: ",x); (x)|=(x)>>16; writeln("X: ",x); ++(x); writeln("X: ",x); return x; } int main(){ int num = 31; num = kroundup32(num); writeln("Num:", num); return 0; } Is this way of using pragma the same as your way? I am still new to this so I want to understand more.And is it a good idea to do manipulate 'num' directly so I can omit 'return' and avoid re-assigning statement? That's what C version does.if you want the the function to affect the variable use a 'ref' as in void kroundup32(T)(ref T x) { pragma(inline, true); --(x); (x)|=(x)>>1; (x)|=(x)>>2; (x)|=(x)>>4; (x)|=(x)>>8; (x)|=(x)>>16; return ++(x); } int main(){ int num = 31; writeln("Before: ",num); // 31 kroundup32(num); writeln("After: ", num); //32 return 0; } is it a good idea? I would not think it is necessary. As an aside the C version has parentheses around the "x" because it is a macro and it is substituted as text not symbolically, they are not needed in D.
Apr 08 2017
On Saturday, 8 April 2017 at 11:24:02 UTC, Nicholas Wilson wrote:The ':' means that it applies to everything that follows it, so while it doesn't matters in this example if you had pragma( inline, true ): int kroundup32( int x) { ... } auto someVeryLargeFunction( Args args) { // ... } and then you used someVeryLargeFunction in a bunch of places then that would cause a lot of binary bloat.That's big difference! Thank you for pointing this out for me.if you want the the function to affect the variable use a 'ref' as in void kroundup32(T)(ref T x) { pragma(inline, true); --(x); (x)|=(x)>>1; (x)|=(x)>>2; (x)|=(x)>>4; (x)|=(x)>>8; (x)|=(x)>>16; return ++(x); } int main(){ int num = 31; writeln("Before: ",num); // 31 kroundup32(num); writeln("After: ", num); //32 return 0; } is it a good idea? I would not think it is necessary. As an aside the C version has parentheses around the "x" because it is a macro and it is substituted as text not symbolically, they are not needed in D.This thing now is clear and settled while I try to navigate my mind around many new things. Really appreciate your help, Nicolas.
Apr 08 2017
On Saturday, 8 April 2017 at 10:02:01 UTC, Mike Parker wrote:I would expect if you implement it as a function the compiler will inline it. You can always use the pragma(inline, true) [1] with -inline to verify. [1] https://dlang.org/spec/pragma.html#inlineThanks for mentioning pragma. However, anyway to do it with mixin? It's so cool so I want to do more stuffs with it :)
Apr 08 2017
On 04/08/2017 03:11 AM, biocyberman wrote:On Saturday, 8 April 2017 at 10:02:01 UTC, Mike Parker wrote:You can mixin declarations with a template but I don't see how it can help here. A string mixin would work but it's really ugly at the use site: string roundUp(alias x)() if (is (typeof(x) == uint)) { import std.string : format; return format(q{ --%1$s; %1$s |= %1$s >> 1; %1$s |= %1$s >> 2; %1$s |= %1$s >> 4; %1$s |= %1$s >> 8; %1$s |= %1$s >> 16; ++%1$s; }, x.stringof); } void main() { uint i = 42; mixin (roundUp!i); // <-- Ugly assert(i == 64); } Compare that to the following natural syntax that a function provides: void roundUp(ref uint x) { // ... } void main() { uint i = 42; i.roundUp(); // <-- Natural } AliI would expect if you implement it as a function the compiler will inline it. You can always use the pragma(inline, true) [1] with -inline to verify. [1] https://dlang.org/spec/pragma.html#inlineThanks for mentioning pragma. However, anyway to do it with mixin? It's so cool so I want to do more stuffs with it :)
Apr 08 2017
On Saturday, 8 April 2017 at 21:34:30 UTC, Ali Çehreli wrote:You can mixin declarations with a template but I don't see how it can help here. A string mixin would work but it's really ugly at the use site: string roundUp(alias x)() if (is (typeof(x) == uint)) { import std.string : format; return format(q{ --%1$s; %1$s |= %1$s >> 1; %1$s |= %1$s >> 2; %1$s |= %1$s >> 4; %1$s |= %1$s >> 8; %1$s |= %1$s >> 16; ++%1$s; }, x.stringof); } void main() { uint i = 42; mixin (roundUp!i); // <-- Ugly assert(i == 64); } Compare that to the following natural syntax that a function provides: void roundUp(ref uint x) { // ... } void main() { uint i = 42; i.roundUp(); // <-- Natural } AliYou made the point, it looks really ugly :). However, sometimes if this ugliness offer better performance, I would - in a desperate mood - use it. That's only 'if'. I put two other variant to a test, and this ugly version does worst as well. You can check out here: https://gist.github.com/biocyberman/0ad27721780e66546cbb6a39c0770d99 Maybe it is because string formating cost. Moving the import statement out of the function does not speed things up.
Apr 09 2017