type_safe icon indicating copy to clipboard operation
type_safe copied to clipboard

Bitwise operations for integer_ops

Open stevemk14ebr opened this issue 3 years ago • 5 comments

Cool library!

The type_safe::strong_typedef_op could use the bitwise operations like &, |, ~, etc. For the integer op type these should probably be default.

stevemk14ebr avatar Jun 13 '22 17:06 stevemk14ebr

Motivating example. On windows typedef DWORD ACCESS_MASK;. To check the flags one must do bitwise checks like mask & GENERIC_READ etc. This type can't be recreated with the strong_types as is.

stevemk14ebr avatar Jun 13 '22 17:06 stevemk14ebr

If you define your type like this

struct my_access_mask : type_safe::strong_typedef<my_access_mask, DWORD>,
                type_safe::strong_typedef_op::bitmask<my_access_mask>
{
    using strong_typedef::strong_typedef;
};

my_access_mask add_read(my_access_mask mask) {
  return mask & my_access_mask{ GENERIC_READ };
}

you get what you want, I think. Godbolt link https://godbolt.org/z/6Knj6sjbq

See Jonathan's blog post/tutorial as well, for some background on how to use this very useful library

gerboengels avatar Jun 13 '22 20:06 gerboengels

I did not notice the bitmask op existed thank you. Perhaps this could be added to the integer ops by default, I had expected them to be present there.

stevemk14ebr avatar Jun 14 '22 18:06 stevemk14ebr

hmm doing mask & MY_ACCESS_MASK{ GENERIC_READ } isn't giving me a bool as I'd like. By default the bitwise mask is giving back another MY_ACCESS_MASK, an automatic bool operator would be nice.

stevemk14ebr avatar Jun 14 '22 20:06 stevemk14ebr

I did not notice the bitmask op existed thank you. Perhaps this could be added to the integer ops by default, I had expected them to be present there.

I'm trying to make an explicit distinction between "integer operations" and "bit operations". In my opinion, integers and bit strings are different types and should be treated differently.

hmm doing mask & MY_ACCESS_MASK{ GENERIC_READ } isn't giving me a bool as I'd like. By default the bitwise mask is giving back another MY_ACCESS_MASK, an automatic bool operator would be nice.

The library explicitly tries to prevent implicit conversions. If you want, you can always write one:

struct my_access_mask : type_safe::strong_typedef<my_access_mask, DWORD>,
                type_safe::strong_typedef_op::bitmask<my_access_mask>
{
    using strong_typedef::strong_typedef;

     operator bool() const
    { return static_cast<DWORD>(*this) != 0; }
};

my_access_mask add_read(my_access_mask mask) {
  return mask & my_access_mask{ GENERIC_READ };
}

You might also be interested in using type_safe::flag_set instead: https://www.foonathan.net/2017/03/implementation-challenge-bitmask/

foonathan avatar Jun 15 '22 19:06 foonathan