Gears里面的string16
转自:http://hzx5.blog.163.com/blog/static/407443882011717104450654/
string16是一个基本的长字符(2byte的wchar_t)的string类型,这在Windows或Linux下都通用。
为什么要定义string16呢?
Firefox中用2个字节的宽字符(UTF-16),Windows中用的wchar_t,也是2个字节(UCS2),但是在Linux中,sizeof(wchar_t)则是默认4个字节!虽然我们可以用GCC标记 -fshort-wchar 来让其成为2字节,但只这会导致std::wstring在运行时出错,因为这个类调用了一些诸如wcslen等的glibc函数,而glibc是用4个字节的wchar_t来构建的!
因此,需要定义一个std::string16,它类似于std::wstring但是却手动替换了所有glibc里面的函数,完成了2字节宽字符的兼容工作。幸运的是,std::wstring在.h文件中用几乎内联的基于wchar_t的函数(例如wmemcmp),所以不需要重载。
string16的实现
1.如果在windows下,定义wchar_t为char16,std里面定义wstring为string16;如果是其他操作体统,则定义一个unsigned short为char16,在std中定义string_basic<char16>为string16;
2.char16_wmemmove和char16_wmemcpy直接调用memmove和memcpy来实现;
3.char16_wmemcmp不能直接调用memcmp因为语义可能已经变了(4个或2个字节的字符),所以要用一个while逐个比较;
4.char16_wmemchr查找某串前N个字符是否包含某字符,char16_wmemset替换某串前N个字符为指定字符,char16_wcslen返回某串长度。这些都比较容易实现,因为内联的,原则是代码要少,变量少,速度要快,效率要高。
5.定义了char_traits<char16>,它类似于gcc 3.2.2的char_traits<wchar_t>。包含char16对象的属性。
6.定义std::string IntegerToString(int32 i);std::string16 IntegerToString16(int32 i);std::string Integer64ToString(int64 i);std::string16 Integer64ToString16(int64 i);这四个函数都是从inline CharT *FastIntToBuffer(IntT i, CharT* buffer)来的。
7.上面的四个函数都引用了FastIntToBuffer,这个函数就是一个把整型转化成字符串用的,主要思想就是用/10和%10来操作。可是仔细看它对于负数的处理,是先给负数加上10用/10和%10处理一次,再给负数减去1还原原值后继续处理。这是为什么呢?因为int的最小值,也就是32位全为1的时候的数,是没办法进行i=-i的操作的(位数不够了),这里是要注意的地方