<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
  "http://www.w3.org/TR/1998/REC-html40-19980424/strict.dtd">
<html> 
<head> 
<title>Problems with bitmask types in the library</title> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="author" content="Jonathan Wakely">
<style type="text/css"> 
ins, .inserted
{
    color: black;
    background: #a0ffa0;
    text-decoration: underline;
}
del, .deleted
{
    color: black;
    background: #ffa0a0;
    text-decoration: line-through;
}
.standardtext
{
    margin-left: 2em;
}
</style> 
</head> 
<body> 
<table>
<tr><td>Document number:</td><td>N3110=10-0100</td></tr>
<tr><td>Author:</td><td>Jonathan Wakely</td></tr>
<tr><td>Date:</td><td>2010-08-04</td></tr> 
</table> 
 
<h3 id="history">Revision history</h3>

<p>
This is an update of the paper attached to the GB ballot comments on the FCD.
Changes requested by the LWG are adding <code>static</code> to
<code>constexpr</code> data members, changing the value for bitmask constants
to <em>see below</em>, and not adding <code>constexpr</code> to the compound
assignment operators for the example bitmask type.
This version also fixes the table references for the <code>regex_constants</code>
which incorrectly used the table numbers from an earlier draft, not the FCD.
</p>

<h1>Problems with bitmask types in the library</h1> 
 
<p>The library defines the <em>bitmask types</em> (17.5.2.1.3)
<code>ios_base::fmtflags</code>,
<code>ios_base::iostate</code>,
<code>ios_base::openmode</code>,
<code>regex_constants::syntax_option_type</code> and
<code>regex_constants::match_flag_type</code>.
Each is defined as an unscoped enumeration without a fixed
underlying type.
Each has <code>operator&amp;</code>, <code>operator|</code> and
<code>operator~</code> overloaded.
</p>
<p>The library also defines the <em>enumerated types</em> (17.5.2.1.2)
<code>ios_base::seekdir</code> and
<code>regex_constants::error_type</code>.

<p>There are several problems related to these types:</p>

<ul>
  <li>Bitmask type operators declared as members of <code>ios_base</code>,</li>
  <li>bitmask type operators defined for enumerated types,</li>
  <li><code>operator^</code> is missing,</li>
  <li><code>operator~</code> is defined incorrectly,</li>
  <li>the underlying type should be fixed,</li>
  <li>value of <code>goodbit</code> is not unspecified,</li>
  <li>bitmask types are inconsistent with the requirements and over-specified.</li>
</ul>
 
<h3 id="members">Bitmask operators declared as members of <code>ios_base</code></h3>

<p>The bitwise operators for the <code>ios_base</code> bitmask types are
declared in the body of <code>ios_base</code>, making them members of the
class, but they should be non-member functions.
This is largely an editorial issue, but is addressed by the proposed changes
below.</p>

<h3 id="seekdir">Bitmask type operators defined for enumerated types</h3>

<p>As specified in 27.5.2p1 and 27.5.2.1.5p1, <code>ios_base::seekdir</code>
is an enumerated type (17.5.2.1.2) not a bitmask type (17.5.2.1.3) and so
should not have bitwise operators defined.
The operators were added by the <code>constexpr</code> proposal, n2349, but
should be removed.
</p>
<p>
The same applies to <code>regex_constants::error_type</code> (28.5.3)
although 28.5.3p1 incorrectly uses the term "enumeration type" instead
of "enumerated type".
</p>

<h3 id="xor"><code>operator^</code> is missing</h3>

<p>n2349 proposed the following additional overload which is missing from the
FCD:
</p>
<pre>constexpr fmtflags operator^(fmtflags lhs, fmtflags rhs)
{
   return fmtflags(int(lhs) ^ int(rhs));
}
</pre>

<p>This operator would be needed for all the bitmask types if they were defined
as enumeration types.
</p> 

<h3 id="comp"><code>operator~</code> is defined incorrectly</h3>

<p>The FCD specifies:</p>
<pre>constexpr fmtflags operator~(fmtflags f)
{
   return fmtflags( f);
}
</pre>

<p>This seems to be an editorial error as n2349 proposed:</p>
<pre>constexpr fmtflags operator~(fmtflags f)
{
   return fmtflags(~(f));
}
</pre>

<p>This isn't right either, since it will lead to infinite recursion.
I think the intended definition is:</p>

<pre>constexpr fmtflags operator~(fmtflags f)
{
   return fmtflags(~int(f));
}
</pre>

<h3 id="underlying">The underlying type should be fixed</h3>

<p>Bitmask types need <code>operator~</code> in order to clear a value
from the bitmask type, as show in 17.5.2.1.3 paragraph 4:
</p>
<div class="standardtext">
<p>&mdash; To <em>clear</em> a value <em>Y</em> in an object <em>X</em> is to evaluate
the expression <em>X &amp;= ~Y</em>.</p>
</div>
<p>However the definition for <code>fmtflags</code> above does not have
well-specified behaviour
if the underlying type is smaller than <code>int</code>, because 
<code>~int(f)</code> is likely to produce a value outside the range of
<code>fmtflags</code>.</p>

<p>
The same problem is present in the example implementation in 17.5.2.1.3
because <code>int_type</code> is only stated to be capable of holding
all the values of <em>bitmask</em> so there is no guarantee that
<code> sizeof(int_type) == sizeof(bitmask)</code> and therefore no
guarantee that the code given for <code>operator~</code> works as intended.
</p>

<p>This could be solved by giving the enumeration a fixed underlying type
which is the same type as used for the conversions used by the bitwise
operators.  An alternative solution would be to do all conversions
to and from <code>std::underlying_type&lt;bitmask&gt;</code>.
</p>

<h3 id="goodbit">Value of <code>goodbit</code> is not unspecified.</h3>

<p>The synopsis in 27.5.2 includes:</p>
<pre class="standardtext">goodbit = <em>unspecified</em>,</pre>
<p>but 27.5.2.1.3 specifies that <code>goodbit</code> has the value zero.</p>
 
<h3 id="overspec">Bitmasks types are inconsistent with the requirements and over-specified.</h3>

<p>In C++03 implementions were allowed to use any of the options
in 17.5.2.1.3 for the bitmask types defined by the library and
e.g. <code>std::ios::in</code> is an object of bitmask type
with an implementation-defined value.
The FCD specifies that bitmask types are implemented as
enumerations and <code>std::ios::in</code> is an enumerator not
an object. Not only is this inconsistent with the stated requirements
in 17.5.2.1.3 but it means that existing implementations which define
bitmask types as an integer type must change, and it breaks the following
valid C++03 code: 
</p>
<pre>
#include &lt;ios&gt;
std::ios::openmode* p = &amp;std::ios::in;
</pre>

<p>If all the library's bitmask types are required to be
enumeration types then there is no reason for 17.5.2.1.3 to 
allow integer types or a <code>bitset</code>.
</p>

<p>
Existing C++03 implementations choose to implement bitmask types
as integer types for efficiency, because enumerations with overloaded
operators are less efficient without <code>constexpr</code>. Since the FCD
defines the bitmask types as enumerations with overloaded <code>constexpr</code>
operators, implementations cannot provide a common definition for C++03 and C++0x.
This is of no benefit to users or implementations.
</p>

<h2>Proposed Solution</h2> 

<p>
The over-specification of the library's bitmask types should be reverted.
The example bitmask in clause 17 can be updated to use <code>constexpr</code>
and an enumeration type with a fixed underlying type.
<code>constexpr</code> can also be used for declaring the objects of bitmask type.
Proposed wording for this change is given below.
</p>

<p>An alternative solution would be to fix all the issues listed above except
the over-specification, but this would still require existing implementations
to change, has the chance of breaking valid C++03 programs, and leaves the
definitions of bitmask types inconsistent with the requirements in Clause 17.
</p>


<h2>Proposed Wording</h2> 

<h3>Modifications to Bitmask types</h3> 
 
<p>Make the following changes to 17.5.2.1.3: </p> 

<div class="standardtext"> 
The bitmask type <em>bitmask</em> can be written:
<pre>
<ins><em>// For exposition only.
// <code>int_type</code> is an integral type capable of
// representing all values of bitmask</em> </ins>
enum <em>bitmask</em> <ins>: int_type</ins> {
  <em>V0</em> = 1 &lt;&lt; 0, <em>V1</em> = 1 &lt;&lt; 1, <em>V2</em> = 1 &lt;&lt; 2, <em>V3</em> = 1 &lt;&lt; 3, .....
};

<del>static const</del><ins>constexpr</ins> <em>bitmask</em> <em>C0</em> (<em>V0</em>);
<del>static const</del><ins>constexpr</ins> <em>bitmask</em> <em>C1</em> (<em>V1</em>);
<del>static const</del><ins>constexpr</ins> <em>bitmask</em> <em>C2</em> (<em>V2</em>);
<del>static const</del><ins>constexpr</ins> <em>bitmask</em> <em>C3</em> (<em>V3</em>);
  .....

<del><em>// For exposition only.
// <code>int_type</code> is an integral type capable of
// representing all values of bitmask</em></del>
<ins>constexpr</ins> <em>bitmask</em> operator&amp; (<em>bitmask</em> <em>X</em> , <em>bitmask</em> <em>Y</em> ) {
  return static_cast&lt;<em>bitmask</em> &gt;(
    static_cast&lt;int_type&gt;(<em>X</em> ) &amp;
    static_cast&lt;int_type&gt;(<em>Y</em> ));
}
<ins>constexpr</ins> <em>bitmask</em> operator| (<em>bitmask</em> <em>X</em> , <em>bitmask</em> <em>Y</em> ) {
  return static_cast&lt;<em>bitmask</em> &gt;(
    static_cast&lt;int_type&gt;(<em>X</em> ) |
    static_cast&lt;int_type&gt;(<em>Y</em> ));
}
<ins>constexpr</ins> <em>bitmask</em> operator^ (<em>bitmask</em> <em>X</em> , <em>bitmask</em> <em>Y</em> ){
  return static_cast&lt;<em>bitmask</em> &gt;(
    static_cast&lt;int_type&gt;(<em>X</em> ) ^
    static_cast&lt;int_type&gt;(<em>Y</em> ));
}
<ins>constexpr</ins> <em>bitmask</em> operator~ (<em>bitmask</em> <em>X</em> ){
  return static_cast&lt;<em>bitmask</em> &gt;(~static_cast&lt;int_type&gt;(<em>X</em> ));
}
</pre> 
</div>

<h3>Modifications to Class <code>ios_base</code></h3> 
 
<p>Make the following changes to the synopsis in 27.5.2: </p> 

<pre class="standardtext">
class ios_base {
public:
  class failure;

<ins>
  typedef <em>T1</em> fmtflags;
  static constexpr fmtflags boolalpha = <em>unspecified</em>;
  static constexpr fmtflags dec = <em>unspecified</em>;
  static constexpr fmtflags fixed = <em>unspecified</em>;
  static constexpr fmtflags hex = <em>unspecified</em>;
  static constexpr fmtflags internal = <em>unspecified</em>;
  static constexpr fmtflags left = <em>unspecified</em>;
  static constexpr fmtflags oct = <em>unspecified</em>;
  static constexpr fmtflags right = <em>unspecified</em>;
  static constexpr fmtflags scientific = <em>unspecified</em>;
  static constexpr fmtflags showbase = <em>unspecified</em>;
  static constexpr fmtflags showpoint = <em>unspecified</em>;
  static constexpr fmtflags showpos = <em>unspecified</em>;
  static constexpr fmtflags skipws = <em>unspecified</em>;
  static constexpr fmtflags unitbuf = <em>unspecified</em>;
  static constexpr fmtflags uppercase = <em>unspecified</em>;
  static constexpr fmtflags adjustfield = <em>see below</em>;
  static constexpr fmtflags basefield = <em>see below</em>;
  static constexpr fmtflags floatfield = <em>see below</em>;
</ins>
<del>  <em>// 27.5.2.1.2 fmtflags</em>
  enum fmtflags {
    boolalpha = <em>unspecified</em>,
    dec = <em>unspecified</em>,
    fixed = <em>unspecified</em>,
    hex = <em>unspecified</em>,
    internal = <em>unspecified</em>,
    left = <em>unspecified</em>,
    oct = <em>unspecified</em>,
    right = <em>unspecified</em>,
    scientific = <em>unspecified</em>,
    showbase = <em>unspecified</em>,
    showpoint = <em>unspecified</em>,
    showpos = <em>unspecified</em>,
    skipws = <em>unspecified</em>,
    unitbuf = <em>unspecified</em>,
    uppercase = <em>unspecified</em>,
    adjustfield = <em>unspecified</em>,
    basefield = <em>unspecified</em>,
    floatfield = <em>unspecified</em>,
  };

  constexpr fmtflags operator~(fmtflags f);
  constexpr fmtflags operator&amp;(fmtflags lhs, fmtflags rhs);
  constexpr fmtflags operator|(fmtflags lhs, fmtflags rhs);
</del>

<ins>
  typedef <em>T2</em> iostate;
  static constexpr iostate badbit = <em>unspecified</em>;
  static constexpr iostate eofbit = <em>unspecified</em>;
  static constexpr iostate failbit = <em>unspecified</em>;
  static constexpr iostate goodbit = <em>see below</em>;
</ins><del>
  <em>// 27.5.2.1.3 iostate</em>
  enum iostate {
    badbit = <em>unspecified</em>,
    eofbit = <em>unspecified</em>,
    failbit = <em>unspecified</em>,
    goodbit = <em>unspecified</em>,
  };

  constexpr iostate operator~(iostate f);
  constexpr iostate operator&amp;(iostate lhs, iostate rhs);
  constexpr iostate operator|(iostate lhs, iostate rhs);
</del>
<ins>
  typedef <em>T3</em> openmode;
  static constexpr openmode app = <em>unspecified</em>;
  static constexpr openmode ate = <em>unspecified</em>;
  static constexpr openmode binary = <em>unspecified</em>;
  static constexpr openmode in = <em>unspecified</em>;
  static constexpr openmode out = <em>unspecified</em>;
  static constexpr openmode trunc = <em>unspecified</em>;
</ins><del>
  <em>// 27.5.2.1.4 openmode</em>
  enum openmode {
    app = <em>unspecified</em>,
    ate = <em>unspecified</em>,
    binary = <em>unspecified</em>,
    in = <em>unspecified</em>,
    out = <em>unspecified</em>,
    trunc = <em>unspecified</em>,
  };

  constexpr openmode operator~(openmode f);
  constexpr openmode operator&amp;(openmode lhs, openmode rhs);
  constexpr openmode operator|(openmode lhs, openmode rhs);
</del>

<ins>
  typedef <em>T4</em> seekdir;
  static constexpr seekdir beg = <em>unspecified</em>;
  static constexpr seekdir cur = <em>unspecified</em>;
  static constexpr seekdir end = <em>unspecified</em>;
</ins>
  <del>
  <em>// 27.5.2.1.5 seekdir</em>
  enum seekdir {
    beg = <em>unspecified</em>,
    cur = <em>unspecified</em>,
    end = <em>unspecified</em>,
  };

  constexpr seekdir operator~(seekdir f);
  constexpr seekdir operator&amp;(seekdir lhs, seekdir rhs);
  constexpr seekdir operator|(seekdir lhs, seekdir rhs);
</del>
</pre>

<p>Revert the changes from n2349, making the following changes to 27.5.2.1.2:</p>

<div class="standardtext"><pre>
  <ins>typedef <em>T1</em> fmtflags;</ins>
  <del>enum fmtflags;</del>
</pre>
<p>1 The type <code>fmtflags</code> is a bitmask type (17.5.2.1.3). Setting its elements has the effects indicated in Table 112.</p>
<p>2 Type <code>fmtflags</code> also defines the constants indicated in Table 113.</p>
<div class="deleted"> 
<pre>  constexpr fmtflags ios_base::operator~(fmtflags f);</pre>
<p>3 <em>Returns:</em> <code>fmtflags( f)</code>.</p>

<pre>  constexpr fmtflags ios_base::operator&amp;(fmtflags lhs, fmtflags rhs);</pre>
<p>4 <em>Returns:</em> <code>fmtflags(int(lhs) &amp; int(rhs))</code>.</p>

<pre>  constexpr fmtflags ios_base::operator|(fmtflags lhs, fmtflags rhs);</pre>
<p>5 <em>Returns:</em> <code>fmtflags(int(lhs) | int(rhs))</code>.</p>
</div>

</div>

<p>Make the following changes to 27.5.2.1.3:</p>

<div class="standardtext"><pre>
  <ins>typedef <em>T2</em> iostate;</ins>
  <del>enum iostate;</del>
</pre>
<p>1 The type <code>iostate</code> is a bitmask type (17.5.2.1.3) that contains the elements indicated in Table 114.</p>
<div class="deleted">
<pre>  constexpr iostate ios_base::operator~(iostate f);</pre>
<p>2 <em>Returns:</em> <code>iostate(f)</code>.</p>

<pre>  constexpr iostate ios_base::operator&amp;(iostate lhs, iostate rhs);</pre>
<p>3 <em>Returns:</em> <code>iostate(int(lhs) &amp; int(rhs))</code>.</p>

<pre>  constexpr iostate ios_base::operator|(iostate lhs, iostate rhs);</pre>
<p>4 <em>Returns:</em> <code>iostate(int(lhs) | int(rhs))</code>.</p>
</div>

</div>

<p>Make the following changes to 27.5.2.1.4:</p>

<div class="standardtext"><pre>
  <ins>typedef <em>T3</em> openmode;</ins>
  <del>enum openmode;</del>
</pre>
<p>1 The type <code>openmode</code> is a bitmask type (17.5.2.1.3). It contains the elements indicated in Table 115.</p>
<div class="deleted">
<pre>  constexpr openmode ios_base::operator~(openmode f);</pre>
<p>2 <em>Returns:</em> <code>openmode(f)</code>.</p>

<pre>  constexpr openmode ios_base::operator&amp;(openmode lhs, openmode rhs);</pre>
<p>3 <em>Returns:</em> <code>openmode(int(lhs) &amp; int(rhs))</code>.</p>

<pre>  constexpr openmode ios_base::operator|(openmode lhs, openmode rhs);</pre>
<p>4 <em>Returns:</em> <code>openmode(int(lhs) | int(rhs))</code>.</p>
</div>

</div>

<p>Make the following changes to 27.5.2.1.5:</p>

<div class="standardtext"><pre>
  <ins>typedef <em>T4</em> seekdir;</ins>
  <del>enum seekdir;</del>
</pre>
<p>1 The type seekdir is an enumerated type (17.5.2.1.2) that contains the elements indicated in Table 116.</p>
<div class="deleted"> 
<pre>  constexpr seekdir ios_base::operator~(seekdir f);</pre>
<p>2 <em>Returns:</em> <code>seekdir(f)</code>.</p>

<pre>  constexpr seekdir ios_base::operator&amp;(seekdir lhs, seekdir rhs);</pre>
<p>3 <em>Returns:</em> <code>seekdir(int(lhs) &amp; int(rhs))</code>.</p>

<pre>  constexpr seekdir ios_base::operator|(seekdir lhs, seekdir rhs);</pre>
<p>4 <em>Returns:</em> <code>seekdir(int(lhs) | int(rhs))</code>.</p>

</div>
</div>

<h3>Modifications to Bitmask Type <code>regex_constants::syntax_option_type</code></h3>

<p>Make the following changes to 28.5.1:</p>

<div class="standardtext"> 
<pre>
namespace std {
 namespace regex_constants {
<ins>  typedef <em>bitmask_type</em> syntax_option_type;
  constexpr syntax_option_type icase = <em>unspecified</em>;
  constexpr syntax_option_type nosubs = <em>unspecified</em>;
  constexpr syntax_option_type optimize = <em>unspecified</em>;
  constexpr syntax_option_type collate = <em>unspecified</em>;
  constexpr syntax_option_type ECMAScript = <em>unspecified</em>;
  constexpr syntax_option_type basic = <em>unspecified</em>;
  constexpr syntax_option_type extended = <em>unspecified</em>;
  constexpr syntax_option_type awk = <em>unspecified</em>;
  constexpr syntax_option_type grep = <em>unspecified</em>;
  constexpr syntax_option_type egrep = <em>unspecified</em>;
</ins><del>
  enum syntax_option_type {
    icase = <em>implementation-defined</em>,
    nosubs = <em>implementation-defined</em>,
    optimize = <em>implementation-defined</em>,
    collate = <em>implementation-defined</em>,
    ECMAScript = <em>implementation-defined</em>,
    basic = <em>implementation-defined</em>,
    extended = <em>implementation-defined</em>,
    awk = <em>implementation-defined</em>,
    grep = <em>implementation-defined</em>,
    egrep = <em>implementation-defined</em>,
  };
  constexpr syntax_option_type operator~(syntax_option_type f);
  constexpr syntax_option_type operator&amp;(syntax_option_type lhs, syntax_option_type rhs);
  constexpr syntax_option_type operator|(syntax_option_type lhs, syntax_option_type rhs);
</del> }
}
</pre>

<p>1 The type <code>syntax_option_type</code> is an implementation-defined bitmask type (17.5.2.1.3).
Setting its elements has the effects listed in table 135.
A valid value of type <code>syntax_option_type</code> shall have exactly one of the
elements <code>ECMAScript</code>, <code>basic</code>, <code>extended</code>,
<code>awk</code>, <code>grep</code>, <code>egrep</code>, set.
</p>

<div class="deleted">
<pre>  constexpr syntax_option_type operator~(syntax_option_type f);</pre>
<p>2 <em>Returns:</em> <code>syntax_option_type(f)</code>.</p>

<pre>  constexpr syntax_option_type operator&amp;(syntax_option_type lhs, syntax_option_type rhs);</pre>
<p>3 <em>Returns:</em> <code>syntax_option_type(int(lhs) &amp; int(rhs))</code>.</p>

<pre>  constexpr syntax_option_type operator|(syntax_option_type lhs, syntax_option_type rhs);</pre>
<p>4 <em>Returns:</em> <code>syntax_option_type(int(lhs) | int(rhs))</code>.</p>
</div>
</div>


<h3>Modifications to Bitmask Type <code>regex_constants::syntax_option_type</code></h3>

<p>Make the following changes to 28.5.2:</p>

<div class="standardtext"> 
<pre>
namespace std {
 namespace regex_constants{<ins>
  typedef <em>bitmask_type</em> match_flag_type;
  constexpr match_flag_type match_default{ 0 };
  constexpr match_flag_type match_not_bol = <em>unspecified</em>;
  constexpr match_flag_type match_not_eol = <em>unspecified</em>;
  constexpr match_flag_type match_not_bow = <em>unspecified</em>;
  constexpr match_flag_type match_not_eow = <em>unspecified</em>;
  constexpr match_flag_type match_any = <em>unspecified</em>;
  constexpr match_flag_type match_not_null = <em>unspecified</em>;
  constexpr match_flag_type match_continuous = <em>unspecified</em>;
  constexpr match_flag_type match_prev_avail = <em>unspecified</em>;
  constexpr match_flag_type format_default{ 0 };
  constexpr match_flag_type format_sed = <em>unspecified</em>;
  constexpr match_flag_type format_no_copy = <em>unspecified</em>;
  constexpr match_flag_type format_first_only = <em>unspecified</em>;
</ins><del>
  enum match_flag_type {
    match_default = 0,
    match_not_bol = <em>implementation-defined</em>,
    match_not_eol = <em>implementation-defined</em>,
    match_not_bow = <em>implementation-defined</em>,
    match_not_eow = <em>implementation-defined</em>,
    match_any = <em>implementation-defined</em>,
    match_not_null = <em>implementation-defined</em>,
    match_continuous = <em>implementation-defined</em>,
    match_prev_avail = <em>implementation-defined</em>,
    format_default = 0,
    format_sed = <em>implementation-defined</em>,
    format_no_copy = <em>implementation-defined</em>,
    format_first_only = <em>implementation-defined</em>,
  };
  constexpr match_flag_type operator~(match_flag_type f);
  constexpr match_flag_type operator&amp;(match_flag_type lhs, match_flag_type rhs);
  constexpr match_flag_type operator|(match_flag_type lhs, match_flag_type rhs);
</del> }
}
</pre>
<p>1 The type <code>regex_constants::match_flag_type</code> is an implementation-defined bitmask type (17.5.2.1.3).
Matching a regular expression against a sequence of characters <code>[first,last)</code> proceeds according to the
rules of the grammar specified for the regular expression object, modified according to the effects listed in
table 136 for any bitmask elements set.
</p>

<div class="deleted"> 
<pre>  constexpr match_flag_type operator~(match_flag_type f);</pre>
<p>2 <em>Returns:</em> <code>match_flag_type(f)</code>.</p>

<pre>  constexpr match_flag_type operator&amp;(match_flag_type lhs, match_flag_type rhs);</pre>
<p>3 <em>Returns:</em> <code>match_flag_type(int(lhs) &amp; int(rhs))</code>.</p>

<pre>  constexpr match_flag_type operator|(match_flag_type lhs, match_flag_type rhs);</pre>
<p>4 <em>Returns:</em> <code>match_flag_type(int(lhs) | int(rhs))</code>.</p>
</div>

</div>

<h3>Modifications to Bitmask Type <code>regex_constants::error_type</code></h3>

<p>Make the following changes to 28.5.3:</p>

<div class="standardtext"><pre>
namespace std {
 namespace regex_constants {
<ins>  typedef <em>implementation-defined</em> error_type;
  constexpr error_type error_collate = <em>unspecified</em>;
  constexpr error_type error_ctype = <em>unspecified</em>;
  constexpr error_type error_escape = <em>unspecified</em>;
  constexpr error_type error_backref = <em>unspecified</em>;
  constexpr error_type error_brack = <em>unspecified</em>;
  constexpr error_type error_paren = <em>unspecified</em>;
  constexpr error_type error_brace = <em>unspecified</em>;
  constexpr error_type error_badbrace = <em>unspecified</em>;
  constexpr error_type error_range = <em>unspecified</em>;
  constexpr error_type error_space = <em>unspecified</em>;
  constexpr error_type error_badrepeat = <em>unspecified</em>;
  constexpr error_type error_complexity = <em>unspecified</em>;
  constexpr error_type error_stack = <em>unspecified</em>;
</ins><del>
  enum error_type {
    error_collate = <em>implementation-defined</em>,
    error_ctype = <em>implementation-defined</em>,
    error_escape = <em>implementation-defined</em>,
    error_backref = <em>implementation-defined</em>,
    error_brack = <em>implementation-defined</em>,
    error_paren = <em>implementation-defined</em>,
    error_brace = <em>implementation-defined</em>,
    error_badbrace = <em>implementation-defined</em>,
    error_range = <em>implementation-defined</em>,
    error_space = <em>implementation-defined</em>,
    error_badrepeat = <em>implementation-defined</em>,
    error_complexity = <em>implementation-defined</em>,
    error_stack = <em>implementation-defined</em>,
  };
  constexpr error_type operator~(error_type f);
  constexpr error_type operator&amp;(error_type lhs, error_type rhs);
  constexpr error_type operator|(error_type lhs, error_type rhs);
</del> }
}
</pre>

<p>1 The type <code>error_type</code> is an implementation-defined enumerat<del>ion</del><ins>ed</ins> type (17.5.2.1.2). Values of type <code>error_type</code> represent the error conditions described in table 137:
</p>

<div class="deleted"> 
<pre>  constexpr error_type operator~(error_type f);</pre>
<p>2 <em>Returns:</em> <code>error_type(f)</code>.</p>

<pre>  constexpr error_type operator&amp;(error_type lhs, error_type rhs);</pre>
<p>3 <em>Returns:</em> <code>error_type(int(lhs) &amp; int(rhs))</code>.</p>

<pre>  constexpr error_type operator|(error_type lhs, error_type rhs);</pre>
<p>4 <em>Returns:</em> <code>error_type(int(lhs) | int(rhs))</code>.</p>
</div>

</div>

</body></html> 

