touched. It does so * by returning ctype:: 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::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:: 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::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::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::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::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 hÅ&Æ&Ç&È&É&Ê&Ë&Ì&Í&Î&Ï&Ð&Ñ&Ò&Ó&Ô&Õ&Ö&×&Ø&Ù&Ú&Û&Ü&Ý&Þ&ß&à&á&â&ã&ä&å&æ&ç&è&é&ê&ë&ì&í&î&ï&ð&ñ&ò&ó&ô&õ&ö&÷&ø&ù&ú&û&ü&ý&þ&ÿ&''''''''' ' ' ' ' ''''''i. */ 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 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 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 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 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 locale::id ctype<_CharT>::id; // 22.2.1.3 ctype specialization. /** * @brief The ctype 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 : 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(-1)]; mutable char _M_narrow[1 + static_cast(-1)]; mutable char _M_narrow_ok; // 0 uninitialized, 1 init, // 2 memcpy can't be used public: /// The facet id for ctype static locale::id id; /// The size of the mask table. It is SCHAR_MAX + 1. static const size_t table_size = 1 + static_cast(-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::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:: 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::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:: 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 facet, the * argument will be returned unchanged. * * This function works as if it returns ctype::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(__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 * facet, the argument will be copied unchanged. * * This function works as if it returns ctype::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) { __builtin_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 facet, @a c * will be returned unchanged. * * This function works as if it returns ctype::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(__c)]) return _M_narrow[static_cast(__c)]; const char __t = do_narrow(__c, __dfault); if (__t != __dfault) _M_narrow[static_cast(__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 * facet, the argument will be copied unchanged. * * This function works as if it returns ctype::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)) { __builtin_memcpy(__to, __lo, __hi - __lo); return __hi; } if (!_M_narrow_ok) _M_narrow_init(); return this->do_narrow(__lo, __hi, __dfault, __to); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 695. ctype::classic_table() not accessible. /// 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(); protected: /** * @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 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 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 { __builtin_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 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 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 { __builtin_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 (__builtin_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 (__builtin_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& use_facet >(const locale& __loc); #ifdef _GLIBCXX_USE_WCHAR_T // 22.2.1.3 ctype specialization /** * @brief The ctype 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 inherits its public methods from * __ctype_abstract_base. */ template<> class ctype : public __ctype_abstract_base { 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(-1)]; // Pre-computed elements for do_is. mask _M_bit[16]; __wmask_type _M_wmask[16]; public: // Data Members: /// The facet id for ctype 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 * 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 * facet, the argument will be copied, casting each element 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 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; /** * @brief Narrow wchar_t to char * * This virtual function converts the argument to char using * the simplest reasonable transformation. If the conversion * fails, dfault is returned instead. For an underived * ctype facet, @a c will be cast to char and * returned. * * 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 wchar_t to convert. * @param dfault Char to return if conversion fails. * @return The converted char. */ virtual char do_narrow(char_type, char __dfault) const; /** * @brief Narrow wchar_t array to char array * * This virtual function converts each wchar_t in the range [lo,hi) to * char using the simplest reasonable transformation and writes the * results to the destination array. For any wchar_t in the input that * cannot be converted, @a dfault is used instead. For an underived * ctype facet, the argument will be copied, casting each * element to char. * * 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; // For use at construction time only. void _M_initialize_ctype(); }; template<> const ctype& use_facet >(const locale& __loc); #endif //_GLIBCXX_USE_WCHAR_T /// class ctype_byname [22.2.1.2]. template class ctype_byname : public ctype<_CharT> { public: typedef typename ctype<_CharT>::mask mask; explicit ctype_byname(const char* __s, size_t __refs = 0); protected: virtual ~ctype_byname() { }; }; /// 22.2.1.4 Class ctype_byname specializations. template<> class ctype_byname : public ctype { public: explicit ctype_byname(const char* __s, size_t __refs = 0); protected: virtual ~ctype_byname(); }; #ifdef _GLIBCXX_USE_WCHAR_T template<> class ctype_byname : public ctype { public: explicit ctype_byname(const char* __s, size_t __refs = 0); protected: virtual ~ctype_byname(); }; #endif _GLIBCXX_END_NAMESPACE // Include host and configuration specific ctype inlines. #include _GLIBCXX_BEGIN_NAMESPACE(std) // 22.2.2 The numeric category. class __num_base { public: // NB: Code depends on the order of _S_atoms_out elements. // Below are the indices into _S_atoms_out. enum { _S_ominus, _S_oplus, _S_ox, _S_oX, _S_odigits, _S_odigits_end = _S_odigits + 16, _S_oudigits = _S_odigits_end, _S_oudigits_end = _S_oudigits + 16, _S_oe = _S_odigits + 14, // For scientific notation, 'e' _S_oE = _S_oudigits + 14, // For scientific notation, 'E' _S_oend = _S_oudigits_end }; // A list of valid numeric literals for output. This array // contains chars that will be passed through the current locale's // ctype<_CharT>.widen() and then used to render numbers. // For the standard "C" locale, this is // "-+xX0123456789abcdef0123456789ABCDEF". static const char* _S_atoms_out; // String literal of acceptable (narrow) input, for num_get. // "-+xX0123456789abcdefABCDEF" static const char* _S_atoms_in; enum { _S_iminus, _S_iplus, _S_ix, _S_iX, _S_izero, _S_ie = _S_izero + 14, _S_iE = _S_izero + 20, _S_iend = 26 }; // num_put // Construct and return valid scanf format for floating point types. static void _S_format_float(const ios_base& __io, char* __fptr, char __mod); }; template struct __numpunct_cache : public locale::facet { const char* _M_grouping; size_t _M_grouping_size; bool _M_use_grouping; const _CharT* _M_truename; size_t _M_truename_size; const _CharT* _M_falsename; size_t _M_falsename_size; _CharT _M_decimal_point; _CharT _M_thousands_sep; // A list of valid numeric literals for output: in the standard // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF". // This array contains the chars after having been passed // through the current locale's ctype<_CharT>.widen(). _CharT _M_atoms_out[__num_base::_S_oend]; // A list of valid numeric literals for input: in the standard // "C" locale, this is "-+xX0123456789abcdefABCDEF" // This array contains the chars after having been passed // through the current locale's ctype<_CharT>.widen(). _CharT _M_atoms_in[__num_base::_S_iend]; bool _M_allocated; __numpunct_cache(size_t __refs = 0) : facet(__refs), _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false), _M_truename(NULL), _M_truename_size(0), _M_falsename(NULL), _M_falsename_size(0), _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), _M_allocated(false) { } ~__numpunct_cache(); void _M_cache(const locale& __loc); private: __numpunct_cache& operator=(const __numpunct_cache&); explicit __numpunct_cache(const __numpunct_cache&); }; template __numpunct_cache<_CharT>::~__numpunct_cache() { if (_M_allocated) { delete [] _M_grouping; delete [] _M_truename; delete [] _M_falsename; } } /** * @brief Numpunct facet. * * This facet stores several pieces of information related to printing and * scanning numbers, such as the decimal point character. It takes a * template parameter specifying the char type. The numpunct facet is * used by streams for many I/O operations involving numbers. * * The numpunct template uses protected virtual functions to provide the * actual results. The public accessors forward the call to the virtual * functions. These virtual functions are hooks for developers to * implement the behavior they require from a numpunct facet. */ template class numpunct : public locale::facet { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef basic_string<_CharT> string_type; //@} typedef __numpunct_cache<_CharT> __cache_type; protected: __cache_type* _M_data; public: /// Numpunct facet id. static locale::id id; /** * @brief Numpunct constructor. * * @param refs Refcount to pass to the base class. */ explicit numpunct(size_t __refs = 0) : facet(__refs), _M_data(NULL) { _M_initialize_numpunct(); } /** * @brief Internal constructor. Not for general use. * * This is a constructor for use by the library itself to set up the * predefined locale facets. * * @param cache __numpunct_cache object. * @param refs Refcount to pass to the base class. */ explicit numpunct(__cache_type* __cache, size_t __refs = 0) : facet(__refs), _M_data(__cache) { _M_initialize_numpunct(); } /** * @brief Internal constructor. Not for general use. * * This is a constructor for use by the library itself to set up new * locales. * * @param cloc The "C" locale. * @param refs Refcount to pass to the base class. */ explicit numpunct(__c_locale __cloc, size_t __refs = 0) : facet(__refs), _M_data(NULL) { _M_initialize_numpunct(__cloc); } /** * @brief Return decimal point character. * * This function returns a char_type to use as a decimal point. It * does so by returning returning * numpunct::do_decimal_point(). * * @return @a char_type representing a decimal point. */ char_type decimal_point() const { return this->do_decimal_point(); } /** * @brief Return thousands separator character. * * This function returns a char_type to use as a thousands * separator. It does so by returning returning * numpunct::do_thousands_sep(). * * @return char_type representing a thousands separator. */ char_type thousands_sep() const { return this->do_thousands_sep(); } /** * @brief Return grouping specification. * * This function returns a string representing groupings for the * integer part of a number. Groupings indicate where thousands * separators should be inserted in the integer part of a number. * * Each char in the return string is interpret as an integer * rather than a character. These numbers represent the number * of digits in a group. The first char in the string * represents the number of digits in the least significant * group. If a char is negative, it indicates an unlimited * number of digits for the group. If more chars from the * string are required to group a number, the last char is used * repeatedly. * * For example, if the grouping() returns "\003\002" and is * applied to the number 123456789, this corresponds to * 12,34,56,789. Note that if the string was "32", this would * put more than 50 digits into the least significant group if * the character set is ASCII. * * The string is returned by calling * numpunct::do_grouping(). * * @return string representing grouping specification. */ string grouping() const { return this->do_grouping(); } /** * @brief Return string representation of bool true. * * This function returns a string_type containing the text * representation for true bool variables. It does so by calling * numpunct::do_truename(). * * @return string_type representing printed form of true. */ string_type truename() const { return this->do_truename(); } /** * @brief Return string representation of bool false. * * This function returns a string_type containing the text * representation for false bool variables. It does so by calling * numpunct::do_falsename(). * * @return string_type representing printed form of false. */ string_type falsename() const { return this->do_falsename(); } protected: /// Destructor. virtual ~numpunct(); /** * @brief Return decimal point character. * * Returns a char_type to use as a decimal point. This function is a * hook for derived classes to change the value returned. * * @return @a char_type representing a decimal point. */ virtual char_type do_decimal_point() const { return _M_data->_M_decimal_point; } /** * @brief Return thousands separator character. * * Returns a char_type to use as a thousands separator. This function * is a hook for derived classes to change the value returned. * * @return @a char_type representing a thousands separator. */ virtual char_type do_thousands_sep() const { return _M_data->_M_thousands_sep; } /** * @brief Return grouping specification. * * Returns a string representing groupings for the integer part of a * number. This function is a hook for derived classes to change the * value returned. @see grouping() for details. * * @return String representing grouping specification. */ virtual string do_grouping() const { return _M_data->_M_grouping; } /** * @brief Return string representation of bool true. * * Returns a string_type containing the text representation for true * bool variables. This function is a hook for derived classes to * change the value returned. * * @return string_type representing printed form of true. */ virtual string_type do_truename() const { return _M_data->_M_truename; } /** * @brief Return string representation of bool false. * * Returns a string_type containing the text representation for false * bool variables. This function is a hook for derived classes to * change the value returned. * * @return string_type representing printed form of false. */ virtual string_type do_falsename() const { return _M_data->_M_falsename; } // For use at construction time only. void _M_initialize_numpunct(__c_locale __cloc = NULL); }; template locale::id numpunct<_CharT>::id; template<> numpunct::~numpunct(); template<> void numpunct::_M_initialize_numpunct(__c_locale __cloc); #ifdef _GLIBCXX_USE_WCHAR_T template<> numpunct::~numpunct(); template<> void numpunct::_M_initialize_numpunct(__c_locale __cloc); #endif /// class numpunct_byname [22.2.3.2]. template class numpunct_byname : public numpunct<_CharT> { public: typedef _CharT char_type; typedef basic_string<_CharT> string_type; explicit numpunct_byname(const char* __s, size_t __refs = 0) : numpunct<_CharT>(__refs) { if (__builtin_strcmp(__s, "C") != 0 && __builtin_strcmp(__s, "POSIX") != 0) { __c_locale __tmp; this->_S_create_c_locale(__tmp, __s); this->_M_initialize_numpunct(__tmp); this->_S_destroy_c_locale(__tmp); } } protected: virtual ~numpunct_byname() { } }; _GLIBCXX_BEGIN_LDBL_NAMESPACE /** * @brief Facet for parsing number strings. * * This facet encapsulates the code to parse and return a number * from a string. It is used by the istream numeric extraction * operators. * * The num_get template uses protected virtual functions to provide the * actual results. The public accessors forward the call to the virtual * functions. These virtual functions are hooks for developers to * implement the behavior they require from the num_get facet. */ template class num_get : public locale::facet { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef _InIter iter_type; //@} /// Numpunct facet id. 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 num_get(size_t __refs = 0) : facet(__refs) { } /** * @brief Numeric parsing. * * Parses the input stream into the bool @a v. It does so by calling * num_get::do_get(). * * If ios_base::boolalpha is set, attempts to read * ctype::truename() or ctype::falsename(). Sets * @a v to true or false if successful. Sets err to * ios_base::failbit if reading the string fails. Sets err to * ios_base::eofbit if the stream is emptied. * * If ios_base::boolalpha is not set, proceeds as with reading a long, * except if the value is 1, sets @a v to true, if the value is 0, sets * @a v to false, and otherwise set err to ios_base::failbit. * * @param in Start of input stream. * @param end End of input stream. * @param io Source of locale and flags. * @param err Error flags to set. * @param v Value to format and insert. * @return Iterator after reading. */ iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool& __v) const { return this->do_get(__in, __end, __io, __err, __v); } //@{ /** * @brief Numeric parsing. * * Parses the input stream into the integral variable @a v. It does so * by calling num_get::do_get(). * * Parsing is affected by the flag settings in @a io. * * The basic parse is affected by the value of io.flags() & * ios_base::basefield. If equal to ios_base::oct, parses like the * scanf %o specifier. Else if equal to ios_base::hex, parses like %X * specifier. Else if basefield equal to 0, parses like the %i * specifier. Otherwise, parses like %d for signed and %u for unsigned * types. The matching type length modifier is also used. * * Digit grouping is interpreted according to numpunct::grouping() and * numpunct::thousands_sep(). If the pattern of digit groups isn't * consistent, sets err to ios_base::failbit. * * If parsing the string yields a valid value for @a v, @a v is set. * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. * Sets err to ios_base::eofbit if the stream is emptied. * * @param in Start of input stream. * @param end End of input stream. * @param io Source of locale and flags. * @param err Error flags to set. * @param v Value to format and insert. * @return Iterator after reading. */ iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned short& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned int& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } #ifdef _GLIBCXX_USE_LONG_LONG iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, long long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } #endif //@} //@{ /** * @brief Numeric parsing. * * Parses the input stream into the integral variable @a v. It does so * by calling num_get::do_get(). * * The input characters are parsed like the scanf %g specifier. The * matching type length modifier is also used. * * The decimal point character used is numpunct::decimal_point(). * Digit grouping is interpreted according to numpunct::grouping() and * numpunct::thousands_sep(). If the pattern of digit groups isn't * consistent, sets err to ios_base::failbit. * * If parsing the string yields a valid value for @a v, @a v is set. * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. * Sets err to ios_base::eofbit if the stream is emptied. * * @param in Start of input stream. * @param end End of input stream. * @param io Source of locale and flags. * @param err Error flags to set. * @param v Value to format and insert. * @return Iterator after reading. */ iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, float& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, double& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, long double& __v) const { return this->do_get(__in, __end, __io, __err, __v); } //@} /** * @brief Numeric parsing. * * Parses the input stream into the pointer varia