xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/locale_facets.h (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // Locale support -*- C++ -*-
238fd1498Szrj 
338fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj 
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj 
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj 
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj 
2538fd1498Szrj /** @file bits/locale_facets.h
2638fd1498Szrj  *  This is an internal header file, included by other library headers.
2738fd1498Szrj  *  Do not attempt to use it directly. @headername{locale}
2838fd1498Szrj  */
2938fd1498Szrj 
3038fd1498Szrj //
3138fd1498Szrj // ISO C++ 14882: 22.1  Locales
3238fd1498Szrj //
3338fd1498Szrj 
3438fd1498Szrj #ifndef _LOCALE_FACETS_H
3538fd1498Szrj #define _LOCALE_FACETS_H 1
3638fd1498Szrj 
3738fd1498Szrj #pragma GCC system_header
3838fd1498Szrj 
3938fd1498Szrj #include <cwctype>	// For wctype_t
4038fd1498Szrj #include <cctype>
4138fd1498Szrj #include <bits/ctype_base.h>
4238fd1498Szrj #include <iosfwd>
4338fd1498Szrj #include <bits/ios_base.h>  // For ios_base, ios_base::iostate
4438fd1498Szrj #include <streambuf>
4538fd1498Szrj #include <bits/cpp_type_traits.h>
4638fd1498Szrj #include <ext/type_traits.h>
4738fd1498Szrj #include <ext/numeric_traits.h>
4838fd1498Szrj #include <bits/streambuf_iterator.h>
4938fd1498Szrj 
_GLIBCXX_VISIBILITY(default)5038fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
5138fd1498Szrj {
5238fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
5338fd1498Szrj 
5438fd1498Szrj   // NB: Don't instantiate required wchar_t facets if no wchar_t support.
5538fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T
5638fd1498Szrj # define  _GLIBCXX_NUM_FACETS 28
5738fd1498Szrj # define  _GLIBCXX_NUM_CXX11_FACETS 16
5838fd1498Szrj #else
5938fd1498Szrj # define  _GLIBCXX_NUM_FACETS 14
6038fd1498Szrj # define  _GLIBCXX_NUM_CXX11_FACETS 8
6138fd1498Szrj #endif
6238fd1498Szrj #ifdef _GLIBCXX_USE_C99_STDINT_TR1
6338fd1498Szrj # define _GLIBCXX_NUM_UNICODE_FACETS 2
6438fd1498Szrj #else
6538fd1498Szrj # define _GLIBCXX_NUM_UNICODE_FACETS 0
6638fd1498Szrj #endif
6738fd1498Szrj 
6838fd1498Szrj   // Convert string to numeric value of type _Tp and store results.
6938fd1498Szrj   // NB: This is specialized for all required types, there is no
7038fd1498Szrj   // generic definition.
7138fd1498Szrj   template<typename _Tp>
7238fd1498Szrj     void
7338fd1498Szrj     __convert_to_v(const char*, _Tp&, ios_base::iostate&,
7438fd1498Szrj 		   const __c_locale&) throw();
7538fd1498Szrj 
7638fd1498Szrj   // Explicit specializations for required types.
7738fd1498Szrj   template<>
7838fd1498Szrj     void
7938fd1498Szrj     __convert_to_v(const char*, float&, ios_base::iostate&,
8038fd1498Szrj 		   const __c_locale&) throw();
8138fd1498Szrj 
8238fd1498Szrj   template<>
8338fd1498Szrj     void
8438fd1498Szrj     __convert_to_v(const char*, double&, ios_base::iostate&,
8538fd1498Szrj 		   const __c_locale&) throw();
8638fd1498Szrj 
8738fd1498Szrj   template<>
8838fd1498Szrj     void
8938fd1498Szrj     __convert_to_v(const char*, long double&, ios_base::iostate&,
9038fd1498Szrj 		   const __c_locale&) throw();
9138fd1498Szrj 
9238fd1498Szrj   // NB: __pad is a struct, rather than a function, so it can be
9338fd1498Szrj   // partially-specialized.
9438fd1498Szrj   template<typename _CharT, typename _Traits>
9538fd1498Szrj     struct __pad
9638fd1498Szrj     {
9738fd1498Szrj       static void
9838fd1498Szrj       _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
9938fd1498Szrj 	     const _CharT* __olds, streamsize __newlen, streamsize __oldlen);
10038fd1498Szrj     };
10138fd1498Szrj 
10238fd1498Szrj   // Used by both numeric and monetary facets.
10338fd1498Szrj   // Inserts "group separator" characters into an array of characters.
10438fd1498Szrj   // It's recursive, one iteration per group.  It moves the characters
10538fd1498Szrj   // in the buffer this way: "xxxx12345" -> "12,345xxx".  Call this
10638fd1498Szrj   // only with __gsize != 0.
10738fd1498Szrj   template<typename _CharT>
10838fd1498Szrj     _CharT*
10938fd1498Szrj     __add_grouping(_CharT* __s, _CharT __sep,
11038fd1498Szrj 		   const char* __gbeg, size_t __gsize,
11138fd1498Szrj 		   const _CharT* __first, const _CharT* __last);
11238fd1498Szrj 
11338fd1498Szrj   // This template permits specializing facet output code for
11438fd1498Szrj   // ostreambuf_iterator.  For ostreambuf_iterator, sputn is
11538fd1498Szrj   // significantly more efficient than incrementing iterators.
11638fd1498Szrj   template<typename _CharT>
11738fd1498Szrj     inline
11838fd1498Szrj     ostreambuf_iterator<_CharT>
11938fd1498Szrj     __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)
12038fd1498Szrj     {
12138fd1498Szrj       __s._M_put(__ws, __len);
12238fd1498Szrj       return __s;
12338fd1498Szrj     }
12438fd1498Szrj 
12538fd1498Szrj   // This is the unspecialized form of the template.
12638fd1498Szrj   template<typename _CharT, typename _OutIter>
12738fd1498Szrj     inline
12838fd1498Szrj     _OutIter
12938fd1498Szrj     __write(_OutIter __s, const _CharT* __ws, int __len)
13038fd1498Szrj     {
13138fd1498Szrj       for (int __j = 0; __j < __len; __j++, ++__s)
13238fd1498Szrj 	*__s = __ws[__j];
13338fd1498Szrj       return __s;
13438fd1498Szrj     }
13538fd1498Szrj 
13638fd1498Szrj 
13738fd1498Szrj   // 22.2.1.1  Template class ctype
13838fd1498Szrj   // Include host and configuration specific ctype enums for ctype_base.
13938fd1498Szrj 
14038fd1498Szrj   /**
14138fd1498Szrj    *  @brief  Common base for ctype facet
14238fd1498Szrj    *
14338fd1498Szrj    *  This template class provides implementations of the public functions
14438fd1498Szrj    *  that forward to the protected virtual functions.
14538fd1498Szrj    *
14638fd1498Szrj    *  This template also provides abstract stubs for the protected virtual
14738fd1498Szrj    *  functions.
14838fd1498Szrj   */
14938fd1498Szrj   template<typename _CharT>
15038fd1498Szrj     class __ctype_abstract_base : public locale::facet, public ctype_base
15138fd1498Szrj     {
15238fd1498Szrj     public:
15338fd1498Szrj       // Types:
15438fd1498Szrj       /// Typedef for the template parameter
15538fd1498Szrj       typedef _CharT char_type;
15638fd1498Szrj 
15738fd1498Szrj       /**
15838fd1498Szrj        *  @brief  Test char_type classification.
15938fd1498Szrj        *
16038fd1498Szrj        *  This function finds a mask M for @a __c and compares it to
16138fd1498Szrj        *  mask @a __m.  It does so by returning the value of
16238fd1498Szrj        *  ctype<char_type>::do_is().
16338fd1498Szrj        *
16438fd1498Szrj        *  @param __c  The char_type to compare the mask of.
16538fd1498Szrj        *  @param __m  The mask to compare against.
16638fd1498Szrj        *  @return  (M & __m) != 0.
16738fd1498Szrj       */
16838fd1498Szrj       bool
16938fd1498Szrj       is(mask __m, char_type __c) const
17038fd1498Szrj       { return this->do_is(__m, __c); }
17138fd1498Szrj 
17238fd1498Szrj       /**
17338fd1498Szrj        *  @brief  Return a mask array.
17438fd1498Szrj        *
17538fd1498Szrj        *  This function finds the mask for each char_type in the range [lo,hi)
17638fd1498Szrj        *  and successively writes it to vec.  vec must have as many elements
17738fd1498Szrj        *  as the char array.  It does so by returning the value of
17838fd1498Szrj        *  ctype<char_type>::do_is().
17938fd1498Szrj        *
18038fd1498Szrj        *  @param __lo  Pointer to start of range.
18138fd1498Szrj        *  @param __hi  Pointer to end of range.
18238fd1498Szrj        *  @param __vec  Pointer to an array of mask storage.
18338fd1498Szrj        *  @return  @a __hi.
18438fd1498Szrj       */
18538fd1498Szrj       const char_type*
18638fd1498Szrj       is(const char_type *__lo, const char_type *__hi, mask *__vec) const
18738fd1498Szrj       { return this->do_is(__lo, __hi, __vec); }
18838fd1498Szrj 
18938fd1498Szrj       /**
19038fd1498Szrj        *  @brief  Find char_type matching a mask
19138fd1498Szrj        *
19238fd1498Szrj        *  This function searches for and returns the first char_type c in
19338fd1498Szrj        *  [lo,hi) for which is(m,c) is true.  It does so by returning
19438fd1498Szrj        *  ctype<char_type>::do_scan_is().
19538fd1498Szrj        *
19638fd1498Szrj        *  @param __m  The mask to compare against.
19738fd1498Szrj        *  @param __lo  Pointer to start of range.
19838fd1498Szrj        *  @param __hi  Pointer to end of range.
19938fd1498Szrj        *  @return  Pointer to matching char_type if found, else @a __hi.
20038fd1498Szrj       */
20138fd1498Szrj       const char_type*
20238fd1498Szrj       scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
20338fd1498Szrj       { return this->do_scan_is(__m, __lo, __hi); }
20438fd1498Szrj 
20538fd1498Szrj       /**
20638fd1498Szrj        *  @brief  Find char_type not matching a mask
20738fd1498Szrj        *
20838fd1498Szrj        *  This function searches for and returns the first char_type c in
20938fd1498Szrj        *  [lo,hi) for which is(m,c) is false.  It does so by returning
21038fd1498Szrj        *  ctype<char_type>::do_scan_not().
21138fd1498Szrj        *
21238fd1498Szrj        *  @param __m  The mask to compare against.
21338fd1498Szrj        *  @param __lo  Pointer to first char in range.
21438fd1498Szrj        *  @param __hi  Pointer to end of range.
21538fd1498Szrj        *  @return  Pointer to non-matching char if found, else @a __hi.
21638fd1498Szrj       */
21738fd1498Szrj       const char_type*
21838fd1498Szrj       scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
21938fd1498Szrj       { return this->do_scan_not(__m, __lo, __hi); }
22038fd1498Szrj 
22138fd1498Szrj       /**
22238fd1498Szrj        *  @brief  Convert to uppercase.
22338fd1498Szrj        *
22438fd1498Szrj        *  This function converts the argument to uppercase if possible.
22538fd1498Szrj        *  If not possible (for example, '2'), returns the argument.  It does
22638fd1498Szrj        *  so by returning ctype<char_type>::do_toupper().
22738fd1498Szrj        *
22838fd1498Szrj        *  @param __c  The char_type to convert.
22938fd1498Szrj        *  @return  The uppercase char_type if convertible, else @a __c.
23038fd1498Szrj       */
23138fd1498Szrj       char_type
23238fd1498Szrj       toupper(char_type __c) const
23338fd1498Szrj       { return this->do_toupper(__c); }
23438fd1498Szrj 
23538fd1498Szrj       /**
23638fd1498Szrj        *  @brief  Convert array to uppercase.
23738fd1498Szrj        *
23838fd1498Szrj        *  This function converts each char_type in the range [lo,hi) to
23938fd1498Szrj        *  uppercase if possible.  Other elements remain untouched.  It does so
24038fd1498Szrj        *  by returning ctype<char_type>:: do_toupper(lo, hi).
24138fd1498Szrj        *
24238fd1498Szrj        *  @param __lo  Pointer to start of range.
24338fd1498Szrj        *  @param __hi  Pointer to end of range.
24438fd1498Szrj        *  @return  @a __hi.
24538fd1498Szrj       */
24638fd1498Szrj       const char_type*
24738fd1498Szrj       toupper(char_type *__lo, const char_type* __hi) const
24838fd1498Szrj       { return this->do_toupper(__lo, __hi); }
24938fd1498Szrj 
25038fd1498Szrj       /**
25138fd1498Szrj        *  @brief  Convert to lowercase.
25238fd1498Szrj        *
25338fd1498Szrj        *  This function converts the argument to lowercase if possible.  If
25438fd1498Szrj        *  not possible (for example, '2'), returns the argument.  It does so
25538fd1498Szrj        *  by returning ctype<char_type>::do_tolower(c).
25638fd1498Szrj        *
25738fd1498Szrj        *  @param __c  The char_type to convert.
25838fd1498Szrj        *  @return  The lowercase char_type if convertible, else @a __c.
25938fd1498Szrj       */
26038fd1498Szrj       char_type
26138fd1498Szrj       tolower(char_type __c) const
26238fd1498Szrj       { return this->do_tolower(__c); }
26338fd1498Szrj 
26438fd1498Szrj       /**
26538fd1498Szrj        *  @brief  Convert array to lowercase.
26638fd1498Szrj        *
26738fd1498Szrj        *  This function converts each char_type in the range [__lo,__hi) to
26838fd1498Szrj        *  lowercase if possible.  Other elements remain untouched.  It does so
26938fd1498Szrj        *  by returning ctype<char_type>:: do_tolower(__lo, __hi).
27038fd1498Szrj        *
27138fd1498Szrj        *  @param __lo  Pointer to start of range.
27238fd1498Szrj        *  @param __hi  Pointer to end of range.
27338fd1498Szrj        *  @return  @a __hi.
27438fd1498Szrj       */
27538fd1498Szrj       const char_type*
27638fd1498Szrj       tolower(char_type* __lo, const char_type* __hi) const
27738fd1498Szrj       { return this->do_tolower(__lo, __hi); }
27838fd1498Szrj 
27938fd1498Szrj       /**
28038fd1498Szrj        *  @brief  Widen char to char_type
28138fd1498Szrj        *
28238fd1498Szrj        *  This function converts the char argument to char_type using the
28338fd1498Szrj        *  simplest reasonable transformation.  It does so by returning
28438fd1498Szrj        *  ctype<char_type>::do_widen(c).
28538fd1498Szrj        *
28638fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
28738fd1498Szrj        *  codecvt for that.
28838fd1498Szrj        *
28938fd1498Szrj        *  @param __c  The char to convert.
29038fd1498Szrj        *  @return  The converted char_type.
29138fd1498Szrj       */
29238fd1498Szrj       char_type
29338fd1498Szrj       widen(char __c) const
29438fd1498Szrj       { return this->do_widen(__c); }
29538fd1498Szrj 
29638fd1498Szrj       /**
29738fd1498Szrj        *  @brief  Widen array to char_type
29838fd1498Szrj        *
29938fd1498Szrj        *  This function converts each char in the input to char_type using the
30038fd1498Szrj        *  simplest reasonable transformation.  It does so by returning
30138fd1498Szrj        *  ctype<char_type>::do_widen(c).
30238fd1498Szrj        *
30338fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
30438fd1498Szrj        *  codecvt for that.
30538fd1498Szrj        *
30638fd1498Szrj        *  @param __lo  Pointer to start of range.
30738fd1498Szrj        *  @param __hi  Pointer to end of range.
30838fd1498Szrj        *  @param __to  Pointer to the destination array.
30938fd1498Szrj        *  @return  @a __hi.
31038fd1498Szrj       */
31138fd1498Szrj       const char*
31238fd1498Szrj       widen(const char* __lo, const char* __hi, char_type* __to) const
31338fd1498Szrj       { return this->do_widen(__lo, __hi, __to); }
31438fd1498Szrj 
31538fd1498Szrj       /**
31638fd1498Szrj        *  @brief  Narrow char_type to char
31738fd1498Szrj        *
31838fd1498Szrj        *  This function converts the char_type to char using the simplest
31938fd1498Szrj        *  reasonable transformation.  If the conversion fails, dfault is
32038fd1498Szrj        *  returned instead.  It does so by returning
32138fd1498Szrj        *  ctype<char_type>::do_narrow(__c).
32238fd1498Szrj        *
32338fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
32438fd1498Szrj        *  codecvt for that.
32538fd1498Szrj        *
32638fd1498Szrj        *  @param __c  The char_type to convert.
32738fd1498Szrj        *  @param __dfault  Char to return if conversion fails.
32838fd1498Szrj        *  @return  The converted char.
32938fd1498Szrj       */
33038fd1498Szrj       char
33138fd1498Szrj       narrow(char_type __c, char __dfault) const
33238fd1498Szrj       { return this->do_narrow(__c, __dfault); }
33338fd1498Szrj 
33438fd1498Szrj       /**
33538fd1498Szrj        *  @brief  Narrow array to char array
33638fd1498Szrj        *
33738fd1498Szrj        *  This function converts each char_type in the input to char using the
33838fd1498Szrj        *  simplest reasonable transformation and writes the results to the
33938fd1498Szrj        *  destination array.  For any char_type in the input that cannot be
34038fd1498Szrj        *  converted, @a dfault is used instead.  It does so by returning
34138fd1498Szrj        *  ctype<char_type>::do_narrow(__lo, __hi, __dfault, __to).
34238fd1498Szrj        *
34338fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
34438fd1498Szrj        *  codecvt for that.
34538fd1498Szrj        *
34638fd1498Szrj        *  @param __lo  Pointer to start of range.
34738fd1498Szrj        *  @param __hi  Pointer to end of range.
34838fd1498Szrj        *  @param __dfault  Char to use if conversion fails.
34938fd1498Szrj        *  @param __to  Pointer to the destination array.
35038fd1498Szrj        *  @return  @a __hi.
35138fd1498Szrj       */
35238fd1498Szrj       const char_type*
35338fd1498Szrj       narrow(const char_type* __lo, const char_type* __hi,
35438fd1498Szrj 	      char __dfault, char* __to) const
35538fd1498Szrj       { return this->do_narrow(__lo, __hi, __dfault, __to); }
35638fd1498Szrj 
35738fd1498Szrj     protected:
35838fd1498Szrj       explicit
35938fd1498Szrj       __ctype_abstract_base(size_t __refs = 0): facet(__refs) { }
36038fd1498Szrj 
36138fd1498Szrj       virtual
36238fd1498Szrj       ~__ctype_abstract_base() { }
36338fd1498Szrj 
36438fd1498Szrj       /**
36538fd1498Szrj        *  @brief  Test char_type classification.
36638fd1498Szrj        *
36738fd1498Szrj        *  This function finds a mask M for @a c and compares it to mask @a m.
36838fd1498Szrj        *
36938fd1498Szrj        *  do_is() is a hook for a derived facet to change the behavior of
37038fd1498Szrj        *  classifying.  do_is() must always return the same result for the
37138fd1498Szrj        *  same input.
37238fd1498Szrj        *
37338fd1498Szrj        *  @param __c  The char_type to find the mask of.
37438fd1498Szrj        *  @param __m  The mask to compare against.
37538fd1498Szrj        *  @return  (M & __m) != 0.
37638fd1498Szrj       */
37738fd1498Szrj       virtual bool
37838fd1498Szrj       do_is(mask __m, char_type __c) const = 0;
37938fd1498Szrj 
38038fd1498Szrj       /**
38138fd1498Szrj        *  @brief  Return a mask array.
38238fd1498Szrj        *
38338fd1498Szrj        *  This function finds the mask for each char_type in the range [lo,hi)
38438fd1498Szrj        *  and successively writes it to vec.  vec must have as many elements
38538fd1498Szrj        *  as the input.
38638fd1498Szrj        *
38738fd1498Szrj        *  do_is() is a hook for a derived facet to change the behavior of
38838fd1498Szrj        *  classifying.  do_is() must always return the same result for the
38938fd1498Szrj        *  same input.
39038fd1498Szrj        *
39138fd1498Szrj        *  @param __lo  Pointer to start of range.
39238fd1498Szrj        *  @param __hi  Pointer to end of range.
39338fd1498Szrj        *  @param __vec  Pointer to an array of mask storage.
39438fd1498Szrj        *  @return  @a __hi.
39538fd1498Szrj       */
39638fd1498Szrj       virtual const char_type*
39738fd1498Szrj       do_is(const char_type* __lo, const char_type* __hi,
39838fd1498Szrj 	    mask* __vec) const = 0;
39938fd1498Szrj 
40038fd1498Szrj       /**
40138fd1498Szrj        *  @brief  Find char_type matching mask
40238fd1498Szrj        *
40338fd1498Szrj        *  This function searches for and returns the first char_type c in
40438fd1498Szrj        *  [__lo,__hi) for which is(__m,c) is true.
40538fd1498Szrj        *
40638fd1498Szrj        *  do_scan_is() is a hook for a derived facet to change the behavior of
40738fd1498Szrj        *  match searching.  do_is() must always return the same result for the
40838fd1498Szrj        *  same input.
40938fd1498Szrj        *
41038fd1498Szrj        *  @param __m  The mask to compare against.
41138fd1498Szrj        *  @param __lo  Pointer to start of range.
41238fd1498Szrj        *  @param __hi  Pointer to end of range.
41338fd1498Szrj        *  @return  Pointer to a matching char_type if found, else @a __hi.
41438fd1498Szrj       */
41538fd1498Szrj       virtual const char_type*
41638fd1498Szrj       do_scan_is(mask __m, const char_type* __lo,
41738fd1498Szrj 		 const char_type* __hi) const = 0;
41838fd1498Szrj 
41938fd1498Szrj       /**
42038fd1498Szrj        *  @brief  Find char_type not matching mask
42138fd1498Szrj        *
42238fd1498Szrj        *  This function searches for and returns a pointer to the first
42338fd1498Szrj        *  char_type c of [lo,hi) for which is(m,c) is false.
42438fd1498Szrj        *
42538fd1498Szrj        *  do_scan_is() is a hook for a derived facet to change the behavior of
42638fd1498Szrj        *  match searching.  do_is() must always return the same result for the
42738fd1498Szrj        *  same input.
42838fd1498Szrj        *
42938fd1498Szrj        *  @param __m  The mask to compare against.
43038fd1498Szrj        *  @param __lo  Pointer to start of range.
43138fd1498Szrj        *  @param __hi  Pointer to end of range.
43238fd1498Szrj        *  @return  Pointer to a non-matching char_type if found, else @a __hi.
43338fd1498Szrj       */
43438fd1498Szrj       virtual const char_type*
43538fd1498Szrj       do_scan_not(mask __m, const char_type* __lo,
43638fd1498Szrj 		  const char_type* __hi) const = 0;
43738fd1498Szrj 
43838fd1498Szrj       /**
43938fd1498Szrj        *  @brief  Convert to uppercase.
44038fd1498Szrj        *
44138fd1498Szrj        *  This virtual function converts the char_type argument to uppercase
44238fd1498Szrj        *  if possible.  If not possible (for example, '2'), returns the
44338fd1498Szrj        *  argument.
44438fd1498Szrj        *
44538fd1498Szrj        *  do_toupper() is a hook for a derived facet to change the behavior of
44638fd1498Szrj        *  uppercasing.  do_toupper() must always return the same result for
44738fd1498Szrj        *  the same input.
44838fd1498Szrj        *
44938fd1498Szrj        *  @param __c  The char_type to convert.
45038fd1498Szrj        *  @return  The uppercase char_type if convertible, else @a __c.
45138fd1498Szrj       */
45238fd1498Szrj       virtual char_type
45338fd1498Szrj       do_toupper(char_type __c) const = 0;
45438fd1498Szrj 
45538fd1498Szrj       /**
45638fd1498Szrj        *  @brief  Convert array to uppercase.
45738fd1498Szrj        *
45838fd1498Szrj        *  This virtual function converts each char_type in the range [__lo,__hi)
45938fd1498Szrj        *  to uppercase if possible.  Other elements remain untouched.
46038fd1498Szrj        *
46138fd1498Szrj        *  do_toupper() is a hook for a derived facet to change the behavior of
46238fd1498Szrj        *  uppercasing.  do_toupper() must always return the same result for
46338fd1498Szrj        *  the same input.
46438fd1498Szrj        *
46538fd1498Szrj        *  @param __lo  Pointer to start of range.
46638fd1498Szrj        *  @param __hi  Pointer to end of range.
46738fd1498Szrj        *  @return  @a __hi.
46838fd1498Szrj       */
46938fd1498Szrj       virtual const char_type*
47038fd1498Szrj       do_toupper(char_type* __lo, const char_type* __hi) const = 0;
47138fd1498Szrj 
47238fd1498Szrj       /**
47338fd1498Szrj        *  @brief  Convert to lowercase.
47438fd1498Szrj        *
47538fd1498Szrj        *  This virtual function converts the argument to lowercase if
47638fd1498Szrj        *  possible.  If not possible (for example, '2'), returns the argument.
47738fd1498Szrj        *
47838fd1498Szrj        *  do_tolower() is a hook for a derived facet to change the behavior of
47938fd1498Szrj        *  lowercasing.  do_tolower() must always return the same result for
48038fd1498Szrj        *  the same input.
48138fd1498Szrj        *
48238fd1498Szrj        *  @param __c  The char_type to convert.
48338fd1498Szrj        *  @return  The lowercase char_type if convertible, else @a __c.
48438fd1498Szrj       */
48538fd1498Szrj       virtual char_type
48638fd1498Szrj       do_tolower(char_type __c) const = 0;
48738fd1498Szrj 
48838fd1498Szrj       /**
48938fd1498Szrj        *  @brief  Convert array to lowercase.
49038fd1498Szrj        *
49138fd1498Szrj        *  This virtual function converts each char_type in the range [__lo,__hi)
49238fd1498Szrj        *  to lowercase if possible.  Other elements remain untouched.
49338fd1498Szrj        *
49438fd1498Szrj        *  do_tolower() is a hook for a derived facet to change the behavior of
49538fd1498Szrj        *  lowercasing.  do_tolower() must always return the same result for
49638fd1498Szrj        *  the same input.
49738fd1498Szrj        *
49838fd1498Szrj        *  @param __lo  Pointer to start of range.
49938fd1498Szrj        *  @param __hi  Pointer to end of range.
50038fd1498Szrj        *  @return  @a __hi.
50138fd1498Szrj       */
50238fd1498Szrj       virtual const char_type*
50338fd1498Szrj       do_tolower(char_type* __lo, const char_type* __hi) const = 0;
50438fd1498Szrj 
50538fd1498Szrj       /**
50638fd1498Szrj        *  @brief  Widen char
50738fd1498Szrj        *
50838fd1498Szrj        *  This virtual function converts the char to char_type using the
50938fd1498Szrj        *  simplest reasonable transformation.
51038fd1498Szrj        *
51138fd1498Szrj        *  do_widen() is a hook for a derived facet to change the behavior of
51238fd1498Szrj        *  widening.  do_widen() must always return the same result for the
51338fd1498Szrj        *  same input.
51438fd1498Szrj        *
51538fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
51638fd1498Szrj        *  codecvt for that.
51738fd1498Szrj        *
51838fd1498Szrj        *  @param __c  The char to convert.
51938fd1498Szrj        *  @return  The converted char_type
52038fd1498Szrj       */
52138fd1498Szrj       virtual char_type
52238fd1498Szrj       do_widen(char __c) const = 0;
52338fd1498Szrj 
52438fd1498Szrj       /**
52538fd1498Szrj        *  @brief  Widen char array
52638fd1498Szrj        *
52738fd1498Szrj        *  This function converts each char in the input to char_type using the
52838fd1498Szrj        *  simplest reasonable transformation.
52938fd1498Szrj        *
53038fd1498Szrj        *  do_widen() is a hook for a derived facet to change the behavior of
53138fd1498Szrj        *  widening.  do_widen() must always return the same result for the
53238fd1498Szrj        *  same input.
53338fd1498Szrj        *
53438fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
53538fd1498Szrj        *  codecvt for that.
53638fd1498Szrj        *
53738fd1498Szrj        *  @param __lo  Pointer to start range.
53838fd1498Szrj        *  @param __hi  Pointer to end of range.
53938fd1498Szrj        *  @param __to  Pointer to the destination array.
54038fd1498Szrj        *  @return  @a __hi.
54138fd1498Szrj       */
54238fd1498Szrj       virtual const char*
54338fd1498Szrj       do_widen(const char* __lo, const char* __hi, char_type* __to) const = 0;
54438fd1498Szrj 
54538fd1498Szrj       /**
54638fd1498Szrj        *  @brief  Narrow char_type to char
54738fd1498Szrj        *
54838fd1498Szrj        *  This virtual function converts the argument to char using the
54938fd1498Szrj        *  simplest reasonable transformation.  If the conversion fails, dfault
55038fd1498Szrj        *  is returned instead.
55138fd1498Szrj        *
55238fd1498Szrj        *  do_narrow() is a hook for a derived facet to change the behavior of
55338fd1498Szrj        *  narrowing.  do_narrow() must always return the same result for the
55438fd1498Szrj        *  same input.
55538fd1498Szrj        *
55638fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
55738fd1498Szrj        *  codecvt for that.
55838fd1498Szrj        *
55938fd1498Szrj        *  @param __c  The char_type to convert.
56038fd1498Szrj        *  @param __dfault  Char to return if conversion fails.
56138fd1498Szrj        *  @return  The converted char.
56238fd1498Szrj       */
56338fd1498Szrj       virtual char
56438fd1498Szrj       do_narrow(char_type __c, char __dfault) const = 0;
56538fd1498Szrj 
56638fd1498Szrj       /**
56738fd1498Szrj        *  @brief  Narrow char_type array to char
56838fd1498Szrj        *
56938fd1498Szrj        *  This virtual function converts each char_type in the range
57038fd1498Szrj        *  [__lo,__hi) to char using the simplest reasonable
57138fd1498Szrj        *  transformation and writes the results to the destination
57238fd1498Szrj        *  array.  For any element in the input that cannot be
57338fd1498Szrj        *  converted, @a __dfault is used instead.
57438fd1498Szrj        *
57538fd1498Szrj        *  do_narrow() is a hook for a derived facet to change the behavior of
57638fd1498Szrj        *  narrowing.  do_narrow() must always return the same result for the
57738fd1498Szrj        *  same input.
57838fd1498Szrj        *
57938fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
58038fd1498Szrj        *  codecvt for that.
58138fd1498Szrj        *
58238fd1498Szrj        *  @param __lo  Pointer to start of range.
58338fd1498Szrj        *  @param __hi  Pointer to end of range.
58438fd1498Szrj        *  @param __dfault  Char to use if conversion fails.
58538fd1498Szrj        *  @param __to  Pointer to the destination array.
58638fd1498Szrj        *  @return  @a __hi.
58738fd1498Szrj       */
58838fd1498Szrj       virtual const char_type*
58938fd1498Szrj       do_narrow(const char_type* __lo, const char_type* __hi,
59038fd1498Szrj 		char __dfault, char* __to) const = 0;
59138fd1498Szrj     };
59238fd1498Szrj 
59338fd1498Szrj   /**
59438fd1498Szrj    *  @brief  Primary class template ctype facet.
59538fd1498Szrj    *  @ingroup locales
59638fd1498Szrj    *
59738fd1498Szrj    *  This template class defines classification and conversion functions for
59838fd1498Szrj    *  character sets.  It wraps cctype functionality.  Ctype gets used by
59938fd1498Szrj    *  streams for many I/O operations.
60038fd1498Szrj    *
60138fd1498Szrj    *  This template provides the protected virtual functions the developer
60238fd1498Szrj    *  will have to replace in a derived class or specialization to make a
60338fd1498Szrj    *  working facet.  The public functions that access them are defined in
60438fd1498Szrj    *  __ctype_abstract_base, to allow for implementation flexibility.  See
60538fd1498Szrj    *  ctype<wchar_t> for an example.  The functions are documented in
60638fd1498Szrj    *  __ctype_abstract_base.
60738fd1498Szrj    *
60838fd1498Szrj    *  Note: implementations are provided for all the protected virtual
60938fd1498Szrj    *  functions, but will likely not be useful.
61038fd1498Szrj   */
61138fd1498Szrj   template<typename _CharT>
61238fd1498Szrj     class ctype : public __ctype_abstract_base<_CharT>
61338fd1498Szrj     {
61438fd1498Szrj     public:
61538fd1498Szrj       // Types:
61638fd1498Szrj       typedef _CharT			char_type;
61738fd1498Szrj       typedef typename __ctype_abstract_base<_CharT>::mask mask;
61838fd1498Szrj 
61938fd1498Szrj       /// The facet id for ctype<char_type>
62038fd1498Szrj       static locale::id			id;
62138fd1498Szrj 
62238fd1498Szrj       explicit
62338fd1498Szrj       ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
62438fd1498Szrj 
62538fd1498Szrj    protected:
62638fd1498Szrj       virtual
62738fd1498Szrj       ~ctype();
62838fd1498Szrj 
62938fd1498Szrj       virtual bool
63038fd1498Szrj       do_is(mask __m, char_type __c) const;
63138fd1498Szrj 
63238fd1498Szrj       virtual const char_type*
63338fd1498Szrj       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
63438fd1498Szrj 
63538fd1498Szrj       virtual const char_type*
63638fd1498Szrj       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
63738fd1498Szrj 
63838fd1498Szrj       virtual const char_type*
63938fd1498Szrj       do_scan_not(mask __m, const char_type* __lo,
64038fd1498Szrj 		  const char_type* __hi) const;
64138fd1498Szrj 
64238fd1498Szrj       virtual char_type
64338fd1498Szrj       do_toupper(char_type __c) const;
64438fd1498Szrj 
64538fd1498Szrj       virtual const char_type*
64638fd1498Szrj       do_toupper(char_type* __lo, const char_type* __hi) const;
64738fd1498Szrj 
64838fd1498Szrj       virtual char_type
64938fd1498Szrj       do_tolower(char_type __c) const;
65038fd1498Szrj 
65138fd1498Szrj       virtual const char_type*
65238fd1498Szrj       do_tolower(char_type* __lo, const char_type* __hi) const;
65338fd1498Szrj 
65438fd1498Szrj       virtual char_type
65538fd1498Szrj       do_widen(char __c) const;
65638fd1498Szrj 
65738fd1498Szrj       virtual const char*
65838fd1498Szrj       do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
65938fd1498Szrj 
66038fd1498Szrj       virtual char
66138fd1498Szrj       do_narrow(char_type, char __dfault) const;
66238fd1498Szrj 
66338fd1498Szrj       virtual const char_type*
66438fd1498Szrj       do_narrow(const char_type* __lo, const char_type* __hi,
66538fd1498Szrj 		char __dfault, char* __to) const;
66638fd1498Szrj     };
66738fd1498Szrj 
66838fd1498Szrj   template<typename _CharT>
66938fd1498Szrj     locale::id ctype<_CharT>::id;
67038fd1498Szrj 
67138fd1498Szrj   /**
67238fd1498Szrj    *  @brief  The ctype<char> specialization.
67338fd1498Szrj    *  @ingroup locales
67438fd1498Szrj    *
67538fd1498Szrj    *  This class defines classification and conversion functions for
67638fd1498Szrj    *  the char type.  It gets used by char streams for many I/O
67738fd1498Szrj    *  operations.  The char specialization provides a number of
67838fd1498Szrj    *  optimizations as well.
67938fd1498Szrj   */
68038fd1498Szrj   template<>
68138fd1498Szrj     class ctype<char> : public locale::facet, public ctype_base
68238fd1498Szrj     {
68338fd1498Szrj     public:
68438fd1498Szrj       // Types:
68538fd1498Szrj       /// Typedef for the template parameter char.
68638fd1498Szrj       typedef char		char_type;
68738fd1498Szrj 
68838fd1498Szrj     protected:
68938fd1498Szrj       // Data Members:
69038fd1498Szrj       __c_locale		_M_c_locale_ctype;
69138fd1498Szrj       bool			_M_del;
69238fd1498Szrj       __to_type			_M_toupper;
69338fd1498Szrj       __to_type			_M_tolower;
69438fd1498Szrj       const mask*		_M_table;
69538fd1498Szrj       mutable char		_M_widen_ok;
69638fd1498Szrj       mutable char		_M_widen[1 + static_cast<unsigned char>(-1)];
69738fd1498Szrj       mutable char		_M_narrow[1 + static_cast<unsigned char>(-1)];
69838fd1498Szrj       mutable char		_M_narrow_ok;	// 0 uninitialized, 1 init,
69938fd1498Szrj 						// 2 memcpy can't be used
70038fd1498Szrj 
70138fd1498Szrj     public:
70238fd1498Szrj       /// The facet id for ctype<char>
70338fd1498Szrj       static locale::id        id;
70438fd1498Szrj       /// The size of the mask table.  It is SCHAR_MAX + 1.
70538fd1498Szrj       static const size_t      table_size = 1 + static_cast<unsigned char>(-1);
70638fd1498Szrj 
70738fd1498Szrj       /**
70838fd1498Szrj        *  @brief  Constructor performs initialization.
70938fd1498Szrj        *
71038fd1498Szrj        *  This is the constructor provided by the standard.
71138fd1498Szrj        *
71238fd1498Szrj        *  @param __table If non-zero, table is used as the per-char mask.
71338fd1498Szrj        *               Else classic_table() is used.
71438fd1498Szrj        *  @param __del   If true, passes ownership of table to this facet.
71538fd1498Szrj        *  @param __refs  Passed to the base facet class.
71638fd1498Szrj       */
71738fd1498Szrj       explicit
71838fd1498Szrj       ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0);
71938fd1498Szrj 
72038fd1498Szrj       /**
72138fd1498Szrj        *  @brief  Constructor performs static initialization.
72238fd1498Szrj        *
72338fd1498Szrj        *  This constructor is used to construct the initial C locale facet.
72438fd1498Szrj        *
72538fd1498Szrj        *  @param __cloc  Handle to C locale data.
72638fd1498Szrj        *  @param __table If non-zero, table is used as the per-char mask.
72738fd1498Szrj        *  @param __del   If true, passes ownership of table to this facet.
72838fd1498Szrj        *  @param __refs  Passed to the base facet class.
72938fd1498Szrj       */
73038fd1498Szrj       explicit
73138fd1498Szrj       ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false,
73238fd1498Szrj 	    size_t __refs = 0);
73338fd1498Szrj 
73438fd1498Szrj       /**
73538fd1498Szrj        *  @brief  Test char classification.
73638fd1498Szrj        *
73738fd1498Szrj        *  This function compares the mask table[c] to @a __m.
73838fd1498Szrj        *
73938fd1498Szrj        *  @param __c  The char to compare the mask of.
74038fd1498Szrj        *  @param __m  The mask to compare against.
74138fd1498Szrj        *  @return  True if __m & table[__c] is true, false otherwise.
74238fd1498Szrj       */
74338fd1498Szrj       inline bool
74438fd1498Szrj       is(mask __m, char __c) const;
74538fd1498Szrj 
74638fd1498Szrj       /**
74738fd1498Szrj        *  @brief  Return a mask array.
74838fd1498Szrj        *
74938fd1498Szrj        *  This function finds the mask for each char in the range [lo, hi) and
75038fd1498Szrj        *  successively writes it to vec.  vec must have as many elements as
75138fd1498Szrj        *  the char array.
75238fd1498Szrj        *
75338fd1498Szrj        *  @param __lo  Pointer to start of range.
75438fd1498Szrj        *  @param __hi  Pointer to end of range.
75538fd1498Szrj        *  @param __vec  Pointer to an array of mask storage.
75638fd1498Szrj        *  @return  @a __hi.
75738fd1498Szrj       */
75838fd1498Szrj       inline const char*
75938fd1498Szrj       is(const char* __lo, const char* __hi, mask* __vec) const;
76038fd1498Szrj 
76138fd1498Szrj       /**
76238fd1498Szrj        *  @brief  Find char matching a mask
76338fd1498Szrj        *
76438fd1498Szrj        *  This function searches for and returns the first char in [lo,hi) for
76538fd1498Szrj        *  which is(m,char) is true.
76638fd1498Szrj        *
76738fd1498Szrj        *  @param __m  The mask to compare against.
76838fd1498Szrj        *  @param __lo  Pointer to start of range.
76938fd1498Szrj        *  @param __hi  Pointer to end of range.
77038fd1498Szrj        *  @return  Pointer to a matching char if found, else @a __hi.
77138fd1498Szrj       */
77238fd1498Szrj       inline const char*
77338fd1498Szrj       scan_is(mask __m, const char* __lo, const char* __hi) const;
77438fd1498Szrj 
77538fd1498Szrj       /**
77638fd1498Szrj        *  @brief  Find char not matching a mask
77738fd1498Szrj        *
77838fd1498Szrj        *  This function searches for and returns a pointer to the first char
77938fd1498Szrj        *  in [__lo,__hi) for which is(m,char) is false.
78038fd1498Szrj        *
78138fd1498Szrj        *  @param __m  The mask to compare against.
78238fd1498Szrj        *  @param __lo  Pointer to start of range.
78338fd1498Szrj        *  @param __hi  Pointer to end of range.
78438fd1498Szrj        *  @return  Pointer to a non-matching char if found, else @a __hi.
78538fd1498Szrj       */
78638fd1498Szrj       inline const char*
78738fd1498Szrj       scan_not(mask __m, const char* __lo, const char* __hi) const;
78838fd1498Szrj 
78938fd1498Szrj       /**
79038fd1498Szrj        *  @brief  Convert to uppercase.
79138fd1498Szrj        *
79238fd1498Szrj        *  This function converts the char argument to uppercase if possible.
79338fd1498Szrj        *  If not possible (for example, '2'), returns the argument.
79438fd1498Szrj        *
79538fd1498Szrj        *  toupper() acts as if it returns ctype<char>::do_toupper(c).
79638fd1498Szrj        *  do_toupper() must always return the same result for the same input.
79738fd1498Szrj        *
79838fd1498Szrj        *  @param __c  The char to convert.
79938fd1498Szrj        *  @return  The uppercase char if convertible, else @a __c.
80038fd1498Szrj       */
80138fd1498Szrj       char_type
80238fd1498Szrj       toupper(char_type __c) const
80338fd1498Szrj       { return this->do_toupper(__c); }
80438fd1498Szrj 
80538fd1498Szrj       /**
80638fd1498Szrj        *  @brief  Convert array to uppercase.
80738fd1498Szrj        *
80838fd1498Szrj        *  This function converts each char in the range [__lo,__hi) to uppercase
80938fd1498Szrj        *  if possible.  Other chars remain untouched.
81038fd1498Szrj        *
81138fd1498Szrj        *  toupper() acts as if it returns ctype<char>:: do_toupper(__lo, __hi).
81238fd1498Szrj        *  do_toupper() must always return the same result for the same input.
81338fd1498Szrj        *
81438fd1498Szrj        *  @param __lo  Pointer to first char in range.
81538fd1498Szrj        *  @param __hi  Pointer to end of range.
81638fd1498Szrj        *  @return  @a __hi.
81738fd1498Szrj       */
81838fd1498Szrj       const char_type*
81938fd1498Szrj       toupper(char_type *__lo, const char_type* __hi) const
82038fd1498Szrj       { return this->do_toupper(__lo, __hi); }
82138fd1498Szrj 
82238fd1498Szrj       /**
82338fd1498Szrj        *  @brief  Convert to lowercase.
82438fd1498Szrj        *
82538fd1498Szrj        *  This function converts the char argument to lowercase if possible.
82638fd1498Szrj        *  If not possible (for example, '2'), returns the argument.
82738fd1498Szrj        *
82838fd1498Szrj        *  tolower() acts as if it returns ctype<char>::do_tolower(__c).
82938fd1498Szrj        *  do_tolower() must always return the same result for the same input.
83038fd1498Szrj        *
83138fd1498Szrj        *  @param __c  The char to convert.
83238fd1498Szrj        *  @return  The lowercase char if convertible, else @a __c.
83338fd1498Szrj       */
83438fd1498Szrj       char_type
83538fd1498Szrj       tolower(char_type __c) const
83638fd1498Szrj       { return this->do_tolower(__c); }
83738fd1498Szrj 
83838fd1498Szrj       /**
83938fd1498Szrj        *  @brief  Convert array to lowercase.
84038fd1498Szrj        *
84138fd1498Szrj        *  This function converts each char in the range [lo,hi) to lowercase
84238fd1498Szrj        *  if possible.  Other chars remain untouched.
84338fd1498Szrj        *
84438fd1498Szrj        *  tolower() acts as if it returns ctype<char>:: do_tolower(__lo, __hi).
84538fd1498Szrj        *  do_tolower() must always return the same result for the same input.
84638fd1498Szrj        *
84738fd1498Szrj        *  @param __lo  Pointer to first char in range.
84838fd1498Szrj        *  @param __hi  Pointer to end of range.
84938fd1498Szrj        *  @return  @a __hi.
85038fd1498Szrj       */
85138fd1498Szrj       const char_type*
85238fd1498Szrj       tolower(char_type* __lo, const char_type* __hi) const
85338fd1498Szrj       { return this->do_tolower(__lo, __hi); }
85438fd1498Szrj 
85538fd1498Szrj       /**
85638fd1498Szrj        *  @brief  Widen char
85738fd1498Szrj        *
85838fd1498Szrj        *  This function converts the char to char_type using the simplest
85938fd1498Szrj        *  reasonable transformation.  For an underived ctype<char> facet, the
86038fd1498Szrj        *  argument will be returned unchanged.
86138fd1498Szrj        *
86238fd1498Szrj        *  This function works as if it returns ctype<char>::do_widen(c).
86338fd1498Szrj        *  do_widen() must always return the same result for the same input.
86438fd1498Szrj        *
86538fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
86638fd1498Szrj        *  codecvt for that.
86738fd1498Szrj        *
86838fd1498Szrj        *  @param __c  The char to convert.
86938fd1498Szrj        *  @return  The converted character.
87038fd1498Szrj       */
87138fd1498Szrj       char_type
87238fd1498Szrj       widen(char __c) const
87338fd1498Szrj       {
87438fd1498Szrj 	if (_M_widen_ok)
87538fd1498Szrj 	  return _M_widen[static_cast<unsigned char>(__c)];
87638fd1498Szrj 	this->_M_widen_init();
87738fd1498Szrj 	return this->do_widen(__c);
87838fd1498Szrj       }
87938fd1498Szrj 
88038fd1498Szrj       /**
88138fd1498Szrj        *  @brief  Widen char array
88238fd1498Szrj        *
88338fd1498Szrj        *  This function converts each char in the input to char using the
88438fd1498Szrj        *  simplest reasonable transformation.  For an underived ctype<char>
88538fd1498Szrj        *  facet, the argument will be copied unchanged.
88638fd1498Szrj        *
88738fd1498Szrj        *  This function works as if it returns ctype<char>::do_widen(c).
88838fd1498Szrj        *  do_widen() must always return the same result for the same input.
88938fd1498Szrj        *
89038fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
89138fd1498Szrj        *  codecvt for that.
89238fd1498Szrj        *
89338fd1498Szrj        *  @param __lo  Pointer to first char in range.
89438fd1498Szrj        *  @param __hi  Pointer to end of range.
89538fd1498Szrj        *  @param __to  Pointer to the destination array.
89638fd1498Szrj        *  @return  @a __hi.
89738fd1498Szrj       */
89838fd1498Szrj       const char*
89938fd1498Szrj       widen(const char* __lo, const char* __hi, char_type* __to) const
90038fd1498Szrj       {
90138fd1498Szrj 	if (_M_widen_ok == 1)
90238fd1498Szrj 	  {
903*58e805e6Szrj 	    if (__builtin_expect(__hi != __lo, true))
90438fd1498Szrj 	      __builtin_memcpy(__to, __lo, __hi - __lo);
90538fd1498Szrj 	    return __hi;
90638fd1498Szrj 	  }
90738fd1498Szrj 	if (!_M_widen_ok)
90838fd1498Szrj 	  _M_widen_init();
90938fd1498Szrj 	return this->do_widen(__lo, __hi, __to);
91038fd1498Szrj       }
91138fd1498Szrj 
91238fd1498Szrj       /**
91338fd1498Szrj        *  @brief  Narrow char
91438fd1498Szrj        *
91538fd1498Szrj        *  This function converts the char to char using the simplest
91638fd1498Szrj        *  reasonable transformation.  If the conversion fails, dfault is
91738fd1498Szrj        *  returned instead.  For an underived ctype<char> facet, @a c
91838fd1498Szrj        *  will be returned unchanged.
91938fd1498Szrj        *
92038fd1498Szrj        *  This function works as if it returns ctype<char>::do_narrow(c).
92138fd1498Szrj        *  do_narrow() must always return the same result for the same input.
92238fd1498Szrj        *
92338fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
92438fd1498Szrj        *  codecvt for that.
92538fd1498Szrj        *
92638fd1498Szrj        *  @param __c  The char to convert.
92738fd1498Szrj        *  @param __dfault  Char to return if conversion fails.
92838fd1498Szrj        *  @return  The converted character.
92938fd1498Szrj       */
93038fd1498Szrj       char
93138fd1498Szrj       narrow(char_type __c, char __dfault) const
93238fd1498Szrj       {
93338fd1498Szrj 	if (_M_narrow[static_cast<unsigned char>(__c)])
93438fd1498Szrj 	  return _M_narrow[static_cast<unsigned char>(__c)];
93538fd1498Szrj 	const char __t = do_narrow(__c, __dfault);
93638fd1498Szrj 	if (__t != __dfault)
93738fd1498Szrj 	  _M_narrow[static_cast<unsigned char>(__c)] = __t;
93838fd1498Szrj 	return __t;
93938fd1498Szrj       }
94038fd1498Szrj 
94138fd1498Szrj       /**
94238fd1498Szrj        *  @brief  Narrow char array
94338fd1498Szrj        *
94438fd1498Szrj        *  This function converts each char in the input to char using the
94538fd1498Szrj        *  simplest reasonable transformation and writes the results to the
94638fd1498Szrj        *  destination array.  For any char in the input that cannot be
94738fd1498Szrj        *  converted, @a dfault is used instead.  For an underived ctype<char>
94838fd1498Szrj        *  facet, the argument will be copied unchanged.
94938fd1498Szrj        *
95038fd1498Szrj        *  This function works as if it returns ctype<char>::do_narrow(lo, hi,
95138fd1498Szrj        *  dfault, to).  do_narrow() must always return the same result for the
95238fd1498Szrj        *  same input.
95338fd1498Szrj        *
95438fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
95538fd1498Szrj        *  codecvt for that.
95638fd1498Szrj        *
95738fd1498Szrj        *  @param __lo  Pointer to start of range.
95838fd1498Szrj        *  @param __hi  Pointer to end of range.
95938fd1498Szrj        *  @param __dfault  Char to use if conversion fails.
96038fd1498Szrj        *  @param __to  Pointer to the destination array.
96138fd1498Szrj        *  @return  @a __hi.
96238fd1498Szrj       */
96338fd1498Szrj       const char_type*
96438fd1498Szrj       narrow(const char_type* __lo, const char_type* __hi,
96538fd1498Szrj 	     char __dfault, char* __to) const
96638fd1498Szrj       {
96738fd1498Szrj 	if (__builtin_expect(_M_narrow_ok == 1, true))
96838fd1498Szrj 	  {
969*58e805e6Szrj 	    if (__builtin_expect(__hi != __lo, true))
97038fd1498Szrj 	      __builtin_memcpy(__to, __lo, __hi - __lo);
97138fd1498Szrj 	    return __hi;
97238fd1498Szrj 	  }
97338fd1498Szrj 	if (!_M_narrow_ok)
97438fd1498Szrj 	  _M_narrow_init();
97538fd1498Szrj 	return this->do_narrow(__lo, __hi, __dfault, __to);
97638fd1498Szrj       }
97738fd1498Szrj 
97838fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
97938fd1498Szrj       // DR 695. ctype<char>::classic_table() not accessible.
98038fd1498Szrj       /// Returns a pointer to the mask table provided to the constructor, or
98138fd1498Szrj       /// the default from classic_table() if none was provided.
98238fd1498Szrj       const mask*
98338fd1498Szrj       table() const throw()
98438fd1498Szrj       { return _M_table; }
98538fd1498Szrj 
98638fd1498Szrj       /// Returns a pointer to the C locale mask table.
98738fd1498Szrj       static const mask*
98838fd1498Szrj       classic_table() throw();
98938fd1498Szrj     protected:
99038fd1498Szrj 
99138fd1498Szrj       /**
99238fd1498Szrj        *  @brief  Destructor.
99338fd1498Szrj        *
99438fd1498Szrj        *  This function deletes table() if @a del was true in the
99538fd1498Szrj        *  constructor.
99638fd1498Szrj       */
99738fd1498Szrj       virtual
99838fd1498Szrj       ~ctype();
99938fd1498Szrj 
100038fd1498Szrj       /**
100138fd1498Szrj        *  @brief  Convert to uppercase.
100238fd1498Szrj        *
100338fd1498Szrj        *  This virtual function converts the char argument to uppercase if
100438fd1498Szrj        *  possible.  If not possible (for example, '2'), returns the argument.
100538fd1498Szrj        *
100638fd1498Szrj        *  do_toupper() is a hook for a derived facet to change the behavior of
100738fd1498Szrj        *  uppercasing.  do_toupper() must always return the same result for
100838fd1498Szrj        *  the same input.
100938fd1498Szrj        *
101038fd1498Szrj        *  @param __c  The char to convert.
101138fd1498Szrj        *  @return  The uppercase char if convertible, else @a __c.
101238fd1498Szrj       */
101338fd1498Szrj       virtual char_type
101438fd1498Szrj       do_toupper(char_type __c) const;
101538fd1498Szrj 
101638fd1498Szrj       /**
101738fd1498Szrj        *  @brief  Convert array to uppercase.
101838fd1498Szrj        *
101938fd1498Szrj        *  This virtual function converts each char in the range [lo,hi) to
102038fd1498Szrj        *  uppercase if possible.  Other chars remain untouched.
102138fd1498Szrj        *
102238fd1498Szrj        *  do_toupper() is a hook for a derived facet to change the behavior of
102338fd1498Szrj        *  uppercasing.  do_toupper() must always return the same result for
102438fd1498Szrj        *  the same input.
102538fd1498Szrj        *
102638fd1498Szrj        *  @param __lo  Pointer to start of range.
102738fd1498Szrj        *  @param __hi  Pointer to end of range.
102838fd1498Szrj        *  @return  @a __hi.
102938fd1498Szrj       */
103038fd1498Szrj       virtual const char_type*
103138fd1498Szrj       do_toupper(char_type* __lo, const char_type* __hi) const;
103238fd1498Szrj 
103338fd1498Szrj       /**
103438fd1498Szrj        *  @brief  Convert to lowercase.
103538fd1498Szrj        *
103638fd1498Szrj        *  This virtual function converts the char argument to lowercase if
103738fd1498Szrj        *  possible.  If not possible (for example, '2'), returns the argument.
103838fd1498Szrj        *
103938fd1498Szrj        *  do_tolower() is a hook for a derived facet to change the behavior of
104038fd1498Szrj        *  lowercasing.  do_tolower() must always return the same result for
104138fd1498Szrj        *  the same input.
104238fd1498Szrj        *
104338fd1498Szrj        *  @param __c  The char to convert.
104438fd1498Szrj        *  @return  The lowercase char if convertible, else @a __c.
104538fd1498Szrj       */
104638fd1498Szrj       virtual char_type
104738fd1498Szrj       do_tolower(char_type __c) const;
104838fd1498Szrj 
104938fd1498Szrj       /**
105038fd1498Szrj        *  @brief  Convert array to lowercase.
105138fd1498Szrj        *
105238fd1498Szrj        *  This virtual function converts each char in the range [lo,hi) to
105338fd1498Szrj        *  lowercase if possible.  Other chars remain untouched.
105438fd1498Szrj        *
105538fd1498Szrj        *  do_tolower() is a hook for a derived facet to change the behavior of
105638fd1498Szrj        *  lowercasing.  do_tolower() must always return the same result for
105738fd1498Szrj        *  the same input.
105838fd1498Szrj        *
105938fd1498Szrj        *  @param __lo  Pointer to first char in range.
106038fd1498Szrj        *  @param __hi  Pointer to end of range.
106138fd1498Szrj        *  @return  @a __hi.
106238fd1498Szrj       */
106338fd1498Szrj       virtual const char_type*
106438fd1498Szrj       do_tolower(char_type* __lo, const char_type* __hi) const;
106538fd1498Szrj 
106638fd1498Szrj       /**
106738fd1498Szrj        *  @brief  Widen char
106838fd1498Szrj        *
106938fd1498Szrj        *  This virtual function converts the char to char using the simplest
107038fd1498Szrj        *  reasonable transformation.  For an underived ctype<char> facet, the
107138fd1498Szrj        *  argument will be returned unchanged.
107238fd1498Szrj        *
107338fd1498Szrj        *  do_widen() is a hook for a derived facet to change the behavior of
107438fd1498Szrj        *  widening.  do_widen() must always return the same result for the
107538fd1498Szrj        *  same input.
107638fd1498Szrj        *
107738fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
107838fd1498Szrj        *  codecvt for that.
107938fd1498Szrj        *
108038fd1498Szrj        *  @param __c  The char to convert.
108138fd1498Szrj        *  @return  The converted character.
108238fd1498Szrj       */
108338fd1498Szrj       virtual char_type
108438fd1498Szrj       do_widen(char __c) const
108538fd1498Szrj       { return __c; }
108638fd1498Szrj 
108738fd1498Szrj       /**
108838fd1498Szrj        *  @brief  Widen char array
108938fd1498Szrj        *
109038fd1498Szrj        *  This function converts each char in the range [lo,hi) to char using
109138fd1498Szrj        *  the simplest reasonable transformation.  For an underived
109238fd1498Szrj        *  ctype<char> facet, the argument will be copied unchanged.
109338fd1498Szrj        *
109438fd1498Szrj        *  do_widen() is a hook for a derived facet to change the behavior of
109538fd1498Szrj        *  widening.  do_widen() must always return the same result for the
109638fd1498Szrj        *  same input.
109738fd1498Szrj        *
109838fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
109938fd1498Szrj        *  codecvt for that.
110038fd1498Szrj        *
110138fd1498Szrj        *  @param __lo  Pointer to start of range.
110238fd1498Szrj        *  @param __hi  Pointer to end of range.
110338fd1498Szrj        *  @param __to  Pointer to the destination array.
110438fd1498Szrj        *  @return  @a __hi.
110538fd1498Szrj       */
110638fd1498Szrj       virtual const char*
110738fd1498Szrj       do_widen(const char* __lo, const char* __hi, char_type* __to) const
110838fd1498Szrj       {
1109*58e805e6Szrj 	if (__builtin_expect(__hi != __lo, true))
111038fd1498Szrj 	  __builtin_memcpy(__to, __lo, __hi - __lo);
111138fd1498Szrj 	return __hi;
111238fd1498Szrj       }
111338fd1498Szrj 
111438fd1498Szrj       /**
111538fd1498Szrj        *  @brief  Narrow char
111638fd1498Szrj        *
111738fd1498Szrj        *  This virtual function converts the char to char using the simplest
111838fd1498Szrj        *  reasonable transformation.  If the conversion fails, dfault is
111938fd1498Szrj        *  returned instead.  For an underived ctype<char> facet, @a c will be
112038fd1498Szrj        *  returned unchanged.
112138fd1498Szrj        *
112238fd1498Szrj        *  do_narrow() is a hook for a derived facet to change the behavior of
112338fd1498Szrj        *  narrowing.  do_narrow() must always return the same result for the
112438fd1498Szrj        *  same input.
112538fd1498Szrj        *
112638fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
112738fd1498Szrj        *  codecvt for that.
112838fd1498Szrj        *
112938fd1498Szrj        *  @param __c  The char to convert.
113038fd1498Szrj        *  @param __dfault  Char to return if conversion fails.
113138fd1498Szrj        *  @return  The converted char.
113238fd1498Szrj       */
113338fd1498Szrj       virtual char
113438fd1498Szrj       do_narrow(char_type __c, char __dfault __attribute__((__unused__))) const
113538fd1498Szrj       { return __c; }
113638fd1498Szrj 
113738fd1498Szrj       /**
113838fd1498Szrj        *  @brief  Narrow char array to char array
113938fd1498Szrj        *
114038fd1498Szrj        *  This virtual function converts each char in the range [lo,hi) to
114138fd1498Szrj        *  char using the simplest reasonable transformation and writes the
114238fd1498Szrj        *  results to the destination array.  For any char in the input that
114338fd1498Szrj        *  cannot be converted, @a dfault is used instead.  For an underived
114438fd1498Szrj        *  ctype<char> facet, the argument will be copied unchanged.
114538fd1498Szrj        *
114638fd1498Szrj        *  do_narrow() is a hook for a derived facet to change the behavior of
114738fd1498Szrj        *  narrowing.  do_narrow() must always return the same result for the
114838fd1498Szrj        *  same input.
114938fd1498Szrj        *
115038fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
115138fd1498Szrj        *  codecvt for that.
115238fd1498Szrj        *
115338fd1498Szrj        *  @param __lo  Pointer to start of range.
115438fd1498Szrj        *  @param __hi  Pointer to end of range.
115538fd1498Szrj        *  @param __dfault  Char to use if conversion fails.
115638fd1498Szrj        *  @param __to  Pointer to the destination array.
115738fd1498Szrj        *  @return  @a __hi.
115838fd1498Szrj       */
115938fd1498Szrj       virtual const char_type*
116038fd1498Szrj       do_narrow(const char_type* __lo, const char_type* __hi,
116138fd1498Szrj 		char __dfault __attribute__((__unused__)), char* __to) const
116238fd1498Szrj       {
1163*58e805e6Szrj 	if (__builtin_expect(__hi != __lo, true))
116438fd1498Szrj 	  __builtin_memcpy(__to, __lo, __hi - __lo);
116538fd1498Szrj 	return __hi;
116638fd1498Szrj       }
116738fd1498Szrj 
116838fd1498Szrj     private:
116938fd1498Szrj       void _M_narrow_init() const;
117038fd1498Szrj       void _M_widen_init() const;
117138fd1498Szrj     };
117238fd1498Szrj 
117338fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T
117438fd1498Szrj   /**
117538fd1498Szrj    *  @brief  The ctype<wchar_t> specialization.
117638fd1498Szrj    *  @ingroup locales
117738fd1498Szrj    *
117838fd1498Szrj    *  This class defines classification and conversion functions for the
117938fd1498Szrj    *  wchar_t type.  It gets used by wchar_t streams for many I/O operations.
118038fd1498Szrj    *  The wchar_t specialization provides a number of optimizations as well.
118138fd1498Szrj    *
118238fd1498Szrj    *  ctype<wchar_t> inherits its public methods from
118338fd1498Szrj    *  __ctype_abstract_base<wchar_t>.
118438fd1498Szrj   */
118538fd1498Szrj   template<>
118638fd1498Szrj     class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
118738fd1498Szrj     {
118838fd1498Szrj     public:
118938fd1498Szrj       // Types:
119038fd1498Szrj       /// Typedef for the template parameter wchar_t.
119138fd1498Szrj       typedef wchar_t		char_type;
119238fd1498Szrj       typedef wctype_t		__wmask_type;
119338fd1498Szrj 
119438fd1498Szrj     protected:
119538fd1498Szrj       __c_locale		_M_c_locale_ctype;
119638fd1498Szrj 
119738fd1498Szrj       // Pre-computed narrowed and widened chars.
119838fd1498Szrj       bool                      _M_narrow_ok;
119938fd1498Szrj       char                      _M_narrow[128];
120038fd1498Szrj       wint_t                    _M_widen[1 + static_cast<unsigned char>(-1)];
120138fd1498Szrj 
120238fd1498Szrj       // Pre-computed elements for do_is.
120338fd1498Szrj       mask                      _M_bit[16];
120438fd1498Szrj       __wmask_type              _M_wmask[16];
120538fd1498Szrj 
120638fd1498Szrj     public:
120738fd1498Szrj       // Data Members:
120838fd1498Szrj       /// The facet id for ctype<wchar_t>
120938fd1498Szrj       static locale::id		id;
121038fd1498Szrj 
121138fd1498Szrj       /**
121238fd1498Szrj        *  @brief  Constructor performs initialization.
121338fd1498Szrj        *
121438fd1498Szrj        *  This is the constructor provided by the standard.
121538fd1498Szrj        *
121638fd1498Szrj        *  @param __refs  Passed to the base facet class.
121738fd1498Szrj       */
121838fd1498Szrj       explicit
121938fd1498Szrj       ctype(size_t __refs = 0);
122038fd1498Szrj 
122138fd1498Szrj       /**
122238fd1498Szrj        *  @brief  Constructor performs static initialization.
122338fd1498Szrj        *
122438fd1498Szrj        *  This constructor is used to construct the initial C locale facet.
122538fd1498Szrj        *
122638fd1498Szrj        *  @param __cloc  Handle to C locale data.
122738fd1498Szrj        *  @param __refs  Passed to the base facet class.
122838fd1498Szrj       */
122938fd1498Szrj       explicit
123038fd1498Szrj       ctype(__c_locale __cloc, size_t __refs = 0);
123138fd1498Szrj 
123238fd1498Szrj     protected:
123338fd1498Szrj       __wmask_type
123438fd1498Szrj       _M_convert_to_wmask(const mask __m) const throw();
123538fd1498Szrj 
123638fd1498Szrj       /// Destructor
123738fd1498Szrj       virtual
123838fd1498Szrj       ~ctype();
123938fd1498Szrj 
124038fd1498Szrj       /**
124138fd1498Szrj        *  @brief  Test wchar_t classification.
124238fd1498Szrj        *
124338fd1498Szrj        *  This function finds a mask M for @a c and compares it to mask @a m.
124438fd1498Szrj        *
124538fd1498Szrj        *  do_is() is a hook for a derived facet to change the behavior of
124638fd1498Szrj        *  classifying.  do_is() must always return the same result for the
124738fd1498Szrj        *  same input.
124838fd1498Szrj        *
124938fd1498Szrj        *  @param __c  The wchar_t to find the mask of.
125038fd1498Szrj        *  @param __m  The mask to compare against.
125138fd1498Szrj        *  @return  (M & __m) != 0.
125238fd1498Szrj       */
125338fd1498Szrj       virtual bool
125438fd1498Szrj       do_is(mask __m, char_type __c) const;
125538fd1498Szrj 
125638fd1498Szrj       /**
125738fd1498Szrj        *  @brief  Return a mask array.
125838fd1498Szrj        *
125938fd1498Szrj        *  This function finds the mask for each wchar_t in the range [lo,hi)
126038fd1498Szrj        *  and successively writes it to vec.  vec must have as many elements
126138fd1498Szrj        *  as the input.
126238fd1498Szrj        *
126338fd1498Szrj        *  do_is() is a hook for a derived facet to change the behavior of
126438fd1498Szrj        *  classifying.  do_is() must always return the same result for the
126538fd1498Szrj        *  same input.
126638fd1498Szrj        *
126738fd1498Szrj        *  @param __lo  Pointer to start of range.
126838fd1498Szrj        *  @param __hi  Pointer to end of range.
126938fd1498Szrj        *  @param __vec  Pointer to an array of mask storage.
127038fd1498Szrj        *  @return  @a __hi.
127138fd1498Szrj       */
127238fd1498Szrj       virtual const char_type*
127338fd1498Szrj       do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
127438fd1498Szrj 
127538fd1498Szrj       /**
127638fd1498Szrj        *  @brief  Find wchar_t matching mask
127738fd1498Szrj        *
127838fd1498Szrj        *  This function searches for and returns the first wchar_t c in
127938fd1498Szrj        *  [__lo,__hi) for which is(__m,c) is true.
128038fd1498Szrj        *
128138fd1498Szrj        *  do_scan_is() is a hook for a derived facet to change the behavior of
128238fd1498Szrj        *  match searching.  do_is() must always return the same result for the
128338fd1498Szrj        *  same input.
128438fd1498Szrj        *
128538fd1498Szrj        *  @param __m  The mask to compare against.
128638fd1498Szrj        *  @param __lo  Pointer to start of range.
128738fd1498Szrj        *  @param __hi  Pointer to end of range.
128838fd1498Szrj        *  @return  Pointer to a matching wchar_t if found, else @a __hi.
128938fd1498Szrj       */
129038fd1498Szrj       virtual const char_type*
129138fd1498Szrj       do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
129238fd1498Szrj 
129338fd1498Szrj       /**
129438fd1498Szrj        *  @brief  Find wchar_t not matching mask
129538fd1498Szrj        *
129638fd1498Szrj        *  This function searches for and returns a pointer to the first
129738fd1498Szrj        *  wchar_t c of [__lo,__hi) for which is(__m,c) is false.
129838fd1498Szrj        *
129938fd1498Szrj        *  do_scan_is() is a hook for a derived facet to change the behavior of
130038fd1498Szrj        *  match searching.  do_is() must always return the same result for the
130138fd1498Szrj        *  same input.
130238fd1498Szrj        *
130338fd1498Szrj        *  @param __m  The mask to compare against.
130438fd1498Szrj        *  @param __lo  Pointer to start of range.
130538fd1498Szrj        *  @param __hi  Pointer to end of range.
130638fd1498Szrj        *  @return  Pointer to a non-matching wchar_t if found, else @a __hi.
130738fd1498Szrj       */
130838fd1498Szrj       virtual const char_type*
130938fd1498Szrj       do_scan_not(mask __m, const char_type* __lo,
131038fd1498Szrj 		  const char_type* __hi) const;
131138fd1498Szrj 
131238fd1498Szrj       /**
131338fd1498Szrj        *  @brief  Convert to uppercase.
131438fd1498Szrj        *
131538fd1498Szrj        *  This virtual function converts the wchar_t argument to uppercase if
131638fd1498Szrj        *  possible.  If not possible (for example, '2'), returns the argument.
131738fd1498Szrj        *
131838fd1498Szrj        *  do_toupper() is a hook for a derived facet to change the behavior of
131938fd1498Szrj        *  uppercasing.  do_toupper() must always return the same result for
132038fd1498Szrj        *  the same input.
132138fd1498Szrj        *
132238fd1498Szrj        *  @param __c  The wchar_t to convert.
132338fd1498Szrj        *  @return  The uppercase wchar_t if convertible, else @a __c.
132438fd1498Szrj       */
132538fd1498Szrj       virtual char_type
132638fd1498Szrj       do_toupper(char_type __c) const;
132738fd1498Szrj 
132838fd1498Szrj       /**
132938fd1498Szrj        *  @brief  Convert array to uppercase.
133038fd1498Szrj        *
133138fd1498Szrj        *  This virtual function converts each wchar_t in the range [lo,hi) to
133238fd1498Szrj        *  uppercase if possible.  Other elements remain untouched.
133338fd1498Szrj        *
133438fd1498Szrj        *  do_toupper() is a hook for a derived facet to change the behavior of
133538fd1498Szrj        *  uppercasing.  do_toupper() must always return the same result for
133638fd1498Szrj        *  the same input.
133738fd1498Szrj        *
133838fd1498Szrj        *  @param __lo  Pointer to start of range.
133938fd1498Szrj        *  @param __hi  Pointer to end of range.
134038fd1498Szrj        *  @return  @a __hi.
134138fd1498Szrj       */
134238fd1498Szrj       virtual const char_type*
134338fd1498Szrj       do_toupper(char_type* __lo, const char_type* __hi) const;
134438fd1498Szrj 
134538fd1498Szrj       /**
134638fd1498Szrj        *  @brief  Convert to lowercase.
134738fd1498Szrj        *
134838fd1498Szrj        *  This virtual function converts the argument to lowercase if
134938fd1498Szrj        *  possible.  If not possible (for example, '2'), returns the argument.
135038fd1498Szrj        *
135138fd1498Szrj        *  do_tolower() is a hook for a derived facet to change the behavior of
135238fd1498Szrj        *  lowercasing.  do_tolower() must always return the same result for
135338fd1498Szrj        *  the same input.
135438fd1498Szrj        *
135538fd1498Szrj        *  @param __c  The wchar_t to convert.
135638fd1498Szrj        *  @return  The lowercase wchar_t if convertible, else @a __c.
135738fd1498Szrj       */
135838fd1498Szrj       virtual char_type
135938fd1498Szrj       do_tolower(char_type __c) const;
136038fd1498Szrj 
136138fd1498Szrj       /**
136238fd1498Szrj        *  @brief  Convert array to lowercase.
136338fd1498Szrj        *
136438fd1498Szrj        *  This virtual function converts each wchar_t in the range [lo,hi) to
136538fd1498Szrj        *  lowercase if possible.  Other elements remain untouched.
136638fd1498Szrj        *
136738fd1498Szrj        *  do_tolower() is a hook for a derived facet to change the behavior of
136838fd1498Szrj        *  lowercasing.  do_tolower() must always return the same result for
136938fd1498Szrj        *  the same input.
137038fd1498Szrj        *
137138fd1498Szrj        *  @param __lo  Pointer to start of range.
137238fd1498Szrj        *  @param __hi  Pointer to end of range.
137338fd1498Szrj        *  @return  @a __hi.
137438fd1498Szrj       */
137538fd1498Szrj       virtual const char_type*
137638fd1498Szrj       do_tolower(char_type* __lo, const char_type* __hi) const;
137738fd1498Szrj 
137838fd1498Szrj       /**
137938fd1498Szrj        *  @brief  Widen char to wchar_t
138038fd1498Szrj        *
138138fd1498Szrj        *  This virtual function converts the char to wchar_t using the
138238fd1498Szrj        *  simplest reasonable transformation.  For an underived ctype<wchar_t>
138338fd1498Szrj        *  facet, the argument will be cast to wchar_t.
138438fd1498Szrj        *
138538fd1498Szrj        *  do_widen() is a hook for a derived facet to change the behavior of
138638fd1498Szrj        *  widening.  do_widen() must always return the same result for the
138738fd1498Szrj        *  same input.
138838fd1498Szrj        *
138938fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
139038fd1498Szrj        *  codecvt for that.
139138fd1498Szrj        *
139238fd1498Szrj        *  @param __c  The char to convert.
139338fd1498Szrj        *  @return  The converted wchar_t.
139438fd1498Szrj       */
139538fd1498Szrj       virtual char_type
139638fd1498Szrj       do_widen(char __c) const;
139738fd1498Szrj 
139838fd1498Szrj       /**
139938fd1498Szrj        *  @brief  Widen char array to wchar_t array
140038fd1498Szrj        *
140138fd1498Szrj        *  This function converts each char in the input to wchar_t using the
140238fd1498Szrj        *  simplest reasonable transformation.  For an underived ctype<wchar_t>
140338fd1498Szrj        *  facet, the argument will be copied, casting each element to wchar_t.
140438fd1498Szrj        *
140538fd1498Szrj        *  do_widen() is a hook for a derived facet to change the behavior of
140638fd1498Szrj        *  widening.  do_widen() must always return the same result for the
140738fd1498Szrj        *  same input.
140838fd1498Szrj        *
140938fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
141038fd1498Szrj        *  codecvt for that.
141138fd1498Szrj        *
141238fd1498Szrj        *  @param __lo  Pointer to start range.
141338fd1498Szrj        *  @param __hi  Pointer to end of range.
141438fd1498Szrj        *  @param __to  Pointer to the destination array.
141538fd1498Szrj        *  @return  @a __hi.
141638fd1498Szrj       */
141738fd1498Szrj       virtual const char*
141838fd1498Szrj       do_widen(const char* __lo, const char* __hi, char_type* __to) const;
141938fd1498Szrj 
142038fd1498Szrj       /**
142138fd1498Szrj        *  @brief  Narrow wchar_t to char
142238fd1498Szrj        *
142338fd1498Szrj        *  This virtual function converts the argument to char using
142438fd1498Szrj        *  the simplest reasonable transformation.  If the conversion
142538fd1498Szrj        *  fails, dfault is returned instead.  For an underived
142638fd1498Szrj        *  ctype<wchar_t> facet, @a c will be cast to char and
142738fd1498Szrj        *  returned.
142838fd1498Szrj        *
142938fd1498Szrj        *  do_narrow() is a hook for a derived facet to change the
143038fd1498Szrj        *  behavior of narrowing.  do_narrow() must always return the
143138fd1498Szrj        *  same result for the same input.
143238fd1498Szrj        *
143338fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
143438fd1498Szrj        *  codecvt for that.
143538fd1498Szrj        *
143638fd1498Szrj        *  @param __c  The wchar_t to convert.
143738fd1498Szrj        *  @param __dfault  Char to return if conversion fails.
143838fd1498Szrj        *  @return  The converted char.
143938fd1498Szrj       */
144038fd1498Szrj       virtual char
144138fd1498Szrj       do_narrow(char_type __c, char __dfault) const;
144238fd1498Szrj 
144338fd1498Szrj       /**
144438fd1498Szrj        *  @brief  Narrow wchar_t array to char array
144538fd1498Szrj        *
144638fd1498Szrj        *  This virtual function converts each wchar_t in the range [lo,hi) to
144738fd1498Szrj        *  char using the simplest reasonable transformation and writes the
144838fd1498Szrj        *  results to the destination array.  For any wchar_t in the input that
144938fd1498Szrj        *  cannot be converted, @a dfault is used instead.  For an underived
145038fd1498Szrj        *  ctype<wchar_t> facet, the argument will be copied, casting each
145138fd1498Szrj        *  element to char.
145238fd1498Szrj        *
145338fd1498Szrj        *  do_narrow() is a hook for a derived facet to change the behavior of
145438fd1498Szrj        *  narrowing.  do_narrow() must always return the same result for the
145538fd1498Szrj        *  same input.
145638fd1498Szrj        *
145738fd1498Szrj        *  Note: this is not what you want for codepage conversions.  See
145838fd1498Szrj        *  codecvt for that.
145938fd1498Szrj        *
146038fd1498Szrj        *  @param __lo  Pointer to start of range.
146138fd1498Szrj        *  @param __hi  Pointer to end of range.
146238fd1498Szrj        *  @param __dfault  Char to use if conversion fails.
146338fd1498Szrj        *  @param __to  Pointer to the destination array.
146438fd1498Szrj        *  @return  @a __hi.
146538fd1498Szrj       */
146638fd1498Szrj       virtual const char_type*
146738fd1498Szrj       do_narrow(const char_type* __lo, const char_type* __hi,
146838fd1498Szrj 		char __dfault, char* __to) const;
146938fd1498Szrj 
147038fd1498Szrj       // For use at construction time only.
147138fd1498Szrj       void
147238fd1498Szrj       _M_initialize_ctype() throw();
147338fd1498Szrj     };
147438fd1498Szrj #endif //_GLIBCXX_USE_WCHAR_T
147538fd1498Szrj 
147638fd1498Szrj   /// class ctype_byname [22.2.1.2].
147738fd1498Szrj   template<typename _CharT>
147838fd1498Szrj     class ctype_byname : public ctype<_CharT>
147938fd1498Szrj     {
148038fd1498Szrj     public:
148138fd1498Szrj       typedef typename ctype<_CharT>::mask  mask;
148238fd1498Szrj 
148338fd1498Szrj       explicit
148438fd1498Szrj       ctype_byname(const char* __s, size_t __refs = 0);
148538fd1498Szrj 
148638fd1498Szrj #if __cplusplus >= 201103L
148738fd1498Szrj       explicit
148838fd1498Szrj       ctype_byname(const string& __s, size_t __refs = 0)
148938fd1498Szrj       : ctype_byname(__s.c_str(), __refs) { }
149038fd1498Szrj #endif
149138fd1498Szrj 
149238fd1498Szrj     protected:
149338fd1498Szrj       virtual
149438fd1498Szrj       ~ctype_byname() { }
149538fd1498Szrj     };
149638fd1498Szrj 
149738fd1498Szrj   /// 22.2.1.4  Class ctype_byname specializations.
149838fd1498Szrj   template<>
149938fd1498Szrj     class ctype_byname<char> : public ctype<char>
150038fd1498Szrj     {
150138fd1498Szrj     public:
150238fd1498Szrj       explicit
150338fd1498Szrj       ctype_byname(const char* __s, size_t __refs = 0);
150438fd1498Szrj 
150538fd1498Szrj #if __cplusplus >= 201103L
150638fd1498Szrj       explicit
150738fd1498Szrj       ctype_byname(const string& __s, size_t __refs = 0);
150838fd1498Szrj #endif
150938fd1498Szrj 
151038fd1498Szrj     protected:
151138fd1498Szrj       virtual
151238fd1498Szrj       ~ctype_byname();
151338fd1498Szrj     };
151438fd1498Szrj 
151538fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T
151638fd1498Szrj   template<>
151738fd1498Szrj     class ctype_byname<wchar_t> : public ctype<wchar_t>
151838fd1498Szrj     {
151938fd1498Szrj     public:
152038fd1498Szrj       explicit
152138fd1498Szrj       ctype_byname(const char* __s, size_t __refs = 0);
152238fd1498Szrj 
152338fd1498Szrj #if __cplusplus >= 201103L
152438fd1498Szrj       explicit
152538fd1498Szrj       ctype_byname(const string& __s, size_t __refs = 0);
152638fd1498Szrj #endif
152738fd1498Szrj 
152838fd1498Szrj     protected:
152938fd1498Szrj       virtual
153038fd1498Szrj       ~ctype_byname();
153138fd1498Szrj     };
153238fd1498Szrj #endif
153338fd1498Szrj 
153438fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
153538fd1498Szrj } // namespace
153638fd1498Szrj 
153738fd1498Szrj // Include host and configuration specific ctype inlines.
153838fd1498Szrj #include <bits/ctype_inline.h>
153938fd1498Szrj 
_GLIBCXX_VISIBILITY(default)154038fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
154138fd1498Szrj {
154238fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
154338fd1498Szrj 
154438fd1498Szrj   // 22.2.2  The numeric category.
154538fd1498Szrj   class __num_base
154638fd1498Szrj   {
154738fd1498Szrj   public:
154838fd1498Szrj     // NB: Code depends on the order of _S_atoms_out elements.
154938fd1498Szrj     // Below are the indices into _S_atoms_out.
155038fd1498Szrj     enum
155138fd1498Szrj       {
155238fd1498Szrj 	_S_ominus,
155338fd1498Szrj 	_S_oplus,
155438fd1498Szrj 	_S_ox,
155538fd1498Szrj 	_S_oX,
155638fd1498Szrj 	_S_odigits,
155738fd1498Szrj 	_S_odigits_end = _S_odigits + 16,
155838fd1498Szrj 	_S_oudigits = _S_odigits_end,
155938fd1498Szrj 	_S_oudigits_end = _S_oudigits + 16,
156038fd1498Szrj 	_S_oe = _S_odigits + 14,  // For scientific notation, 'e'
156138fd1498Szrj 	_S_oE = _S_oudigits + 14, // For scientific notation, 'E'
156238fd1498Szrj 	_S_oend = _S_oudigits_end
156338fd1498Szrj       };
156438fd1498Szrj 
156538fd1498Szrj     // A list of valid numeric literals for output.  This array
156638fd1498Szrj     // contains chars that will be passed through the current locale's
156738fd1498Szrj     // ctype<_CharT>.widen() and then used to render numbers.
156838fd1498Szrj     // For the standard "C" locale, this is
156938fd1498Szrj     // "-+xX0123456789abcdef0123456789ABCDEF".
157038fd1498Szrj     static const char* _S_atoms_out;
157138fd1498Szrj 
157238fd1498Szrj     // String literal of acceptable (narrow) input, for num_get.
157338fd1498Szrj     // "-+xX0123456789abcdefABCDEF"
157438fd1498Szrj     static const char* _S_atoms_in;
157538fd1498Szrj 
157638fd1498Szrj     enum
157738fd1498Szrj     {
157838fd1498Szrj       _S_iminus,
157938fd1498Szrj       _S_iplus,
158038fd1498Szrj       _S_ix,
158138fd1498Szrj       _S_iX,
158238fd1498Szrj       _S_izero,
158338fd1498Szrj       _S_ie = _S_izero + 14,
158438fd1498Szrj       _S_iE = _S_izero + 20,
158538fd1498Szrj       _S_iend = 26
158638fd1498Szrj     };
158738fd1498Szrj 
158838fd1498Szrj     // num_put
158938fd1498Szrj     // Construct and return valid scanf format for floating point types.
159038fd1498Szrj     static void
159138fd1498Szrj     _S_format_float(const ios_base& __io, char* __fptr, char __mod) throw();
159238fd1498Szrj   };
159338fd1498Szrj 
159438fd1498Szrj   template<typename _CharT>
159538fd1498Szrj     struct __numpunct_cache : public locale::facet
159638fd1498Szrj     {
159738fd1498Szrj       const char*			_M_grouping;
159838fd1498Szrj       size_t                            _M_grouping_size;
159938fd1498Szrj       bool				_M_use_grouping;
160038fd1498Szrj       const _CharT*			_M_truename;
160138fd1498Szrj       size_t                            _M_truename_size;
160238fd1498Szrj       const _CharT*			_M_falsename;
160338fd1498Szrj       size_t                            _M_falsename_size;
160438fd1498Szrj       _CharT				_M_decimal_point;
160538fd1498Szrj       _CharT				_M_thousands_sep;
160638fd1498Szrj 
160738fd1498Szrj       // A list of valid numeric literals for output: in the standard
160838fd1498Szrj       // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF".
160938fd1498Szrj       // This array contains the chars after having been passed
161038fd1498Szrj       // through the current locale's ctype<_CharT>.widen().
161138fd1498Szrj       _CharT				_M_atoms_out[__num_base::_S_oend];
161238fd1498Szrj 
161338fd1498Szrj       // A list of valid numeric literals for input: in the standard
161438fd1498Szrj       // "C" locale, this is "-+xX0123456789abcdefABCDEF"
161538fd1498Szrj       // This array contains the chars after having been passed
161638fd1498Szrj       // through the current locale's ctype<_CharT>.widen().
161738fd1498Szrj       _CharT				_M_atoms_in[__num_base::_S_iend];
161838fd1498Szrj 
161938fd1498Szrj       bool				_M_allocated;
162038fd1498Szrj 
162138fd1498Szrj       __numpunct_cache(size_t __refs = 0)
162238fd1498Szrj       : facet(__refs), _M_grouping(0), _M_grouping_size(0),
162338fd1498Szrj 	_M_use_grouping(false),
162438fd1498Szrj 	_M_truename(0), _M_truename_size(0), _M_falsename(0),
162538fd1498Szrj 	_M_falsename_size(0), _M_decimal_point(_CharT()),
162638fd1498Szrj 	_M_thousands_sep(_CharT()), _M_allocated(false)
162738fd1498Szrj 	{ }
162838fd1498Szrj 
162938fd1498Szrj       ~__numpunct_cache();
163038fd1498Szrj 
163138fd1498Szrj       void
163238fd1498Szrj       _M_cache(const locale& __loc);
163338fd1498Szrj 
163438fd1498Szrj     private:
163538fd1498Szrj       __numpunct_cache&
163638fd1498Szrj       operator=(const __numpunct_cache&);
163738fd1498Szrj 
163838fd1498Szrj       explicit
163938fd1498Szrj       __numpunct_cache(const __numpunct_cache&);
164038fd1498Szrj     };
164138fd1498Szrj 
164238fd1498Szrj   template<typename _CharT>
164338fd1498Szrj     __numpunct_cache<_CharT>::~__numpunct_cache()
164438fd1498Szrj     {
164538fd1498Szrj       if (_M_allocated)
164638fd1498Szrj 	{
164738fd1498Szrj 	  delete [] _M_grouping;
164838fd1498Szrj 	  delete [] _M_truename;
164938fd1498Szrj 	  delete [] _M_falsename;
165038fd1498Szrj 	}
165138fd1498Szrj     }
165238fd1498Szrj 
165338fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_CXX11
165438fd1498Szrj 
165538fd1498Szrj   /**
165638fd1498Szrj    *  @brief  Primary class template numpunct.
165738fd1498Szrj    *  @ingroup locales
165838fd1498Szrj    *
165938fd1498Szrj    *  This facet stores several pieces of information related to printing and
166038fd1498Szrj    *  scanning numbers, such as the decimal point character.  It takes a
166138fd1498Szrj    *  template parameter specifying the char type.  The numpunct facet is
166238fd1498Szrj    *  used by streams for many I/O operations involving numbers.
166338fd1498Szrj    *
166438fd1498Szrj    *  The numpunct template uses protected virtual functions to provide the
166538fd1498Szrj    *  actual results.  The public accessors forward the call to the virtual
166638fd1498Szrj    *  functions.  These virtual functions are hooks for developers to
166738fd1498Szrj    *  implement the behavior they require from a numpunct facet.
166838fd1498Szrj   */
166938fd1498Szrj   template<typename _CharT>
167038fd1498Szrj     class numpunct : public locale::facet
167138fd1498Szrj     {
167238fd1498Szrj     public:
167338fd1498Szrj       // Types:
167438fd1498Szrj       //@{
167538fd1498Szrj       /// Public typedefs
167638fd1498Szrj       typedef _CharT			char_type;
167738fd1498Szrj       typedef basic_string<_CharT>	string_type;
167838fd1498Szrj       //@}
167938fd1498Szrj       typedef __numpunct_cache<_CharT>  __cache_type;
168038fd1498Szrj 
168138fd1498Szrj     protected:
168238fd1498Szrj       __cache_type*			_M_data;
168338fd1498Szrj 
168438fd1498Szrj     public:
168538fd1498Szrj       /// Numpunct facet id.
168638fd1498Szrj       static locale::id			id;
168738fd1498Szrj 
168838fd1498Szrj       /**
168938fd1498Szrj        *  @brief  Numpunct constructor.
169038fd1498Szrj        *
169138fd1498Szrj        *  @param  __refs  Refcount to pass to the base class.
169238fd1498Szrj        */
169338fd1498Szrj       explicit
169438fd1498Szrj       numpunct(size_t __refs = 0)
169538fd1498Szrj       : facet(__refs), _M_data(0)
169638fd1498Szrj       { _M_initialize_numpunct(); }
169738fd1498Szrj 
169838fd1498Szrj       /**
169938fd1498Szrj        *  @brief  Internal constructor.  Not for general use.
170038fd1498Szrj        *
170138fd1498Szrj        *  This is a constructor for use by the library itself to set up the
170238fd1498Szrj        *  predefined locale facets.
170338fd1498Szrj        *
170438fd1498Szrj        *  @param  __cache  __numpunct_cache object.
170538fd1498Szrj        *  @param  __refs  Refcount to pass to the base class.
170638fd1498Szrj        */
170738fd1498Szrj       explicit
170838fd1498Szrj       numpunct(__cache_type* __cache, size_t __refs = 0)
170938fd1498Szrj       : facet(__refs), _M_data(__cache)
171038fd1498Szrj       { _M_initialize_numpunct(); }
171138fd1498Szrj 
171238fd1498Szrj       /**
171338fd1498Szrj        *  @brief  Internal constructor.  Not for general use.
171438fd1498Szrj        *
171538fd1498Szrj        *  This is a constructor for use by the library itself to set up new
171638fd1498Szrj        *  locales.
171738fd1498Szrj        *
171838fd1498Szrj        *  @param  __cloc  The C locale.
171938fd1498Szrj        *  @param  __refs  Refcount to pass to the base class.
172038fd1498Szrj        */
172138fd1498Szrj       explicit
172238fd1498Szrj       numpunct(__c_locale __cloc, size_t __refs = 0)
172338fd1498Szrj       : facet(__refs), _M_data(0)
172438fd1498Szrj       { _M_initialize_numpunct(__cloc); }
172538fd1498Szrj 
172638fd1498Szrj       /**
172738fd1498Szrj        *  @brief  Return decimal point character.
172838fd1498Szrj        *
172938fd1498Szrj        *  This function returns a char_type to use as a decimal point.  It
173038fd1498Szrj        *  does so by returning returning
173138fd1498Szrj        *  numpunct<char_type>::do_decimal_point().
173238fd1498Szrj        *
173338fd1498Szrj        *  @return  @a char_type representing a decimal point.
173438fd1498Szrj       */
173538fd1498Szrj       char_type
173638fd1498Szrj       decimal_point() const
173738fd1498Szrj       { return this->do_decimal_point(); }
173838fd1498Szrj 
173938fd1498Szrj       /**
174038fd1498Szrj        *  @brief  Return thousands separator character.
174138fd1498Szrj        *
174238fd1498Szrj        *  This function returns a char_type to use as a thousands
174338fd1498Szrj        *  separator.  It does so by returning returning
174438fd1498Szrj        *  numpunct<char_type>::do_thousands_sep().
174538fd1498Szrj        *
174638fd1498Szrj        *  @return  char_type representing a thousands separator.
174738fd1498Szrj       */
174838fd1498Szrj       char_type
174938fd1498Szrj       thousands_sep() const
175038fd1498Szrj       { return this->do_thousands_sep(); }
175138fd1498Szrj 
175238fd1498Szrj       /**
175338fd1498Szrj        *  @brief  Return grouping specification.
175438fd1498Szrj        *
175538fd1498Szrj        *  This function returns a string representing groupings for the
175638fd1498Szrj        *  integer part of a number.  Groupings indicate where thousands
175738fd1498Szrj        *  separators should be inserted in the integer part of a number.
175838fd1498Szrj        *
175938fd1498Szrj        *  Each char in the return string is interpret as an integer
176038fd1498Szrj        *  rather than a character.  These numbers represent the number
176138fd1498Szrj        *  of digits in a group.  The first char in the string
176238fd1498Szrj        *  represents the number of digits in the least significant
176338fd1498Szrj        *  group.  If a char is negative, it indicates an unlimited
176438fd1498Szrj        *  number of digits for the group.  If more chars from the
176538fd1498Szrj        *  string are required to group a number, the last char is used
176638fd1498Szrj        *  repeatedly.
176738fd1498Szrj        *
176838fd1498Szrj        *  For example, if the grouping() returns "\003\002" and is
176938fd1498Szrj        *  applied to the number 123456789, this corresponds to
177038fd1498Szrj        *  12,34,56,789.  Note that if the string was "32", this would
177138fd1498Szrj        *  put more than 50 digits into the least significant group if
177238fd1498Szrj        *  the character set is ASCII.
177338fd1498Szrj        *
177438fd1498Szrj        *  The string is returned by calling
177538fd1498Szrj        *  numpunct<char_type>::do_grouping().
177638fd1498Szrj        *
177738fd1498Szrj        *  @return  string representing grouping specification.
177838fd1498Szrj       */
177938fd1498Szrj       string
178038fd1498Szrj       grouping() const
178138fd1498Szrj       { return this->do_grouping(); }
178238fd1498Szrj 
178338fd1498Szrj       /**
178438fd1498Szrj        *  @brief  Return string representation of bool true.
178538fd1498Szrj        *
178638fd1498Szrj        *  This function returns a string_type containing the text
178738fd1498Szrj        *  representation for true bool variables.  It does so by calling
178838fd1498Szrj        *  numpunct<char_type>::do_truename().
178938fd1498Szrj        *
179038fd1498Szrj        *  @return  string_type representing printed form of true.
179138fd1498Szrj       */
179238fd1498Szrj       string_type
179338fd1498Szrj       truename() const
179438fd1498Szrj       { return this->do_truename(); }
179538fd1498Szrj 
179638fd1498Szrj       /**
179738fd1498Szrj        *  @brief  Return string representation of bool false.
179838fd1498Szrj        *
179938fd1498Szrj        *  This function returns a string_type containing the text
180038fd1498Szrj        *  representation for false bool variables.  It does so by calling
180138fd1498Szrj        *  numpunct<char_type>::do_falsename().
180238fd1498Szrj        *
180338fd1498Szrj        *  @return  string_type representing printed form of false.
180438fd1498Szrj       */
180538fd1498Szrj       string_type
180638fd1498Szrj       falsename() const
180738fd1498Szrj       { return this->do_falsename(); }
180838fd1498Szrj 
180938fd1498Szrj     protected:
181038fd1498Szrj       /// Destructor.
181138fd1498Szrj       virtual
181238fd1498Szrj       ~numpunct();
181338fd1498Szrj 
181438fd1498Szrj       /**
181538fd1498Szrj        *  @brief  Return decimal point character.
181638fd1498Szrj        *
181738fd1498Szrj        *  Returns a char_type to use as a decimal point.  This function is a
181838fd1498Szrj        *  hook for derived classes to change the value returned.
181938fd1498Szrj        *
182038fd1498Szrj        *  @return  @a char_type representing a decimal point.
182138fd1498Szrj       */
182238fd1498Szrj       virtual char_type
182338fd1498Szrj       do_decimal_point() const
182438fd1498Szrj       { return _M_data->_M_decimal_point; }
182538fd1498Szrj 
182638fd1498Szrj       /**
182738fd1498Szrj        *  @brief  Return thousands separator character.
182838fd1498Szrj        *
182938fd1498Szrj        *  Returns a char_type to use as a thousands separator.  This function
183038fd1498Szrj        *  is a hook for derived classes to change the value returned.
183138fd1498Szrj        *
183238fd1498Szrj        *  @return  @a char_type representing a thousands separator.
183338fd1498Szrj       */
183438fd1498Szrj       virtual char_type
183538fd1498Szrj       do_thousands_sep() const
183638fd1498Szrj       { return _M_data->_M_thousands_sep; }
183738fd1498Szrj 
183838fd1498Szrj       /**
183938fd1498Szrj        *  @brief  Return grouping specification.
184038fd1498Szrj        *
184138fd1498Szrj        *  Returns a string representing groupings for the integer part of a
184238fd1498Szrj        *  number.  This function is a hook for derived classes to change the
184338fd1498Szrj        *  value returned.  @see grouping() for details.
184438fd1498Szrj        *
184538fd1498Szrj        *  @return  String representing grouping specification.
184638fd1498Szrj       */
184738fd1498Szrj       virtual string
184838fd1498Szrj       do_grouping() const
184938fd1498Szrj       { return _M_data->_M_grouping; }
185038fd1498Szrj 
185138fd1498Szrj       /**
185238fd1498Szrj        *  @brief  Return string representation of bool true.
185338fd1498Szrj        *
185438fd1498Szrj        *  Returns a string_type containing the text representation for true
185538fd1498Szrj        *  bool variables.  This function is a hook for derived classes to
185638fd1498Szrj        *  change the value returned.
185738fd1498Szrj        *
185838fd1498Szrj        *  @return  string_type representing printed form of true.
185938fd1498Szrj       */
186038fd1498Szrj       virtual string_type
186138fd1498Szrj       do_truename() const
186238fd1498Szrj       { return _M_data->_M_truename; }
186338fd1498Szrj 
186438fd1498Szrj       /**
186538fd1498Szrj        *  @brief  Return string representation of bool false.
186638fd1498Szrj        *
186738fd1498Szrj        *  Returns a string_type containing the text representation for false
186838fd1498Szrj        *  bool variables.  This function is a hook for derived classes to
186938fd1498Szrj        *  change the value returned.
187038fd1498Szrj        *
187138fd1498Szrj        *  @return  string_type representing printed form of false.
187238fd1498Szrj       */
187338fd1498Szrj       virtual string_type
187438fd1498Szrj       do_falsename() const
187538fd1498Szrj       { return _M_data->_M_falsename; }
187638fd1498Szrj 
187738fd1498Szrj       // For use at construction time only.
187838fd1498Szrj       void
187938fd1498Szrj       _M_initialize_numpunct(__c_locale __cloc = 0);
188038fd1498Szrj     };
188138fd1498Szrj 
188238fd1498Szrj   template<typename _CharT>
188338fd1498Szrj     locale::id numpunct<_CharT>::id;
188438fd1498Szrj 
188538fd1498Szrj   template<>
188638fd1498Szrj     numpunct<char>::~numpunct();
188738fd1498Szrj 
188838fd1498Szrj   template<>
188938fd1498Szrj     void
189038fd1498Szrj     numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);
189138fd1498Szrj 
189238fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T
189338fd1498Szrj   template<>
189438fd1498Szrj     numpunct<wchar_t>::~numpunct();
189538fd1498Szrj 
189638fd1498Szrj   template<>
189738fd1498Szrj     void
189838fd1498Szrj     numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);
189938fd1498Szrj #endif
190038fd1498Szrj 
190138fd1498Szrj   /// class numpunct_byname [22.2.3.2].
190238fd1498Szrj   template<typename _CharT>
190338fd1498Szrj     class numpunct_byname : public numpunct<_CharT>
190438fd1498Szrj     {
190538fd1498Szrj     public:
190638fd1498Szrj       typedef _CharT			char_type;
190738fd1498Szrj       typedef basic_string<_CharT>	string_type;
190838fd1498Szrj 
190938fd1498Szrj       explicit
191038fd1498Szrj       numpunct_byname(const char* __s, size_t __refs = 0)
191138fd1498Szrj       : numpunct<_CharT>(__refs)
191238fd1498Szrj       {
191338fd1498Szrj 	if (__builtin_strcmp(__s, "C") != 0
191438fd1498Szrj 	    && __builtin_strcmp(__s, "POSIX") != 0)
191538fd1498Szrj 	  {
191638fd1498Szrj 	    __c_locale __tmp;
191738fd1498Szrj 	    this->_S_create_c_locale(__tmp, __s);
191838fd1498Szrj 	    this->_M_initialize_numpunct(__tmp);
191938fd1498Szrj 	    this->_S_destroy_c_locale(__tmp);
192038fd1498Szrj 	  }
192138fd1498Szrj       }
192238fd1498Szrj 
192338fd1498Szrj #if __cplusplus >= 201103L
192438fd1498Szrj       explicit
192538fd1498Szrj       numpunct_byname(const string& __s, size_t __refs = 0)
192638fd1498Szrj       : numpunct_byname(__s.c_str(), __refs) { }
192738fd1498Szrj #endif
192838fd1498Szrj 
192938fd1498Szrj     protected:
193038fd1498Szrj       virtual
193138fd1498Szrj       ~numpunct_byname() { }
193238fd1498Szrj     };
193338fd1498Szrj 
193438fd1498Szrj _GLIBCXX_END_NAMESPACE_CXX11
193538fd1498Szrj 
193638fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_LDBL
193738fd1498Szrj 
193838fd1498Szrj   /**
193938fd1498Szrj    *  @brief  Primary class template num_get.
194038fd1498Szrj    *  @ingroup locales
194138fd1498Szrj    *
194238fd1498Szrj    *  This facet encapsulates the code to parse and return a number
194338fd1498Szrj    *  from a string.  It is used by the istream numeric extraction
194438fd1498Szrj    *  operators.
194538fd1498Szrj    *
194638fd1498Szrj    *  The num_get template uses protected virtual functions to provide the
194738fd1498Szrj    *  actual results.  The public accessors forward the call to the virtual
194838fd1498Szrj    *  functions.  These virtual functions are hooks for developers to
194938fd1498Szrj    *  implement the behavior they require from the num_get facet.
195038fd1498Szrj   */
195138fd1498Szrj   template<typename _CharT, typename _InIter>
195238fd1498Szrj     class num_get : public locale::facet
195338fd1498Szrj     {
195438fd1498Szrj     public:
195538fd1498Szrj       // Types:
195638fd1498Szrj       //@{
195738fd1498Szrj       /// Public typedefs
195838fd1498Szrj       typedef _CharT			char_type;
195938fd1498Szrj       typedef _InIter			iter_type;
196038fd1498Szrj       //@}
196138fd1498Szrj 
196238fd1498Szrj       /// Numpunct facet id.
196338fd1498Szrj       static locale::id			id;
196438fd1498Szrj 
196538fd1498Szrj       /**
196638fd1498Szrj        *  @brief  Constructor performs initialization.
196738fd1498Szrj        *
196838fd1498Szrj        *  This is the constructor provided by the standard.
196938fd1498Szrj        *
197038fd1498Szrj        *  @param __refs  Passed to the base facet class.
197138fd1498Szrj       */
197238fd1498Szrj       explicit
197338fd1498Szrj       num_get(size_t __refs = 0) : facet(__refs) { }
197438fd1498Szrj 
197538fd1498Szrj       /**
197638fd1498Szrj        *  @brief  Numeric parsing.
197738fd1498Szrj        *
197838fd1498Szrj        *  Parses the input stream into the bool @a v.  It does so by calling
197938fd1498Szrj        *  num_get::do_get().
198038fd1498Szrj        *
198138fd1498Szrj        *  If ios_base::boolalpha is set, attempts to read
198238fd1498Szrj        *  ctype<CharT>::truename() or ctype<CharT>::falsename().  Sets
198338fd1498Szrj        *  @a v to true or false if successful.  Sets err to
198438fd1498Szrj        *  ios_base::failbit if reading the string fails.  Sets err to
198538fd1498Szrj        *  ios_base::eofbit if the stream is emptied.
198638fd1498Szrj        *
198738fd1498Szrj        *  If ios_base::boolalpha is not set, proceeds as with reading a long,
198838fd1498Szrj        *  except if the value is 1, sets @a v to true, if the value is 0, sets
198938fd1498Szrj        *  @a v to false, and otherwise set err to ios_base::failbit.
199038fd1498Szrj        *
199138fd1498Szrj        *  @param  __in  Start of input stream.
199238fd1498Szrj        *  @param  __end  End of input stream.
199338fd1498Szrj        *  @param  __io  Source of locale and flags.
199438fd1498Szrj        *  @param  __err  Error flags to set.
199538fd1498Szrj        *  @param  __v  Value to format and insert.
199638fd1498Szrj        *  @return  Iterator after reading.
199738fd1498Szrj       */
199838fd1498Szrj       iter_type
199938fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
200038fd1498Szrj 	  ios_base::iostate& __err, bool& __v) const
200138fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
200238fd1498Szrj 
200338fd1498Szrj       //@{
200438fd1498Szrj       /**
200538fd1498Szrj        *  @brief  Numeric parsing.
200638fd1498Szrj        *
200738fd1498Szrj        *  Parses the input stream into the integral variable @a v.  It does so
200838fd1498Szrj        *  by calling num_get::do_get().
200938fd1498Szrj        *
201038fd1498Szrj        *  Parsing is affected by the flag settings in @a io.
201138fd1498Szrj        *
201238fd1498Szrj        *  The basic parse is affected by the value of io.flags() &
201338fd1498Szrj        *  ios_base::basefield.  If equal to ios_base::oct, parses like the
201438fd1498Szrj        *  scanf %o specifier.  Else if equal to ios_base::hex, parses like %X
201538fd1498Szrj        *  specifier.  Else if basefield equal to 0, parses like the %i
201638fd1498Szrj        *  specifier.  Otherwise, parses like %d for signed and %u for unsigned
201738fd1498Szrj        *  types.  The matching type length modifier is also used.
201838fd1498Szrj        *
201938fd1498Szrj        *  Digit grouping is interpreted according to
202038fd1498Szrj        *  numpunct::grouping() and numpunct::thousands_sep().  If the
202138fd1498Szrj        *  pattern of digit groups isn't consistent, sets err to
202238fd1498Szrj        *  ios_base::failbit.
202338fd1498Szrj        *
202438fd1498Szrj        *  If parsing the string yields a valid value for @a v, @a v is set.
202538fd1498Szrj        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
202638fd1498Szrj        *  Sets err to ios_base::eofbit if the stream is emptied.
202738fd1498Szrj        *
202838fd1498Szrj        *  @param  __in  Start of input stream.
202938fd1498Szrj        *  @param  __end  End of input stream.
203038fd1498Szrj        *  @param  __io  Source of locale and flags.
203138fd1498Szrj        *  @param  __err  Error flags to set.
203238fd1498Szrj        *  @param  __v  Value to format and insert.
203338fd1498Szrj        *  @return  Iterator after reading.
203438fd1498Szrj       */
203538fd1498Szrj       iter_type
203638fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
203738fd1498Szrj 	  ios_base::iostate& __err, long& __v) const
203838fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
203938fd1498Szrj 
204038fd1498Szrj       iter_type
204138fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
204238fd1498Szrj 	  ios_base::iostate& __err, unsigned short& __v) const
204338fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
204438fd1498Szrj 
204538fd1498Szrj       iter_type
204638fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
204738fd1498Szrj 	  ios_base::iostate& __err, unsigned int& __v)   const
204838fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
204938fd1498Szrj 
205038fd1498Szrj       iter_type
205138fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
205238fd1498Szrj 	  ios_base::iostate& __err, unsigned long& __v)  const
205338fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
205438fd1498Szrj 
205538fd1498Szrj #ifdef _GLIBCXX_USE_LONG_LONG
205638fd1498Szrj       iter_type
205738fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
205838fd1498Szrj 	  ios_base::iostate& __err, long long& __v) const
205938fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
206038fd1498Szrj 
206138fd1498Szrj       iter_type
206238fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
206338fd1498Szrj 	  ios_base::iostate& __err, unsigned long long& __v)  const
206438fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
206538fd1498Szrj #endif
206638fd1498Szrj       //@}
206738fd1498Szrj 
206838fd1498Szrj       //@{
206938fd1498Szrj       /**
207038fd1498Szrj        *  @brief  Numeric parsing.
207138fd1498Szrj        *
207238fd1498Szrj        *  Parses the input stream into the integral variable @a v.  It does so
207338fd1498Szrj        *  by calling num_get::do_get().
207438fd1498Szrj        *
207538fd1498Szrj        *  The input characters are parsed like the scanf %g specifier.  The
207638fd1498Szrj        *  matching type length modifier is also used.
207738fd1498Szrj        *
207838fd1498Szrj        *  The decimal point character used is numpunct::decimal_point().
207938fd1498Szrj        *  Digit grouping is interpreted according to
208038fd1498Szrj        *  numpunct::grouping() and numpunct::thousands_sep().  If the
208138fd1498Szrj        *  pattern of digit groups isn't consistent, sets err to
208238fd1498Szrj        *  ios_base::failbit.
208338fd1498Szrj        *
208438fd1498Szrj        *  If parsing the string yields a valid value for @a v, @a v is set.
208538fd1498Szrj        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
208638fd1498Szrj        *  Sets err to ios_base::eofbit if the stream is emptied.
208738fd1498Szrj        *
208838fd1498Szrj        *  @param  __in  Start of input stream.
208938fd1498Szrj        *  @param  __end  End of input stream.
209038fd1498Szrj        *  @param  __io  Source of locale and flags.
209138fd1498Szrj        *  @param  __err  Error flags to set.
209238fd1498Szrj        *  @param  __v  Value to format and insert.
209338fd1498Szrj        *  @return  Iterator after reading.
209438fd1498Szrj       */
209538fd1498Szrj       iter_type
209638fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
209738fd1498Szrj 	  ios_base::iostate& __err, float& __v) const
209838fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
209938fd1498Szrj 
210038fd1498Szrj       iter_type
210138fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
210238fd1498Szrj 	  ios_base::iostate& __err, double& __v) const
210338fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
210438fd1498Szrj 
210538fd1498Szrj       iter_type
210638fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
210738fd1498Szrj 	  ios_base::iostate& __err, long double& __v) const
210838fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
210938fd1498Szrj       //@}
211038fd1498Szrj 
211138fd1498Szrj       /**
211238fd1498Szrj        *  @brief  Numeric parsing.
211338fd1498Szrj        *
211438fd1498Szrj        *  Parses the input stream into the pointer variable @a v.  It does so
211538fd1498Szrj        *  by calling num_get::do_get().
211638fd1498Szrj        *
211738fd1498Szrj        *  The input characters are parsed like the scanf %p specifier.
211838fd1498Szrj        *
211938fd1498Szrj        *  Digit grouping is interpreted according to
212038fd1498Szrj        *  numpunct::grouping() and numpunct::thousands_sep().  If the
212138fd1498Szrj        *  pattern of digit groups isn't consistent, sets err to
212238fd1498Szrj        *  ios_base::failbit.
212338fd1498Szrj        *
212438fd1498Szrj        *  Note that the digit grouping effect for pointers is a bit ambiguous
212538fd1498Szrj        *  in the standard and shouldn't be relied on.  See DR 344.
212638fd1498Szrj        *
212738fd1498Szrj        *  If parsing the string yields a valid value for @a v, @a v is set.
212838fd1498Szrj        *  Otherwise, sets err to ios_base::failbit and leaves @a v unaltered.
212938fd1498Szrj        *  Sets err to ios_base::eofbit if the stream is emptied.
213038fd1498Szrj        *
213138fd1498Szrj        *  @param  __in  Start of input stream.
213238fd1498Szrj        *  @param  __end  End of input stream.
213338fd1498Szrj        *  @param  __io  Source of locale and flags.
213438fd1498Szrj        *  @param  __err  Error flags to set.
213538fd1498Szrj        *  @param  __v  Value to format and insert.
213638fd1498Szrj        *  @return  Iterator after reading.
213738fd1498Szrj       */
213838fd1498Szrj       iter_type
213938fd1498Szrj       get(iter_type __in, iter_type __end, ios_base& __io,
214038fd1498Szrj 	  ios_base::iostate& __err, void*& __v) const
214138fd1498Szrj       { return this->do_get(__in, __end, __io, __err, __v); }
214238fd1498Szrj 
214338fd1498Szrj     protected:
214438fd1498Szrj       /// Destructor.
214538fd1498Szrj       virtual ~num_get() { }
214638fd1498Szrj 
214738fd1498Szrj       _GLIBCXX_DEFAULT_ABI_TAG
214838fd1498Szrj       iter_type
214938fd1498Szrj       _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
215038fd1498Szrj 		       string&) const;
215138fd1498Szrj 
215238fd1498Szrj       template<typename _ValueT>
215338fd1498Szrj 	_GLIBCXX_DEFAULT_ABI_TAG
215438fd1498Szrj 	iter_type
215538fd1498Szrj 	_M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
215638fd1498Szrj 		       _ValueT&) const;
215738fd1498Szrj 
215838fd1498Szrj       template<typename _CharT2>
215938fd1498Szrj       typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, int>::__type
216038fd1498Szrj 	_M_find(const _CharT2*, size_t __len, _CharT2 __c) const
216138fd1498Szrj 	{
216238fd1498Szrj 	  int __ret = -1;
216338fd1498Szrj 	  if (__len <= 10)
216438fd1498Szrj 	    {
216538fd1498Szrj 	      if (__c >= _CharT2('0') && __c < _CharT2(_CharT2('0') + __len))
216638fd1498Szrj 		__ret = __c - _CharT2('0');
216738fd1498Szrj 	    }
216838fd1498Szrj 	  else
216938fd1498Szrj 	    {
217038fd1498Szrj 	      if (__c >= _CharT2('0') && __c <= _CharT2('9'))
217138fd1498Szrj 		__ret = __c - _CharT2('0');
217238fd1498Szrj 	      else if (__c >= _CharT2('a') && __c <= _CharT2('f'))
217338fd1498Szrj 		__ret = 10 + (__c - _CharT2('a'));
217438fd1498Szrj 	      else if (__c >= _CharT2('A') && __c <= _CharT2('F'))
217538fd1498Szrj 		__ret = 10 + (__c - _CharT2('A'));
217638fd1498Szrj 	    }
217738fd1498Szrj 	  return __ret;
217838fd1498Szrj 	}
217938fd1498Szrj 
218038fd1498Szrj       template<typename _CharT2>
218138fd1498Szrj       typename __gnu_cxx::__enable_if<!__is_char<_CharT2>::__value,
218238fd1498Szrj 				      int>::__type
218338fd1498Szrj 	_M_find(const _CharT2* __zero, size_t __len, _CharT2 __c) const
218438fd1498Szrj 	{
218538fd1498Szrj 	  int __ret = -1;
218638fd1498Szrj 	  const char_type* __q = char_traits<_CharT2>::find(__zero, __len, __c);
218738fd1498Szrj 	  if (__q)
218838fd1498Szrj 	    {
218938fd1498Szrj 	      __ret = __q - __zero;
219038fd1498Szrj 	      if (__ret > 15)
219138fd1498Szrj 		__ret -= 6;
219238fd1498Szrj 	    }
219338fd1498Szrj 	  return __ret;
219438fd1498Szrj 	}
219538fd1498Szrj 
219638fd1498Szrj       //@{
219738fd1498Szrj       /**
219838fd1498Szrj        *  @brief  Numeric parsing.
219938fd1498Szrj        *
220038fd1498Szrj        *  Parses the input stream into the variable @a v.  This function is a
220138fd1498Szrj        *  hook for derived classes to change the value returned.  @see get()
220238fd1498Szrj        *  for more details.
220338fd1498Szrj        *
220438fd1498Szrj        *  @param  __beg  Start of input stream.
220538fd1498Szrj        *  @param  __end  End of input stream.
220638fd1498Szrj        *  @param  __io  Source of locale and flags.
220738fd1498Szrj        *  @param  __err  Error flags to set.
220838fd1498Szrj        *  @param  __v  Value to format and insert.
220938fd1498Szrj        *  @return  Iterator after reading.
221038fd1498Szrj       */
221138fd1498Szrj       virtual iter_type
221238fd1498Szrj       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
221338fd1498Szrj 
221438fd1498Szrj       virtual iter_type
221538fd1498Szrj       do_get(iter_type __beg, iter_type __end, ios_base& __io,
221638fd1498Szrj 	     ios_base::iostate& __err, long& __v) const
221738fd1498Szrj       { return _M_extract_int(__beg, __end, __io, __err, __v); }
221838fd1498Szrj 
221938fd1498Szrj       virtual iter_type
222038fd1498Szrj       do_get(iter_type __beg, iter_type __end, ios_base& __io,
222138fd1498Szrj 	     ios_base::iostate& __err, unsigned short& __v) const
222238fd1498Szrj       { return _M_extract_int(__beg, __end, __io, __err, __v); }
222338fd1498Szrj 
222438fd1498Szrj       virtual iter_type
222538fd1498Szrj       do_get(iter_type __beg, iter_type __end, ios_base& __io,
222638fd1498Szrj 	     ios_base::iostate& __err, unsigned int& __v) const
222738fd1498Szrj       { return _M_extract_int(__beg, __end, __io, __err, __v); }
222838fd1498Szrj 
222938fd1498Szrj       virtual iter_type
223038fd1498Szrj       do_get(iter_type __beg, iter_type __end, ios_base& __io,
223138fd1498Szrj 	     ios_base::iostate& __err, unsigned long& __v) const
223238fd1498Szrj       { return _M_extract_int(__beg, __end, __io, __err, __v); }
223338fd1498Szrj 
223438fd1498Szrj #ifdef _GLIBCXX_USE_LONG_LONG
223538fd1498Szrj       virtual iter_type
223638fd1498Szrj       do_get(iter_type __beg, iter_type __end, ios_base& __io,
223738fd1498Szrj 	     ios_base::iostate& __err, long long& __v) const
223838fd1498Szrj       { return _M_extract_int(__beg, __end, __io, __err, __v); }
223938fd1498Szrj 
224038fd1498Szrj       virtual iter_type
224138fd1498Szrj       do_get(iter_type __beg, iter_type __end, ios_base& __io,
224238fd1498Szrj 	     ios_base::iostate& __err, unsigned long long& __v) const
224338fd1498Szrj       { return _M_extract_int(__beg, __end, __io, __err, __v); }
224438fd1498Szrj #endif
224538fd1498Szrj 
224638fd1498Szrj       virtual iter_type
224738fd1498Szrj       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, float&) const;
224838fd1498Szrj 
224938fd1498Szrj       virtual iter_type
225038fd1498Szrj       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
225138fd1498Szrj 	     double&) const;
225238fd1498Szrj 
225338fd1498Szrj       // XXX GLIBCXX_ABI Deprecated
225438fd1498Szrj #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
225538fd1498Szrj       virtual iter_type
225638fd1498Szrj       __do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
225738fd1498Szrj 	       double&) const;
225838fd1498Szrj #else
225938fd1498Szrj       virtual iter_type
226038fd1498Szrj       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
226138fd1498Szrj 	     long double&) const;
226238fd1498Szrj #endif
226338fd1498Szrj 
226438fd1498Szrj       virtual iter_type
226538fd1498Szrj       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, void*&) const;
226638fd1498Szrj 
226738fd1498Szrj       // XXX GLIBCXX_ABI Deprecated
226838fd1498Szrj #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
226938fd1498Szrj       virtual iter_type
227038fd1498Szrj       do_get(iter_type, iter_type, ios_base&, ios_base::iostate&,
227138fd1498Szrj 	     long double&) const;
227238fd1498Szrj #endif
227338fd1498Szrj       //@}
227438fd1498Szrj     };
227538fd1498Szrj 
227638fd1498Szrj   template<typename _CharT, typename _InIter>
227738fd1498Szrj     locale::id num_get<_CharT, _InIter>::id;
227838fd1498Szrj 
227938fd1498Szrj 
228038fd1498Szrj   /**
228138fd1498Szrj    *  @brief  Primary class template num_put.
228238fd1498Szrj    *  @ingroup locales
228338fd1498Szrj    *
228438fd1498Szrj    *  This facet encapsulates the code to convert a number to a string.  It is
228538fd1498Szrj    *  used by the ostream numeric insertion operators.
228638fd1498Szrj    *
228738fd1498Szrj    *  The num_put template uses protected virtual functions to provide the
228838fd1498Szrj    *  actual results.  The public accessors forward the call to the virtual
228938fd1498Szrj    *  functions.  These virtual functions are hooks for developers to
229038fd1498Szrj    *  implement the behavior they require from the num_put facet.
229138fd1498Szrj   */
229238fd1498Szrj   template<typename _CharT, typename _OutIter>
229338fd1498Szrj     class num_put : public locale::facet
229438fd1498Szrj     {
229538fd1498Szrj     public:
229638fd1498Szrj       // Types:
229738fd1498Szrj       //@{
229838fd1498Szrj       /// Public typedefs
229938fd1498Szrj       typedef _CharT		char_type;
230038fd1498Szrj       typedef _OutIter		iter_type;
230138fd1498Szrj       //@}
230238fd1498Szrj 
230338fd1498Szrj       /// Numpunct facet id.
230438fd1498Szrj       static locale::id		id;
230538fd1498Szrj 
230638fd1498Szrj       /**
230738fd1498Szrj        *  @brief  Constructor performs initialization.
230838fd1498Szrj        *
230938fd1498Szrj        *  This is the constructor provided by the standard.
231038fd1498Szrj        *
231138fd1498Szrj        *  @param __refs  Passed to the base facet class.
231238fd1498Szrj       */
231338fd1498Szrj       explicit
231438fd1498Szrj       num_put(size_t __refs = 0) : facet(__refs) { }
231538fd1498Szrj 
231638fd1498Szrj       /**
231738fd1498Szrj        *  @brief  Numeric formatting.
231838fd1498Szrj        *
231938fd1498Szrj        *  Formats the boolean @a v and inserts it into a stream.  It does so
232038fd1498Szrj        *  by calling num_put::do_put().
232138fd1498Szrj        *
232238fd1498Szrj        *  If ios_base::boolalpha is set, writes ctype<CharT>::truename() or
232338fd1498Szrj        *  ctype<CharT>::falsename().  Otherwise formats @a v as an int.
232438fd1498Szrj        *
232538fd1498Szrj        *  @param  __s  Stream to write to.
232638fd1498Szrj        *  @param  __io  Source of locale and flags.
232738fd1498Szrj        *  @param  __fill  Char_type to use for filling.
232838fd1498Szrj        *  @param  __v  Value to format and insert.
232938fd1498Szrj        *  @return  Iterator after writing.
233038fd1498Szrj       */
233138fd1498Szrj       iter_type
233238fd1498Szrj       put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const
233338fd1498Szrj       { return this->do_put(__s, __io, __fill, __v); }
233438fd1498Szrj 
233538fd1498Szrj       //@{
233638fd1498Szrj       /**
233738fd1498Szrj        *  @brief  Numeric formatting.
233838fd1498Szrj        *
233938fd1498Szrj        *  Formats the integral value @a v and inserts it into a
234038fd1498Szrj        *  stream.  It does so by calling num_put::do_put().
234138fd1498Szrj        *
234238fd1498Szrj        *  Formatting is affected by the flag settings in @a io.
234338fd1498Szrj        *
234438fd1498Szrj        *  The basic format is affected by the value of io.flags() &
234538fd1498Szrj        *  ios_base::basefield.  If equal to ios_base::oct, formats like the
234638fd1498Szrj        *  printf %o specifier.  Else if equal to ios_base::hex, formats like
234738fd1498Szrj        *  %x or %X with ios_base::uppercase unset or set respectively.
234838fd1498Szrj        *  Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu
234938fd1498Szrj        *  for unsigned values.  Note that if both oct and hex are set, neither
235038fd1498Szrj        *  will take effect.
235138fd1498Szrj        *
235238fd1498Szrj        *  If ios_base::showpos is set, '+' is output before positive values.
235338fd1498Szrj        *  If ios_base::showbase is set, '0' precedes octal values (except 0)
235438fd1498Szrj        *  and '0[xX]' precedes hex values.
235538fd1498Szrj        *
235638fd1498Szrj        *  The decimal point character used is numpunct::decimal_point().
235738fd1498Szrj        *  Thousands separators are inserted according to
235838fd1498Szrj        *  numpunct::grouping() and numpunct::thousands_sep().
235938fd1498Szrj        *
236038fd1498Szrj        *  If io.width() is non-zero, enough @a fill characters are inserted to
236138fd1498Szrj        *  make the result at least that wide.  If
236238fd1498Szrj        *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
236338fd1498Szrj        *  padded at the end.  If ios_base::internal, then padding occurs
236438fd1498Szrj        *  immediately after either a '+' or '-' or after '0x' or '0X'.
236538fd1498Szrj        *  Otherwise, padding occurs at the beginning.
236638fd1498Szrj        *
236738fd1498Szrj        *  @param  __s  Stream to write to.
236838fd1498Szrj        *  @param  __io  Source of locale and flags.
236938fd1498Szrj        *  @param  __fill  Char_type to use for filling.
237038fd1498Szrj        *  @param  __v  Value to format and insert.
237138fd1498Szrj        *  @return  Iterator after writing.
237238fd1498Szrj       */
237338fd1498Szrj       iter_type
237438fd1498Szrj       put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
237538fd1498Szrj       { return this->do_put(__s, __io, __fill, __v); }
237638fd1498Szrj 
237738fd1498Szrj       iter_type
237838fd1498Szrj       put(iter_type __s, ios_base& __io, char_type __fill,
237938fd1498Szrj 	  unsigned long __v) const
238038fd1498Szrj       { return this->do_put(__s, __io, __fill, __v); }
238138fd1498Szrj 
238238fd1498Szrj #ifdef _GLIBCXX_USE_LONG_LONG
238338fd1498Szrj       iter_type
238438fd1498Szrj       put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const
238538fd1498Szrj       { return this->do_put(__s, __io, __fill, __v); }
238638fd1498Szrj 
238738fd1498Szrj       iter_type
238838fd1498Szrj       put(iter_type __s, ios_base& __io, char_type __fill,
238938fd1498Szrj 	  unsigned long long __v) const
239038fd1498Szrj       { return this->do_put(__s, __io, __fill, __v); }
239138fd1498Szrj #endif
239238fd1498Szrj       //@}
239338fd1498Szrj 
239438fd1498Szrj       //@{
239538fd1498Szrj       /**
239638fd1498Szrj        *  @brief  Numeric formatting.
239738fd1498Szrj        *
239838fd1498Szrj        *  Formats the floating point value @a v and inserts it into a stream.
239938fd1498Szrj        *  It does so by calling num_put::do_put().
240038fd1498Szrj        *
240138fd1498Szrj        *  Formatting is affected by the flag settings in @a io.
240238fd1498Szrj        *
240338fd1498Szrj        *  The basic format is affected by the value of io.flags() &
240438fd1498Szrj        *  ios_base::floatfield.  If equal to ios_base::fixed, formats like the
240538fd1498Szrj        *  printf %f specifier.  Else if equal to ios_base::scientific, formats
240638fd1498Szrj        *  like %e or %E with ios_base::uppercase unset or set respectively.
240738fd1498Szrj        *  Otherwise, formats like %g or %G depending on uppercase.  Note that
240838fd1498Szrj        *  if both fixed and scientific are set, the effect will also be like
240938fd1498Szrj        *  %g or %G.
241038fd1498Szrj        *
241138fd1498Szrj        *  The output precision is given by io.precision().  This precision is
241238fd1498Szrj        *  capped at numeric_limits::digits10 + 2 (different for double and
241338fd1498Szrj        *  long double).  The default precision is 6.
241438fd1498Szrj        *
241538fd1498Szrj        *  If ios_base::showpos is set, '+' is output before positive values.
241638fd1498Szrj        *  If ios_base::showpoint is set, a decimal point will always be
241738fd1498Szrj        *  output.
241838fd1498Szrj        *
241938fd1498Szrj        *  The decimal point character used is numpunct::decimal_point().
242038fd1498Szrj        *  Thousands separators are inserted according to
242138fd1498Szrj        *  numpunct::grouping() and numpunct::thousands_sep().
242238fd1498Szrj        *
242338fd1498Szrj        *  If io.width() is non-zero, enough @a fill characters are inserted to
242438fd1498Szrj        *  make the result at least that wide.  If
242538fd1498Szrj        *  (io.flags() & ios_base::adjustfield) == ios_base::left, result is
242638fd1498Szrj        *  padded at the end.  If ios_base::internal, then padding occurs
242738fd1498Szrj        *  immediately after either a '+' or '-' or after '0x' or '0X'.
242838fd1498Szrj        *  Otherwise, padding occurs at the beginning.
242938fd1498Szrj        *
243038fd1498Szrj        *  @param  __s  Stream to write to.
243138fd1498Szrj        *  @param  __io  Source of locale and flags.
243238fd1498Szrj        *  @param  __fill  Char_type to use for filling.
243338fd1498Szrj        *  @param  __v  Value to format and insert.
243438fd1498Szrj        *  @return  Iterator after writing.
243538fd1498Szrj       */
243638fd1498Szrj       iter_type
243738fd1498Szrj       put(iter_type __s, ios_base& __io, char_type __fill, double __v) const
243838fd1498Szrj       { return this->do_put(__s, __io, __fill, __v); }
243938fd1498Szrj 
244038fd1498Szrj       iter_type
244138fd1498Szrj       put(iter_type __s, ios_base& __io, char_type __fill,
244238fd1498Szrj 	  long double __v) const
244338fd1498Szrj       { return this->do_put(__s, __io, __fill, __v); }
244438fd1498Szrj       //@}
244538fd1498Szrj 
244638fd1498Szrj       /**
244738fd1498Szrj        *  @brief  Numeric formatting.
244838fd1498Szrj        *
244938fd1498Szrj        *  Formats the pointer value @a v and inserts it into a stream.  It
245038fd1498Szrj        *  does so by calling num_put::do_put().
245138fd1498Szrj        *
245238fd1498Szrj        *  This function formats @a v as an unsigned long with ios_base::hex
245338fd1498Szrj        *  and ios_base::showbase set.
245438fd1498Szrj        *
245538fd1498Szrj        *  @param  __s  Stream to write to.
245638fd1498Szrj        *  @param  __io  Source of locale and flags.
245738fd1498Szrj        *  @param  __fill  Char_type to use for filling.
245838fd1498Szrj        *  @param  __v  Value to format and insert.
245938fd1498Szrj        *  @return  Iterator after writing.
246038fd1498Szrj       */
246138fd1498Szrj       iter_type
246238fd1498Szrj       put(iter_type __s, ios_base& __io, char_type __fill,
246338fd1498Szrj 	  const void* __v) const
246438fd1498Szrj       { return this->do_put(__s, __io, __fill, __v); }
246538fd1498Szrj 
246638fd1498Szrj     protected:
246738fd1498Szrj       template<typename _ValueT>
246838fd1498Szrj 	iter_type
246938fd1498Szrj 	_M_insert_float(iter_type, ios_base& __io, char_type __fill,
247038fd1498Szrj 			char __mod, _ValueT __v) const;
247138fd1498Szrj 
247238fd1498Szrj       void
247338fd1498Szrj       _M_group_float(const char* __grouping, size_t __grouping_size,
247438fd1498Szrj 		     char_type __sep, const char_type* __p, char_type* __new,
247538fd1498Szrj 		     char_type* __cs, int& __len) const;
247638fd1498Szrj 
247738fd1498Szrj       template<typename _ValueT>
247838fd1498Szrj 	iter_type
247938fd1498Szrj 	_M_insert_int(iter_type, ios_base& __io, char_type __fill,
248038fd1498Szrj 		      _ValueT __v) const;
248138fd1498Szrj 
248238fd1498Szrj       void
248338fd1498Szrj       _M_group_int(const char* __grouping, size_t __grouping_size,
248438fd1498Szrj 		   char_type __sep, ios_base& __io, char_type* __new,
248538fd1498Szrj 		   char_type* __cs, int& __len) const;
248638fd1498Szrj 
248738fd1498Szrj       void
248838fd1498Szrj       _M_pad(char_type __fill, streamsize __w, ios_base& __io,
248938fd1498Szrj 	     char_type* __new, const char_type* __cs, int& __len) const;
249038fd1498Szrj 
249138fd1498Szrj       /// Destructor.
249238fd1498Szrj       virtual
249338fd1498Szrj       ~num_put() { }
249438fd1498Szrj 
249538fd1498Szrj       //@{
249638fd1498Szrj       /**
249738fd1498Szrj        *  @brief  Numeric formatting.
249838fd1498Szrj        *
249938fd1498Szrj        *  These functions do the work of formatting numeric values and
250038fd1498Szrj        *  inserting them into a stream. This function is a hook for derived
250138fd1498Szrj        *  classes to change the value returned.
250238fd1498Szrj        *
250338fd1498Szrj        *  @param  __s  Stream to write to.
250438fd1498Szrj        *  @param  __io  Source of locale and flags.
250538fd1498Szrj        *  @param  __fill  Char_type to use for filling.
250638fd1498Szrj        *  @param  __v  Value to format and insert.
250738fd1498Szrj        *  @return  Iterator after writing.
250838fd1498Szrj       */
250938fd1498Szrj       virtual iter_type
251038fd1498Szrj       do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const;
251138fd1498Szrj 
251238fd1498Szrj       virtual iter_type
251338fd1498Szrj       do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const
251438fd1498Szrj       { return _M_insert_int(__s, __io, __fill, __v); }
251538fd1498Szrj 
251638fd1498Szrj       virtual iter_type
251738fd1498Szrj       do_put(iter_type __s, ios_base& __io, char_type __fill,
251838fd1498Szrj 	     unsigned long __v) const
251938fd1498Szrj       { return _M_insert_int(__s, __io, __fill, __v); }
252038fd1498Szrj 
252138fd1498Szrj #ifdef _GLIBCXX_USE_LONG_LONG
252238fd1498Szrj       virtual iter_type
252338fd1498Szrj       do_put(iter_type __s, ios_base& __io, char_type __fill,
252438fd1498Szrj 	     long long __v) const
252538fd1498Szrj       { return _M_insert_int(__s, __io, __fill, __v); }
252638fd1498Szrj 
252738fd1498Szrj       virtual iter_type
252838fd1498Szrj       do_put(iter_type __s, ios_base& __io, char_type __fill,
252938fd1498Szrj 	     unsigned long long __v) const
253038fd1498Szrj       { return _M_insert_int(__s, __io, __fill, __v); }
253138fd1498Szrj #endif
253238fd1498Szrj 
253338fd1498Szrj       virtual iter_type
253438fd1498Szrj       do_put(iter_type, ios_base&, char_type, double) const;
253538fd1498Szrj 
253638fd1498Szrj       // XXX GLIBCXX_ABI Deprecated
253738fd1498Szrj #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
253838fd1498Szrj       virtual iter_type
253938fd1498Szrj       __do_put(iter_type, ios_base&, char_type, double) const;
254038fd1498Szrj #else
254138fd1498Szrj       virtual iter_type
254238fd1498Szrj       do_put(iter_type, ios_base&, char_type, long double) const;
254338fd1498Szrj #endif
254438fd1498Szrj 
254538fd1498Szrj       virtual iter_type
254638fd1498Szrj       do_put(iter_type, ios_base&, char_type, const void*) const;
254738fd1498Szrj 
254838fd1498Szrj       // XXX GLIBCXX_ABI Deprecated
254938fd1498Szrj #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
255038fd1498Szrj       virtual iter_type
255138fd1498Szrj       do_put(iter_type, ios_base&, char_type, long double) const;
255238fd1498Szrj #endif
255338fd1498Szrj       //@}
255438fd1498Szrj     };
255538fd1498Szrj 
255638fd1498Szrj   template <typename _CharT, typename _OutIter>
255738fd1498Szrj     locale::id num_put<_CharT, _OutIter>::id;
255838fd1498Szrj 
255938fd1498Szrj _GLIBCXX_END_NAMESPACE_LDBL
256038fd1498Szrj 
256138fd1498Szrj   // Subclause convenience interfaces, inlines.
256238fd1498Szrj   // NB: These are inline because, when used in a loop, some compilers
256338fd1498Szrj   // can hoist the body out of the loop; then it's just as fast as the
256438fd1498Szrj   // C is*() function.
256538fd1498Szrj 
256638fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::space, __c).
256738fd1498Szrj   template<typename _CharT>
256838fd1498Szrj     inline bool
256938fd1498Szrj     isspace(_CharT __c, const locale& __loc)
257038fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }
257138fd1498Szrj 
257238fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::print, __c).
257338fd1498Szrj   template<typename _CharT>
257438fd1498Szrj     inline bool
257538fd1498Szrj     isprint(_CharT __c, const locale& __loc)
257638fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }
257738fd1498Szrj 
257838fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::cntrl, __c).
257938fd1498Szrj   template<typename _CharT>
258038fd1498Szrj     inline bool
258138fd1498Szrj     iscntrl(_CharT __c, const locale& __loc)
258238fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }
258338fd1498Szrj 
258438fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::upper, __c).
258538fd1498Szrj   template<typename _CharT>
258638fd1498Szrj     inline bool
258738fd1498Szrj     isupper(_CharT __c, const locale& __loc)
258838fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }
258938fd1498Szrj 
259038fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::lower, __c).
259138fd1498Szrj   template<typename _CharT>
259238fd1498Szrj     inline bool
259338fd1498Szrj     islower(_CharT __c, const locale& __loc)
259438fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }
259538fd1498Szrj 
259638fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::alpha, __c).
259738fd1498Szrj   template<typename _CharT>
259838fd1498Szrj     inline bool
259938fd1498Szrj     isalpha(_CharT __c, const locale& __loc)
260038fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }
260138fd1498Szrj 
260238fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::digit, __c).
260338fd1498Szrj   template<typename _CharT>
260438fd1498Szrj     inline bool
260538fd1498Szrj     isdigit(_CharT __c, const locale& __loc)
260638fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }
260738fd1498Szrj 
260838fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::punct, __c).
260938fd1498Szrj   template<typename _CharT>
261038fd1498Szrj     inline bool
261138fd1498Szrj     ispunct(_CharT __c, const locale& __loc)
261238fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }
261338fd1498Szrj 
261438fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::xdigit, __c).
261538fd1498Szrj   template<typename _CharT>
261638fd1498Szrj     inline bool
261738fd1498Szrj     isxdigit(_CharT __c, const locale& __loc)
261838fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }
261938fd1498Szrj 
262038fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::alnum, __c).
262138fd1498Szrj   template<typename _CharT>
262238fd1498Szrj     inline bool
262338fd1498Szrj     isalnum(_CharT __c, const locale& __loc)
262438fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }
262538fd1498Szrj 
262638fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::graph, __c).
262738fd1498Szrj   template<typename _CharT>
262838fd1498Szrj     inline bool
262938fd1498Szrj     isgraph(_CharT __c, const locale& __loc)
263038fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }
263138fd1498Szrj 
263238fd1498Szrj #if __cplusplus >= 201103L
263338fd1498Szrj   /// Convenience interface to ctype.is(ctype_base::blank, __c).
263438fd1498Szrj   template<typename _CharT>
263538fd1498Szrj     inline bool
263638fd1498Szrj     isblank(_CharT __c, const locale& __loc)
263738fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::blank, __c); }
263838fd1498Szrj #endif
263938fd1498Szrj 
264038fd1498Szrj   /// Convenience interface to ctype.toupper(__c).
264138fd1498Szrj   template<typename _CharT>
264238fd1498Szrj     inline _CharT
264338fd1498Szrj     toupper(_CharT __c, const locale& __loc)
264438fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }
264538fd1498Szrj 
264638fd1498Szrj   /// Convenience interface to ctype.tolower(__c).
264738fd1498Szrj   template<typename _CharT>
264838fd1498Szrj     inline _CharT
264938fd1498Szrj     tolower(_CharT __c, const locale& __loc)
265038fd1498Szrj     { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }
265138fd1498Szrj 
265238fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
265338fd1498Szrj } // namespace std
265438fd1498Szrj 
265538fd1498Szrj # include <bits/locale_facets.tcc>
265638fd1498Szrj 
265738fd1498Szrj #endif
2658