Static Parameter Function Specialization in D
Xinok
xinok at live.com
Mon Nov 11 06:39:54 PST 2013
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.
More information about the Digitalmars-d-announce
mailing list