是否有人编写了一些通用函数来扩展core.bitop
位操作以处理任何值类型?
像
这样的东西bool getBit(T)(in T a, int bitnum); // bt
T setBit(T)(in T a, int bitnum); // bts
auto ref setBitInPlace(T)(ref T a, int bitnum);
我知道这相对容易实现,所以我很好奇为什么它不是Phobos。
更新
这是我第一次尝试:
bool getBit(T, I)(in T a, I bitnum) @safe pure nothrow if (isIntegral!T &&
isIntegral!I) {
return a & (((cast(I)1) << bitnum)) ? true : false;
}
bool getBit(T, I)(in T a, I bitnum) @trusted pure nothrow if ((!(isIntegral!T)) &&
isIntegral!I) {
enum nBits = 8*T.sizeof;
static if (nBits == 8) alias I = ubyte;
else static if (nBits == 16) alias I = ushort;
else static if (nBits == 32) alias I = uint;
else static if (nBits == 64) alias I = ulong;
return (*(cast(I*)&a)).getBit(bitnum); // reuse integer variant
}
alias bt = getBit;
我的想法是让getBit
适用于所有具有价值语义的类型。这就是为什么我需要演员(我认为)。是否存在检查类型是否具有值语义的特征?
还有一个特性可以检查类型是否支持按位和&
等特定操作?我总是可以使用__traits(compiles, ...)
,但标准化很好。
为了使它更好,我想我需要一个明确的重载T来支持位操作,以使这个变量@safe对吗?在我上面的通用解决方案中,我需要cast
,那就是@unsafe。
答案 0 :(得分:1)
是否存在检查类型是否具有值语义的特征?
价值类型没有特征,至少在the documentation中没有 但是,在使用“is expression”之前,我已检查了值类型:
import std.stdio;
struct Foo {}
auto fn(T)(T type)
{
static if (is(T == struct)) {
writeln(T.stringof ~ " is a value type");
} else if (is(T == class)) {
writeln(T.stringof ~ " is a reference type");
} else {
writeln(T.stringof ~ " is something else");
}
}
void main()
{
Foo f;
fn(f);
fn(new Object());
fn(1);
}
还有一个特征来检查类型是否支持特定操作 如bitwise和&amp;?
除了编译的特性之外,这也可以通过is表达式来实现。这类似于ranges, for example目前的工作方式:
import std.stdio;
struct Foo {
auto opBinary(string op)(Foo rhs)
if (op == "&")
{
return rhs.init; // dummy implementation
}
};
template canUseBitOps(T)
{
enum bool canUseBitOps = is(typeof(
(inout int = 0)
{
T t1 = T.init;
T t2 = T.init;
auto r = t1 & t2;
}));
}
void main()
{
assert(canUseBitOps!int);
assert(!canUseBitOps!string);
assert(canUseBitOps!Foo);
}
答案 1 :(得分:1)
我在https://github.com/atilaneves/cerealed的序列化库中做了类似的事情。这不是你所要求的,但你可以从中获得想法。