<html>

<head>
  <meta name="description" content="Deprecating &lt;codecvt&gt;">
  <meta name="keywords" content="C++,cplusplus,wg21">
  <meta name="author" content="Alisdair Meredith">

  <title>Deprecating &lt;codecvt&gt;</title>

  <style type="text/css">
    ins {background-color:#A0FFA0}
    del {background-color:#FFA0A0}
    p {text-align:justify}
    li {text-align:justify}
    blockquote.note
    {
      background-color:#E0E0E0;
      padding-left: 15px;
      padding-right: 15px;
      padding-top: 1px;
      padding-bottom: 1px;
    }
  </style>
</head>

<body>
<table>
<tr>
  <td align="left">Doc. no.</td>
  <td align="left">P0618R0</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2017-03-02</td>
</tr>
<tr>
  <td align="left">Project:</td>
  <td align="left">Programming Language C++</td>
</tr>
<tr>
  <td align="left">Audience:</td>
  <td align="left">Library Working Group</td>
</tr>
<tr>
  <td align="left">Reply to:</td>
  <td align="left">Alisdair Meredith &lt;<a href="mailto:ameredith1@bloomberg.net">ameredith1@bloomberg.net</a>&gt;</td>
</tr>
</table>

<h1>Deprecating &lt;codecvt&gt;</h1>

<h2>Table of Contents</h2>
<ol>
<li><a href="#rev.hist">Revision History</a></li>
  <ul>
  <li><a href="#rev.0">Revision 0</a></li>
  </ul>
<li><a href="#1.0">1 Introduction</a></li>
<li><a href="#2.0">2 Stating the problem</a></li>
<li><a href="#3.0">3 Propose Solution</a></li>
<li><a href="#4.0">4 Other Directions</a></li>
<li><a href="#5.0">5 Formal Wording</a></li>
</ol>


<h2><a name="rev.hist">Revision History</a></h2>

<h3><a name="rev.0">Revision 0</a></h3>
<p>
Original version of the paper.
</p>

<h2><a name="1.0">1 Introduction</a></h2>
<p>
This paper aims to address NB comment: GB-57, which was tentatively reviewed
and accepted by LEWG at Issaquah 2016 (check wiki minutes to verify claim).
</p>

<h2><a name="2.0">2 Stating the problem</a></h2>
<p>
As per GB-57:
</p>
<p>
The contents of <codecvt> are underspecified, and will take a reasonable amount
of work to identify and correct all of the issues. There appears to be a
general feeling that this is not the best way to address unicode transcoding in
the first place, and this library component should be retired to Annex D, along
side <strstream>, until a suitable replacement is standardized.
</p>

<p>
Reviewing the NB comments, Beman Dawes (who provided a review and wording for
updating our Unicode standard reference) gave additional feedback:
</p>
<p>
&quot;I'm in favor of this proposed change, but won't be in Kona so Marshall
asked me to post my views on the reflector. Here is some additional rationale
of deprecation.&quot;
</p>

<ul>
<li>As the Unicode standard and security experts point out, ill-formed UTF can
be and has been used as an attack vector. Yet the <tt>&lt;codecvt&gt;</tt>
facets don't provide the safe forms of error handling as their defaults, and it
is far to hard to use them in a safe way.
</li>
<li>
I've wanted to use <tt>&lt;codecvt&gt;</tt> in production code three or four
times where <codecvt> turned out to not be suitable, but because the spec is so
obscure, it took far too much time to realize that.
</li>
<li>In the couple of cases where <tt>&lt;codecvt&gt;</tt> would have been
suitable, I couldn't use it because the code had to be portable, yet libstdc++
didn't support <codecvt> until very recently. That, coupled with the fact that
<codecvt> is a new header, means there just aren't a lot of users.
</li>
<li>In published usage surveys like BuiltWith, use of formerly popular non-UTF
encodings like Shift-JIS and Big5 is plummeting compared to UTF encodings. The
standard library badly needs modern C++ UTF conversion facilities, yet
<tt>&lt;codecvt&gt;</tt> is an embarrassment. Let's deprecate it to clear the
path for the future.
</li>
</ul>
<h2><a name="3.0">3 Proposed Solution</a></h2>
<p>
Move the whole of clause 22.5 [locale.stdcvt] to Annex D, updating the stable
reference tags with a <b>depr.</b> prefix.
</p>

<p>
Deliberately retain the dated reference to ISO 10646, rather than relying on
the dated reference in 1.2 [intro.refs], as a concession to the deprecated
material retaining references to UCS-2.
</p>

<p>
Review by the Library Working Group in Kona (2017) recommended that the
<tt>wstring_convert</tt> and <tt>wbuffer_convert</tt> facilities from
<tt>&lt;locale&gt;</tt> be deprecated at the same time.
</p>

<h2><a name="4.0">4 Other Directions</a></h2>
<p>
The prospect of filing 30-40 defect reports and trying to beat this clause into
reasonably well-specified and correct behavior is unappealing, but potentially
vialble way to make progress.
</p>

<p>
Note that deprecation does not prohibit filing and fixing issues, but is is
likely to reduce the priority given to such issues in the limited LWG time.
</p>

<h2><a name="5.0">5 Formal Wording</a></h2>
<p>
These changes are relative to
<a href = "http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4640">N4640</a>
in the pre-Kona mailing.
</p>

<blockquote class="note">
Editor's note: the change for the draft document is almost entirely a cut and
paste of the relevant clauses.  The only differences are new stable names, some
introductory text for the purposes of deprecatation, and D.Xp1 is moved up from
D.X.1p1, in order to serve as the introductory text.
</blockquote>

<h4>22.1 General [localization.general]</h4>
<ol start="2">
<li>
The following subclauses describe components for locales themselves, the
standard facets, and facilities from the ISO C library, as summarized in Table
68.
</li>
</ol>

<blockquote>
<table>
<tr>
  <td></td>
  <td><b>Subclause</b></td>
  <td><b>Header(s)</b></td>
</tr>
<tr>
  <td>22.3</td>
  <td>Locales</td>
  <td><tt>&lt;locale&gt;</tt></td>
</tr>
<tr>
  <td>22.4</td>
  <td>Standard <tt>locale</tt> categories</td>
  <td></td>
</tr>
<tr>
  <td><del>22.5</del></td>
  <td><del>Standard code conversion facets</del></td>
  <td><del><tt>&lt;codecvt&gt;</tt></del></td>
</tr>
<tr>
  <td>22.6</td>
  <td>C library locales</td>
  <td><tt>&lt;clocale&gt;</tt></td>
</tr>
</table>
</blockquote>

<h4>22.2 Header &lt;locale&gt; synopsis [locale.syn]</h4>
<pre><blockquote>
namespace std {
  <i>// 22.3.1, locale</i>
  class locale;
  template &lt;class Facet&gt; const Facet&amp; use_facet(const locale&amp;);
  template &lt;class Facet&gt; bool         has_facet(const locale&amp;) noexcept;

  <i>// 22.3.3, convenience interfaces</i>
  template &lt;class charT&gt; bool isspace (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool isprint (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool iscntrl (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool isupper (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool islower (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool isalpha (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool isdigit (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool ispunct (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool isxdigit(charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool isalnum (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool isgraph (charT c, const locale&amp; loc);
  template &lt;class charT&gt; bool isblank (charT c, const locale&amp; loc);
  template &lt;class charT&gt; charT toupper(charT c, const locale&amp; loc);
  template &lt;class charT&gt; charT tolower(charT c, const locale&amp; loc);
  <del>template &lt;class Codecvt, class Elem = wchar_t,</del>
            <del>class Wide_alloc = allocator&lt;Elem&gt;,</del>
            <del>class Byte_alloc = allocator&lt;char&gt;&gt;</del>
    <del>class wstring_convert;</del>
  <del>template &lt;class Codecvt, class Elem = wchar_t,</del>
            <del>class Tr = char_traits&lt;Elem&gt;&gt;</del>
    <del>class wbuffer_convert;</del>

  // ...
}
</blockquote></pre>

<h4><del>22.3.3.2.2 Class template wstring_convert [conversions.string]</del></h4>
<ol>
<li><del>
Class template <tt>wstring_convert</tt> performs conversions between a wide
string and a byte string.  It lets you specify a code conversion facet (like
class template <tt>codecvt</tt>) to perform the conversions, without affecting
any streams or locales.  [ <i>Example:</i> If you want to use the code
conversion facet <tt>codecvt_utf8</tt> to output to <tt>cout</tt> a UTF-8
multibyte sequence corresponding to a wide string, but you don’t want to alter
the locale for <tt>cout</tt>, you can write something like:
<pre><blockquote>
<del>wstring_convert&lt;std::codecvt_utf8&lt;wchar_t&gt;&gt; myconv;</del>
<del>std::string mbstring = myconv.to_bytes(L"Hello\n");</del>
<del>std::cout &lt;&lt; mbstring;</del>
</blockquote></pre>
&mdash; <i>end example</i> ]
</del></del></li>

<pre><blockquote>
<del>namespace std {</del>
<del>template &lt;class Codecvt, class Elem = wchar_t,</del>
          <del>class Wide_alloc = allocator&lt;Elem&gt;,</del>
          <del>class Byte_alloc = allocator&lt;char&gt;&gt;</del>
  <del>class wstring_convert {</del>
  <del>public:</del>
    <del>using byte_string = basic_string&lt;char, char_traits&lt;char&gt;, Byte_alloc&gt;;</del>
    <del>using wide_string = basic_string&lt;Elem, char_traits&lt;Elem&gt;, Wide_alloc&gt;;</del>
    <del>using state_type  = typename Codecvt::state_type;</del>
    <del>using int_type    = typename wide_string::traits_type::int_type;</del>

    <del>explicit wstring_convert(Codecvt* pcvt = new Codecvt);</del>
    <del>wstring_convert(Codecvt* pcvt, state_type state);</del>
    <del>explicit wstring_convert(const byte_string&amp; byte_err,</del>
                             <del>const wide_string&amp; wide_err = wide_string());</del>
    <del>~wstring_convert();</del>

    <del>wstring_convert(const wstring_convert&amp;) = delete;</del>
    <del>wstring_convert&amp; operator=(const wstring_convert&amp;) = delete;</del>

    <del>wide_string from_bytes(char byte);</del>
    <del>wide_string from_bytes(const char* ptr);</del>
    <del>wide_string from_bytes(const byte_string&amp; str);</del>
    <del>wide_string from_bytes(const char* first, const char* last);</del>
    <del>byte_string to_bytes(Elem wchar);</del>
    <del>byte_string to_bytes(const Elem* wptr);</del>
    <del>byte_string to_bytes(const wide_string&amp; wstr);</del>
    <del>byte_string to_bytes(const Elem* first, const Elem* last);</del>
    <del>size_t converted() const noexcept;</del>
    <del>state_type state() const;</del>
  <del>private:</del>
    <del>byte_string byte_err_string;</del>
    <del>wide_string wide_err_string;</del>
    <del>Codecvt* cvtptr;</del>
    <del>state_type cvtstate;</del>
    <del>size_t cvtcount;</del>
  <del>};</del>
<del>}</del>
</blockquote></pre>

<li><del>
The class template describes an object that controls conversions between wide
string objects of class
<tt>basic_string&lt;Elem, char_traits&lt;Elem&gt;, Wide_alloc&gt;</tt> and
byte string objects of class
<tt>basic_string&lt;char, char_traits&lt;char&gt;, Byte_alloc&gt;</tt>.
The class template defines the types <tt>wide_string</tt> and
<tt>byte_string</tt> as synonyms for these two types. Conversion between a
sequence of <tt>Elem</tt> values (stored in a <tt>wide_string</tt> object) and
multibyte sequences (stored in a <tt>byte_string</tt> object) is performed by
an object of class <tt>Codecvt</tt>, which meets the requirements of the
standard code-conversion facet <tt>codecvt&lt;Elem, char, mbstate_t&gt;</tt>.
</del></li>
<li><del>
An object of this class template stores:
  <ol>
  <li><del>
  &mdash; <tt>byte_err_string</tt> &mdash; a byte string to display on errors
  </del></li>
  <li><del>
  &mdash; <tt>wide_err_string</tt> &mdash; a wide string to display on errors
  </del></li>
  <li><del>
  &mdash; <tt>cvtptr</tt> &mdash; a pointer to the allocated conversion object
  (which is freed when the <tt>wstring_convert</tt> object is destroyed)
  </del></li>
  <li><del>
  &mdash; <tt>cvtstate</tt> &mdash; a conversion state object
  </del></li>
  <li><del>
  &mdash; <tt>cvtcount</tt> &mdash; a conversion count
  </del></li>
  </ol>
</del></li>

<pre><blockquote>
<del>using byte_string = basic_string&lt;char, char_traits&lt;char&gt;, Byte_alloc&gt;;</del>
</blockquote></pre>
<li><del>
The type shall be a synonym for
<tt>basic_string&lt;char, char_traits&lt;char&gt;, Byte_alloc&gt;</tt>
</del></li>

<pre><blockquote>
<del>size_t converted() const noexcept;</del>
</blockquote></pre>
<li><del>
<i>Returns:</i> <tt>cvtcount</tt>.
</del></li>

<pre><blockquote>
<del>wide_string from_bytes(char byte);</del>
<del>wide_string from_bytes(const char* ptr);</del>
<del>wide_string from_bytes(const byte_string&amp; str);</del>
<del>wide_string from_bytes(const char* first, const char* last);</del>
</blockquote></pre>
<li><del>
<i>Effects:</i> The first member function shall convert the single-element
sequence <tt>byte</tt> to a wide string. The second member function shall
convert the null-terminated sequence beginning at <tt>ptr</tt> to a wide
string. The third member function shall convert the sequence stored in str to a
wide string. The fourth member function shall convert the sequence defined by
the range <tt>[first, last)</tt> to a wide string.
</del></li>
<li><del>
In all cases:
  <ol>
  <li><del>
&mdash; If the <tt>cvtstate</tt> object was not constructed with an explicit
value, it shall be set to its default value (the initial conversion state)
before the conversion begins. Otherwise it shall be left unchanged.
  </del></li>
  <li><del>
&mdash; The number of input elements successfully converted shall be stored in
<tt>cvtcount</tt>.
  </del></li>
  </ol>
</del></li>

<li><del>
<i>Returns:</i> If no conversion error occurs, the member function shall return
the converted wide string. Otherwise, if the object was constructed with a
wide-error string, the member function shall return the wide-error string.
Otherwise, the member function throws an object of class <tt>range_error</tt>.
</del></li>

<pre><blockquote>
<del>using int_type = typename wide_string::traits_type::int_type;</del>
</blockquote></pre>
<li><del>
The type shall be a synonym for <tt>wide_string::traits_type::int_type</tt>.
</del></li>

<pre><blockquote>
<del>state_type state() const;</del>
</blockquote></pre>
<li><del>
returns <tt>cvtstate</tt>.
</del></li>

<pre><blockquote>
<del>using state_type = typename Codecvt::state_type;</del>
</blockquote></pre>
<li><del>
The type shall be a synonym for <tt>Codecvt::state_type</tt>.
</del></li>

<pre><blockquote>
<del>byte_string to_bytes(Elem wchar);</del>
<del>byte_string to_bytes(const Elem* wptr);</del>
<del>byte_string to_bytes(const wide_string&amp; wstr);</del>
<del>byte_string to_bytes(const Elem* first, const Elem* last);</del>
</blockquote></pre>
<li><del>
<i>Effects:</i> The first member function shall convert the single-element
sequence <tt>wchar</tt> to a byte string. The second member function shall
convert the null-terminated sequence beginning at <tt>wptr</tt> to a byte
string. The third member function shall convert the sequence stored in wstr to
a byte string. The fourth member function shall convert the sequence defined by
the range <tt>[first, last)</tt> to a byte string.
</del></li>

<li><del>
In all cases:
  <ol>
  <li><del>
&mdash; If the <tt>cvtstate</tt> object was not constructed with an explicit
value, it shall be set to its default value (the initial conversion state)
before the conversion begins. Otherwise it shall be left unchanged.
  </del></li>
  <li><del>
&mdash; The number of input elements successfully converted shall be stored in
<tt>cvtcount</tt>.
  </del></li>
  </ol>
</del></li>

<li><del>
<i>Returns:</i> If no conversion error occurs, the member function shall return
the converted byte string. Otherwise, if the object was constructed with a
byte-error string, the member function shall return the byte-error string.
Otherwise, the member function shall throw an object of class
<tt>range_error</tt>.
</del></li>

<pre><blockquote>
<del>using wide_string = basic_string&lt;Elem, char_traits&lt;Elem&gt;, Wide_alloc&gt;;</del>
</blockquote></pre>
<li><del>
The type shall be a synonym for
<tt>basic_string&lt;Elem, char_traits&lt;Elem&gt;, Wide_alloc&gt;</tt>.
</del></li>

<pre><blockquote>
<del>explicit wstring_convert(Codecvt* pcvt = new Codecvt);</del>
<del>wstring_convert(Codecvt* pcvt, state_type state);</del>
<del>explicit wstring_convert(const byte_string&amp; byte_err,</del>
    <del>const wide_string&amp; wide_err = wide_string());</del>
</blockquote></pre>
<li><del>
<i>Requires:</i> For the first and second constructors, <tt>pcvt != nullptr</tt>.
</del></li>

<li><del>
<i>Effects:</i> The first constructor shall store <tt>pcvt</tt> in
<tt>cvtptr</tt> and default values in <tt>cvtstate</tt>,
<tt>byte_err_string</tt>, and <tt>wide_err_string</tt>. The second constructor
shall store <tt>pcvt</tt> in <tt>cvtptr</tt>, <tt>state</tt> in
<tt>cvtstate</tt>, and default values in <tt>byte_err_string</tt> and
<tt>wide_err_string</tt>; moreover the stored state shall be retained between
calls to <tt>from_bytes</tt> and <tt>to_bytes</tt>. The third constructor shall
store <tt>new Codecvt</tt> in <tt>cvtptr</tt>, <tt>state_type()</tt> in
<tt>cvtstate</tt>, <tt>byte_err</tt> in <tt>byte_err_string</tt>, and
<tt>wide_err</tt> in <tt>wide_err_string</tt>.
</del></li>

<pre><blockquote>
<del>~wstring_convert();</del>
</blockquote></pre>
<li><del>
<i>Effects:</i> The destructor shall delete <tt>cvtptr</tt>.
</del></li>
</ol>


<h4><del>22.3.3.2.3 Class template wbuffer_convert [conversions.buffer]</del></h4>
<ol>
<li><del>
Class template <tt>wbuffer_convert</tt> looks like a wide stream buffer, but
performs all its I/O through an underlying byte stream buffer that you specify
when you construct it. Like class template <tt>wstring_convert</tt>, it lets
you specify a code conversion facet to perform the conversions, without
affecting any streams or locales.
</del></li>
<pre><blockquote>
<del>namespace std {</del>
<del>template &lt;class Codecvt, class Elem = wchar_t, class Tr = char_traits&lt;Elem&gt;&gt;</del>
  <del>class wbuffer_convert</del>
    <del>: public basic_streambuf&lt;Elem, Tr&gt; {</del>
  <del>public:</del>
    <del>using state_type = typename Codecvt::state_type;</del>

    <del>explicit wbuffer_convert(streambuf* bytebuf = 0,</del>
                             <del>Codecvt* pcvt = new Codecvt,</del>
                             <del>state_type state = state_type());</del>

    <del>~wbuffer_convert();</del>

    <del>wbuffer_convert(const wbuffer_convert&amp;) = delete;</del>
    <del>wbuffer_convert&amp; operator=(const wbuffer_convert&amp;) = delete;</del>

    <del>streambuf* rdbuf() const;</del>
    <del>streambuf* rdbuf(streambuf* bytebuf);</del>

    <del>state_type state() const;</del>

  <del>private:</del>
    <del>streambuf* bufptr;        // exposition only</del>
    <del>Codecvt* cvtptr;          // exposition only</del>
    <del>state_type cvtstate;      // exposition only</del>
  <del>};</del>
<del>}</del>
</blockquote></pre>
<li><del>
The class template describes a stream buffer that controls the transmission of
elements of type <tt>Elem</tt>, whose character traits are described by the class <tt>Tr</tt>, to
and from a byte stream buffer of type <tt>streambuf</tt>.  Conversion between a sequence
of <tt>Elem</tt> values and multibyte sequences is performed by an object of class
<tt>Codecvt</tt>, which shall meet the requirements of the standard code-conversion
facet <tt>codecvt&lt;Elem, char, mbstate_t&gt;</tt>.
</del></li>

<li><del>
An object of this class template stores:
  <ol>
  <li><del>
&mdash; <tt>bufptr</tt> &mdash; a pointer to its underlying byte stream buffer
  </del></li>
  <li><del>
&mdash; <tt>cvtptr</tt> &mdash; a pointer to the allocated conversion object (which is freed when the <tt>wbuffer_convert</tt> object is destroyed)
  </del></li>
  <li><del>
&mdash; <tt>cvtstate</tt> &mdash; a conversion state object
  </del></li>
  </ol>
</del></li>

<pre><blockquote>
<del>state_type state() const;</del>
</blockquote></pre>
<li><del>
<i>Returns:</i> <tt>cvtstate</tt>.
</del></li>

<pre><blockquote>
<del>streambuf* rdbuf() const;</del>
</blockquote></pre>
</del></li>
<li><del>
<i>Returns:</i> <tt>bufptr</tt>.
</del></li>

<pre><blockquote>
<del>streambuf* rdbuf(streambuf* bytebuf);</del>
</blockquote></pre>
<li><del>
<i>Effects:</i> Stores <tt>bytebuf</tt> in <tt>bufptr</tt>.
</del></li>
<li><del>
<i>Returns:</i> The previous value of <tt>bufptr</tt>.
</del></li>

<pre><blockquote>
<del>using state_type = typename Codecvt::state_type;</del>
</blockquote></pre>
<li><del>
The type shall be a synonym for <tt>Codecvt::state_type</tt>.
</del></li>

<pre><blockquote>
<del>explicit wbuffer_convert(streambuf* bytebuf = 0,</del>
    <del>Codecvt* pcvt = new Codecvt, state_type state = state_type());</del>
</blockquote></pre>
<li><del>
<i>Requires:</i> <tt>pcvt != nullptr</tt>.
</del></li>
<li><del>
<i>Effects:</i> The constructor constructs a stream buffer object, initializes
<tt>bufptr</tt> to <tt>bytebuf</tt>, initializes <tt>cvtptr</tt> to
<tt>pcvt</tt>, and initializes <tt>cvtstate</tt> to <tt>state</tt>.
</del></li>

<pre><blockquote>
<del>~wbuffer_convert();</del>
</blockquote></pre>

<li><del>
<i>Effects:</i> The destructor shall delete <tt>cvtptr</tt>.
</del></li>
</ol>


<h3><del>22.5 Standard code conversion facets [locale.stdcvt]</del></h3>
<h4><del>22.5.1 Header <tt>&lt;codecvt&gt;</tt> synopsis [codecvt.syn]</del></h4>
<pre><blockquote>
<del>namespace std {</del>
  <del>enum codecvt_mode {</del>
    <del>consume_header = 4,</del>
    <del>generate_header = 2,</del>
    <del>little_endian = 1</del>
  <del>};</del>

  <del>template&lt;class Elem, unsigned long Maxcode = 0x10ffff,</del>
    <del>codecvt_mode Mode = (codecvt_mode)0&gt;</del>
  <del>class codecvt_utf8</del>
    <del>: public codecvt&lt;Elem, char, mbstate_t&gt; {</del>
  <del>public:</del>
    <del>explicit codecvt_utf8(size_t refs = 0);</del>
    <del>~codecvt_utf8();</del>
  <del>};</del>

  <del>template&lt;class Elem, unsigned long Maxcode = 0x10ffff,</del>
    <del>codecvt_mode Mode = (codecvt_mode)0&gt;</del>
  <del>class codecvt_utf16</del>
    <del>: public codecvt&lt;Elem, char, mbstate_t&gt; {</del>
  <del>public:</del>
    <del>explicit codecvt_utf16(size_t refs = 0);</del>
    <del>~codecvt_utf16();</del>
  <del>};</del>

  <del>template&lt;class Elem, unsigned long Maxcode = 0x10ffff,</del>
    <del>codecvt_mode Mode = (codecvt_mode)0&gt;</del>
  <del>class codecvt_utf8_utf16</del>
    <del>: public codecvt&lt;Elem, char, mbstate_t&gt; {</del>
  <del>public:</del>
    <del>explicit codecvt_utf8_utf16(size_t refs = 0);</del>
    <del>~codecvt_utf8_utf16();</del>
  <del>};</del>
<del>}</del>
</blockquote></pre>
<ol>
<li><del>
The header <tt>&lt;codecvt&gt;</tt> provides code conversion facets for various
character encodings.
</del></li>
</ol>

<h4><del>22.5.2 Requirements [locale.stdcvt.req]</del></h4>
<ol>
<li><del>
For each of the three code conversion facets <tt>codecvt_utf8</tt>,
<tt>codecvt_utf16</tt>, and <tt>codecvt_utf8_utf16</tt>:
<ol>
<li><del>
&mdash; <tt>Elem</tt> is the wide-character type, such as <tt>wchar_t</tt>,
<tt>char16_t</tt>, or <tt>char32_t</tt>.
</del></li>
<li><del>
&mdash; <tt>Maxcode</tt> is the largest wide-character code that the facet will
read or write without reporting a conversion error.
</del></li>
<li><del>
&mdash; If <tt>(Mode &amp; consume_header)</tt>, the facet shall consume an
initial header sequence, if present, when reading a multibyte sequence to
determine the endianness of the subsequent multibyte sequence to be read.
</del></li>
<li><del>
&mdash; If <tt>(Mode &amp; generate_header)</tt>, the facet shall generate an
initial header sequence when writing a multibyte sequence to advertise the
endianness of the subsequent multibyte sequence to be written.
</del></li>
<li><del>
&mdash; If <tt>(Mode &amp; little_endian)</tt>, the facet shall generate a
multibyte sequence in little-endian order, as opposed to the default big-endian
order.
</del></li>
</ol>
</del></li>

<li><del>
For the facet <tt>codecvt_utf8</tt>:
<ol>
<li><del>
&mdash; The facet shall convert between UTF-8 multibyte sequences and UCS2 or
UCS4 (depending on the size of <tt>Elem</tt>) within the program.
</del></li>
<li><del>
&mdash; Endianness shall not affect how multibyte sequences are read or written.
</del></li>
<li><del>
&mdash; The multibyte sequences may be written as either a text or a binary file.
</del></li>
</ol>
</del></li>

<li><del>
For the facet <tt>codecvt_utf16</tt>:
<ol>
<li><del>
&mdash; The facet shall convert between UTF-16 multibyte sequences and UCS2 or
UCS4 (depending on the size of <tt>Elem</tt>) within the program.
</del></li>
<li><del>
&mdash; Multibyte sequences shall be read or written according to the
<tt>Mode</tt> flag, as set out above.
</del></li>
<li><del>
&mdash; The multibyte sequences may be written only as a binary file.
Attempting to write to a text file produces undefined behavior.
</del></li>
</ol>
</del></li>

<li><del>
For the facet <tt>codecvt_utf8_utf16</tt>:
<ol>
<li><del>
&mdash; The facet shall convert between UTF-8 multibyte sequences and UTF-16
(one or two 16-bit codes) within the program.
</del></li>
<li><del>
&mdash; Endianness shall not affect how multibyte sequences are read or written.
</del></li>
<li><del>
&mdash; The multibyte sequences may be written as either a text or a binary file.
</del></li>
</ol>
See also: ISO/IEC 10646-1:1993.
</del></li>
</ol>


<h3><ins>D.X Standard code conversion facets [depr.locale.stdcvt]</ins></h3>
<ol>
<li><ins>
The header <tt>&lt;codecvt&gt;</tt> provides code conversion facets for various
character encodings.
</ins></li>
</ol>

<h4><ins>D.X.1 Header <tt>&lt;codecvt&gt;</tt> synopsis [depr.codecvt.syn]</ins></h4>
<pre><blockquote>
<ins>namespace std {</ins>
  <ins>enum codecvt_mode {</ins>
    <ins>consume_header = 4,</ins>
    <ins>generate_header = 2,</ins>
    <ins>little_endian = 1</ins>
  <ins>};</ins>

  <ins>template&lt;class Elem, unsigned long Maxcode = 0x10ffff,</ins>
    <ins>codecvt_mode Mode = (codecvt_mode)0&gt;</ins>
  <ins>class codecvt_utf8</ins>
    <ins>: public codecvt&lt;Elem, char, mbstate_t&gt; {</ins>
  <ins>public:</ins>
    <ins>explicit codecvt_utf8(size_t refs = 0);</ins>
    <ins>~codecvt_utf8();</ins>
  <ins>};</ins>

  <ins>template&lt;class Elem, unsigned long Maxcode = 0x10ffff,</ins>
    <ins>codecvt_mode Mode = (codecvt_mode)0&gt;</ins>
  <ins>class codecvt_utf16</ins>
    <ins>: public codecvt&lt;Elem, char, mbstate_t&gt; {</ins>
  <ins>public:</ins>
    <ins>explicit codecvt_utf16(size_t refs = 0);</ins>
    <ins>~codecvt_utf16();</ins>
  <ins>};</ins>

  <ins>template&lt;class Elem, unsigned long Maxcode = 0x10ffff,</ins>
    <ins>codecvt_mode Mode = (codecvt_mode)0&gt;</ins>
  <ins>class codecvt_utf8_utf16</ins>
    <ins>: public codecvt&lt;Elem, char, mbstate_t&gt; {</ins>
  <ins>public:</ins>
    <ins>explicit codecvt_utf8_utf16(size_t refs = 0);</ins>
    <ins>~codecvt_utf8_utf16();</ins>
  <ins>};</ins>
<ins>}</ins>
<blockquote></pre>


<h4><ins>D.X.2 Requirements [depr.locale.stdcvt.req]</ins></h4>
<ol>
<li><ins>
For each of the three code conversion facets <tt>codecvt_utf8</tt>,
<tt>codecvt_utf16</tt>, and <tt>codecvt_utf8_utf16</tt>:
<ol>
<li><ins>
&mdash; <tt>Elem</tt> is the wide-character type, such as <tt>wchar_t</tt>,
<tt>char16_t</tt>, or <tt>char32_t</tt>.
</ins></li>
<li><ins>
&mdash; <tt>Maxcode</tt> is the largest wide-character code that the facet will
read or write without reporting a conversion error.
</ins></li>
<li><ins>
&mdash; If <tt>(Mode &amp; consume_header)</tt>, the facet shall consume an
initial header sequence, if present, when reading a multibyte sequence to
determine the endianness of the subsequent multibyte sequence to be read.
</ins></li>
<li><ins>
&mdash; If <tt>(Mode &amp; generate_header)</tt>, the facet shall generate an
initial header sequence when writing a multibyte sequence to advertise the
endianness of the subsequent multibyte sequence to be written.
</ins></li>
<li><ins>
&mdash; If <tt>(Mode &amp; little_endian)</tt>, the facet shall generate a
multibyte sequence in little-endian order, as opposed to the default big-endian
order.
</ins></li>
</ol>
</ins></li>

<li><ins>
For the facet <tt>codecvt_utf8</tt>:
<ol>
<li><ins>
&mdash; The facet shall convert between UTF-8 multibyte sequences and UCS2 or
UCS4 (depending on the size of <tt>Elem</tt>) within the program.
</ins></li>
<li><ins>
&mdash; Endianness shall not affect how multibyte sequences are read or written.
</ins></li>
<li><ins>
&mdash; The multibyte sequences may be written as either a text or a binary file.
</ins></li>
</ol>
</ins></li>

<li><ins>
For the facet <tt>codecvt_utf16</tt>:
<ol>
<li><ins>
&mdash; The facet shall convert between UTF-16 multibyte sequences and UCS2 or
UCS4 (depending on the size of <tt>Elem</tt>) within the program.
</ins></li>
<li><ins>
&mdash; Multibyte sequences shall be read or written according to the
<tt>Mode</tt> flag, as set out above.
</ins></li>
<li><ins>
&mdash; The multibyte sequences may be written only as a binary file.
Attempting to write to a text file produces undefined behavior.
</ins></li>
</ol>
</ins></li>

<li><ins>
For the facet <tt>codecvt_utf8_utf16</tt>:
<ol>
<li><ins>
&mdash; The facet shall convert between UTF-8 multibyte sequences and UTF-16
(one or two 16-bit codes) within the program.
</ins></li>
<li><ins>
&mdash; Endianness shall not affect how multibyte sequences are read or written.
</ins></li>
<li><ins>
&mdash; The multibyte sequences may be written as either a text or a binary file.
</ins></li>
</ol>
See also: ISO/IEC 10646-1:1993.
</ins></li>
</ol>


<h3><ins>D.Y Deprecated Character Conversions [depr.conversions]</ins></h3>
<p><ins>
The header <tt>&lt;locale&gt;</tt> has the following additions:
</ins></p>

<blockquote><pre>
<ins>template&lt;class Codecvt, class Elem = wchar_t,</ins>
         <ins>class Wide_alloc = allocator&lt;Elem&gt;,</ins>
         <ins>class Byte_alloc = allocator&lt;char&gt;&gt;</ins>
  <ins>class wstring_convert;</ins>
<ins>template&lt;class Codecvt, class Elem = wchar_t,</ins>
         <ins>class Tr = char_traits&lt;Elem&gt;&gt;</ins>
  <ins>class wbuffer_convert;</ins>
</pre></blockquote>




<h4><ins>D.Y.1 Class template wstring_convert [depr.conversions.string]</ins></h4>
<ol>
<li><ins>
Class template <tt>wstring_convert</tt> performs conversions between a wide
string and a byte string.  It lets you specify a code conversion facet (like
class template <tt>codecvt</tt>) to perform the conversions, without affecting
any streams or locales.  [ <i>Example:</i> If you want to use the code
conversion facet <tt>codecvt_utf8</tt> to output to <tt>cout</tt> a UTF-8
multibyte sequence corresponding to a wide string, but you don’t want to alter
the locale for <tt>cout</tt>, you can write something like:
<pre><blockquote>
<ins>wstring_convert&lt;std::codecvt_utf8&lt;wchar_t&gt;&gt; myconv;</ins>
<ins>std::string mbstring = myconv.to_bytes(L"Hello\n");</ins>
<ins>std::cout &lt;&lt; mbstring;</ins>
</blockquote></pre>
&mdash; <i>end example</i> ]
</ins></ins></li>

<pre><blockquote>
<ins>namespace std {</ins>
<ins>template &lt;class Codecvt, class Elem = wchar_t,</ins>
          <ins>class Wide_alloc = allocator&lt;Elem&gt;,</ins>
          <ins>class Byte_alloc = allocator&lt;char&gt;&gt;</ins>
  <ins>class wstring_convert {</ins>
  <ins>public:</ins>
    <ins>using byte_string = basic_string&lt;char, char_traits&lt;char&gt;, Byte_alloc&gt;;</ins>
    <ins>using wide_string = basic_string&lt;Elem, char_traits&lt;Elem&gt;, Wide_alloc&gt;;</ins>
    <ins>using state_type  = typename Codecvt::state_type;</ins>
    <ins>using int_type    = typename wide_string::traits_type::int_type;</ins>

    <ins>explicit wstring_convert(Codecvt* pcvt = new Codecvt);</ins>
    <ins>wstring_convert(Codecvt* pcvt, state_type state);</ins>
    <ins>explicit wstring_convert(const byte_string&amp; byte_err,</ins>
                             <ins>const wide_string&amp; wide_err = wide_string());</ins>
    <ins>~wstring_convert();</ins>

    <ins>wstring_convert(const wstring_convert&amp;) = delete;</ins>
    <ins>wstring_convert&amp; operator=(const wstring_convert&amp;) = delete;</ins>

    <ins>wide_string from_bytes(char byte);</ins>
    <ins>wide_string from_bytes(const char* ptr);</ins>
    <ins>wide_string from_bytes(const byte_string&amp; str);</ins>
    <ins>wide_string from_bytes(const char* first, const char* last);</ins>
    <ins>byte_string to_bytes(Elem wchar);</ins>
    <ins>byte_string to_bytes(const Elem* wptr);</ins>
    <ins>byte_string to_bytes(const wide_string&amp; wstr);</ins>
    <ins>byte_string to_bytes(const Elem* first, const Elem* last);</ins>
    <ins>size_t converted() const noexcept;</ins>
    <ins>state_type state() const;</ins>
  <ins>private:</ins>
    <ins>byte_string byte_err_string;</ins>
    <ins>wide_string wide_err_string;</ins>
    <ins>Codecvt* cvtptr;</ins>
    <ins>state_type cvtstate;</ins>
    <ins>size_t cvtcount;</ins>
  <ins>};</ins>
<ins>}</ins>
</blockquote></pre>

<li><ins>
The class template describes an object that controls conversions between wide
string objects of class
<tt>basic_string&lt;Elem, char_traits&lt;Elem&gt;, Wide_alloc&gt;</tt> and
byte string objects of class
<tt>basic_string&lt;char, char_traits&lt;char&gt;, Byte_alloc&gt;</tt>.
The class template defines the types <tt>wide_string</tt> and
<tt>byte_string</tt> as synonyms for these two types. Conversion between a
sequence of <tt>Elem</tt> values (stored in a <tt>wide_string</tt> object) and
multibyte sequences (stored in a <tt>byte_string</tt> object) is performed by
an object of class <tt>Codecvt</tt>, which meets the requirements of the
standard code-conversion facet <tt>codecvt&lt;Elem, char, mbstate_t&gt;</tt>.
</ins></li>
<li><ins>
An object of this class template stores:
  <ol>
  <li><ins>
  &mdash; <tt>byte_err_string</tt> &mdash; a byte string to display on errors
  </ins></li>
  <li><ins>
  &mdash; <tt>wide_err_string</tt> &mdash; a wide string to display on errors
  </ins></li>
  <li><ins>
  &mdash; <tt>cvtptr</tt> &mdash; a pointer to the allocated conversion object
  (which is freed when the <tt>wstring_convert</tt> object is destroyed)
  </ins></li>
  <li><ins>
  &mdash; <tt>cvtstate</tt> &mdash; a conversion state object
  </ins></li>
  <li><ins>
  &mdash; <tt>cvtcount</tt> &mdash; a conversion count
  </ins></li>
  </ol>
</ins></li>

<pre><blockquote>
<ins>using byte_string = basic_string&lt;char, char_traits&lt;char&gt;, Byte_alloc&gt;;</ins>
</blockquote></pre>
<li><ins>
The type shall be a synonym for
<tt>basic_string&lt;char, char_traits&lt;char&gt;, Byte_alloc&gt;</tt>
</ins></li>

<pre><blockquote>
<ins>size_t converted() const noexcept;</ins>
</blockquote></pre>
<li><ins>
<i>Returns:</i> <tt>cvtcount</tt>.
</ins></li>

<pre><blockquote>
<ins>wide_string from_bytes(char byte);</ins>
<ins>wide_string from_bytes(const char* ptr);</ins>
<ins>wide_string from_bytes(const byte_string&amp; str);</ins>
<ins>wide_string from_bytes(const char* first, const char* last);</ins>
</blockquote></pre>
<li><ins>
<i>Effects:</i> The first member function shall convert the single-element
sequence <tt>byte</tt> to a wide string. The second member function shall
convert the null-terminated sequence beginning at <tt>ptr</tt> to a wide
string. The third member function shall convert the sequence stored in str to a
wide string. The fourth member function shall convert the sequence defined by
the range <tt>[first, last)</tt> to a wide string.
</ins></li>
<li><ins>
In all cases:
  <ol>
  <li><ins>
&mdash; If the <tt>cvtstate</tt> object was not constructed with an explicit
value, it shall be set to its default value (the initial conversion state)
before the conversion begins. Otherwise it shall be left unchanged.
  </ins></li>
  <li><ins>
&mdash; The number of input elements successfully converted shall be stored in
<tt>cvtcount</tt>.
  </ins></li>
  </ol>
</ins></li>

<li><ins>
<i>Returns:</i> If no conversion error occurs, the member function shall return
the converted wide string. Otherwise, if the object was constructed with a
wide-error string, the member function shall return the wide-error string.
Otherwise, the member function throws an object of class <tt>range_error</tt>.
</ins></li>

<pre><blockquote>
<ins>using int_type = typename wide_string::traits_type::int_type;</ins>
</blockquote></pre>
<li><ins>
The type shall be a synonym for <tt>wide_string::traits_type::int_type</tt>.
</ins></li>

<pre><blockquote>
<ins>state_type state() const;</ins>
</blockquote></pre>
<li><ins>
returns <tt>cvtstate</tt>.
</ins></li>

<pre><blockquote>
<ins>using state_type = typename Codecvt::state_type;</ins>
</blockquote></pre>
<li><ins>
The type shall be a synonym for <tt>Codecvt::state_type</tt>.
</ins></li>

<pre><blockquote>
<ins>byte_string to_bytes(Elem wchar);</ins>
<ins>byte_string to_bytes(const Elem* wptr);</ins>
<ins>byte_string to_bytes(const wide_string&amp; wstr);</ins>
<ins>byte_string to_bytes(const Elem* first, const Elem* last);</ins>
</blockquote></pre>
<li><ins>
<i>Effects:</i> The first member function shall convert the single-element
sequence <tt>wchar</tt> to a byte string. The second member function shall
convert the null-terminated sequence beginning at <tt>wptr</tt> to a byte
string. The third member function shall convert the sequence stored in wstr to
a byte string. The fourth member function shall convert the sequence defined by
the range <tt>[first, last)</tt> to a byte string.
</ins></li>

<li><ins>
In all cases:
  <ol>
  <li><ins>
&mdash; If the <tt>cvtstate</tt> object was not constructed with an explicit
value, it shall be set to its default value (the initial conversion state)
before the conversion begins. Otherwise it shall be left unchanged.
  </ins></li>
  <li><ins>
&mdash; The number of input elements successfully converted shall be stored in
<tt>cvtcount</tt>.
  </ins></li>
  </ol>
</ins></li>

<li><ins>
<i>Returns:</i> If no conversion error occurs, the member function shall return
the converted byte string. Otherwise, if the object was constructed with a
byte-error string, the member function shall return the byte-error string.
Otherwise, the member function shall throw an object of class
<tt>range_error</tt>.
</ins></li>

<pre><blockquote>
<ins>using wide_string = basic_string&lt;Elem, char_traits&lt;Elem&gt;, Wide_alloc&gt;;</ins>
</blockquote></pre>
<li><ins>
The type shall be a synonym for
<tt>basic_string&lt;Elem, char_traits&lt;Elem&gt;, Wide_alloc&gt;</tt>.
</ins></li>

<pre><blockquote>
<ins>explicit wstring_convert(Codecvt* pcvt = new Codecvt);</ins>
<ins>wstring_convert(Codecvt* pcvt, state_type state);</ins>
<ins>explicit wstring_convert(const byte_string&amp; byte_err,</ins>
    <ins>const wide_string&amp; wide_err = wide_string());</ins>
</blockquote></pre>
<li><ins>
<i>Requires:</i> For the first and second constructors, <tt>pcvt != nullptr</tt>.
</ins></li>

<li><ins>
<i>Effects:</i> The first constructor shall store <tt>pcvt</tt> in
<tt>cvtptr</tt> and default values in <tt>cvtstate</tt>,
<tt>byte_err_string</tt>, and <tt>wide_err_string</tt>. The second constructor
shall store <tt>pcvt</tt> in <tt>cvtptr</tt>, <tt>state</tt> in
<tt>cvtstate</tt>, and default values in <tt>byte_err_string</tt> and
<tt>wide_err_string</tt>; moreover the stored state shall be retained between
calls to <tt>from_bytes</tt> and <tt>to_bytes</tt>. The third constructor shall
store <tt>new Codecvt</tt> in <tt>cvtptr</tt>, <tt>state_type()</tt> in
<tt>cvtstate</tt>, <tt>byte_err</tt> in <tt>byte_err_string</tt>, and
<tt>wide_err</tt> in <tt>wide_err_string</tt>.
</ins></li>

<pre><blockquote>
<ins>~wstring_convert();</ins>
</blockquote></pre>
<li><ins>
<i>Effects:</i> The destructor shall delete <tt>cvtptr</tt>.
</ins></li>
</ol>


<h4><ins>D.Y.2 Class template wbuffer_convert [depr.conversions.buffer]</ins></h4>
<ol>
<li><ins>
Class template <tt>wbuffer_convert</tt> looks like a wide stream buffer, but
performs all its I/O through an underlying byte stream buffer that you specify
when you construct it. Like class template <tt>wstring_convert</tt>, it lets
you specify a code conversion facet to perform the conversions, without
affecting any streams or locales.
</ins></li>
<pre><blockquote>
<ins>namespace std {</ins>
<ins>template &lt;class Codecvt, class Elem = wchar_t, class Tr = char_traits&lt;Elem&gt;&gt;</ins>
  <ins>class wbuffer_convert</ins>
    <ins>: public basic_streambuf&lt;Elem, Tr&gt; {</ins>
  <ins>public:</ins>
    <ins>using state_type = typename Codecvt::state_type;</ins>

    <ins>explicit wbuffer_convert(streambuf* bytebuf = 0,</ins>
                             <ins>Codecvt* pcvt = new Codecvt,</ins>
                             <ins>state_type state = state_type());</ins>

    <ins>~wbuffer_convert();</ins>

    <ins>wbuffer_convert(const wbuffer_convert&amp;) = delete;</ins>
    <ins>wbuffer_convert&amp; operator=(const wbuffer_convert&amp;) = delete;</ins>

    <ins>streambuf* rdbuf() const;</ins>
    <ins>streambuf* rdbuf(streambuf* bytebuf);</ins>

    <ins>state_type state() const;</ins>

  <ins>private:</ins>
    <ins>streambuf* bufptr;        // exposition only</ins>
    <ins>Codecvt* cvtptr;          // exposition only</ins>
    <ins>state_type cvtstate;      // exposition only</ins>
  <ins>};</ins>
<ins>}</ins>
</blockquote></pre>
<li><ins>
The class template describes a stream buffer that controls the transmission of
elements of type <tt>Elem</tt>, whose character traits are described by the class <tt>Tr</tt>, to
and from a byte stream buffer of type <tt>streambuf</tt>.  Conversion between a sequence
of <tt>Elem</tt> values and multibyte sequences is performed by an object of class
<tt>Codecvt</tt>, which shall meet the requirements of the standard code-conversion
facet <tt>codecvt&lt;Elem, char, mbstate_t&gt;</tt>.
</ins></li>

<li><ins>
An object of this class template stores:
  <ol>
  <li><ins>
&mdash; <tt>bufptr</tt> &mdash; a pointer to its underlying byte stream buffer
  </ins></li>
  <li><ins>
&mdash; <tt>cvtptr</tt> &mdash; a pointer to the allocated conversion object (which is freed when the <tt>wbuffer_convert</tt> object is destroyed)
  </ins></li>
  <li><ins>
&mdash; <tt>cvtstate</tt> &mdash; a conversion state object
  </ins></li>
  </ol>
</ins></li>

<pre><blockquote>
<ins>state_type state() const;</ins>
</blockquote></pre>
<li><ins>
<i>Returns:</i> <tt>cvtstate</tt>.
</ins></li>

<pre><blockquote>
<ins>streambuf* rdbuf() const;</ins>
</blockquote></pre>
</ins></li>
<li><ins>
<i>Returns:</i> <tt>bufptr</tt>.
</ins></li>

<pre><blockquote>
<ins>streambuf* rdbuf(streambuf* bytebuf);</ins>
</blockquote></pre>
<li><ins>
<i>Effects:</i> Stores <tt>bytebuf</tt> in <tt>bufptr</tt>.
</ins></li>
<li><ins>
<i>Returns:</i> The previous value of <tt>bufptr</tt>.
</ins></li>

<pre><blockquote>
<ins>using state_type = typename Codecvt::state_type;</ins>
</blockquote></pre>
<li><ins>
The type shall be a synonym for <tt>Codecvt::state_type</tt>.
</ins></li>

<pre><blockquote>
<ins>explicit wbuffer_convert(streambuf* bytebuf = 0,</ins>
    <ins>Codecvt* pcvt = new Codecvt, state_type state = state_type());</ins>
</blockquote></pre>
<li><ins>
<i>Requires:</i> <tt>pcvt != nullptr</tt>.
</ins></li>
<li><ins>
<i>Effects:</i> The constructor constructs a stream buffer object, initializes
<tt>bufptr</tt> to <tt>bytebuf</tt>, initializes <tt>cvtptr</tt> to <tt>pcvt</tt>, and initializes <tt>cvtstate</tt> to <tt>state</tt>.

<pre><blockquote>
<ins>~wbuffer_convert();</ins>
</blockquote></pre>

</ins></li>
<li><ins>
<i>Effects:</i> The destructor shall delete <tt>cvtptr</tt>.
</ins></li>
</ol>

</body>
</html>
