1  // Locale support (codecvt) -*- C++ -*-
       2  
       3  // Copyright (C) 2000-2023 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@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