This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.

### 347. locale::category and bitmask requirements

Section: 30.3.1.2.1 [locale.category] Status: CD1 Submitter: P.J. Plauger, Nathan Myers Opened: 2001-10-23 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [locale.category].

View all issues with CD1 status.

Discussion:

In 30.3.1.2.1 [locale.category] paragraph 1, the category members are described as bitmask elements. In fact, the bitmask requirements in 16.3.3.3.4 [bitmask.types] don't seem quite right: `none` and `all` are bitmask constants, not bitmask elements.

In particular, the requirements for `none` interact poorly with the requirement that the LC_* constants from the C library must be recognizable as C++ locale category constants. LC_* values should not be mixed with these values to make category values.

We have two options for the proposed resolution. Informally: option 1 removes the requirement that LC_* values be recognized as category arguments. Option 2 changes the category type so that this requirement is implementable, by allowing `none` to be some value such as 0x1000 instead of 0.

Nathan writes: "I believe my proposed resolution [Option 2] merely re-expresses the status quo more clearly, without introducing any changes beyond resolving the DR.

Proposed resolution:

Replace the first two paragraphs of 30.3.1.2 [locale.types] with:

>         typedef int category;

> Valid category values include the `locale` member bitmask elements `collate`, `ctype`, `monetary`, `numeric`, `time`, and `messages`, each of which represents a single locale category. In addition, `locale` member bitmask constant `none` is defined as zero and represents no category. And locale member bitmask constant `all` is defined such that the expression

>         (collate | ctype | monetary | numeric | time | messages | all) == all

> is `true`, and represents the union of all categories. Further the expression `(X | Y)`, where `X` and `Y` each represent a single category, represents the union of the two categories.

> `locale` member functions expecting a `category` argument require one of the `category` values defined above, or the union of two or more such values. Such a `category` argument identifies a set of locale categories. Each locale category, in turn, identifies a set of locale facets, including at least those shown in Table 51:

[Curaçao: need input from locale experts.]

Rationale:

The LWG considered, and rejected, an alternate proposal (described as "Option 2" in the discussion). The main reason for rejecting it was that library implementors were concerened about implementation difficult, given that getting a C++ library to work smoothly with a separately written C library is already a delicate business. Some library implementers were also concerned about the issue of adding extra locale categories.

> Option 2:
> Replace the first paragraph of 30.3.1.2 [locale.types] with:

> > Valid category values include the enumerated values. In addition, the result of applying commutative operators | and & to any two valid values is valid, and results in the setwise union and intersection, respectively, of the argument categories. The values `all` and `none` are defined such that for any valid value `cat`, the expressions `(cat | all == all)`, `(cat & all == cat)`, `(cat | none == cat)` and `(cat & none == none)` are true. For non-equal values `cat1` and `cat2` of the remaining enumerated values, `(cat1 & cat2 == none)` is true. For any valid categories `cat1` and `cat2`, the result of `(cat1 & ~cat2)` is valid, and equals the setwise union of those categories found in `cat1` but not found in `cat2`. [Footnote: it is not required that `all` equal the setwise union of the other enumerated values; implementations may add extra categories.]