|
Boost : |
Subject: [boost] [Library idea] Type-safe Flagsets
From: Julien Vernay (julienvernay99_at_[hidden])
Date: 2018-06-24 18:43:21
Hello everybody,
I want to know if some people are interested in a type-safe flagsets. I
define flagsets as a container similar to a bitset, but where each bit has
a meaning.
For example, we could have in some game :
enum Direction : unsigned {
UP = 0b0001,
DOWN = 0b0010,
LEFT = 0b0100,
RIGHT = 0b1000
};
...
unsigned player_dir = UP | RIGHT;
if ((player_dir & (UP|LEFT)) == (UP|LEFT))
player.setAnim("up_left");
player_dir &= ~UP; //removing UP from player_dir
I think there are some issues with this kind of flagset :
- you need to think about power-of-twos when attributing values to your
flags.
- you need to use bitwise operations which can be non-trivial, even for
removing only one flag.
- it is not safe:
for example with another flagset using the flag INIT_VIDEO (in a window
library like SDL),
you can do " UP | INIT_VIDEO " even if the two flagsets have nothing in
common
With a type-safe flagset library, this code would become :
namespace Direction {
struct UP;
struct DOWN;
struct LEFT;
struct RIGHT;
using Type = flagset<unsigned, UP, DOWN, LEFT, RIGHT>;
//unsigned is the underlying type
};
...
auto player_dir = Direction::Type::Value<Direction::UP, Direction::RIGHT>();
if (player_dir.allOf<Direction::UP,Direction::LEFT>())
player.setAnim("up_left");
player_dir.reset<Direction::UP>();
It is more verbose but also more safe and easy to use.
I actually have a partial implementation on GitHub, supporting read, write
and conversions to strings : https://github.com/J-Vernay/flagset
I would like to know if some people are interested in this kind of library,
and if yes, what they think about the current syntax/implementation.
Thanks for reading !
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk