类模板 __char_traits_base 用来作为 char_traits 的基类。
template <class _CharT, class _IntT> class __char_traits_base {
####类模板 __char_traits_base####
__char_traits_base 中定义了两个公有属性的成员类型。
public:
typedef _CharT char_type;
typedef _IntT int_type;
__char_traits_base 定义了一系列的成员函数,char_traits 中大量的成员函数都是继承自基类。
函数 assign 用 char_type 类型的给定变量 __c2 对另一个 char_type 类型的变量进行赋值。
static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; }
函数 eq 判断两个类型为 char_type 的变量是否相等。
static bool eq(const _CharT& __c1, const _CharT& __c2)
{ return __c1 == __c2; }
函数 lt 判断给定的 char_type 类型的变量 __c1 是否要小于另一个同类型的变量 __c2 。
static bool lt(const _CharT& __c1, const _CharT& __c2)
{ return __c1 < __c2; }
函数比较从 __s1 开始长度为 __n 的序列是否和从 __s2 开始长度为 __n 的序列大小,如果第一个序列小,则返回 -1,如果第一个序列大,则返回 1 。如果两个序列相等,则返回 0 。
static int compare(const _CharT* __s1, const _CharT* __s2, size_t __n) {
for (size_t __i = 0; __i < __n; ++__i)
if (!eq(__s1[__i], __s2[__i]))
return __s1[__i] < __s2[__i] ? -1 : 1;
return 0;
}
函数 length 计算从 __s 开始的序列的长度,函数声明一个 CharT 类型的空实例 __nullchar 。从 __s 开始往后遍历,如果碰到一个为 __nullchar 的元素,则停止遍历,并返回 __nullchar 之前的元素个数。
static size_t length(const _CharT* __s) {
const _CharT __nullchar = _CharT();
size_t __i;
for (__i = 0; !eq(__s[__i], __nullchar); ++__i)
{}
return __i;
}
在从 __s 开始长度为 __n 的序列中查找值为 __c 的元素。
static const _CharT* find(const _CharT* __s, size_t __n, const _CharT& __c)
{
for ( ; __n > 0 ; ++__s, --__n)
if (eq(*__s, __c))
return __s;
return 0;
}
函数 move 调用 memmove 将从 __s2 开始长度为 __n 的序列移动到 __s1 开始的位置。memmove 能保证当 __s2 和 __s1 之间有重叠时也能顺利移动。
static _CharT* move(_CharT* __s1, const _CharT* __s2, size_t __n) {
memmove(__s1, __s2, __n * sizeof(_CharT));
return __s1;
}
函数 copy 调用 memcpy 将从 __s2 开始长度为 __n 的序列复制到 __s1 开始的位置。当 __s1 和 __s2 之间有重叠时可能会产生覆盖的问题。
static _CharT* copy(_CharT* __s1, const _CharT* __s2, size_t __n) {
memcpy(__s1, __s2, __n * sizeof(_CharT));
return __s1;
}
函数 assign 将 __s 开始长度为 __n 的序列中的元素都赋值为 __c 。
static _CharT* assign(_CharT* __s, size_t __n, _CharT __c) {
for (size_t __i = 0; __i < __n; ++__i)
__s[__i] = __c;
return __s;
}
函数 not_eof 判断 __c 是否为 eof 。
static int_type not_eof(const int_type& __c) {
return !eq_int_type(__c, eof()) ? __c : 0;
}
函数 to_char_type 将 int_type 类型的变量 __c 强制转换为 char_type 类型的变量,并将强制转换得到的变量作为返回值返回。
static char_type to_char_type(const int_type& __c) {
return static_cast<char_type>(__c);
}
函数 to_int_type 将 char_type 类型的变量 __c 强制转换为 int_type 类型的变量,并将强制转换得到的变量作为返回值返回。
static int_type to_int_type(const char_type& __c) {
return static_cast<int_type>(__c);
}
函数 eq_int_type 判断两个 int_type 类型的变量 __c1 和 __c2 是否相等。
static bool eq_int_type(const int_type& __c1, const int_type& __c2) {
return __c1 == __c2;
}
函数 eof 用来返回 eof(即 -1)。
static int_type eof() {
return static_cast<int_type>(-1);
}
####类模板 char_traits####
类模板 char_traits 继承自 __char_traits_base<_CharT, _CharT> 。
template <class _CharT> class char_traits
: public __char_traits_base<_CharT, _CharT>
{};
当 char_traits 的模板实参为 char 时, char_traits 有如下的偏特化定义。该定义中重定义了 to_char_type, to_int_type, compare, length, assign 函数。
to_char_type 函数将 int 类型的变量强制转换为 char 类型,to_int_type 类型变量将 char 类型变量转换为 int 类型。 compare 调用 memcmp 比较两个字符串的大小。 length 函数调用 strlen 求给定字符串的长度。 assign 函数实现 const char 类型的变量对 char 类型变量的赋值,而第二个 assign 函数调用 memset 对从 __s 开始长度为 __n 的字符串中的字符赋同一个值。
__STL_TEMPLATE_NULL class char_traits<char>
: public __char_traits_base<char, int>
{
public:
static char_type to_char_type(const int_type& __c) {
return static_cast<char_type>(static_cast<unsigned char>(__c));
}
static int_type to_int_type(const char_type& __c) {
return static_cast<unsigned char>(__c);
}
static int compare(const char* __s1, const char* __s2, size_t __n)
{ return memcmp(__s1, __s2, __n); }
static size_t length(const char* __s) { return strlen(__s); }
static void assign(char& __c1, const char& __c2) { __c1 = __c2; }
static char* assign(char* __s, size_t __n, char __c)
{ memset(__s, __c, __n); return __s; }
};
当char_traits 的模板实参为 wchar_t 时使用如下偏特化定义。
__STL_TEMPLATE_NULL class char_traits<wchar_t>
: public __char_traits_base<wchar_t, wint_t>
{};