操纵任何值类型的位



是否有人煮了一些通用功能,这些函数将core.bitop BitManipulation扩展到任何值类型?

之类的东西
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在具有价值语义的所有类型上使用。这就是为什么我需要演员(我认为)。是否有特征可以检查一种类型是否具有价值语义?

还存在一个特征可以检查一种类型是否支持特定操作,例如bitwise和 &?我总是可以使用__traits(compiles, ...),但标准化很好。

为了使它变得更好,我想我需要对T的显式超载,以使Bit操纵以使此变体@SAFE对吗?在上面的通用解决方案中,我需要cast,那是@unsafe。

另请参阅:http://forum.dlang.org/thread/tekrnzkemcbujbivvfpvfpvfpvfpvfpvpv@forum.dlang.org.org.org#post-tekrnzkemcbujbujbivvfpv:40forum.dlang.org.org.org.org.org

是否有特质可以检查类型是否具有价值语义?

值类型没有特征,至少在文档中没有但是,在使用" 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表达来实现这一点。这类似于当前对范围的完成方式,例如:

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);
}

我在https://github.com/atilaneves/cerealed的序列化库中做类似的事情。这不是您想要的,但您可能会从中得到想法。

最新更新