Le 04/02/2016 16:19, Niall Douglas a écrit :
Firstly I'd like to thank Vicente and Tongari for their ideas as without their feedback I wouldn't have come up with https://gist.github.com/ned14/614d8f3cca25924964ea which combines ideas from all three of us.
I'm relatively happy with this solution. Declaration is as follows:
BOOST_AFIO_BITFIELD_BEGIN(flag) { none=0, delete_on_close=1, disable_safety_fsyncs=2 } BOOST_AFIO_BITFIELD_END(flag)
Example usage:
flag f(flag::disable_safety_fsyncs); flag f2(f&flag::none); f2|=flag::delete_on_close; constexpr flag f3(flag::disable_safety_fsyncs); constexpr flag f4(f3&flag::none); if(f) ... Yes, this is much better. This solution is convenient for programmers to use, works as you'd expect from a bitfield, if(bf) works and is 100% constexpr and generates zero runtime overhead, and it's ODR-used correct. The tradeoff is unfortunately now individual flag::XXX are not typesafe and have implicit convertibility to int, though 'flag' itself and any output of any operation on 'flag' is typesafe. Also, there is an ugly macro begin and end of the declaration, but I think this is the best typesafe bitfield I can think of which has a syntax resembling C bitfields.
Any comments absolutely welcome.
C/C++ bit fields means already something else
(http://en.cppreference.com/w/cpp/language/bit_field).
I will name the utility in some other way.
Do you see something wrong having two classes one for the bits enum and
one for the set of those bits enums?
Mixing both, the element and the set in a single class, has some
drawbacks. The flag type is not an enum, that is, is_enum<flag>::value
is false.
I don't see the added value of the macros and the inheritance
#define BOOST_AFIO_BITFIELD_BEGIN(type) \
struct type##_base \
{ \
enum enum_type
#define BOOST_AFIO_BITFIELD_END(type) \
;}; \
using type = bitfield