Thread overview |
---|
November 11, 2013 Static Parameter Function Specialization in D | ||||
---|---|---|---|---|
| ||||
I've read somewhere that D supports specialization of functions to calls where arguments are compile-time constants. Typical use of this is in matrix power functions (if exponent is 2 `x*x` is often faster than the general case). I want this in my member function bool opIndexAssign(bool b, size_t i) @trusted pure nothrow in { assert(i < len); // TODO: Add static assert(i < len) when i is constant } body { b ? bts(ptr, i) : btr(ptr, i); return b; } of a statically sized `BitSet` struct I'm writing. This in order to, when possible, get compile-time bounds checking on the index variable `i`. I thought bool opIndexAssign(bool b, const size_t i) @trusted pure nothrow in { static assert(i < len); } body { b ? bts(ptr, i) : btr(ptr, i); return b; } would suffice but then DMD complains as follows dmd -debug -gc -gs -unittest -D -Dd/home/per/.emacs.d/auto-builds/dmd/Debug-Boundscheck-Unittest/home/per/Work/justd/ -w -main ~/Work/justd/bitset.d /home/per/Work/justd/assert_ex.d -of/home/per/.emacs.d/auto-builds/dmd/Debug-Boundscheck-Unittest/home/per/Work/justd/bitset /home/per/Work/justd/bitset.d(58): Error: bitset.BitSet!2.BitSet.opIndexAssign called with argument types (bool, int) matches both: /home/per/Work/justd/bitset.d(49): opIndexAssign(bool b, ulong i) and: /home/per/Work/justd/bitset.d(65): opIndexAssign(bool b, const(ulong) i) /home/per/Work/justd/bitset.d(66): Error: variable i cannot be read at compile time /home/per/Work/justd/bitset.d(66): while evaluating: static assert(i < 2LU) /home/per/Work/justd/bitset.d(58): Error: bitset.BitSet!2.BitSet.opIndexAssign called with argument types (bool, int) matches both: /home/per/Work/justd/bitset.d(49): opIndexAssign(bool b, ulong i) Do I have to make parameter `i` a template parameter, say using type `U`, and then use static if `someTypeTrait!U`. I tried this but isMutable!Index always evaluates to true. import std.traits: isIntegral; bool opIndexAssign(Index)(bool b, Index i) @trusted pure nothrow if (isIntegral!Index) in { import std.traits: isMutable; // See also: http://stackoverflow.com/questions/19906516/static-parameter-function-specialization-in-d static if (isMutable!Index) { assert(i < len); } else { import std.conv: to; static assert(i < len, "Index " ~ to!string(i) ~ " must be smaller than BitSet length " ~ to!string(len)); } } body { b ? bts(ptr, i) : btr(ptr, i); return b; } |
November 11, 2013 Re: Static Parameter Function Specialization in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Monday, 11 November 2013 at 13:41:04 UTC, Nordlöw wrote:
> I've read somewhere that D supports specialization of functions to calls where arguments are compile-time constants. Typical use of this is in matrix power functions (if exponent is 2 `x*x` is often faster than the general case).
>
> I want this in my member function
>
> bool opIndexAssign(bool b, size_t i) @trusted pure nothrow in {
> assert(i < len); // TODO: Add static assert(i < len) when i is constant
> } body {
> b ? bts(ptr, i) : btr(ptr, i);
> return b;
> }
>
> of a statically sized `BitSet` struct I'm writing. This in order to, when possible, get compile-time bounds checking on the index variable `i`. I thought
>
> bool opIndexAssign(bool b, const size_t i) @trusted pure nothrow in {
> static assert(i < len);
> } body {
> b ? bts(ptr, i) : btr(ptr, i);
> return b;
> }
>
> would suffice but then DMD complains as follows
>
> dmd -debug -gc -gs -unittest -D -Dd/home/per/.emacs.d/auto-builds/dmd/Debug-Boundscheck-Unittest/home/per/Work/justd/ -w -main ~/Work/justd/bitset.d /home/per/Work/justd/assert_ex.d -of/home/per/.emacs.d/auto-builds/dmd/Debug-Boundscheck-Unittest/home/per/Work/justd/bitset
> /home/per/Work/justd/bitset.d(58): Error: bitset.BitSet!2.BitSet.opIndexAssign called with argument types (bool, int) matches both:
> /home/per/Work/justd/bitset.d(49): opIndexAssign(bool b, ulong i)
> and:
> /home/per/Work/justd/bitset.d(65): opIndexAssign(bool b, const(ulong) i)
> /home/per/Work/justd/bitset.d(66): Error: variable i cannot be read at compile time
> /home/per/Work/justd/bitset.d(66): while evaluating: static assert(i < 2LU)
> /home/per/Work/justd/bitset.d(58): Error: bitset.BitSet!2.BitSet.opIndexAssign called with argument types (bool, int) matches both:
> /home/per/Work/justd/bitset.d(49): opIndexAssign(bool b, ulong i)
>
> Do I have to make parameter `i` a template parameter, say using type `U`, and then use static if `someTypeTrait!U`. I tried this but isMutable!Index always evaluates to true.
>
> import std.traits: isIntegral;
> bool opIndexAssign(Index)(bool b, Index i) @trusted pure nothrow if (isIntegral!Index) in {
> import std.traits: isMutable;
> // See also: http://stackoverflow.com/questions/19906516/static-parameter-function-specialization-in-d
> static if (isMutable!Index) {
> assert(i < len);
> } else {
> import std.conv: to;
> static assert(i < len,
> "Index " ~ to!string(i) ~ " must be smaller than BitSet length " ~ to!string(len));
> }
> } body {
> b ? bts(ptr, i) : btr(ptr, i);
> return b;
> }
It's possible that the compiler can inline the function and optimize the code from there, but I don't know of any language feature that can do this explicitly.
|
November 11, 2013 Re: Static Parameter Function Specialization in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | Please never post such questions to announcement list. There is a D.learn for that. |
November 11, 2013 Re: Static Parameter Function Specialization in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Monday, 11 November 2013 at 14:41:14 UTC, Dicebot wrote:
> Please never post such questions to announcement list. There is a D.learn for that.
I'm very sorry. It was a mistake. Can I move or delete this post?
|
November 12, 2013 Re: Static Parameter Function Specialization in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Monday, November 11, 2013 17:56:38 Nordlöw wrote:
> On Monday, 11 November 2013 at 14:41:14 UTC, Dicebot wrote:
> > Please never post such questions to announcement list. There is a D.learn for that.
>
> I'm very sorry. It was a mistake. Can I move or delete this post?
No. This forum has three front-ends - nntp newsgroup, mailing list, and the website - with nntp as the backend. So, in general, once it's out there, it's out there. Occasionally, Walter will remove spam from the nntp server so that it doesn't end up in the archives, but that's pretty much it. Just be more careful about where you post in the future.
- Jonathan M Davis
|
November 12, 2013 Re: Static Parameter Function Specialization in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On 11/11/2013 11:56 AM, "Nordlöw" wrote:
> Can I move or delete this post?
>
I use Thunderbird and it's pretty easy to cancel my own messages:
Just select the post, go to 'Message' menu and click 'Cancel message'
The 'Delete' option is different though, it just deletes the message from your local computer while it still exists in the newsgroup for others to see.
|
November 12, 2013 Re: Static Parameter Function Specialization in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to John J | On Tuesday, 12 November 2013 at 22:17:46 UTC, John J wrote:
> On 11/11/2013 11:56 AM, "Nordlöw" wrote:
>> Can I move or delete this post?
>>
>
> I use Thunderbird and it's pretty easy to cancel my own messages:
> Just select the post, go to 'Message' menu and click 'Cancel message'
It will actually send a new message that says that previous one should be discarded. Some mail servers / clients can be configured to respect that request but I'd be surprised to see that for NG.
|
Copyright © 1999-2021 by the D Language Foundation