Difference between revisions of "cpp/string/char traits"
Line 1: | Line 1: | ||
{{cpp/title|char_traits}} | {{cpp/title|char_traits}} | ||
{{cpp/string/char_traits/navbar}} | {{cpp/string/char_traits/navbar}} | ||
− | {{ddcl | header=string | 1= | + | {{ddcl|header=string|1= |
template< | template< | ||
class CharT | class CharT | ||
Line 9: | Line 9: | ||
The {{tt|char_traits}} class is a traits class template that abstracts basic character and string operations for a given character type. The defined operation set is such that generic algorithms almost always can be implemented in terms of it. It is thus possible to use such algorithms with almost any possible character or string type, just by supplying a customized {{tt|char_traits}} class. | The {{tt|char_traits}} class is a traits class template that abstracts basic character and string operations for a given character type. The defined operation set is such that generic algorithms almost always can be implemented in terms of it. It is thus possible to use such algorithms with almost any possible character or string type, just by supplying a customized {{tt|char_traits}} class. | ||
− | The {{tt|char_traits}} class template serves as a basis for explicit instantiations. The user can [[cpp/language/extending std|provide a specialization]] for any custom character types. Several specializations are | + | The {{tt|char_traits}} class template serves as a basis for explicit instantiations. The user can [[cpp/language/extending std|provide a specialization]] for any custom character types. Several explicit specializations are provided for the standard character types (see below), other specializations are not required to satisfy the requirements of {{named req|CharTraits}}. |
− | + | ===Specializations=== | |
+ | The standard library provides the following standard specializations: | ||
+ | {{dsc begin}} | ||
+ | {{dsc header|string}} | ||
+ | {{dsc|{{c/core|std::char_traits<char>}}|the standard character traits of {{c/core|char}}}} | ||
+ | {{dsc|{{c/core|std::char_traits<wchar_t>}}|the standard character traits of {{c/core|wchar_t}}}} | ||
+ | {{dsc|{{c/core|std::char_traits<char8_t>}} {{mark c++20}}|the standard character traits of {{c/core|char8_t}}}} | ||
+ | {{dsc|{{c/core|std::char_traits<char16_t>}} {{mark c++11}}|the standard character traits of {{c/core|char16_t}}}} | ||
+ | {{dsc|{{c/core|std::char_traits<char32_t>}} {{mark c++11}}|the standard character traits of {{c/core|char32_t}}}} | ||
+ | {{dsc end}} | ||
− | + | All these specializations satisfy the requirements of {{named req|CharTraits}}. | |
− | + | ||
− | { | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | {| | + | ====Member types==== |
− | | | + | The standard specializations define the following member types required by {{named req|CharTraits}}: |
− | ! Member type | + | {|class=wikitable style="text-align: center;" |
− | + | !rowspan=2|{{tt|CharT}} | |
− | |- | + | !colspan=5|Member type |
− | | {{tt|off_type}} | + | |- |
− | | {{lc|std::streamoff}} | + | !{{nbsp}}{{tt|char_type}}{{nbsp}} |
− | | | + | !{{tt|int_type}} |
− | | {{ | + | !{{tt|off_type}} |
− | | {{lc|std:: | + | !{{tt|pos_type}} |
− | |- | + | !{{tt|state_type}} |
− | | {{ | + | |- |
− | | {{lc|std:: | + | |{{c/core|char}} |
+ | |{{c/core|char}} | ||
+ | |{{c/core|int}} | ||
+ | |rowspan=5|{{nbsp}}{{lc|std::streamoff}}{{nbsp}} | ||
+ | |{{lc|std::streampos}} | ||
+ | |rowspan=5|{{nbsp}}{{lc|std::mbstate_t}}{{nbsp}} | ||
+ | |- | ||
+ | |{{c/core|wchar_t}} | ||
+ | |{{c/core|wchar_t}} | ||
+ | |{{ltt|cpp/string/wide#Types|std::wint_t}} | ||
+ | |{{lc|std::wstreampos}} | ||
+ | |- | ||
+ | |{{c/core|char8_t}} | ||
+ | |{{c/core|char8_t}} | ||
+ | |{{c/core|unsigned int}} | ||
+ | |{{lc|std::u8streampos}} | ||
+ | |- | ||
+ | |{{nbsp}}{{c/core|char16_t}}{{nbsp}} | ||
+ | |{{c/core|char16_t}} | ||
+ | |{{nbsp}}{{lc|std::uint_least16_t}}{{nbsp}} | ||
+ | |{{nbsp}}{{lc|std::u16streampos}}{{nbsp}} | ||
+ | |- | ||
+ | |{{c/core|char32_t}} | ||
+ | |{{c/core|char32_t}} | ||
+ | |{{lc|std::uint_least32_t}} | ||
+ | |{{lc|std::u32streampos}} | ||
|} | |} | ||
− | + | {{rrev|since=c++20| | |
− | { | + | On top of that, the standard specializations also define the member type {{tt|comparison_category}} as {{ltt std|cpp/utility/compare/strong_ordering}}. |
− | + | }} | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | | | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | ===Member | + | ====Member functions==== |
+ | The standard specializations define the following static member functions required by {{named req|CharTraits}}: | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc | + | {{dsc inc|cpp/string/char_traits/dsc assign}} |
− | {{dsc | {{ | + | {{dsc inc|cpp/string/char_traits/dsc cmp}} |
− | {{dsc | {{ | + | {{dsc inc|cpp/string/char_traits/dsc move}} |
− | {{dsc | {{ | + | {{dsc inc|cpp/string/char_traits/dsc copy}} |
− | {{dsc | | + | {{dsc inc|cpp/string/char_traits/dsc compare}} |
− | {{dsc | | + | {{dsc inc|cpp/string/char_traits/dsc length}} |
+ | {{dsc inc|cpp/string/char_traits/dsc find}} | ||
+ | {{dsc inc|cpp/string/char_traits/dsc to_char_type}} | ||
+ | {{dsc inc|cpp/string/char_traits/dsc to_int_type}} | ||
+ | {{dsc inc|cpp/string/char_traits/dsc eq_int_type}} | ||
+ | {{dsc inc|cpp/string/char_traits/dsc eof}} | ||
+ | {{dsc inc|cpp/string/char_traits/dsc not_eof}} | ||
{{dsc end}} | {{dsc end}} | ||
− | === | + | ===Notes=== |
− | {{ | + | {{named req|CharTraits}} does not require defining the types and functions listed above as direct members, it only requires types like {{tt|X::type}} and expressions like {{c|X::func(args)}} are valid and have the required semantics. Users-defined character traits can be derived from other character traits classes and only override some of their members, see the example below. |
− | + | ||
− | {{ | + | |
− | {{ | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
===Example=== | ===Example=== | ||
Line 135: | Line 92: | ||
|User-defined character traits may be used to provide [http://www.gotw.ca/gotw/029.htm case-insensitive comparison]: | |User-defined character traits may be used to provide [http://www.gotw.ca/gotw/029.htm case-insensitive comparison]: | ||
|code= | |code= | ||
+ | #include <cctype> | ||
+ | #include <iostream> | ||
#include <string> | #include <string> | ||
#include <string_view> | #include <string_view> | ||
− | |||
− | |||
struct ci_char_traits : public std::char_traits<char> | struct ci_char_traits : public std::char_traits<char> | ||
Line 173: | Line 130: | ||
static const char* find(const char* s, std::size_t n, char a) | static const char* find(const char* s, std::size_t n, char a) | ||
{ | { | ||
− | auto | + | const auto ua{to_upper(a)}; |
while (n-- != 0) | while (n-- != 0) | ||
{ | { | ||
Line 204: | Line 161: | ||
Hello and heLLo are equal | Hello and heLLo are equal | ||
}} | }} | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
===See also=== | ===See also=== | ||
{{dsc begin}} | {{dsc begin}} | ||
{{dsc inc|cpp/string/dsc basic_string}} | {{dsc inc|cpp/string/dsc basic_string}} | ||
+ | {{dsc inc|cpp/string/dsc basic_string_view}} | ||
+ | {{dsc inc|cpp/io/dsc basic_istream}} | ||
+ | {{dsc inc|cpp/io/dsc basic_ostream}} | ||
+ | {{dsc inc|cpp/io/dsc basic_streambuf}} | ||
{{dsc end}} | {{dsc end}} | ||
{{langlinks|de|es|fr|it|ja|pt|ru|zh}} | {{langlinks|de|es|fr|it|ja|pt|ru|zh}} |
Latest revision as of 15:24, 12 September 2023
Defined in header <string>
|
||
template< class CharT |
||
The char_traits
class is a traits class template that abstracts basic character and string operations for a given character type. The defined operation set is such that generic algorithms almost always can be implemented in terms of it. It is thus possible to use such algorithms with almost any possible character or string type, just by supplying a customized char_traits
class.
The char_traits
class template serves as a basis for explicit instantiations. The user can provide a specialization for any custom character types. Several explicit specializations are provided for the standard character types (see below), other specializations are not required to satisfy the requirements of CharTraits.
Contents |
[edit] Specializations
The standard library provides the following standard specializations:
Defined in header
<string> | |
std::char_traits<char> | the standard character traits of char |
std::char_traits<wchar_t> | the standard character traits of wchar_t |
std::char_traits<char8_t> (C++20) | the standard character traits of char8_t |
std::char_traits<char16_t> (C++11) | the standard character traits of char16_t |
std::char_traits<char32_t> (C++11) | the standard character traits of char32_t |
All these specializations satisfy the requirements of CharTraits.
[edit] Member types
The standard specializations define the following member types required by CharTraits:
CharT
|
Member type | ||||
---|---|---|---|---|---|
char_type
|
int_type
|
off_type
|
pos_type
|
state_type
| |
char | char | int | std::streamoff | std::streampos | std::mbstate_t |
wchar_t | wchar_t | std::wint_t | std::wstreampos | ||
char8_t | char8_t | unsigned int | std::u8streampos | ||
char16_t | char16_t | std::uint_least16_t | std::u16streampos | ||
char32_t | char32_t | std::uint_least32_t | std::u32streampos |
On top of that, the standard specializations also define the member type |
(since C++20) |
[edit] Member functions
The standard specializations define the following static member functions required by CharTraits:
[static] |
assigns a character (public static member function) |
[static] |
compares two characters (public static member function) |
[static] |
moves one character sequence onto another (public static member function) |
[static] |
copies a character sequence (public static member function) |
[static] |
lexicographically compares two character sequences (public static member function) |
[static] |
returns the length of a character sequence (public static member function) |
[static] |
finds a character in a character sequence (public static member function) |
[static] |
converts int_type to equivalent char_type (public static member function) |
[static] |
converts char_type to equivalent int_type (public static member function) |
[static] |
compares two int_type values (public static member function) |
[static] |
returns an eof value (public static member function) |
[static] |
checks whether a character is eof value (public static member function) |
[edit] Notes
CharTraits does not require defining the types and functions listed above as direct members, it only requires types like X::type
and expressions like X::func(args) are valid and have the required semantics. Users-defined character traits can be derived from other character traits classes and only override some of their members, see the example below.
[edit] Example
User-defined character traits may be used to provide case-insensitive comparison:
#include <cctype> #include <iostream> #include <string> #include <string_view> struct ci_char_traits : public std::char_traits<char> { static char to_upper(char ch) { return std::toupper((unsigned char) ch); } static bool eq(char c1, char c2) { return to_upper(c1) == to_upper(c2); } static bool lt(char c1, char c2) { return to_upper(c1) < to_upper(c2); } static int compare(const char* s1, const char* s2, std::size_t n) { while (n-- != 0) { if (to_upper(*s1) < to_upper(*s2)) return -1; if (to_upper(*s1) > to_upper(*s2)) return 1; ++s1; ++s2; } return 0; } static const char* find(const char* s, std::size_t n, char a) { const auto ua{to_upper(a)}; while (n-- != 0) { if (to_upper(*s) == ua) return s; s++; } return nullptr; } }; template<class DstTraits, class CharT, class SrcTraits> constexpr std::basic_string_view<CharT, DstTraits> traits_cast(const std::basic_string_view<CharT, SrcTraits> src) noexcept { return {src.data(), src.size()}; } int main() { using namespace std::literals; constexpr auto s1 = "Hello"sv; constexpr auto s2 = "heLLo"sv; if (traits_cast<ci_char_traits>(s1) == traits_cast<ci_char_traits>(s2)) std::cout << s1 << " and " << s2 << " are equal\n"; }
Output:
Hello and heLLo are equal
[edit] See also
stores and manipulates sequences of characters (class template) | |
(C++17) |
read-only string view (class template) |
wraps a given abstract device (std::basic_streambuf) and provides high-level input interface (class template) | |
wraps a given abstract device (std::basic_streambuf) and provides high-level output interface (class template) | |
abstracts a raw device (class template) |