C ++ 11 and [17.5.2.1.3] Bitmask types

The standard allows you to choose between an integer type, enum and a std::bitset .

Why does the library developer use one of these with these options?

The case, llvm libcxx, seems to use a combination of (at least) two of these implementation options:

ctype_base::mask is implemented using an integer type: <__locale>

regex_constants::syntax_option_type is implemented using enum + overloaded statements: <regex>

The gcc libstdc ++ project uses all three:

ios_base::fmtflags is implemented using overloaded + overloaded operators: <bits/ios_base.h>

regex_constants::syntax_option_type is implemented using an integer type, regex_constants::match_flag_type is implemented using std::bitset
Both: <bits/regex_constants.h>

AFAIK, gdb cannot "detect" the bit field of any of these three options, so there would be no difference in enhanced debugging.

The solution enum solution and the integer type must always use the same space. std::bitset doesn't seem to guarantee that sizeof(std::bitset<32>) == std::uint32_t , so I don't see what is especially attractive to std::bitset .

enum solution seems a little less secure since mask combinations do not generate an enumerator.

Strictly speaking, the above applies to n3376 and not to FDIS (since I do not have access to FDIS).

Any education available in this area would be appreciated.

+7
source share
3 answers

It is truly surprising that the standard limits it to only three alternatives. Why should the class of the class not be acceptable? Anyway...

  • Integral types are the easiest alternative, but they lack type safety. Very old old code will use them, as they are also the oldest.
  • Enum types are safe, but cumbersome, until C ++ 11 is fixed to the size and range of int .
  • std::bitset can have a slightly higher level of security in that bitset<5> and bitset<6> are different types, and adding is not allowed, but otherwise unsafe as an integral type. This would not be a problem if they allowed types derived from std::bitset<N> .

It is clear that enum is an ideal alternative, but experience has shown that type safety is really not needed. Thus, they threw the dice to the implementers and allowed them to take simpler routes. The short answer is that laziness encourages artists to choose int or bitset .

It’s a little strange that the types derived from bitset are not valid, but this is actually a minor thing.

The main specification provided by this proposal is a set of operations defined for these types (for example, bitwise operators).

+2
source

My preference is to use an enumeration, but sometimes there are good reasons to use an integer. Typically, ctype_base::mask interacts with the titles of its own operating systems with a mapping from ctype_base::mask to <ctype.h> constants defined by the implementation, such as _CTYPE_L and _CTYPE_U , used for isupper and islower , etc. Using an integer can simplify the use of ctype_base :: mask directly using the OS’s own APIs.

I do not know why libstdC ++ <regex> uses std::bitset . When this code was complete, I made a mental remark to replace the integer types with an enumeration at some point, but <regex> is not a priority for me.

+2
source

Why does the standard allow different ways to implement a library? And the answer is: why not?

As you saw, all three options are obviously used in some implementations. The standard does not want existing implementations to be inappropriate if this can be avoided.

One reason for using a bit-set may be that its size is better than an enumeration or an integer. Not all systems even have std::uint32_t . Maybe bitset<24> will work there better?

0
source

All Articles