Home | History | Annotate | Line # | Download | only in bits
      1 // Locale support (codecvt) -*- C++ -*-
      2 
      3 // Copyright (C) 2000-2022 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file bits/codecvt.h
     26  *  This is an internal header file, included by other library headers.
     27  *  Do not attempt to use it directly. @headername{locale}
     28  */
     29 
     30 //
     31 // ISO C++ 14882: 22.2.1.5 Template class codecvt
     32 //
     33 
     34 // Written by Benjamin Kosnik <bkoz (at) redhat.com>
     35 
     36 #ifndef _CODECVT_H
     37 #define _CODECVT_H 1
     38 
     39 #pragma GCC system_header
     40 
     41 #include <bits/c++config.h>
     42 #include <bits/locale_classes.h> // locale::facet
     43 
     44 namespace std _GLIBCXX_VISIBILITY(default)
     45 {
     46 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     47 
     48   /// Empty base class for codecvt facet [22.2.1.5].
     49   class codecvt_base
     50   {
     51   public:
     52     enum result
     53     {
     54       ok,
     55       partial,
     56       error,
     57       noconv
     58     };
     59   };
     60 
     61   /**
     62    *  @brief  Common base for codecvt functions.
     63    *
     64    *  This template class provides implementations of the public functions
     65    *  that forward to the protected virtual functions.
     66    *
     67    *  This template also provides abstract stubs for the protected virtual
     68    *  functions.
     69   */
     70   template<typename _InternT, typename _ExternT, typename _StateT>
     71     class __codecvt_abstract_base
     72     : public locale::facet, public codecvt_base
     73     {
     74     public:
     75       // Types:
     76       typedef codecvt_base::result	result;
     77       typedef _InternT			intern_type;
     78       typedef _ExternT			extern_type;
     79       typedef _StateT			state_type;
     80 
     81       // 22.2.1.5.1 codecvt members
     82       /**
     83        *  @brief  Convert from internal to external character set.
     84        *
     85        *  Converts input string of intern_type to output string of
     86        *  extern_type.  This is analogous to wcsrtombs.  It does this by
     87        *  calling codecvt::do_out.
     88        *
     89        *  The source and destination character sets are determined by the
     90        *  facet's locale, internal and external types.
     91        *
     92        *  The characters in [from,from_end) are converted and written to
     93        *  [to,to_end).  from_next and to_next are set to point to the
     94        *  character following the last successfully converted character,
     95        *  respectively.  If the result needed no conversion, from_next and
     96        *  to_next are not affected.
     97        *
     98        *  The @a state argument should be initialized if the input is at the
     99        *  beginning and carried from a previous call if continuing
    100        *  conversion.  There are no guarantees about how @a state is used.
    101        *
    102        *  The result returned is a member of codecvt_base::result.  If
    103        *  all the input is converted, returns codecvt_base::ok.  If no
    104        *  conversion is necessary, returns codecvt_base::noconv.  If
    105        *  the input ends early or there is insufficient space in the
    106        *  output, returns codecvt_base::partial.  Otherwise the
    107        *  conversion failed and codecvt_base::error is returned.
    108        *
    109        *  @param  __state  Persistent conversion state data.
    110        *  @param  __from  Start of input.
    111        *  @param  __from_end  End of input.
    112        *  @param  __from_next  Returns start of unconverted data.
    113        *  @param  __to  Start of output buffer.
    114        *  @param  __to_end  End of output buffer.
    115        *  @param  __to_next  Returns start of unused output area.
    116        *  @return  codecvt_base::result.
    117       */
    118       result
    119       out(state_type& __state, const intern_type* __from,
    120 	  const intern_type* __from_end, const intern_type*& __from_next,
    121 	  extern_type* __to, extern_type* __to_end,
    122 	  extern_type*& __to_next) const
    123       {
    124 	return this->do_out(__state, __from, __from_end, __from_next,
    125 			    __to, __to_end, __to_next);
    126       }
    127 
    128       /**
    129        *  @brief  Reset conversion state.
    130        *
    131        *  Writes characters to output that would restore @a state to initial
    132        *  conditions.  The idea is that if a partial conversion occurs, then
    133        *  the converting the characters written by this function would leave
    134        *  the state in initial conditions, rather than partial conversion
    135        *  state.  It does this by calling codecvt::do_unshift().
    136        *
    137        *  For example, if 4 external characters always converted to 1 internal
    138        *  character, and input to in() had 6 external characters with state
    139        *  saved, this function would write two characters to the output and
    140        *  set the state to initialized conditions.
    141        *
    142        *  The source and destination character sets are determined by the
    143        *  facet's locale, internal and external types.
    144        *
    145        *  The result returned is a member of codecvt_base::result.  If the
    146        *  state could be reset and data written, returns codecvt_base::ok.  If
    147        *  no conversion is necessary, returns codecvt_base::noconv.  If the
    148        *  output has insufficient space, returns codecvt_base::partial.
    149        *  Otherwise the reset failed and codecvt_base::error is returned.
    150        *
    151        *  @param  __state  Persistent conversion state data.
    152        *  @param  __to  Start of output buffer.
    153        *  @param  __to_end  End of output buffer.
    154        *  @param  __to_next  Returns start of unused output area.
    155        *  @return  codecvt_base::result.
    156       */
    157       result
    158       unshift(state_type& __state, extern_type* __to, extern_type* __to_end,
    159 	      extern_type*& __to_next) const
    160       { return this->do_unshift(__state, __to,__to_end,__to_next); }
    161 
    162       /**
    163        *  @brief  Convert from external to internal character set.
    164        *
    165        *  Converts input string of extern_type to output string of
    166        *  intern_type.  This is analogous to mbsrtowcs.  It does this by
    167        *  calling codecvt::do_in.
    168        *
    169        *  The source and destination character sets are determined by the
    170        *  facet's locale, internal and external types.
    171        *
    172        *  The characters in [from,from_end) are converted and written to
    173        *  [to,to_end).  from_next and to_next are set to point to the
    174        *  character following the last successfully converted character,
    175        *  respectively.  If the result needed no conversion, from_next and
    176        *  to_next are not affected.
    177        *
    178        *  The @a state argument should be initialized if the input is at the
    179        *  beginning and carried from a previous call if continuing
    180        *  conversion.  There are no guarantees about how @a state is used.
    181        *
    182        *  The result returned is a member of codecvt_base::result.  If
    183        *  all the input is converted, returns codecvt_base::ok.  If no
    184        *  conversion is necessary, returns codecvt_base::noconv.  If
    185        *  the input ends early or there is insufficient space in the
    186        *  output, returns codecvt_base::partial.  Otherwise the
    187        *  conversion failed and codecvt_base::error is returned.
    188        *
    189        *  @param  __state  Persistent conversion state data.
    190        *  @param  __from  Start of input.
    191        *  @param  __from_end  End of input.
    192        *  @param  __from_next  Returns start of unconverted data.
    193        *  @param  __to  Start of output buffer.
    194        *  @param  __to_end  End of output buffer.
    195        *  @param  __to_next  Returns start of unused output area.
    196        *  @return  codecvt_base::result.
    197       */
    198       result
    199       in(state_type& __state, const extern_type* __from,
    200 	 const extern_type* __from_end, const extern_type*& __from_next,
    201 	 intern_type* __to, intern_type* __to_end,
    202 	 intern_type*& __to_next) const
    203       {
    204 	return this->do_in(__state, __from, __from_end, __from_next,
    205 			   __to, __to_end, __to_next);
    206       }
    207 
    208       int
    209       encoding() const throw()
    210       { return this->do_encoding(); }
    211 
    212       bool
    213       always_noconv() const throw()
    214       { return this->do_always_noconv(); }
    215 
    216       int
    217       length(state_type& __state, const extern_type* __from,
    218 	     const extern_type* __end, size_t __max) const
    219       { return this->do_length(__state, __from, __end, __max); }
    220 
    221       int
    222       max_length() const throw()
    223       { return this->do_max_length(); }
    224 
    225     protected:
    226       explicit
    227       __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { }
    228 
    229       virtual
    230       ~__codecvt_abstract_base() { }
    231 
    232       /**
    233        *  @brief  Convert from internal to external character set.
    234        *
    235        *  Converts input string of intern_type to output string of
    236        *  extern_type.  This function is a hook for derived classes to change
    237        *  the value returned.  @see out for more information.
    238       */
    239       virtual result
    240       do_out(state_type& __state, const intern_type* __from,
    241 	     const intern_type* __from_end, const intern_type*& __from_next,
    242 	     extern_type* __to, extern_type* __to_end,
    243 	     extern_type*& __to_next) const = 0;
    244 
    245       virtual result
    246       do_unshift(state_type& __state, extern_type* __to,
    247 		 extern_type* __to_end, extern_type*& __to_next) const = 0;
    248 
    249       virtual result
    250       do_in(state_type& __state, const extern_type* __from,
    251 	    const extern_type* __from_end, const extern_type*& __from_next,
    252 	    intern_type* __to, intern_type* __to_end,
    253 	    intern_type*& __to_next) const = 0;
    254 
    255       virtual int
    256       do_encoding() const throw() = 0;
    257 
    258       virtual bool
    259       do_always_noconv() const throw() = 0;
    260 
    261       virtual int
    262       do_length(state_type&, const extern_type* __from,
    263 		const extern_type* __end, size_t __max) const = 0;
    264 
    265       virtual int
    266       do_max_length() const throw() = 0;
    267     };
    268 
    269   /**
    270    *  @brief  Primary class template codecvt.
    271    *  @ingroup locales
    272    *
    273    *  NB: Generic, mostly useless implementation.
    274    *
    275   */
    276    template<typename _InternT, typename _ExternT, typename _StateT>
    277     class codecvt
    278     : public __codecvt_abstract_base<_InternT, _ExternT, _StateT>
    279     {
    280     public:
    281       // Types:
    282       typedef codecvt_base::result	result;
    283       typedef _InternT			intern_type;
    284       typedef _ExternT			extern_type;
    285       typedef _StateT			state_type;
    286 
    287     protected:
    288       __c_locale			_M_c_locale_codecvt;
    289 
    290     public:
    291       static locale::id			id;
    292 
    293       explicit
    294       codecvt(size_t __refs = 0)
    295       : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs),
    296 	_M_c_locale_codecvt(0)
    297       { }
    298 
    299       explicit
    300       codecvt(__c_locale __cloc, size_t __refs = 0);
    301 
    302     protected:
    303       virtual
    304       ~codecvt() { }
    305 
    306       virtual result
    307       do_out(state_type& __state, const intern_type* __from,
    308 	     const intern_type* __from_end, const intern_type*& __from_next,
    309 	     extern_type* __to, extern_type* __to_end,
    310 	     extern_type*& __to_next) const;
    311 
    312       virtual result
    313       do_unshift(state_type& __state, extern_type* __to,
    314 		 extern_type* __to_end, extern_type*& __to_next) const;
    315 
    316       virtual result
    317       do_in(state_type& __state, const extern_type* __from,
    318 	    const extern_type* __from_end, const extern_type*& __from_next,
    319 	    intern_type* __to, intern_type* __to_end,
    320 	    intern_type*& __to_next) const;
    321 
    322       virtual int
    323       do_encoding() const throw();
    324 
    325       virtual bool
    326       do_always_noconv() const throw();
    327 
    328       virtual int
    329       do_length(state_type&, const extern_type* __from,
    330 		const extern_type* __end, size_t __max) const;
    331 
    332       virtual int
    333       do_max_length() const throw();
    334     };
    335 
    336   template<typename _InternT, typename _ExternT, typename _StateT>
    337     locale::id codecvt<_InternT, _ExternT, _StateT>::id;
    338 
    339   /// class codecvt<char, char, mbstate_t> specialization.
    340   template<>
    341     class codecvt<char, char, mbstate_t>
    342     : public __codecvt_abstract_base<char, char, mbstate_t>
    343     {
    344       friend class messages<char>;
    345 
    346     public:
    347       // Types:
    348       typedef char			intern_type;
    349       typedef char			extern_type;
    350       typedef mbstate_t			state_type;
    351 
    352     protected:
    353       __c_locale			_M_c_locale_codecvt;
    354 
    355     public:
    356       static locale::id id;
    357 
    358       explicit
    359       codecvt(size_t __refs = 0);
    360 
    361       explicit
    362       codecvt(__c_locale __cloc, size_t __refs = 0);
    363 
    364     protected:
    365       virtual
    366       ~codecvt();
    367 
    368       virtual result
    369       do_out(state_type& __state, const intern_type* __from,
    370 	     const intern_type* __from_end, const intern_type*& __from_next,
    371 	     extern_type* __to, extern_type* __to_end,
    372 	     extern_type*& __to_next) const;
    373 
    374       virtual result
    375       do_unshift(state_type& __state, extern_type* __to,
    376 		 extern_type* __to_end, extern_type*& __to_next) const;
    377 
    378       virtual result
    379       do_in(state_type& __state, const extern_type* __from,
    380 	    const extern_type* __from_end, const extern_type*& __from_next,
    381 	    intern_type* __to, intern_type* __to_end,
    382 	    intern_type*& __to_next) const;
    383 
    384       virtual int
    385       do_encoding() const throw();
    386 
    387       virtual bool
    388       do_always_noconv() const throw();
    389 
    390       virtual int
    391       do_length(state_type&, const extern_type* __from,
    392 		const extern_type* __end, size_t __max) const;
    393 
    394       virtual int
    395       do_max_length() const throw();
    396   };
    397 
    398 #ifdef _GLIBCXX_USE_WCHAR_T
    399   /** @brief  Class codecvt<wchar_t, char, mbstate_t> specialization.
    400    *
    401    *  Converts between narrow and wide characters in the native character set
    402    */
    403   template<>
    404     class codecvt<wchar_t, char, mbstate_t>
    405     : public __codecvt_abstract_base<wchar_t, char, mbstate_t>
    406     {
    407       friend class messages<wchar_t>;
    408 
    409     public:
    410       // Types:
    411       typedef wchar_t			intern_type;
    412       typedef char			extern_type;
    413       typedef mbstate_t			state_type;
    414 
    415     protected:
    416       __c_locale			_M_c_locale_codecvt;
    417 
    418     public:
    419       static locale::id			id;
    420 
    421       explicit
    422       codecvt(size_t __refs = 0);
    423 
    424       explicit
    425       codecvt(__c_locale __cloc, size_t __refs = 0);
    426 
    427     protected:
    428       virtual
    429       ~codecvt();
    430 
    431       virtual result
    432       do_out(state_type& __state, const intern_type* __from,
    433 	     const intern_type* __from_end, const intern_type*& __from_next,
    434 	     extern_type* __to, extern_type* __to_end,
    435 	     extern_type*& __to_next) const;
    436 
    437       virtual result
    438       do_unshift(state_type& __state,
    439 		 extern_type* __to, extern_type* __to_end,
    440 		 extern_type*& __to_next) const;
    441 
    442       virtual result
    443       do_in(state_type& __state,
    444 	     const extern_type* __from, const extern_type* __from_end,
    445 	     const extern_type*& __from_next,
    446 	     intern_type* __to, intern_type* __to_end,
    447 	     intern_type*& __to_next) const;
    448 
    449       virtual
    450       int do_encoding() const throw();
    451 
    452       virtual
    453       bool do_always_noconv() const throw();
    454 
    455       virtual
    456       int do_length(state_type&, const extern_type* __from,
    457 		    const extern_type* __end, size_t __max) const;
    458 
    459       virtual int
    460       do_max_length() const throw();
    461     };
    462 #endif //_GLIBCXX_USE_WCHAR_T
    463 
    464 #if __cplusplus >= 201103L
    465   /** @brief  Class codecvt<char16_t, char, mbstate_t> specialization.
    466    *
    467    *  Converts between UTF-16 and UTF-8.
    468    */
    469   template<>
    470     class codecvt<char16_t, char, mbstate_t>
    471     : public __codecvt_abstract_base<char16_t, char, mbstate_t>
    472     {
    473     public:
    474       // Types:
    475       typedef char16_t			intern_type;
    476       typedef char			extern_type;
    477       typedef mbstate_t			state_type;
    478 
    479     public:
    480       static locale::id			id;
    481 
    482       explicit
    483       codecvt(size_t __refs = 0)
    484       : __codecvt_abstract_base<char16_t, char, mbstate_t>(__refs) { }
    485 
    486     protected:
    487       virtual
    488       ~codecvt();
    489 
    490       virtual result
    491       do_out(state_type& __state, const intern_type* __from,
    492 	     const intern_type* __from_end, const intern_type*& __from_next,
    493 	     extern_type* __to, extern_type* __to_end,
    494 	     extern_type*& __to_next) const;
    495 
    496       virtual result
    497       do_unshift(state_type& __state,
    498 		 extern_type* __to, extern_type* __to_end,
    499 		 extern_type*& __to_next) const;
    500 
    501       virtual result
    502       do_in(state_type& __state,
    503 	     const extern_type* __from, const extern_type* __from_end,
    504 	     const extern_type*& __from_next,
    505 	     intern_type* __to, intern_type* __to_end,
    506 	     intern_type*& __to_next) const;
    507 
    508       virtual
    509       int do_encoding() const throw();
    510 
    511       virtual
    512       bool do_always_noconv() const throw();
    513 
    514       virtual
    515       int do_length(state_type&, const extern_type* __from,
    516 		    const extern_type* __end, size_t __max) const;
    517 
    518       virtual int
    519       do_max_length() const throw();
    520     };
    521 
    522   /** @brief  Class codecvt<char32_t, char, mbstate_t> specialization.
    523    *
    524    *  Converts between UTF-32 and UTF-8.
    525    */
    526   template<>
    527     class codecvt<char32_t, char, mbstate_t>
    528     : public __codecvt_abstract_base<char32_t, char, mbstate_t>
    529     {
    530     public:
    531       // Types:
    532       typedef char32_t			intern_type;
    533       typedef char			extern_type;
    534       typedef mbstate_t			state_type;
    535 
    536     public:
    537       static locale::id			id;
    538 
    539       explicit
    540       codecvt(size_t __refs = 0)
    541       : __codecvt_abstract_base<char32_t, char, mbstate_t>(__refs) { }
    542 
    543     protected:
    544       virtual
    545       ~codecvt();
    546 
    547       virtual result
    548       do_out(state_type& __state, const intern_type* __from,
    549 	     const intern_type* __from_end, const intern_type*& __from_next,
    550 	     extern_type* __to, extern_type* __to_end,
    551 	     extern_type*& __to_next) const;
    552 
    553       virtual result
    554       do_unshift(state_type& __state,
    555 		 extern_type* __to, extern_type* __to_end,
    556 		 extern_type*& __to_next) const;
    557 
    558       virtual result
    559       do_in(state_type& __state,
    560 	     const extern_type* __from, const extern_type* __from_end,
    561 	     const extern_type*& __from_next,
    562 	     intern_type* __to, intern_type* __to_end,
    563 	     intern_type*& __to_next) const;
    564 
    565       virtual
    566       int do_encoding() const throw();
    567 
    568       virtual
    569       bool do_always_noconv() const throw();
    570 
    571       virtual
    572       int do_length(state_type&, const extern_type* __from,
    573 		    const extern_type* __end, size_t __max) const;
    574 
    575       virtual int
    576       do_max_length() const throw();
    577     };
    578 
    579 #ifdef _GLIBCXX_USE_CHAR8_T
    580   /** @brief  Class codecvt<char16_t, char8_t, mbstate_t> specialization.
    581    *
    582    *  Converts between UTF-16 and UTF-8.
    583    */
    584   template<>
    585     class codecvt<char16_t, char8_t, mbstate_t>
    586     : public __codecvt_abstract_base<char16_t, char8_t, mbstate_t>
    587     {
    588     public:
    589       // Types:
    590       typedef char16_t			intern_type;
    591       typedef char8_t			extern_type;
    592       typedef mbstate_t			state_type;
    593 
    594     public:
    595       static locale::id			id;
    596 
    597       explicit
    598       codecvt(size_t __refs = 0)
    599       : __codecvt_abstract_base<char16_t, char8_t, mbstate_t>(__refs) { }
    600 
    601     protected:
    602       virtual
    603       ~codecvt();
    604 
    605       virtual result
    606       do_out(state_type& __state, const intern_type* __from,
    607 	     const intern_type* __from_end, const intern_type*& __from_next,
    608 	     extern_type* __to, extern_type* __to_end,
    609 	     extern_type*& __to_next) const;
    610 
    611       virtual result
    612       do_unshift(state_type& __state,
    613 		 extern_type* __to, extern_type* __to_end,
    614 		 extern_type*& __to_next) const;
    615 
    616       virtual result
    617       do_in(state_type& __state,
    618 	     const extern_type* __from, const extern_type* __from_end,
    619 	     const extern_type*& __from_next,
    620 	     intern_type* __to, intern_type* __to_end,
    621 	     intern_type*& __to_next) const;
    622 
    623       virtual
    624       int do_encoding() const throw();
    625 
    626       virtual
    627       bool do_always_noconv() const throw();
    628 
    629       virtual
    630       int do_length(state_type&, const extern_type* __from,
    631 		    const extern_type* __end, size_t __max) const;
    632 
    633       virtual int
    634       do_max_length() const throw();
    635     };
    636 
    637   /** @brief  Class codecvt<char32_t, char8_t, mbstate_t> specialization.
    638    *
    639    *  Converts between UTF-32 and UTF-8.
    640    */
    641   template<>
    642     class codecvt<char32_t, char8_t, mbstate_t>
    643     : public __codecvt_abstract_base<char32_t, char8_t, mbstate_t>
    644     {
    645     public:
    646       // Types:
    647       typedef char32_t			intern_type;
    648       typedef char8_t			extern_type;
    649       typedef mbstate_t			state_type;
    650 
    651     public:
    652       static locale::id			id;
    653 
    654       explicit
    655       codecvt(size_t __refs = 0)
    656       : __codecvt_abstract_base<char32_t, char8_t, mbstate_t>(__refs) { }
    657 
    658     protected:
    659       virtual
    660       ~codecvt();
    661 
    662       virtual result
    663       do_out(state_type& __state, const intern_type* __from,
    664 	     const intern_type* __from_end, const intern_type*& __from_next,
    665 	     extern_type* __to, extern_type* __to_end,
    666 	     extern_type*& __to_next) const;
    667 
    668       virtual result
    669       do_unshift(state_type& __state,
    670 		 extern_type* __to, extern_type* __to_end,
    671 		 extern_type*& __to_next) const;
    672 
    673       virtual result
    674       do_in(state_type& __state,
    675 	     const extern_type* __from, const extern_type* __from_end,
    676 	     const extern_type*& __from_next,
    677 	     intern_type* __to, intern_type* __to_end,
    678 	     intern_type*& __to_next) const;
    679 
    680       virtual
    681       int do_encoding() const throw();
    682 
    683       virtual
    684       bool do_always_noconv() const throw();
    685 
    686       virtual
    687       int do_length(state_type&, const extern_type* __from,
    688 		    const extern_type* __end, size_t __max) const;
    689 
    690       virtual int
    691       do_max_length() const throw();
    692     };
    693 #endif // _GLIBCXX_USE_CHAR8_T
    694 
    695 #endif // C++11
    696 
    697   /// class codecvt_byname [22.2.1.6].
    698   template<typename _InternT, typename _ExternT, typename _StateT>
    699     class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
    700     {
    701     public:
    702       explicit
    703       codecvt_byname(const char* __s, size_t __refs = 0)
    704       : codecvt<_InternT, _ExternT, _StateT>(__refs)
    705       {
    706 	if (__builtin_strcmp(__s, "C") != 0
    707 	    && __builtin_strcmp(__s, "POSIX") != 0)
    708 	  {
    709 	    this->_S_destroy_c_locale(this->_M_c_locale_codecvt);
    710 	    this->_S_create_c_locale(this->_M_c_locale_codecvt, __s);
    711 	  }
    712       }
    713 
    714 #if __cplusplus >= 201103L
    715       explicit
    716       codecvt_byname(const string& __s, size_t __refs = 0)
    717       : codecvt_byname(__s.c_str(), __refs) { }
    718 #endif
    719 
    720     protected:
    721       virtual
    722       ~codecvt_byname() { }
    723     };
    724 
    725 #if __cplusplus >= 201103L
    726   template<>
    727     class codecvt_byname<char16_t, char, mbstate_t>
    728     : public codecvt<char16_t, char, mbstate_t>
    729     {
    730     public:
    731       explicit
    732       codecvt_byname(const char*, size_t __refs = 0)
    733       : codecvt<char16_t, char, mbstate_t>(__refs) { }
    734 
    735       explicit
    736       codecvt_byname(const string& __s, size_t __refs = 0)
    737       : codecvt_byname(__s.c_str(), __refs) { }
    738 
    739     protected:
    740       virtual
    741       ~codecvt_byname() { }
    742     };
    743 
    744   template<>
    745     class codecvt_byname<char32_t, char, mbstate_t>
    746     : public codecvt<char32_t, char, mbstate_t>
    747     {
    748     public:
    749       explicit
    750       codecvt_byname(const char*, size_t __refs = 0)
    751       : codecvt<char32_t, char, mbstate_t>(__refs) { }
    752 
    753       explicit
    754       codecvt_byname(const string& __s, size_t __refs = 0)
    755       : codecvt_byname(__s.c_str(), __refs) { }
    756 
    757     protected:
    758       virtual
    759       ~codecvt_byname() { }
    760     };
    761 
    762 #if defined(_GLIBCXX_USE_CHAR8_T)
    763   template<>
    764     class codecvt_byname<char16_t, char8_t, mbstate_t>
    765     : public codecvt<char16_t, char8_t, mbstate_t>
    766     {
    767     public:
    768       explicit
    769       codecvt_byname(const char*, size_t __refs = 0)
    770       : codecvt<char16_t, char8_t, mbstate_t>(__refs) { }
    771 
    772       explicit
    773       codecvt_byname(const string& __s, size_t __refs = 0)
    774       : codecvt_byname(__s.c_str(), __refs) { }
    775 
    776     protected:
    777       virtual
    778       ~codecvt_byname() { }
    779     };
    780 
    781   template<>
    782     class codecvt_byname<char32_t, char8_t, mbstate_t>
    783     : public codecvt<char32_t, char8_t, mbstate_t>
    784     {
    785     public:
    786       explicit
    787       codecvt_byname(const char*, size_t __refs = 0)
    788       : codecvt<char32_t, char8_t, mbstate_t>(__refs) { }
    789 
    790       explicit
    791       codecvt_byname(const string& __s, size_t __refs = 0)
    792       : codecvt_byname(__s.c_str(), __refs) { }
    793 
    794     protected:
    795       virtual
    796       ~codecvt_byname() { }
    797     };
    798 #endif
    799 
    800 #endif // C++11
    801 
    802   // Inhibit implicit instantiations for required instantiations,
    803   // which are defined via explicit instantiations elsewhere.
    804 #if _GLIBCXX_EXTERN_TEMPLATE
    805   extern template class codecvt_byname<char, char, mbstate_t>;
    806 
    807   extern template
    808     const codecvt<char, char, mbstate_t>&
    809     use_facet<codecvt<char, char, mbstate_t> >(const locale&);
    810 
    811   extern template
    812     bool
    813     has_facet<codecvt<char, char, mbstate_t> >(const locale&);
    814 
    815 #ifdef _GLIBCXX_USE_WCHAR_T
    816   extern template class codecvt_byname<wchar_t, char, mbstate_t>;
    817 
    818   extern template
    819     const codecvt<wchar_t, char, mbstate_t>&
    820     use_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
    821 
    822   extern template
    823     bool
    824     has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
    825 #endif
    826 
    827 #if __cplusplus >= 201103L
    828   extern template class codecvt_byname<char16_t, char, mbstate_t>;
    829   extern template class codecvt_byname<char32_t, char, mbstate_t>;
    830 
    831 #if defined(_GLIBCXX_USE_CHAR8_T)
    832   extern template class codecvt_byname<char16_t, char8_t, mbstate_t>;
    833   extern template class codecvt_byname<char32_t, char8_t, mbstate_t>;
    834 #endif
    835 
    836 #endif
    837 
    838 #endif
    839 
    840 _GLIBCXX_END_NAMESPACE_VERSION
    841 } // namespace std
    842 
    843 #endif // _CODECVT_H
    844