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