C++17标准在Unicode字符串的支持方面存在一定的空白。标准并没有提供将不同宽度的字符串相互转换的辅助工具,也没有提供按代码点迭代的工具。为了填补这一空白,创建了一个专门用于Unicode的库,不支持其他编码。以下是该库的主要特点:
易于使用:该库是头文件仅包含的,不需要额外的依赖,易于集成和使用。
体积小:由少量头文件组成,没有依赖。
跨平台:支持MSVC、GCC和CLANGC++17编译器。
编译时支持:该库实现了编译时支持,可以提高程序的执行效率。
该库实现了两个级别的API:
低级API:用于代码点和代码单元的操作,包括获取下一个代码点的迭代器、读取当前位置的代码点、在当前位置写入代码点并返回下一个代码点的位置、计算两个迭代器之间的代码点数量、计算指定缓冲区中的代码点数量、将'in'类型的代码点转换为'out'类型、计算给定代码点占用的代码单元数量、计算给定代码点范围占用的代码单元数量、计算给定缓冲区占用的代码单元数量。
高级API:用于字符串和缓冲区的操作,包括将任何类型的字符串转换为UTF8字符串、将任何类型的字符串转换为UTF16/UTF32字符串(平台特定)、将任何类型的字符串转换为UTF8字符串、将任何类型的字符串转换为UTF16字符串、将任何类型的字符串转换为UTF32字符串、将任何类型的字符串转换为指定类型的字符串、将'src'类型的代码单元缓冲区转换为'dst'类型的代码单元缓冲区。
实现:该库包括两个主要的头文件:
utf_codepoint.h
- 提供低级UTF支持。
utf_string.h
- 提供高级UTF支持。
集成:要使用该库,只需包含相应的头文件:
#include <sutfcpplib/utf_codepoint.h>
- 仅包含代码单元和代码点支持。
#include <slimcpplib/utf_string.h>
- 包含完整的UTF支持。
字符串字面量声明:可以使用Unicode字面量来声明字符串,例如:
auto str_utf8 = u8"\U00000041\U000000a9\U00002190\U0001f602\U00000042\U000000ae\U00002705\U0001f973"sv;
- UTF-8字符串
auto str_utf16_or_utf32 = L"\U00000041\U000000a9\U00002190\U0001f602\U00000042\U000000ae\U00002705\U0001f973"sv;
- UTF-16/UTF-32字符串
auto str_utf16 = u"\U00000041\U000000a9\U00002190\U0001f602\U00000042\U000000ae\U00002705\U0001f973"sv;
- UTF-16字符串
auto str_utf32 = U"\U00000041\U000000a9\U00002190\U0001f602\U00000042\U000000ae\U00002705\U0001f973"sv;
- UTF-32字符串
限制:高级函数,如to_string()
或convert()
,在实现中使用内存分配,不能在编译时表达式中使用,与C++17标准相符。低级函数不检查代码点是否符合Unicode标准,总是假设输入缓冲区是代码点对齐的,输出缓冲区有足够的空间。
示例:以下是使用库的主要接口的示例,带有注释:
// 示例文件 main.cpp
// 包含头文件
#include <sutfcpplib/utf_string.h>
// 使用字符串字面量声明字符串
auto str = u8"Hello, 世界!"sv;
// 将字符串转换为UTF-16
auto str_utf16 = sutf::to_u16string(str);
// 将字符串转换为UTF-32
auto str_utf32 = sutf::to_u32string(str);
// 将字符串转换为指定类型的字符串
auto str_any = sutf::to_anystring<char32_t>(str);
// 将代码单元缓冲区转换为另一种类型的代码单元缓冲区
uint8_t src[] = {0xF0, 0x9F, 0x92, 0xA9}; // UTF-8编码的字符串
uint16_t dst[4];