Я где-то читал, что D поддерживает специализацию функций для вызовов, где аргументы являются константами времени компиляции. Типичное использование этого в матричных силовых функциях (если показатель составляет 2 x*x
, часто быстрее, чем в общем случае).Специализация по статическому параметру в D
Я хочу это в моей функции члена
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;
}
статический размером BitSet
-структуры, которую я пишу. Это для того, чтобы, по возможности, получить проверку границ времени компиляции по индексной переменной i
. Я думал
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;
}
хватило бы, но тогда DMD жалуется следующим
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)
Должен ли я сделать параметр i
параметр шаблона, скажем, используя тип U
, а затем использовать статический, если someTypeTrait!U
. Я пробовал это, но isMutable! Index всегда оценивает 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;
}
Ok. Я могу рассчитывать на индексацию, используя, например, 'bitset.at! 3()'. Спасибо. –