/contrib/libstdc++/include/bits/locale_facets.h
https://bitbucket.org/freebsd/freebsd-head/ · C++ Header · 4688 lines · 1690 code · 458 blank · 2540 comment · 53 complexity · 28a678fe0b8b6a609d3302064e0488ac MD5 · raw file
Large files are truncated click here to view the full file
- // Locale support -*- C++ -*-
- // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- // Free Software Foundation, Inc.
- //
- // This file is part of the GNU ISO C++ Library. This library is free
- // software; you can redistribute it and/or modify it under the
- // terms of the GNU General Public License as published by the
- // Free Software Foundation; either version 2, or (at your option)
- // any later version.
- // This library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // You should have received a copy of the GNU General Public License along
- // with this library; see the file COPYING. If not, write to the Free
- // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- // USA.
- // As a special exception, you may use this file as part of a free software
- // library without restriction. Specifically, if other files instantiate
- // templates or use macros or inline functions from this file, or you compile
- // this file and link it with other files to produce an executable, this
- // file does not by itself cause the resulting executable to be covered by
- // the GNU General Public License. This exception does not however
- // invalidate any other reasons why the executable file might be covered by
- // the GNU General Public License.
- /** @file locale_facets.h
- * This is an internal header file, included by other library headers.
- * You should not attempt to use it directly.
- */
- //
- // ISO C++ 14882: 22.1 Locales
- //
- #ifndef _LOCALE_FACETS_H
- #define _LOCALE_FACETS_H 1
- #pragma GCC system_header
- #include <ctime> // For struct tm
- #include <cwctype> // For wctype_t
- #include <bits/ctype_base.h>
- #include <iosfwd>
- #include <bits/ios_base.h> // For ios_base, ios_base::iostate
- #include <streambuf>
- #include <bits/cpp_type_traits.h>
- _GLIBCXX_BEGIN_NAMESPACE(std)
- // NB: Don't instantiate required wchar_t facets if no wchar_t support.
- #ifdef _GLIBCXX_USE_WCHAR_T
- # define _GLIBCXX_NUM_FACETS 28
- #else
- # define _GLIBCXX_NUM_FACETS 14
- #endif
- // Convert string to numeric value of type _Tv and store results.
- // NB: This is specialized for all required types, there is no
- // generic definition.
- template<typename _Tv>
- void
- __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err,
- const __c_locale& __cloc);
- // Explicit specializations for required types.
- template<>
- void
- __convert_to_v(const char*, float&, ios_base::iostate&,
- const __c_locale&);
- template<>
- void
- __convert_to_v(const char*, double&, ios_base::iostate&,
- const __c_locale&);
- template<>
- void
- __convert_to_v(const char*, long double&, ios_base::iostate&,
- const __c_locale&);
- // NB: __pad is a struct, rather than a function, so it can be
- // partially-specialized.
- template<typename _CharT, typename _Traits>
- struct __pad
- {
- static void
- _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,
- const _CharT* __olds, const streamsize __newlen,
- const streamsize __oldlen, const bool __num);
- };
- // Used by both numeric and monetary facets.
- // Inserts "group separator" characters into an array of characters.
- // It's recursive, one iteration per group. It moves the characters
- // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this
- // only with __glen != 0.
- template<typename _CharT>
- _CharT*
- __add_grouping(_CharT* __s, _CharT __sep,
- const char* __gbeg, size_t __gsize,
- const _CharT* __first, const _CharT* __last);
- // This template permits specializing facet output code for
- // ostreambuf_iterator. For ostreambuf_iterator, sputn is
- // significantly more efficient than incrementing iterators.
- template<typename _CharT>
- inline
- ostreambuf_iterator<_CharT>
- __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)
- {
- __s._M_put(__ws, __len);
- return __s;
- }
- // This is the unspecialized form of the template.
- template<typename _CharT, typename _OutIter>
- inline
- _OutIter
- __write(_OutIter __s, const _CharT* __ws, int __len)
- {
- for (int __j = 0; __j < __len; __j++, ++__s)
- *__s = __ws[__j];
- return __s;
- }
- // 22.2.1.1 Template class ctype
- // Include host and configuration specific ctype enums for ctype_base.
- // Common base for ctype<_CharT>.
- /**
- * @brief Common base for ctype facet
- *
- * This template class provides implementations of the public functions
- * that forward to the protected virtual functions.
- *
- * This template also provides abtract stubs for the protected virtual
- * functions.
- */
- template<typename _CharT>
- class __ctype_abstract_base : public locale::facet, public ctype_base
- {
- public:
- // Types:
- /// Typedef for the template parameter
- typedef _CharT char_type;
- /**
- * @brief Test char_type classification.
- *
- * This function finds a mask M for @a c and compares it to mask @a m.
- * It does so by returning the value of ctype<char_type>::do_is().
- *
- * @param c The char_type to compare the mask of.
- * @param m The mask to compare against.
- * @return (M & m) != 0.
- */
- bool
- is(mask __m, char_type __c) const
- { return this->do_is(__m, __c); }
- /**
- * @brief Return a mask array.
- *
- * This function finds the mask for each char_type in the range [lo,hi)
- * and successively writes it to vec. vec must have as many elements
- * as the char array. It does so by returning the value of
- * ctype<char_type>::do_is().
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param vec Pointer to an array of mask storage.
- * @return @a hi.
- */
- const char_type*
- is(const char_type *__lo, const char_type *__hi, mask *__vec) const
- { return this->do_is(__lo, __hi, __vec); }
- /**
- * @brief Find char_type matching a mask
- *
- * This function searches for and returns the first char_type c in
- * [lo,hi) for which is(m,c) is true. It does so by returning
- * ctype<char_type>::do_scan_is().
- *
- * @param m The mask to compare against.
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return Pointer to matching char_type if found, else @a hi.
- */
- const char_type*
- scan_is(mask __m, const char_type* __lo, const char_type* __hi) const
- { return this->do_scan_is(__m, __lo, __hi); }
- /**
- * @brief Find char_type not matching a mask
- *
- * This function searches for and returns the first char_type c in
- * [lo,hi) for which is(m,c) is false. It does so by returning
- * ctype<char_type>::do_scan_not().
- *
- * @param m The mask to compare against.
- * @param lo Pointer to first char in range.
- * @param hi Pointer to end of range.
- * @return Pointer to non-matching char if found, else @a hi.
- */
- const char_type*
- scan_not(mask __m, const char_type* __lo, const char_type* __hi) const
- { return this->do_scan_not(__m, __lo, __hi); }
- /**
- * @brief Convert to uppercase.
- *
- * This function converts the argument to uppercase if possible.
- * If not possible (for example, '2'), returns the argument. It does
- * so by returning ctype<char_type>::do_toupper().
- *
- * @param c The char_type to convert.
- * @return The uppercase char_type if convertible, else @a c.
- */
- char_type
- toupper(char_type __c) const
- { return this->do_toupper(__c); }
- /**
- * @brief Convert array to uppercase.
- *
- * This function converts each char_type in the range [lo,hi) to
- * uppercase if possible. Other elements remain untouched. It does so
- * by returning ctype<char_type>:: do_toupper(lo, hi).
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- const char_type*
- toupper(char_type *__lo, const char_type* __hi) const
- { return this->do_toupper(__lo, __hi); }
- /**
- * @brief Convert to lowercase.
- *
- * This function converts the argument to lowercase if possible. If
- * not possible (for example, '2'), returns the argument. It does so
- * by returning ctype<char_type>::do_tolower(c).
- *
- * @param c The char_type to convert.
- * @return The lowercase char_type if convertible, else @a c.
- */
- char_type
- tolower(char_type __c) const
- { return this->do_tolower(__c); }
- /**
- * @brief Convert array to lowercase.
- *
- * This function converts each char_type in the range [lo,hi) to
- * lowercase if possible. Other elements remain untouched. It does so
- * by returning ctype<char_type>:: do_tolower(lo, hi).
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- const char_type*
- tolower(char_type* __lo, const char_type* __hi) const
- { return this->do_tolower(__lo, __hi); }
- /**
- * @brief Widen char to char_type
- *
- * This function converts the char argument to char_type using the
- * simplest reasonable transformation. It does so by returning
- * ctype<char_type>::do_widen(c).
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param c The char to convert.
- * @return The converted char_type.
- */
- char_type
- widen(char __c) const
- { return this->do_widen(__c); }
- /**
- * @brief Widen array to char_type
- *
- * This function converts each char in the input to char_type using the
- * simplest reasonable transformation. It does so by returning
- * ctype<char_type>::do_widen(c).
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param to Pointer to the destination array.
- * @return @a hi.
- */
- const char*
- widen(const char* __lo, const char* __hi, char_type* __to) const
- { return this->do_widen(__lo, __hi, __to); }
- /**
- * @brief Narrow char_type to char
- *
- * This function converts the char_type to char using the simplest
- * reasonable transformation. If the conversion fails, dfault is
- * returned instead. It does so by returning
- * ctype<char_type>::do_narrow(c).
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param c The char_type to convert.
- * @param dfault Char to return if conversion fails.
- * @return The converted char.
- */
- char
- narrow(char_type __c, char __dfault) const
- { return this->do_narrow(__c, __dfault); }
- /**
- * @brief Narrow array to char array
- *
- * This function converts each char_type in the input to char using the
- * simplest reasonable transformation and writes the results to the
- * destination array. For any char_type in the input that cannot be
- * converted, @a dfault is used instead. It does so by returning
- * ctype<char_type>::do_narrow(lo, hi, dfault, to).
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param dfault Char to use if conversion fails.
- * @param to Pointer to the destination array.
- * @return @a hi.
- */
- const char_type*
- narrow(const char_type* __lo, const char_type* __hi,
- char __dfault, char *__to) const
- { return this->do_narrow(__lo, __hi, __dfault, __to); }
- protected:
- explicit
- __ctype_abstract_base(size_t __refs = 0): facet(__refs) { }
- virtual
- ~__ctype_abstract_base() { }
- /**
- * @brief Test char_type classification.
- *
- * This function finds a mask M for @a c and compares it to mask @a m.
- *
- * do_is() is a hook for a derived facet to change the behavior of
- * classifying. do_is() must always return the same result for the
- * same input.
- *
- * @param c The char_type to find the mask of.
- * @param m The mask to compare against.
- * @return (M & m) != 0.
- */
- virtual bool
- do_is(mask __m, char_type __c) const = 0;
- /**
- * @brief Return a mask array.
- *
- * This function finds the mask for each char_type in the range [lo,hi)
- * and successively writes it to vec. vec must have as many elements
- * as the input.
- *
- * do_is() is a hook for a derived facet to change the behavior of
- * classifying. do_is() must always return the same result for the
- * same input.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param vec Pointer to an array of mask storage.
- * @return @a hi.
- */
- virtual const char_type*
- do_is(const char_type* __lo, const char_type* __hi,
- mask* __vec) const = 0;
- /**
- * @brief Find char_type matching mask
- *
- * This function searches for and returns the first char_type c in
- * [lo,hi) for which is(m,c) is true.
- *
- * do_scan_is() is a hook for a derived facet to change the behavior of
- * match searching. do_is() must always return the same result for the
- * same input.
- *
- * @param m The mask to compare against.
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return Pointer to a matching char_type if found, else @a hi.
- */
- virtual const char_type*
- do_scan_is(mask __m, const char_type* __lo,
- const char_type* __hi) const = 0;
- /**
- * @brief Find char_type not matching mask
- *
- * This function searches for and returns a pointer to the first
- * char_type c of [lo,hi) for which is(m,c) is false.
- *
- * do_scan_is() is a hook for a derived facet to change the behavior of
- * match searching. do_is() must always return the same result for the
- * same input.
- *
- * @param m The mask to compare against.
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return Pointer to a non-matching char_type if found, else @a hi.
- */
- virtual const char_type*
- do_scan_not(mask __m, const char_type* __lo,
- const char_type* __hi) const = 0;
- /**
- * @brief Convert to uppercase.
- *
- * This virtual function converts the char_type argument to uppercase
- * if possible. If not possible (for example, '2'), returns the
- * argument.
- *
- * do_toupper() is a hook for a derived facet to change the behavior of
- * uppercasing. do_toupper() must always return the same result for
- * the same input.
- *
- * @param c The char_type to convert.
- * @return The uppercase char_type if convertible, else @a c.
- */
- virtual char_type
- do_toupper(char_type) const = 0;
- /**
- * @brief Convert array to uppercase.
- *
- * This virtual function converts each char_type in the range [lo,hi)
- * to uppercase if possible. Other elements remain untouched.
- *
- * do_toupper() is a hook for a derived facet to change the behavior of
- * uppercasing. do_toupper() must always return the same result for
- * the same input.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- virtual const char_type*
- do_toupper(char_type* __lo, const char_type* __hi) const = 0;
- /**
- * @brief Convert to lowercase.
- *
- * This virtual function converts the argument to lowercase if
- * possible. If not possible (for example, '2'), returns the argument.
- *
- * do_tolower() is a hook for a derived facet to change the behavior of
- * lowercasing. do_tolower() must always return the same result for
- * the same input.
- *
- * @param c The char_type to convert.
- * @return The lowercase char_type if convertible, else @a c.
- */
- virtual char_type
- do_tolower(char_type) const = 0;
- /**
- * @brief Convert array to lowercase.
- *
- * This virtual function converts each char_type in the range [lo,hi)
- * to lowercase if possible. Other elements remain untouched.
- *
- * do_tolower() is a hook for a derived facet to change the behavior of
- * lowercasing. do_tolower() must always return the same result for
- * the same input.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- virtual const char_type*
- do_tolower(char_type* __lo, const char_type* __hi) const = 0;
- /**
- * @brief Widen char
- *
- * This virtual function converts the char to char_type using the
- * simplest reasonable transformation.
- *
- * do_widen() is a hook for a derived facet to change the behavior of
- * widening. do_widen() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param c The char to convert.
- * @return The converted char_type
- */
- virtual char_type
- do_widen(char) const = 0;
- /**
- * @brief Widen char array
- *
- * This function converts each char in the input to char_type using the
- * simplest reasonable transformation.
- *
- * do_widen() is a hook for a derived facet to change the behavior of
- * widening. do_widen() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param lo Pointer to start range.
- * @param hi Pointer to end of range.
- * @param to Pointer to the destination array.
- * @return @a hi.
- */
- virtual const char*
- do_widen(const char* __lo, const char* __hi,
- char_type* __dest) const = 0;
- /**
- * @brief Narrow char_type to char
- *
- * This virtual function converts the argument to char using the
- * simplest reasonable transformation. If the conversion fails, dfault
- * is returned instead.
- *
- * do_narrow() is a hook for a derived facet to change the behavior of
- * narrowing. do_narrow() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param c The char_type to convert.
- * @param dfault Char to return if conversion fails.
- * @return The converted char.
- */
- virtual char
- do_narrow(char_type, char __dfault) const = 0;
- /**
- * @brief Narrow char_type array to char
- *
- * This virtual function converts each char_type in the range [lo,hi) to
- * char using the simplest reasonable transformation and writes the
- * results to the destination array. For any element in the input that
- * cannot be converted, @a dfault is used instead.
- *
- * do_narrow() is a hook for a derived facet to change the behavior of
- * narrowing. do_narrow() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param dfault Char to use if conversion fails.
- * @param to Pointer to the destination array.
- * @return @a hi.
- */
- virtual const char_type*
- do_narrow(const char_type* __lo, const char_type* __hi,
- char __dfault, char* __dest) const = 0;
- };
- // NB: Generic, mostly useless implementation.
- /**
- * @brief Template ctype facet
- *
- * This template class defines classification and conversion functions for
- * character sets. It wraps <cctype> functionality. Ctype gets used by
- * streams for many I/O operations.
- *
- * This template provides the protected virtual functions the developer
- * will have to replace in a derived class or specialization to make a
- * working facet. The public functions that access them are defined in
- * __ctype_abstract_base, to allow for implementation flexibility. See
- * ctype<wchar_t> for an example. The functions are documented in
- * __ctype_abstract_base.
- *
- * Note: implementations are provided for all the protected virtual
- * functions, but will likely not be useful.
- */
- template<typename _CharT>
- class ctype : public __ctype_abstract_base<_CharT>
- {
- public:
- // Types:
- typedef _CharT char_type;
- typedef typename __ctype_abstract_base<_CharT>::mask mask;
- /// The facet id for ctype<char_type>
- static locale::id id;
- explicit
- ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { }
- protected:
- virtual
- ~ctype();
- virtual bool
- do_is(mask __m, char_type __c) const;
- virtual const char_type*
- do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
- virtual const char_type*
- do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
- virtual const char_type*
- do_scan_not(mask __m, const char_type* __lo,
- const char_type* __hi) const;
- virtual char_type
- do_toupper(char_type __c) const;
- virtual const char_type*
- do_toupper(char_type* __lo, const char_type* __hi) const;
- virtual char_type
- do_tolower(char_type __c) const;
- virtual const char_type*
- do_tolower(char_type* __lo, const char_type* __hi) const;
- virtual char_type
- do_widen(char __c) const;
- virtual const char*
- do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
- virtual char
- do_narrow(char_type, char __dfault) const;
- virtual const char_type*
- do_narrow(const char_type* __lo, const char_type* __hi,
- char __dfault, char* __dest) const;
- };
- template<typename _CharT>
- locale::id ctype<_CharT>::id;
- // 22.2.1.3 ctype<char> specialization.
- /**
- * @brief The ctype<char> specialization.
- *
- * This class defines classification and conversion functions for
- * the char type. It gets used by char streams for many I/O
- * operations. The char specialization provides a number of
- * optimizations as well.
- */
- template<>
- class ctype<char> : public locale::facet, public ctype_base
- {
- public:
- // Types:
- /// Typedef for the template parameter char.
- typedef char char_type;
- protected:
- // Data Members:
- __c_locale _M_c_locale_ctype;
- bool _M_del;
- __to_type _M_toupper;
- __to_type _M_tolower;
- const mask* _M_table;
- mutable char _M_widen_ok;
- mutable char _M_widen[1 + static_cast<unsigned char>(-1)];
- mutable char _M_narrow[1 + static_cast<unsigned char>(-1)];
- mutable char _M_narrow_ok; // 0 uninitialized, 1 init,
- // 2 memcpy can't be used
- public:
- /// The facet id for ctype<char>
- static locale::id id;
- /// The size of the mask table. It is SCHAR_MAX + 1.
- static const size_t table_size = 1 + static_cast<unsigned char>(-1);
- /**
- * @brief Constructor performs initialization.
- *
- * This is the constructor provided by the standard.
- *
- * @param table If non-zero, table is used as the per-char mask.
- * Else classic_table() is used.
- * @param del If true, passes ownership of table to this facet.
- * @param refs Passed to the base facet class.
- */
- explicit
- ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0);
- /**
- * @brief Constructor performs static initialization.
- *
- * This constructor is used to construct the initial C locale facet.
- *
- * @param cloc Handle to C locale data.
- * @param table If non-zero, table is used as the per-char mask.
- * @param del If true, passes ownership of table to this facet.
- * @param refs Passed to the base facet class.
- */
- explicit
- ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false,
- size_t __refs = 0);
- /**
- * @brief Test char classification.
- *
- * This function compares the mask table[c] to @a m.
- *
- * @param c The char to compare the mask of.
- * @param m The mask to compare against.
- * @return True if m & table[c] is true, false otherwise.
- */
- inline bool
- is(mask __m, char __c) const;
- /**
- * @brief Return a mask array.
- *
- * This function finds the mask for each char in the range [lo, hi) and
- * successively writes it to vec. vec must have as many elements as
- * the char array.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param vec Pointer to an array of mask storage.
- * @return @a hi.
- */
- inline const char*
- is(const char* __lo, const char* __hi, mask* __vec) const;
- /**
- * @brief Find char matching a mask
- *
- * This function searches for and returns the first char in [lo,hi) for
- * which is(m,char) is true.
- *
- * @param m The mask to compare against.
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return Pointer to a matching char if found, else @a hi.
- */
- inline const char*
- scan_is(mask __m, const char* __lo, const char* __hi) const;
- /**
- * @brief Find char not matching a mask
- *
- * This function searches for and returns a pointer to the first char
- * in [lo,hi) for which is(m,char) is false.
- *
- * @param m The mask to compare against.
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return Pointer to a non-matching char if found, else @a hi.
- */
- inline const char*
- scan_not(mask __m, const char* __lo, const char* __hi) const;
- /**
- * @brief Convert to uppercase.
- *
- * This function converts the char argument to uppercase if possible.
- * If not possible (for example, '2'), returns the argument.
- *
- * toupper() acts as if it returns ctype<char>::do_toupper(c).
- * do_toupper() must always return the same result for the same input.
- *
- * @param c The char to convert.
- * @return The uppercase char if convertible, else @a c.
- */
- char_type
- toupper(char_type __c) const
- { return this->do_toupper(__c); }
- /**
- * @brief Convert array to uppercase.
- *
- * This function converts each char in the range [lo,hi) to uppercase
- * if possible. Other chars remain untouched.
- *
- * toupper() acts as if it returns ctype<char>:: do_toupper(lo, hi).
- * do_toupper() must always return the same result for the same input.
- *
- * @param lo Pointer to first char in range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- const char_type*
- toupper(char_type *__lo, const char_type* __hi) const
- { return this->do_toupper(__lo, __hi); }
- /**
- * @brief Convert to lowercase.
- *
- * This function converts the char argument to lowercase if possible.
- * If not possible (for example, '2'), returns the argument.
- *
- * tolower() acts as if it returns ctype<char>::do_tolower(c).
- * do_tolower() must always return the same result for the same input.
- *
- * @param c The char to convert.
- * @return The lowercase char if convertible, else @a c.
- */
- char_type
- tolower(char_type __c) const
- { return this->do_tolower(__c); }
- /**
- * @brief Convert array to lowercase.
- *
- * This function converts each char in the range [lo,hi) to lowercase
- * if possible. Other chars remain untouched.
- *
- * tolower() acts as if it returns ctype<char>:: do_tolower(lo, hi).
- * do_tolower() must always return the same result for the same input.
- *
- * @param lo Pointer to first char in range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- const char_type*
- tolower(char_type* __lo, const char_type* __hi) const
- { return this->do_tolower(__lo, __hi); }
- /**
- * @brief Widen char
- *
- * This function converts the char to char_type using the simplest
- * reasonable transformation. For an underived ctype<char> facet, the
- * argument will be returned unchanged.
- *
- * This function works as if it returns ctype<char>::do_widen(c).
- * do_widen() must always return the same result for the same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param c The char to convert.
- * @return The converted character.
- */
- char_type
- widen(char __c) const
- {
- if (_M_widen_ok)
- return _M_widen[static_cast<unsigned char>(__c)];
- this->_M_widen_init();
- return this->do_widen(__c);
- }
- /**
- * @brief Widen char array
- *
- * This function converts each char in the input to char using the
- * simplest reasonable transformation. For an underived ctype<char>
- * facet, the argument will be copied unchanged.
- *
- * This function works as if it returns ctype<char>::do_widen(c).
- * do_widen() must always return the same result for the same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param lo Pointer to first char in range.
- * @param hi Pointer to end of range.
- * @param to Pointer to the destination array.
- * @return @a hi.
- */
- const char*
- widen(const char* __lo, const char* __hi, char_type* __to) const
- {
- if (_M_widen_ok == 1)
- {
- memcpy(__to, __lo, __hi - __lo);
- return __hi;
- }
- if (!_M_widen_ok)
- _M_widen_init();
- return this->do_widen(__lo, __hi, __to);
- }
- /**
- * @brief Narrow char
- *
- * This function converts the char to char using the simplest
- * reasonable transformation. If the conversion fails, dfault is
- * returned instead. For an underived ctype<char> facet, @a c
- * will be returned unchanged.
- *
- * This function works as if it returns ctype<char>::do_narrow(c).
- * do_narrow() must always return the same result for the same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param c The char to convert.
- * @param dfault Char to return if conversion fails.
- * @return The converted character.
- */
- char
- narrow(char_type __c, char __dfault) const
- {
- if (_M_narrow[static_cast<unsigned char>(__c)])
- return _M_narrow[static_cast<unsigned char>(__c)];
- const char __t = do_narrow(__c, __dfault);
- if (__t != __dfault)
- _M_narrow[static_cast<unsigned char>(__c)] = __t;
- return __t;
- }
- /**
- * @brief Narrow char array
- *
- * This function converts each char in the input to char using the
- * simplest reasonable transformation and writes the results to the
- * destination array. For any char in the input that cannot be
- * converted, @a dfault is used instead. For an underived ctype<char>
- * facet, the argument will be copied unchanged.
- *
- * This function works as if it returns ctype<char>::do_narrow(lo, hi,
- * dfault, to). do_narrow() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param dfault Char to use if conversion fails.
- * @param to Pointer to the destination array.
- * @return @a hi.
- */
- const char_type*
- narrow(const char_type* __lo, const char_type* __hi,
- char __dfault, char *__to) const
- {
- if (__builtin_expect(_M_narrow_ok == 1, true))
- {
- memcpy(__to, __lo, __hi - __lo);
- return __hi;
- }
- if (!_M_narrow_ok)
- _M_narrow_init();
- return this->do_narrow(__lo, __hi, __dfault, __to);
- }
- protected:
- /// Returns a pointer to the mask table provided to the constructor, or
- /// the default from classic_table() if none was provided.
- const mask*
- table() const throw()
- { return _M_table; }
- /// Returns a pointer to the C locale mask table.
- static const mask*
- classic_table() throw();
- /**
- * @brief Destructor.
- *
- * This function deletes table() if @a del was true in the
- * constructor.
- */
- virtual
- ~ctype();
- /**
- * @brief Convert to uppercase.
- *
- * This virtual function converts the char argument to uppercase if
- * possible. If not possible (for example, '2'), returns the argument.
- *
- * do_toupper() is a hook for a derived facet to change the behavior of
- * uppercasing. do_toupper() must always return the same result for
- * the same input.
- *
- * @param c The char to convert.
- * @return The uppercase char if convertible, else @a c.
- */
- virtual char_type
- do_toupper(char_type) const;
- /**
- * @brief Convert array to uppercase.
- *
- * This virtual function converts each char in the range [lo,hi) to
- * uppercase if possible. Other chars remain untouched.
- *
- * do_toupper() is a hook for a derived facet to change the behavior of
- * uppercasing. do_toupper() must always return the same result for
- * the same input.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- virtual const char_type*
- do_toupper(char_type* __lo, const char_type* __hi) const;
- /**
- * @brief Convert to lowercase.
- *
- * This virtual function converts the char argument to lowercase if
- * possible. If not possible (for example, '2'), returns the argument.
- *
- * do_tolower() is a hook for a derived facet to change the behavior of
- * lowercasing. do_tolower() must always return the same result for
- * the same input.
- *
- * @param c The char to convert.
- * @return The lowercase char if convertible, else @a c.
- */
- virtual char_type
- do_tolower(char_type) const;
- /**
- * @brief Convert array to lowercase.
- *
- * This virtual function converts each char in the range [lo,hi) to
- * lowercase if possible. Other chars remain untouched.
- *
- * do_tolower() is a hook for a derived facet to change the behavior of
- * lowercasing. do_tolower() must always return the same result for
- * the same input.
- *
- * @param lo Pointer to first char in range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- virtual const char_type*
- do_tolower(char_type* __lo, const char_type* __hi) const;
- /**
- * @brief Widen char
- *
- * This virtual function converts the char to char using the simplest
- * reasonable transformation. For an underived ctype<char> facet, the
- * argument will be returned unchanged.
- *
- * do_widen() is a hook for a derived facet to change the behavior of
- * widening. do_widen() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param c The char to convert.
- * @return The converted character.
- */
- virtual char_type
- do_widen(char __c) const
- { return __c; }
- /**
- * @brief Widen char array
- *
- * This function converts each char in the range [lo,hi) to char using
- * the simplest reasonable transformation. For an underived
- * ctype<char> facet, the argument will be copied unchanged.
- *
- * do_widen() is a hook for a derived facet to change the behavior of
- * widening. do_widen() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param to Pointer to the destination array.
- * @return @a hi.
- */
- virtual const char*
- do_widen(const char* __lo, const char* __hi, char_type* __dest) const
- {
- memcpy(__dest, __lo, __hi - __lo);
- return __hi;
- }
- /**
- * @brief Narrow char
- *
- * This virtual function converts the char to char using the simplest
- * reasonable transformation. If the conversion fails, dfault is
- * returned instead. For an underived ctype<char> facet, @a c will be
- * returned unchanged.
- *
- * do_narrow() is a hook for a derived facet to change the behavior of
- * narrowing. do_narrow() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param c The char to convert.
- * @param dfault Char to return if conversion fails.
- * @return The converted char.
- */
- virtual char
- do_narrow(char_type __c, char) const
- { return __c; }
- /**
- * @brief Narrow char array to char array
- *
- * This virtual function converts each char in the range [lo,hi) to
- * char using the simplest reasonable transformation and writes the
- * results to the destination array. For any char in the input that
- * cannot be converted, @a dfault is used instead. For an underived
- * ctype<char> facet, the argument will be copied unchanged.
- *
- * do_narrow() is a hook for a derived facet to change the behavior of
- * narrowing. do_narrow() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param dfault Char to use if conversion fails.
- * @param to Pointer to the destination array.
- * @return @a hi.
- */
- virtual const char_type*
- do_narrow(const char_type* __lo, const char_type* __hi,
- char, char* __dest) const
- {
- memcpy(__dest, __lo, __hi - __lo);
- return __hi;
- }
- private:
- void _M_widen_init() const
- {
- char __tmp[sizeof(_M_widen)];
- for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
- __tmp[__i] = __i;
- do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
- _M_widen_ok = 1;
- // Set _M_widen_ok to 2 if memcpy can't be used.
- if (memcmp(__tmp, _M_widen, sizeof(_M_widen)))
- _M_widen_ok = 2;
- }
- // Fill in the narrowing cache and flag whether all values are
- // valid or not. _M_narrow_ok is set to 2 if memcpy can't
- // be used.
- void _M_narrow_init() const
- {
- char __tmp[sizeof(_M_narrow)];
- for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
- __tmp[__i] = __i;
- do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow);
- _M_narrow_ok = 1;
- if (memcmp(__tmp, _M_narrow, sizeof(_M_narrow)))
- _M_narrow_ok = 2;
- else
- {
- // Deal with the special case of zero: renarrow with a
- // different default and compare.
- char __c;
- do_narrow(__tmp, __tmp + 1, 1, &__c);
- if (__c == 1)
- _M_narrow_ok = 2;
- }
- }
- };
- template<>
- const ctype<char>&
- use_facet<ctype<char> >(const locale& __loc);
- #ifdef _GLIBCXX_USE_WCHAR_T
- // 22.2.1.3 ctype<wchar_t> specialization
- /**
- * @brief The ctype<wchar_t> specialization.
- *
- * This class defines classification and conversion functions for the
- * wchar_t type. It gets used by wchar_t streams for many I/O operations.
- * The wchar_t specialization provides a number of optimizations as well.
- *
- * ctype<wchar_t> inherits its public methods from
- * __ctype_abstract_base<wchar_t>.
- */
- template<>
- class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>
- {
- public:
- // Types:
- /// Typedef for the template parameter wchar_t.
- typedef wchar_t char_type;
- typedef wctype_t __wmask_type;
- protected:
- __c_locale _M_c_locale_ctype;
- // Pre-computed narrowed and widened chars.
- bool _M_narrow_ok;
- char _M_narrow[128];
- wint_t _M_widen[1 + static_cast<unsigned char>(-1)];
- // Pre-computed elements for do_is.
- mask _M_bit[16];
- __wmask_type _M_wmask[16];
- public:
- // Data Members:
- /// The facet id for ctype<wchar_t>
- static locale::id id;
- /**
- * @brief Constructor performs initialization.
- *
- * This is the constructor provided by the standard.
- *
- * @param refs Passed to the base facet class.
- */
- explicit
- ctype(size_t __refs = 0);
- /**
- * @brief Constructor performs static initialization.
- *
- * This constructor is used to construct the initial C locale facet.
- *
- * @param cloc Handle to C locale data.
- * @param refs Passed to the base facet class.
- */
- explicit
- ctype(__c_locale __cloc, size_t __refs = 0);
- protected:
- __wmask_type
- _M_convert_to_wmask(const mask __m) const;
- /// Destructor
- virtual
- ~ctype();
- /**
- * @brief Test wchar_t classification.
- *
- * This function finds a mask M for @a c and compares it to mask @a m.
- *
- * do_is() is a hook for a derived facet to change the behavior of
- * classifying. do_is() must always return the same result for the
- * same input.
- *
- * @param c The wchar_t to find the mask of.
- * @param m The mask to compare against.
- * @return (M & m) != 0.
- */
- virtual bool
- do_is(mask __m, char_type __c) const;
- /**
- * @brief Return a mask array.
- *
- * This function finds the mask for each wchar_t in the range [lo,hi)
- * and successively writes it to vec. vec must have as many elements
- * as the input.
- *
- * do_is() is a hook for a derived facet to change the behavior of
- * classifying. do_is() must always return the same result for the
- * same input.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @param vec Pointer to an array of mask storage.
- * @return @a hi.
- */
- virtual const char_type*
- do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
- /**
- * @brief Find wchar_t matching mask
- *
- * This function searches for and returns the first wchar_t c in
- * [lo,hi) for which is(m,c) is true.
- *
- * do_scan_is() is a hook for a derived facet to change the behavior of
- * match searching. do_is() must always return the same result for the
- * same input.
- *
- * @param m The mask to compare against.
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return Pointer to a matching wchar_t if found, else @a hi.
- */
- virtual const char_type*
- do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
- /**
- * @brief Find wchar_t not matching mask
- *
- * This function searches for and returns a pointer to the first
- * wchar_t c of [lo,hi) for which is(m,c) is false.
- *
- * do_scan_is() is a hook for a derived facet to change the behavior of
- * match searching. do_is() must always return the same result for the
- * same input.
- *
- * @param m The mask to compare against.
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return Pointer to a non-matching wchar_t if found, else @a hi.
- */
- virtual const char_type*
- do_scan_not(mask __m, const char_type* __lo,
- const char_type* __hi) const;
- /**
- * @brief Convert to uppercase.
- *
- * This virtual function converts the wchar_t argument to uppercase if
- * possible. If not possible (for example, '2'), returns the argument.
- *
- * do_toupper() is a hook for a derived facet to change the behavior of
- * uppercasing. do_toupper() must always return the same result for
- * the same input.
- *
- * @param c The wchar_t to convert.
- * @return The uppercase wchar_t if convertible, else @a c.
- */
- virtual char_type
- do_toupper(char_type) const;
- /**
- * @brief Convert array to uppercase.
- *
- * This virtual function converts each wchar_t in the range [lo,hi) to
- * uppercase if possible. Other elements remain untouched.
- *
- * do_toupper() is a hook for a derived facet to change the behavior of
- * uppercasing. do_toupper() must always return the same result for
- * the same input.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- virtual const char_type*
- do_toupper(char_type* __lo, const char_type* __hi) const;
- /**
- * @brief Convert to lowercase.
- *
- * This virtual function converts the argument to lowercase if
- * possible. If not possible (for example, '2'), returns the argument.
- *
- * do_tolower() is a hook for a derived facet to change the behavior of
- * lowercasing. do_tolower() must always return the same result for
- * the same input.
- *
- * @param c The wchar_t to convert.
- * @return The lowercase wchar_t if convertible, else @a c.
- */
- virtual char_type
- do_tolower(char_type) const;
- /**
- * @brief Convert array to lowercase.
- *
- * This virtual function converts each wchar_t in the range [lo,hi) to
- * lowercase if possible. Other elements remain untouched.
- *
- * do_tolower() is a hook for a derived facet to change the behavior of
- * lowercasing. do_tolower() must always return the same result for
- * the same input.
- *
- * @param lo Pointer to start of range.
- * @param hi Pointer to end of range.
- * @return @a hi.
- */
- virtual const char_type*
- do_tolower(char_type* __lo, const char_type* __hi) const;
- /**
- * @brief Widen char to wchar_t
- *
- * This virtual function converts the char to wchar_t using the
- * simplest reasonable transformation. For an underived ctype<wchar_t>
- * facet, the argument will be cast to wchar_t.
- *
- * do_widen() is a hook for a derived facet to change the behavior of
- * widening. do_widen() must always return the same result for the
- * same input.
- *
- * Note: this is not what you want for codepage conversions. See
- * codecvt for that.
- *
- * @param c The char to convert.
- * @return The converted wchar_t.
- */
- virtual char_type
- do_widen(char) const;
- /**
- * @brief Widen char array to wchar_t array
- *
- * This function converts each char in the input to wchar_t using the
- * simplest reasonable transformation. For an underived ctype<wchar_t>
- * facet, the argu…