Apache C++ Standard Library Reference Guide

## ctype

Library: Localization

               ctype_base
    ctype ...
               locale::facet

- Local Index
- Summary
- Synopsis
- Specializations
- Description
- Interface
- Member Type
- Constructor
- Destructor
- Public Member Functions
- Facet ID
- Protected Member Functions
- Example
- See Also
- Standards Conformance

### Local Index

#### Members

char_type classic_table() ctype() do_is() do_narrow() | do_scan_is() do_scan_not() do_tolower() do_toupper() do_widen() | id is() narrow() scan_is() scan_not() | table() tolower() toupper() widen() ~ctype()

### Summary

A facet that includes character classification facilities.

### Synopsis

    #include <locale>

    namespace std {
      class ctype_base;
      template <class charT> class ctype;
    }

### Specializations

      template <> class ctype<char>;
      template <> class ctype<wchar_t>;

### Description

The class template ctype is a facet that allows you to classify characters and perform simple conversions. ctype also converts upper to lower and lower to upper case, and converts between `charT` and `char`. ctype relies on `ctype_base` for a set of masks that classify the different kinds of characters. The masks are illustrated in Table 17.

#### Table 17: Ctype masks provided by ctype_base

Class | Description | Characters included in the classic C locale
`alnum` | Characters classified as letters or digits. | All of `alpha` and `digit`.
`alpha` | Characters classified as letters. | All of `lower` and `upper`.
`cntrl` | Characters classified as control characters. | None of `alpha` or `print`.
`digit` | Characters classified as decimal digits. | The characters `'0'` through `'9'`.
`graph` | Characters classified as printable characters, excluding the space (`' '`). | All of `alpha`, `digit`, and `punct`, and none of `cntrl`.
`lower` | Characters classified as lowercase letters. | The characters `'a'` through `'z'`.
`print` | Characters classified as printable characters, including the space (`' '`). | The space (`' '`), all of `graph`, and none of `cntrl`.
`punct` | Characters classified as punctuators. | Neither the space (`' '`) character, nor any of `alpha`, `digit`, or `cntrl`.
`space` | Characters classified as whitespace. | The space (`' '`), form-feed (`'\f'`), new line ('`\n'`), carriage return (`'\r'`), horizontal tab (`'\t'`), and vertical tab (`'\v'`) characters.
`upper` | Characters classified as uppercase letters. | The characters `'A'` through `'Z'`.
`xdigit` | Characters classified as hexadecimal digits. | The characters `'A'` through `'F'`, `'a'` through `'f'`, and all of `digit`.

The masks are passed to member functions of ctype to obtain the classifications of a character or range of characters.

### Interface

    namespace std {
      class ctype_base {
      public:
        typedef int mask;
          static const mask alpha;
          static const mask cntrl;
          static const mask digit;
          static const mask graph;
          static const mask lower;
          static const mask print;
          static const mask punct;
          static const mask space;
          static const mask upper;
          static const mask xdigit;
          static const mask alnum = alpha | digit;
    };

      template <class charT>
      class ctype : public locale::facet, public ctype_base
      {
        public:
          typedef charT char_type;

          explicit ctype(size_t refs = 0);

          bool is(mask, char_type) const;

          const char_type*
          is(const char_type*, const char_type*, mask*) const;

          const char_type*
          scan_is(mask, const char_type*, const char_type*) const;

          const char_type*
          scan_not(mask, const char_type*, const char_type*) const;

          char_type toupper(char_type) const;

          const char_type*
          toupper(char_type*, const char_type*) const;

          char_type tolower(char_type) const;

          const char_type*
          tolower(char_type*, const char_type*) const;

          char_type widen(char) const;

          const char*
          widen(const char*, const char*, char_type*) const;

          char narrow(char_type, char) const;

          const char_type*
          narrow(const char_type*, const char_type*, char, char*)
                 const;

          static locale::id id;

        protected:
          virtual ~ctype();

          virtual bool  do_is(mask, char_type) const;

          virtual const char_type*
          do_is(const char_type*, const char_type*, mask*) const;
          virtual const char_type*
          do_scan_is(mask, const char_type*, const char_type*)
                     const;

          virtual const char_type*
          do_scan_not(mask, const char_type*, const char_type*)
                      const;

          virtual char_type do_toupper(char_type) const;

          virtual const char_type*
          do_toupper(char_type*, const char_type*) const;

          virtual char_type
          do_tolower(char_type) const;

          virtual const char_type*
          do_tolower(char_type*, const char_type*) const;

          virtual char_type
          do_widen(char) const;

          virtual const char*
          do_widen(const char*, const char*, char_type*) const;

          virtual char
          do_narrow(char_type, char) const;

          virtual const char_type*
          do_narrow(const char_type*, const char_type*, char, char*)
                    const;
    };

    template <>
      class ctype<char>: public locale::facet, public ctype_base
      {
        public:
          typedef char char_type;

          explicit ctype(const mask* tab = 0, bool del = false,
                         size_t refs = 0);

          bool is (mask, char_type) const;

          const char_type*
          is (const char_type*, const char_type*, mask*) const;

          const char_type*
          scan_is (mask, const char_type*, const char_type*) const;

          const char_type*
          scan_not (mask, const char_type*, const char_type*) const;

          char_type toupper (char_type) const;

          const char_type*
          toupper (char_type*, const char_type*) const;

          char_type tolower (char_type) const;

          const char_type*
          tolower (char_type*, const char_type*) const;

          char_type widen (char) const;

          const char*
          widen (const char*, const char*, char_type*) const;

          char narrow (char_type, char) const;

          const char_type*
          narrow (const char_type*, const char_type*, char, char*)
                  const;

          static locale::id id;
          static const size_t table_size = UCHAR_MAX;

        protected:
          const mask* table() const throw();

          static const mask* classic_table() throw();
          virtual ~ctype();

          virtual bool do_is (mask, char_type) const;

          virtual const char_type*
          do_is (const char_type*, const char_type*, mask*) const;

          virtual const char_type*
          do_scan_is (mask, const char_type*, const char_type*)
                      const;

          virtual const char_type*
          do_scan_not(mask, const char_type*, const char_type*)
                      const;

          virtual char_type do_toupper (char_type) const;

          virtual const char_type*
          do_toupper (char_type*, const char_type*) const;

          virtual char_type
          do_tolower (char_type) const;

          virtual const char_type*
          do_tolower (char_type*, const char_type*) const;

          virtual char_type
          do_widen (char) const;

          virtual const char*
          do_widen (const char*, const char*, char_type*) const;

          virtual char
          do_narrow (char_type, char) const;

          virtual const char_type*
          do_narrow (const char_type*, const char_type*, char,
                     char*) const;
      };
    }

### Member Type

    char_type

The type of the template argument.

### Constructor

    explicit ctype(size_t refs = 0)
    explicit ctype(const mask* tab = 0, bool del = false, size_t
                   refs = 0);

Constructs a ctype object. Calls `locale::facet (refs)`.

The `refs` argument is set to the initial value of the ctype object's reference count. A ctype object `f` constructed with `(refs == 0)` that is installed in one or more locale objects will be destroyed and the storage it occupies will be deallocated when the last locale object containing the facet is destroyed, as if by calling `delete static_cast<locale::facet*>(&f)`. A ctype object constructed with `(refs != 0)` will not be destroyed by any locale objects in which it may have been installed.

The constructor for the `ctype<char>` specialization takes two additional arguments: `tab` and `del`. If `(tab == 0)`, the effect of the constructor is the same as with `(tab == classic_table())`. Otherwise `tab` must point to the first element of an array of masks at least `ctype<char>::table_size` elements large. Each element of the table is a bitmap representing the properties of characters with values in the range `[0, table_size)`. The postcondition of the constructor is `(table() == (tab ? tab : classic_table ()))`. If `(del == true)` holds, the destructor will call `delete[] table()`.

### Destructor

    virtual ~ctype();

Destroys the facet. The `ctype<char>` specialization calls `delete[] table()` if the object was constructed with the first argument `(tbl != 0)` and the second argument `(del == true)`.

### Public Member Functions

The public members of the ctype facet include an interface to protected members. Each public member function `xxx()` calls the corresponding protected virtual member function `do_xxx()`. For instance, the public `widen()` function calls its protected cousin `do_widen()`. The result of the call may be cached. Subsequent calls to the public function may return the cached result to avoid the expense of repeatedly calling the virtual function. The public interface to the protected virtual functions is provided in order to allow derived classes to override some but not necessarily all of the often overloaded virtual functions without hiding those overloads that are not overridden.

When `(static_cast<unsigned char>(c) >= table_size)`, member functions of the `ctype<char>` specialization do not use `table()` to perform the lookup of the character mask, but instead use an unspecified algorithm to obtain its value.

    bool
    is(mask m, char_type c) const;

The primary template returns `do_is(m, c)`. The `ctype<char>` specialization returns `(table()[static_cast<unsigned char>(c)] & m)`.

    const char_type*
    is(const char_type* low,
       const char_type* high, mask* vec) const;

The primary template returns `do_is(low, high, vec)`. The `ctype<char>` specialization assigns `table()[static_cast<unsigned char>(*p)] to vec[p - low]` for all `p` in the range `[low, high)`, and returns `high`.

    char
    narrow(char_type c, char dfault) const;
    const char_type*
    narrow(const char_type* low, const char_type*, char dfault,
           char* to) const;

Returns `do_narrow(c,dfault)` and `do_narrow(low,high,dfault,to)`, respectively.

    const char_type*
    scan_is(mask m, const char_type*, const char_type* high)
            const;

The primary template returns `do_scan_is(m,low,high).` The `ctype<char>` specialization returns the smallest `p` in the range `[low, high)` such that `(table()[static_cast<unsigned char>(*p)] & m) != 0`.

    const char_type*
    scan_not(mask m, const char_type* low, const char_type* high)
             const;

The primary template returns `do_scan_not(m,low,high)`. The `ctype<char>` specialization returns the smallest `p` in the range `[low, high)` such that `(table()[static_cast<unsigned char>(*p)] & m) == 0`.

    char_type
    tolower(char_type c) const;
    const char_type*
    tolower(char_type* low, const char_type* high) const;

Returns `do_tolower(c)` and `do_tolower(low,high)`, respectively.

    char_type
    toupper(char_type c) const;
    const char_type*
    toupper(char_type* low, const char_type* high) const;

Returns `do_toupper(c)` and `do_toupper(low,high)`, respectively.

    char_type
    widen(char c) const;
    const char*
    widen(const char* low, const char* high, char_type* to) const;

Returns `do_widen(c)` and `do_widen(low,high,to)`, respectively.

    const mask*
    table() const throw();

This function is declared only the in the `ctype<char>` specialization. It returns the value of the first constructor argument, `tbl`, if it was nonzero, otherwise `classic_table()`.

### Facet ID

    static locale::id id;

Unique identifier for this type of facet.

### Protected Member Functions

    static const mask*
    classic_table() throw();

This static member function is declared only the in the `ctype<char>` specialization. It returns a pointer to the initial element of an array of at least `table_size` elements which represents the classifications of characters in the classic C locale.

    virtual bool
    do_is(mask m, char_type c) const;

Returns `true` if `c` matches the classification indicated by the mask `m`, where `m` is one of the values available from ctype_base. For instance, the following call returns `true` since `'``a``'` is an alphabetic character:

       use_facet<ctype<char> >(locale::classic ())
           .is (ctype_base::alpha, 'a');

See ctype_base for a description of the masks.

    virtual const char_type*
    do_is(const char_type* low, const char_type* high,
          mask* vec) const;

Fills `vec` with values of type `ctype_base::mask`, one for each element the range of characters indicated by `[low,high)`. Returns `high`. See ctype_base for a description of the masks. For instance, after the following call, the first five entries in the array `v` would each contain the `mask` value:`(alpha|lower|print|alnum|graph)`:

    const char a[] = "abcde";
    ctype_base::mask v[sizeof a];
    use_facet<ctype<char> >(locale::classic ())
            .is (a + 0, a + sizeof a, v);

    virtual char
    do_narrow(char_type c, char dfault) const;

Returns the appropriate `char` representation for `c`, if such exists. Otherwise, `do_narrow()` returns `dfault`.

    virtual const char_type*
    do_narrow(const char_type* low, const char_type* high,
              char dfault, char* dest) const;

Converts each character in the range `[low,high)` to its narrow representation, if possible. If the narrow representation is not available, or if the character is not valid, the character is converted to `dfault`. Returns `high`.

    virtual const char_type*
    do_scan_is(mask m, const char_type* low, const char_type*
               high) const;

Finds the first character in the range `[low,high)` that matches the classification indicated by the mask `m`.

    virtual const char_type*
    do_scan_not(mask m, const char_type* low,
                const charT* high) const;

Finds the first character in the range `[low,high)` that does not match the classification indicated by the mask `m`.

    virtual char_type
    do_tolower(char_type c) const;

Returns the lower case representation of `c,` if such exists. Otherwise, returns `c`.

    virtual const char_type*
    do_tolower(char_type* low, const char_type* high) const;

Converts each character in the range `[low,high)` to its lower case representation, if such exists. If a lower case representation does not exist, or if the character is not valid, then the character is not changed. Returns `high`.

    virtual char_type
    do_toupper(char_type c) const;

Returns the upper case representation of `c,` if such exists. Otherwise, returns `c`.

    virtual const char_type*
    do_toupper(char_type* low, const char_type* high) const;

Converts each character in the range `[low,high)` to its upper case representation, if such exists. If an upper case representation does not exist, or if the character is not valid, the character is not changed. Returns `high`.

    virtual char_type
    do_widen(char c) const;

Returns the appropriate `char_type` representation for `c`.

    virtual const char*
    do_widen(const char* low, const char* high,
             char_type* dest) const;

Converts each character in the range `[low,high)` to its `char_type` representation. Returns `high`.

### Example

    #include <iostream>   // for cout, endl
    #include <locale>     // for ctype

    int main ()
    {
        std::locale loc;
        char s [] = "blues Power";

        // Get a reference to the ctype<char> facet.
        const std::ctype<char>& ct = std::use_facet<std::ctype<char>
           >(loc);

        // Check the classification of the 'a' character.
        std::cout << ct.is (std::ctype_base::alpha, 'a') <<
           std::endl;
        std::cout << ct.is (std::ctype_base::punct, 'a') <<
           std::endl;

        // Scan for the first upper case character.
        std::cout << *ct.scan_is (std::ctype_base::upper,
                                  s, s + sizeof s / sizeof *s)
                  << std::endl;

        // Convert characters to upper case.
        ct.toupper (s, s + sizeof s / sizeof *s);
        std::cout << s << std::endl;

        return 0;
    }

    Program Output:
    1
    0
    P
    BLUES POWER

### See Also

locale, Facets, collate, ctype_byname

### Standards Conformance

ISO/IEC 14882:1998 -- International Standard for Information Systems -- Programming Language C++, Section 22.2.1.1