forgottenmaster / type-safe-bitmasks Goto Github PK
View Code? Open in Web Editor NEWAiming to make type safe bitmasks that are foolproof and easy to make, leveraging the type system and compiler where possible
License: MIT License
Aiming to make type safe bitmasks that are foolproof and easy to make, leveraging the type system and compiler where possible
License: MIT License
Prerequisite of: #2
To prevent accidents or unexpected behaviour when wanting to access the underlying value of the bitmask, it's probably better to be explicit about how many bits we're using.
Therefore I think it might be worth creating a new type "MaskedInteger" or something similar which will be templated with the bit count.
The bitmask will therefore be able to be constructed from such a type as it guarantees any underlying representation will have leading zeros in the unused bits.
By constructing an instance of MaskedInteger, the user will be entering a contract which will let us mask the unused bits to zero. This can be done in a constexpr context in the constructor.
We can then allow conversion to/from Bitmask to MaskedInteger safely with no unforeseen side effects.
The caller of course needs to be able to access the underlying representation as a raw int at some point for serialization and/or storage. But I think doing that in the Bitmask type is not correct and it's better to be as explicit as possible.
Plus the MaskedInteger type can be reused in other situations where we need to guarantee a certain number of bits are used.
NOTE: This can be achieved with a wrapper that deals with bit count, or a wrapper that caps the value of an integer, as we know the value of an integer with N bits set to 1 (in the low end).
Remaining bitwise operators to add:
Bitmask &= Bit
Bitmask |= Bit
Bitmask ^= Bit
Bitmask &= Bitmask
Bitmask |= Bitmask
Bitmask ^= Bitmask
We provide type safe conversions:
Bit => underlying enum class value
This is safe because each Bit is guaranteed to map exactly to the underlying enum class.
Bit => Bitmask
This is safe because each Bit is guaranteed to be safely promotable to a Bitmask with a single bit set in the underlying type.
However, for purposes of serialization and other reasons, the caller will often want to get the underlying value from the Bitmask, or to construct a Bitmask from the underlying type.
However, we cannot just give them a std::uint8_t (or std::uint16_t, etc.) because the caller will assume they can construct a Bitmask from a std::uintx_t as well. While this is safe for the specific case where we're passing back a value we got from the getter, in the general case this is not type-safe.
Somebody could easily, if we were to accept a uint8_t, pass a uint8_t with more bits set than we actually know how to deal with.
In order to be more explicit and leverage the type system, we should instead retrieve and accept a std::bitset where N is the count of bits we're actually using (number of variants passed to the construction macro).
This way, we cannot pass, for example a 7 bit set to a Bitmask that only uses 4 possible bits and is more explicit so the user isn't surprised when they accidentally set bit 7 and it gets ignored in the Bitmask.
However, std::bitset isn't usable in a constexpr context as it is now. While the constructor is constexpr, it seems that the conversions back to integral types are not, so will need a new/similar struct that is constexpr compatible.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.