www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Manipulating Bits of Any Value Type

reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
Has anybody cooked up some generic functions that extend 
`core.bitop` bitmanipulations to work on any value type?

Something like

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

I know this is relatively easy to implement so that's why I'm 
curious to why its not already Phobos.

**Update:**

Here's my first try at this:

     /** Returns: $(D bitnum):th Bit Of $(D a).
         TODO: Why is this already in Phobos?
         TODO: Make this safe for integers
      */
     bool getBit(T, I)(in T a, I bitnum)  trusted pure nothrow if 
(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;
         immutable xi = (*(cast(I*)&a));
         immutable bitMask = ((cast(I)1 << bitnum));
         /* debug dln(eltIx, ",", bitnum, ",", xi, ",", bitMask); 
*/
         return a & bitMask ? true : false;
     }
     alias bt = getBit;

My idea to make `getBit` work on all types that have value 
semantics. That's why I need the cast (I think). Is there a 
traits to check if a type has value semantics or not?

Also is there a trait to check if a type supports a specific 
operation such as bitwise and `&`? I could always use 
`__traits(compiles, ...)` but standardization is good.

To make it even better I guess I need an explicit overload for 
T's that support bit manipulations in order to make this variant 
 safe right? In my generic solution above I need the `cast` and 
that's  unsafe.

See also: 
https://stackoverflow.com/questions/21368664/manipulating-bits-of-any-value-type
Jan 26 2014
parent reply "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
On Sunday, 26 January 2014 at 20:56:29 UTC, Nordlöw wrote:

 My idea to make `getBit` work on all types that have value 
 semantics.
All of them? Arbitrary structs too? floating point types? Static arrays? Might I ask... why do you need this sort of thing? :)
 That's why I need the cast (I think). Is there a traits to 
 check if a type has value semantics or not?
The closest would be std.traits.hasIndirections.
 Also is there a trait to check if a type supports a specific 
 operation such as bitwise and `&`? I could always use 
 `__traits(compiles, ...)` but standardization is good.
No there isn't.
Jan 26 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Sunday, 26 January 2014 at 23:27:58 UTC, Stanislav Blinov 
wrote:
 On Sunday, 26 January 2014 at 20:56:29 UTC, Nordlöw wrote:

 My idea to make `getBit` work on all types that have value 
 semantics.
All of them? Arbitrary structs too? floating point types? Static arrays? Might I ask... why do you need this sort of thing? :)
For bit-parallel run-length encoding for efficient serialization of sets of std.datetime:SysTime structures (16 bytes). I'm trying to differentially pack sets of SysTimes entries more efficiently because for a given directory containing files many of these files often share the majority of their bits. Meta-code: foreach (n; 0..SysTime.sizeof) RLC all n-bits for all SysTimes It is more an interesting experiment :)
 That's why I need the cast (I think). Is there a traits to 
 check if a type has value semantics or not?
The closest would be std.traits.hasIndirections.
Does this work recursively on containing types?
 Also is there a trait to check if a type supports a specific 
 operation such as bitwise and `&`? I could always use 
 `__traits(compiles, ...)` but standardization is good.
No there isn't.
Thx.
Jan 26 2014
parent reply "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
On Sunday, 26 January 2014 at 23:37:40 UTC, Nordlöw wrote:

 Might I ask... why do you need this sort of thing? :)
For bit-parallel run-length encoding for efficient serialization of sets of std.datetime:SysTime structures (16 bytes).
SysTime's representation consists of a long and Rebindable!(immutable(TimeZone)). The latter is a struct containing a reference.
 The closest would be std.traits.hasIndirections.
Does this work recursively on containing types?
AFAIK no, it just checks immediate fields (if any).
Jan 26 2014
parent "Stanislav Blinov" <stanislav.blinov gmail.com> writes:
On Sunday, 26 January 2014 at 23:54:02 UTC, Stanislav Blinov 
wrote:
 On Sunday, 26 January 2014 at 23:37:40 UTC, Nordlöw wrote:
 The closest would be std.traits.hasIndirections.
Does this work recursively on containing types?
AFAIK no, it just checks immediate fields (if any).
OTOH, it seems it does :)
Jan 26 2014