24 Strings library [strings]

24.2 Character traits [char.traits]

This subclause defines requirements on classes representing character traits, and defines a class template char_­traits<charT>, along with four specializations, char_­traits<char>, char_­traits<char16_­t>,
char_­traits<char32_­t>, and char_­traits<wchar_­t>, that satisfy those requirements.

Most classes specified in Clauses [string.classes] and [input.output] need a set of related types and functions to complete the definition of their semantics. These types and functions are provided as a set of member typedef-names and functions in the template parameter traits used by each such template. This subclause defines the semantics of these members.

To specialize those templates to generate a string or iostream class to handle a particular character container type CharT, that and its related character traits class Traits are passed as a pair of parameters to the string or iostream template as parameters charT and traits. Traits​::​char_­type shall be the same as CharT.

This subclause specifies a class template, char_­traits<charT>, and four explicit specializations of it, char_­traits<​char>, char_­traits<char16_­t>, char_­traits<char32_­t>, and char_­traits<wchar_­t>, all of which appear in the header <string> and satisfy the requirements below.

24.2.1 Character traits requirements [char.traits.require]

In Table 54, X denotes a Traits class defining types and functions for the character container type CharT; c and d denote values of type CharT; p and q denote values of type const CharT*; s denotes a value of type CharT*; n, i and j denote values of type size_­t; e and f denote values of type X​::​int_­type; pos denotes a value of type X​::​pos_­type; state denotes a value of type X​::​state_­type; and r denotes an lvalue of type CharT. Operations on Traits shall not throw exceptions.

Table 54 — Character traits requirements
ExpressionReturn typeAssertion/noteComplexity
pre-/post-condition
X​::​char_­type charT (described in [char.traits.typedefs]) compile-time
X​::​int_­type (described in [char.traits.typedefs]) compile-time
X​::​off_­type (described in [char.traits.typedefs]) compile-time
X​::​pos_­type (described in [char.traits.typedefs]) compile-time
X​::​state_­type (described in [char.traits.typedefs]) compile-time
X​::​eq(c,d) bool Returns: whether c is to be treated as equal to d. constant
X​::​lt(c,d) bool Returns: whether c is to be treated as less than d. constant
X​::​compare(p,q,n) int Returns: 0 if for each i in [0,n), X​::​eq(p[i],q[i]) is true; else, a negative value if, for some j in [0,n), X​::​lt(p[j],q[j]) is true and for each i in [0,j) X​::​eq(p[i],q[i]) is true; else a positive value. linear
X​::​length(p) size_­t Returns: the smallest i such that X​::​eq(p[i],charT()) is true. linear
X​::​find(p,n,c) const X​::​char_­type* Returns: the smallest q in [p,p+n) such that X​::​eq(*q,c) is true, zero otherwise. linear
X​::​move(s,p,n) X​::​char_­type* for each i in [0,n), performs X​::​assign(s[i],p[i]). Copies correctly even where the ranges [p,p+n) and [s,s+n) overlap.
Returns: s.
linear
X​::​copy(s,p,n) X​::​char_­type* Requires: p not in [s,s+n). Returns: s.
for each i in [0,n), performs X​::​assign(s[i],p[i]).
linear
X​::​assign(r,d) (not used) assigns r=d. constant
X​::​assign(s,n,c) X​::​char_­type* for each i in [0,n), performs X​::​assign(s[i],c).
Returns: s.
linear
X​::​not_­eof(e) int_­type Returns: e if X​::​eq_­int_­type(e,X​::​eof()) is false, otherwise a value f such that X​::​eq_­int_­type(f,X​::​eof()) is false. constant
X​::​to_­char_­type(e) X​::​char_­type Returns: if for some c, X​::​eq_­int_­type(e,X​::​to_­int_­type(c)) is true, c; else some unspecified value. constant
X​::​to_­int_­type(c) X​::​int_­type Returns: some value e, constrained by the definitions of to_­char_­type and eq_­int_­type. constant
X​::​eq_­int_­type(e,f) bool Returns: for all c and d, X​::​eq(c,d) is equal to X​::​eq_­int_­type(X​::​to_­int_­type(c), X​::​to_­int_­type(d)); otherwise, yields true if e and f are both copies of X​::​eof(); otherwise, yields false if one of e and f is a copy of X​::​eof() and the other is not; otherwise the value is unspecified. constant
X​::​eof() X​::​int_­type Returns: a value e such that X​::​eq_­int_­type(e,X​::​to_­int_­type(c)) is false for all values c. constant

The class template

template<class charT> struct char_traits;

shall be provided in the header <string> as a basis for explicit specializations.

24.2.2 Traits typedefs [char.traits.typedefs]

using char_type = CHAR_T;

The type char_­type is used to refer to the character container type in the implementation of the library classes defined in [string.classes] and Clause [input.output].

using int_type = INT_T;

Requires: For a certain character container type char_­type, a related container type INT_­T shall be a type or class which can represent all of the valid characters converted from the corresponding char_­type values, as well as an end-of-file value, eof(). The type int_­type represents a character container type which can hold end-of-file to be used as a return type of the iostream class member functions.224

using off_type = implementation-defined; using pos_type = implementation-defined;

Requires: Requirements for off_­type and pos_­type are described in [iostreams.limits.pos] and [iostream.forward].

using state_type = STATE_T;

Requires: state_­type shall meet the requirements of CopyAssignable, CopyConstructible, and DefaultConstructible types.

If eof() can be held in char_­type then some iostreams operations may give surprising results.

24.2.3 char_­traits specializations [char.traits.specializations]

namespace std {
  template<> struct char_traits<char>;
  template<> struct char_traits<char16_t>;
  template<> struct char_traits<char32_t>;
  template<> struct char_traits<wchar_t>;
}

The header <string> shall define four specializations of the class template char_­traits: char_­traits<​char>, char_­traits<char16_­t>, char_­traits<char32_­t>, and char_­traits<wchar_­t>.

The requirements for the members of these specializations are given in Clause [char.traits.require].

24.2.3.1 struct char_­traits<char> [char.traits.specializations.char]

namespace std {
  template<> struct char_traits<char> {
    using char_type  = char;
    using int_type   = int;
    using off_type   = streamoff;
    using pos_type   = streampos;
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static char_type* move(char_type* s1, const char_type* s2, size_t n);
    static char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
}

The defined types for int_­type, pos_­type, off_­type, and state_­type shall be int, streampos, streamoff, and mbstate_­t respectively.

The type streampos shall be an implementation-defined type that satisfies the requirements for pos_­type in [iostreams.limits.pos] and [iostream.forward].

The type streamoff shall be an implementation-defined type that satisfies the requirements for off_­type in [iostreams.limits.pos] and [iostream.forward].

The type mbstate_­t is defined in <cwchar> and can represent any of the conversion states that can occur in an implementation-defined set of supported multibyte character encoding rules.

The two-argument member assign shall be defined identically to the built-in operator =. The two-argument members eq and lt shall be defined identically to the built-in operators == and < for type unsigned char.

The member eof() shall return EOF.

24.2.3.2 struct char_­traits<char16_­t> [char.traits.specializations.char16_t]

namespace std {
  template<> struct char_traits<char16_t> {
    using char_type  = char16_t;
    using int_type   = uint_least16_t;
    using off_type   = streamoff;
    using pos_type   = u16streampos;
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static char_type* move(char_type* s1, const char_type* s2, size_t n);
    static char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
}

The type u16streampos shall be an implementation-defined type that satisfies the requirements for pos_­type in [iostreams.limits.pos] and [iostream.forward].

The two-argument members assign, eq, and lt shall be defined identically to the built-in operators =, ==, and < respectively.

The member eof() shall return an implementation-defined constant that cannot appear as a valid UTF-16 code unit.

24.2.3.3 struct char_­traits<char32_­t> [char.traits.specializations.char32_t]

namespace std {
  template<> struct char_traits<char32_t> {
    using char_type  = char32_t;
    using int_type   = uint_least32_t;
    using off_type   = streamoff;
    using pos_type   = u32streampos;
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static char_type* move(char_type* s1, const char_type* s2, size_t n);
    static char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
}

The type u32streampos shall be an implementation-defined type that satisfies the requirements for pos_­type in [iostreams.limits.pos] and [iostream.forward].

The two-argument members assign, eq, and lt shall be defined identically to the built-in operators =, ==, and < respectively.

The member eof() shall return an implementation-defined constant that cannot appear as a Unicode code point.

24.2.3.4 struct char_­traits<wchar_­t> [char.traits.specializations.wchar.t]

namespace std {
  template<> struct char_traits<wchar_t> {
    using char_type  = wchar_t;
    using int_type   = wint_t;
    using off_type   = streamoff;
    using pos_type   = wstreampos;
    using state_type = mbstate_t;

    static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
    static constexpr bool eq(char_type c1, char_type c2) noexcept;
    static constexpr bool lt(char_type c1, char_type c2) noexcept;

    static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
    static constexpr size_t length(const char_type* s);
    static constexpr const char_type* find(const char_type* s, size_t n,
                                           const char_type& a);
    static char_type* move(char_type* s1, const char_type* s2, size_t n);
    static char_type* copy(char_type* s1, const char_type* s2, size_t n);
    static char_type* assign(char_type* s, size_t n, char_type a);

    static constexpr int_type not_eof(int_type c) noexcept;
    static constexpr char_type to_char_type(int_type c) noexcept;
    static constexpr int_type to_int_type(char_type c) noexcept;
    static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
    static constexpr int_type eof() noexcept;
  };
}

The defined types for int_­type, pos_­type, and state_­type shall be wint_­t, wstreampos, and mbstate_­t respectively.

The type wstreampos shall be an implementation-defined type that satisfies the requirements for pos_­type in [iostreams.limits.pos] and [iostream.forward].

The type mbstate_­t is defined in <cwchar> and can represent any of the conversion states that can occur in an implementation-defined set of supported multibyte character encoding rules.

The two-argument members assign, eq, and lt shall be defined identically to the built-in operators =, ==, and < respectively.

The member eof() shall return WEOF.