digitalmars.D.learn - Question about nogc
- Dominikus Dittes Scherkl (15/15) May 20 2014 Did I understand correct that a function can only be @nogc if
- monarch_dodra (5/20) May 20 2014 Right.
- John Colvin (3/18) May 20 2014 Yes, that should be allowed.
- Dominikus Dittes Scherkl (17/39) May 20 2014 Thanks. This is nice to know, because I will use this a lot in
- anonymous (28/43) May 20 2014 max + 1 entries
- monarch_dodra (8/30) May 20 2014 Depending on what the usecase is, you might want to change that
- anonymous (3/11) May 20 2014 That's the "return" line of a template. In the usage example in
- Timon Gehr (7/48) May 20 2014 Wtf. Is this really the point you are trying to make? :o)
- Timon Gehr (3/8) May 20 2014 (Though I'd never actually do template argument checking in a static
- anonymous (3/10) May 20 2014 Ha! That's ... much better. I wasn't trying to make any point,
Did I understand correct that a function can only be nogc if also all functions that it calls are nogc too (and of course it doesn't use the GC itself)? If so, should this be possible: string foo() { // use GC to allocate some string } bar nogc { mixin(foo()); } Because, bar() didn't really call foo() but instead foo() is evaluated during compile time and it's result is now part of the code, right?
May 20 2014
On Tuesday, 20 May 2014 at 12:25:11 UTC, Dominikus Dittes Scherkl wrote:Did I understand correct that a function can only be nogc if also all functions that it calls are nogc too (and of course it doesn't use the GC itself)? If so, should this be possible: string foo() { // use GC to allocate some string } bar nogc { mixin(foo()); } Because, bar() didn't really call foo() but instead foo() is evaluated during compile time and it's result is now part of the code, right?Right. It's the same mechanics you'd get from pure/nothrow and safe+ trusted
May 20 2014
On Tuesday, 20 May 2014 at 12:25:11 UTC, Dominikus Dittes Scherkl wrote:Did I understand correct that a function can only be nogc if also all functions that it calls are nogc too (and of course it doesn't use the GC itself)? If so, should this be possible: string foo() { // use GC to allocate some string } bar nogc { mixin(foo()); } Because, bar() didn't really call foo() but instead foo() is evaluated during compile time and it's result is now part of the code, right?Yes, that should be allowed.
May 20 2014
On Tuesday, 20 May 2014 at 17:14:31 UTC, John Colvin wrote:On Tuesday, 20 May 2014 at 12:25:11 UTC, Dominikus Dittes Scherkl wrote:Thanks. This is nice to know, because I will use this a lot in the future: /// create a fixed size array with the given name and with *max* entries /// of immutable values of the same type as the return value of the /// given function. /// it contains the values of that function in the range [0..max]. string makeLookupTable(alias fn, uint max=255)(string name) pure safe if(is(typeof(fn(max)))) { string table = "immutable " ~ to!string(typeof(fn(max))) ~ "[" ~ to!string(max+1) ~ "] " ~ name ~"= [ "; foreach(i; 0..max) table ~= to!string(fn(i) ~ ", "; return table ~ to!string(fn(max) ~" ]"; }Did I understand correct that a function can only be nogc if also all functions that it calls are nogc too (and of course it doesn't use the GC itself)? If so, should this be possible: string foo() { // use GC to allocate some string } bar nogc { mixin(foo()); } Because, bar() didn't really call foo() but instead foo() is evaluated during compile time and it's result is now part of the code, right?Yes, that should be allowed.
May 20 2014
On Tuesday, 20 May 2014 at 20:15:09 UTC, Dominikus Dittes Scherkl wrote:/// create a fixed size array with the given name and with *max* entriesmax + 1 entries/// of immutable values of the same type as the return value of the /// given function. /// it contains the values of that function in the range [0..max]. string makeLookupTable(alias fn, uint max=255)(string name) pure safe if(is(typeof(fn(max)))) { string table = "immutable " ~ to!string(typeof(fn(max))) ~ "[" ~ to!string(max+1) ~ "] " ~ name ~"= [ "; foreach(i; 0..max) table ~= to!string(fn(i) ~ ", "; return table ~ to!string(fn(max) ~" ]"; }Couldn't resist purging that of the string fiddling: private template staticIota(uint n) { import std.typetuple: TypeTuple; static if(n == 0) alias staticIota = TypeTuple!(); else alias staticIota = TypeTuple!(.staticIota!(n - 1), n - 1); } template lookupTable(alias fn, uint max = 255) { import std.traits: ReturnType; import std.typetuple: staticMap; static assert(max < uint.max); enum length = max + 1; enum ctfn(uint x) = fn(x); alias elements = staticMap!(ctfn, staticIota!length); enum ReturnType!fn[length] lookupTable = [elements]; } void main() { char f(uint x) pure safe {return x == 42 ? '!' : '.';} static immutable t = lookupTable!f; static assert(is(typeof(t) == immutable char[256])); assert(t[42] == '!'); }
May 20 2014
On Tuesday, 20 May 2014 at 21:04:37 UTC, anonymous wrote:On Tuesday, 20 May 2014 at 20:15:09 UTC, Dominikus Dittes Scherkl wrote:Depending on what the usecase is, you might want to change that to static immutable instead: static immutable ReturnType!fn[length] lookupTable = [elements]; Remember that when using an enum, the compiler will create a *new* variable on every use. While the compiler can sometimes avoid actually allocating, it may also insert some object code bloat to do so./// create a fixed size array with the given name and with *max* entriesmax + 1 entries/// of immutable values of the same type as the return value of the /// given function. /// it contains the values of that function in the range [0..max]. string makeLookupTable(alias fn, uint max=255)(string name) pure safe if(is(typeof(fn(max)))) { string table = "immutable " ~ to!string(typeof(fn(max))) ~ "[" ~ to!string(max+1) ~ "] " ~ name ~"= [ "; foreach(i; 0..max) table ~= to!string(fn(i) ~ ", "; return table ~ to!string(fn(max) ~" ]"; }Couldn't resist purging that of the string fiddling: ... enum ReturnType!fn[length] lookupTable = [elements];
May 20 2014
On Tuesday, 20 May 2014 at 21:16:26 UTC, monarch_dodra wrote:That's the "return" line of a template. In the usage example in main() it's static immutable.enum ReturnType!fn[length] lookupTable = [elements];Depending on what the usecase is, you might want to change that to static immutable instead: static immutable ReturnType!fn[length] lookupTable = [elements]; Remember that when using an enum, the compiler will create a *new* variable on every use. While the compiler can sometimes avoid actually allocating, it may also insert some object code bloat to do so.
May 20 2014
On 05/20/2014 11:04 PM, anonymous wrote:On Tuesday, 20 May 2014 at 20:15:09 UTC, Dominikus Dittes Scherkl wrote:Wtf. Is this really the point you are trying to make? :o) This achieves the same: template lookupTable(alias fn,uint max=255){ static assert(max<uint.max); enum ReturnType!fn[max+1] lookupTable=iota(0,max+1).map!fn.array; }/// create a fixed size array with the given name and with *max* entriesmax + 1 entries/// of immutable values of the same type as the return value of the /// given function. /// it contains the values of that function in the range [0..max]. string makeLookupTable(alias fn, uint max=255)(string name) pure safe if(is(typeof(fn(max)))) { string table = "immutable " ~ to!string(typeof(fn(max))) ~ "[" ~ to!string(max+1) ~ "] " ~ name ~"= [ "; foreach(i; 0..max) table ~= to!string(fn(i) ~ ", "; return table ~ to!string(fn(max) ~" ]"; }Couldn't resist purging that of the string fiddling: private template staticIota(uint n) { import std.typetuple: TypeTuple; static if(n == 0) alias staticIota = TypeTuple!(); else alias staticIota = TypeTuple!(.staticIota!(n - 1), n - 1); } template lookupTable(alias fn, uint max = 255) { import std.traits: ReturnType; import std.typetuple: staticMap; static assert(max < uint.max); enum length = max + 1; enum ctfn(uint x) = fn(x); alias elements = staticMap!(ctfn, staticIota!length); enum ReturnType!fn[length] lookupTable = [elements]; } ...void main() { char f(uint x) pure safe {return x == 42 ? '!' : '.';} static immutable t = lookupTable!f; static assert(is(typeof(t) == immutable char[256])); assert(t[42] == '!'); }
May 20 2014
On 05/20/2014 11:48 PM, Timon Gehr wrote:This achieves the same: template lookupTable(alias fn,uint max=255){ static assert(max<uint.max); enum ReturnType!fn[max+1] lookupTable=iota(0,max+1).map!fn.array; }(Though I'd never actually do template argument checking in a static assert within the template body.)
May 20 2014
On Tuesday, 20 May 2014 at 21:48:08 UTC, Timon Gehr wrote:Wtf. Is this really the point you are trying to make? :o) This achieves the same: template lookupTable(alias fn,uint max=255){ static assert(max<uint.max); enum ReturnType!fn[max+1] lookupTable=iota(0,max+1).map!fn.array; }Ha! That's ... much better. I wasn't trying to make any point, though.
May 20 2014