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