2014-01-26 3 views
4

Кто-нибудь приготовил некоторые общие функции, которые расширяют битманипуляции 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); 

Я знаю, что это относительно легко реализовать так, поэтому мне интересно, почему его не уже Фобоса.

Update:

Вот моя первая попытка в этом:

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, ...), но стандартизация хорошая.

Чтобы сделать его еще лучше, я думаю, мне нужна явная перегрузка для тех манипуляций бит поддержки, чтобы этот вариант был @safe правильно? В моем общем решении выше мне нужен cast, и это @ небезопасно.

Смотрите также: http://forum.dlang.org/thread/[email protected]#post-tekrnzkemcbujbivvfpv:40forum.dlang.org

+2

это будет небезопасно независимо от того, что вы делаете, поскольку вы можете нарушать инвариант типа, задавая произвольные биты –

+1

Как насчет бит-массивов, если вы создаете союз, подходит ли он для ваших целей? http://dlang.org/phobos/std_bitmanip.html#.BitArray – MaKo

ответ

1

А есть ли черты, чтобы проверить, если тип имеет семантику значений или нет?

Там нет черты для типов значений, по крайней мере, не в the documentation Однако, я проверил для типов значений перед использованием «выражения является»:

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

Кроме того, есть признак чтобы проверить, поддерживает ли тип конкретную операцию , такую ​​как побитовое и &?

Помимо признаков для компиляции, это также может быть достигнуто с помощью выражения. Это аналогично тому, как это делается в настоящее время для 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

я сделать что-то подобное в моей библиотеке сериализации в https://github.com/atilaneves/cerealed. Это не совсем то, о чем вы просите, но вы можете получить от него идеи.

Смежные вопросы