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