Thursday, November 28, 2024

char_traits

Overview
char_traits classes define common behavior such as comparison, assignment, copy etc. and also other aspects such as eof  type, offset type position type etc.

Details
Syntax
template <class charT> struct char_traits
where charT is the character type of the associated with the traits object.

Specializations
A template specializations are defined for these data types - char,  wchar_t, char16_tand char32_t. 
  1. template <> struct char_traits<char>
  2. template <> struct char_traits<wchar_t>
  3. template <> struct char_traits<char16_t>
  4. template <> struct char_traits<char32_t>

member types
 It defines following properties for each specialization.
NameDescriptionData type
char_typeDefines type of character in the sequence.
  1. char,
  2. wchar_t
  3. char16_t
  4. char32_t
int_typeAn integer type that can represent a character of type char_type or an end-of-file (EOF) character.
  1. int
  2. wint_t
  3. uint_least16_t
  4. uint_least32_t
off_typeAn integer type that can represent offsets between positions in a stream. streamoff
pos_typeAn integer type that can represent positions in a stream. streampos
state_typeA type that represents the conversion state in for multibyte characters in a stream. mbstate_t

 Methods
The following methods are defined.
NameDescription
  1. void assign
    (char_type& t, const char_type& s)
  2. char_type* assign
    (char_type* p, size_t n, char_type s)
  1. Assigns character value from s to t.
  2. Assigns character value from s to p[n].
Example
string UTF32toNarrow(u32string&& strv)
{
    string final;
 
    mbstate_t state{};
    char out[MB_LEN_MAX]{};
    for (char32_t c : strv)
    {
        size_t rc = c32rtomb(out, c, &state);
	if (rc != (size_t)-1)
	    final.append(string{ out, rc });
    }
    return final;
 }


    setlocale(LC_ALL, "en_US.utf8");
    char_traits<char32_t>::char_type tc = U'!';
    char_traits<char32_t>::char_type sc = U'😂';
    char_traits<char32_t>::char_type str[] = U"ಖ್ರಿಷಾ Rao!";
    //1
    //prints: ! -> 😂
    cout << UTF32toNarrow(u32string{tc});
    char_traits<char32_t>::assign ( tc , sc );
    cout << " -> " << UTF32toNarrow(u32string{tc});
    cout << endl;
    
    //2
    //prints: ಖ್ರಿಷಾ Rao! -> ಖ್ರಿಷಾ Rao👸
    cout << UTF32toNarrow(u32string{str});
    auto ret = char_traits<char32_t>::assign ( str+10 , 1 , U'👸' );
    cout << " -> "  << UTF32toNarrow(u32string(str,10)) << UTF32toNarrow(u32string{*ret});
 int compare
(const char_type* s, const char_type* t, size_t n)
Compares the first n characters of the character strings s and t. The comparison is done lexicographically.
If n is zero, strings are considered equal.
Returns a signed integral indicating the relation between the sequences.
s  ==  t    :   Zero
s  <  t      :    Negative 
s  >  t      :    Positive

Example
    const char *s = "CAB", *s2 = "ABC";
    
    //prints 2
    cout << char_traits<char>::compare(s,s2,3) << endl;
    
    //prints 0
    cout << char_traits<char>::compare(s+1,s2,2) << endl;
char_type * copy
(char_type* t, const char_type* s, size_t n)
Copies a n number of characters from s to t. Note that s and t should not overlap. Returns a pointer to the first element of the copied range in t.

Example
    char s[] = "Hello world!";
    char s2[20];

    char * ret = char_traits<char>::copy (s2, s, 12);
    //ret:"Hello world!"
    ret[13] = '\0'; 
int_type eof()Returns the end-of-file (EOF) character.
char             :   -1 (EOF)
wchar_t       :    2^16 -1 or 2^32-1 (WEOF)
char16_t      :    2^16 -1
char32_t      :    2^32-1

Example
    auto ret = char_traits<char>::eof();
bool eq
(const char_type& s, const char_type& t)
Tests whether two char_type characters are equal.

Example
    cout << boolalpha;
    //prints:false
    cout << char_traits<char>::eq('a','A') << endl;
    
    //prints:true
    cout << char_traits<char>::eq('A','A') << endl;
bool eq_int_type
(const int_type& s, const int_type& t)
Tests whether two characters represented as int_types are equal.

Example
    int a = 'a';
    int A = 'A';
    
    cout << boolalpha;
    //prints:false
    cout << char_traits<char>::eq_int_type(a,A) << endl;
    
    //prints:true
    cout << char_traits<char>::eq_int_type(A,A) << endl;
const char_type* find
(const char_type* s, size_t n, const char_type& t)
Searches for the first occurrence of a specified character in the range of characters [s,s+n].  Returns pointer to the first instance of t in the range or nullptr.

Example
    char str[] = "hello, world!";

    //ret:str+4
    auto ret = char_traits<char>::find(str, 13, 'o');
    
    //ret:nullptr
    ret = char_traits<char>::find(str, 13, 'O');
size_t length
(const char_type* s)
Returns the length of a string, not including the null terminator.

Example
    char str[] = "hello, world!";

    //ret:13
    auto ret = char_traits<char>::length(str);
bool lt
(char_type s, char_type t)
Tests whether one character is less than another.

Example
    cout << boolalpha;
    //prints:true
    cout << char_traits<char>::lt('A','a') << endl;

    //prints:false
    cout << char_traits<char>::lt('a','@') << endl;
char_type *  move
(char_type* t, const char_type* s, size_t n)
Moves  n number of characters from s to t. Note that s and t may overlap. Returns a pointer to the first element of the copied range in t.

Example:
    char s[] = "Hello world!";
    char s2[20];

    //ret:"Hello world!"
    char * ret = char_traits<char>::move (s2, s, 12);
    ret[13] = '\0';

    //ret:"Hello!"
    //s2:"Hello Hello!"
    ret = char_traits<char>::move (s2+6, s2, 5);
int_type not_eof
(const int_type& c)
Tests whether a character is not the end-of-file (EOF) character or is the EOF. Returns c if it's not EOF else returns 0.

Example
    //returns:101
    auto ret = char_traits<char>::not_eof('e');
    
    //returns:0
    ret = char_traits<char>::not_eof(-1);
char_type to_char_type
(const int_type& i)
Converts an int_type character to the corresponding char_type character and returns the result.

Example
    //returns:101
    auto ret = char_traits<char>::to_int_type('e');
int_type to_int_type
(const char_type& c)
Converts a char_type character to the corresponding int_type character and returns the result.

Example
    //returns:'e'
    auto ret2 = char_traits<char>::to_char_type(101);

The example 2 demonstrates a custom char_trait that compares literals case agnostically.



No comments:

Post a Comment