<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 459: Requirement for widening in stage 2 is overspecification</title>
<meta property="og:title" content="Issue 459: Requirement for widening in stage 2 is overspecification">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue459.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#NAD">NAD</a> status.</em></p>
<h3 id="459"><a href="lwg-closed.html#459">459</a>. Requirement for widening in stage 2 is overspecification</h3>
<p><b>Section:</b> 28.3.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a> <b>Status:</b> <a href="lwg-active.html#NAD">NAD</a>
 <b>Submitter:</b> Martin Sebor <b>Opened:</b> 2004-03-16 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#facet.num.get.virtuals">active issues</a> in [facet.num.get.virtuals].</p>
<p><b>View all other</b> <a href="lwg-index.html#facet.num.get.virtuals">issues</a> in [facet.num.get.virtuals].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>When parsing strings of wide-character digits, the standard
  requires the library to widen narrow-character "atoms" and compare
  the widened atoms against the characters that are being parsed.
  Simply narrowing the wide characters would be far simpler, and
  probably more efficient.  The two choices are equivalent except in
  convoluted test cases, and many implementations already ignore the
  standard and use narrow instead of widen.</p>

<p>
First, I disagree that using narrow() instead of widen() would
necessarily have unfortunate performance implications. A possible
implementation of narrow() that allows num_get to be implemented
in a much simpler and arguably comparably efficient way as calling
widen() allows, i.e. without making a virtual call to do_narrow every
time, is as follows:
</p>

<pre>
  inline char ctype&lt;wchar_t>::narrow (wchar_t wc, char dflt) const
  {
      const unsigned wi = unsigned (wc);

      if (wi > UCHAR_MAX)
          return typeid (*this) == typeid (ctype&lt;wchar_t>) ?
                 dflt : do_narrow (wc, dflt);

      if (narrow_ [wi] &lt; 0) {
         const char nc = do_narrow (wc, dflt);
         if (nc == dflt)
             return dflt;
         narrow_ [wi] = nc;
      }

      return char (narrow_ [wi]);
  }
</pre>

<p>
Second, I don't think the change proposed in the issue (i.e., to use
narrow() instead of widen() during Stage 2) would be at all
drastic. Existing implementations with the exception of libstdc++
currently already use narrow() so the impact of the change on programs
would presumably be isolated to just a single implementation. Further,
since narrow() is not required to translate alternate wide digit
representations such as those mentioned in issue <a href="lwg-defects.html#303" title="Bitset input operator underspecified (Status: CD1)">303</a><sup><a href="https://cplusplus.github.io/LWG/issue303" title="Latest snapshot">(i)</a></sup> to
their narrow equivalents (i.e., the portable source characters '0'
through '9'), the change does not necessarily imply that these
alternate digits would be treated as ordinary digits and accepted as
part of numbers during parsing. In fact, the requirement in 28.3.4.2.2.3 <a href="https://wg21.link/locale.ctype.virtuals">[locale.ctype.virtuals]</a>, p13 forbids narrow() to translate an alternate
digit character, wc, to an ordinary digit in the basic source
character set unless the expression
(ctype&lt;charT>::is(ctype_base::digit, wc) == true) holds. This in
turn is prohibited by the C standard (7.25.2.1.5, 7.25.2.1.5, and
5.2.1, respectively) for charT of either char or wchar_t.
</p>

<p><i>[Sydney: To a large extent this is a nonproblem. As long as
you're only trafficking in char and wchar_t we're only dealing with a
stable character set, so you don't really need either 'widen' or
'narrow': can just use literals. Finally, it's not even clear whether
widen-vs-narrow is the right question; arguably we should be using
codecvt instead.]</i></p>


<p><i>[
2009-07 Frankfurt
]</i></p>


<blockquote><p>
NAD. The standard is clear enough as written.
</p></blockquote>



<p id="res-459"><b>Proposed resolution:</b></p>
<p>Change stage 2 so that implementations are permitted to use either
technique to perform the comparison:</p>
<ol>
  <li> call widen on the atoms and compare (either by using
      operator== or char_traits&lt;charT>::eq) the input with
      the widened atoms, or</li>
  <li> call narrow on the input and compare the narrow input
      with the atoms</li>
  <li> do (1) or (2) only if charT is not char or wchar_t,
      respectively; i.e., avoid calling widen or narrow
      if it the source and destination types are the same</li>
</ol>





</body>
</html>
