NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
codepoint.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_STRING_CODEPOINT_HPP__
2#define NEFORCE_CORE_STRING_CODEPOINT_HPP__
3
11
14NEFORCE_BEGIN_NAMESPACE__
15
117
126class NEFORCE_API codepoint {
127public:
129 static constexpr uint32_t REPLACEMENT_VALUE = 0xFFFD;
131 static constexpr uint32_t MAX_VALUE = 0x10FFFF;
132
140 NEFORCE_CONST_FUNCTION static constexpr bool is_high_surrogate(const char16_t c) noexcept {
141 return c >= 0xD800 && c <= 0xDBFF;
142 }
143
151 NEFORCE_CONST_FUNCTION static constexpr bool is_low_surrogate(const char16_t c) noexcept {
152 return c >= 0xDC00 && c <= 0xDFFF;
153 }
154
163 NEFORCE_CONST_FUNCTION static constexpr codepoint combine_surrogates(const char16_t high,
164 const char16_t low) noexcept {
165 return codepoint{0x10000 + ((static_cast<uint32_t>(high) - 0xD800) << 10) +
166 (static_cast<uint32_t>(low) - 0xDC00)};
167 }
168
179 static constexpr bool is_valid_codepoint(const uint32_t v) noexcept {
180 return v <= MAX_VALUE && !is_high_surrogate(v) && !is_low_surrogate(v);
181 }
182
189 static constexpr codepoint replacement() noexcept { return codepoint{REPLACEMENT_VALUE}; }
190
195 static constexpr codepoint null() noexcept { return codepoint(0U); }
196
207 static codepoint decode_utf8(const byte_t* data, size_t& i, size_t len) noexcept;
208
221 template <typename T>
222 static codepoint decode_utf16(const T* data, size_t& index, const size_t len, const bool need_swap) noexcept {
223 uint32_t cp = 0;
224 size_t consumed = 0;
225 const bool ok = codepoint::utf16_codepoint(data, index, len, cp, consumed, need_swap);
226 if (consumed == 0) {
227 return replacement();
228 }
229 index += consumed;
230 return ok ? codepoint(cp) : replacement();
231 }
232
240 static constexpr codepoint from_utf32(const char32_t value) noexcept {
241 return codepoint(static_cast<uint32_t>(value));
242 }
243
244private:
245 uint32_t value_{0};
246
247private:
248 template <typename T>
249 static bool utf16_codepoint(const T* data, size_t index, const size_t len, uint32_t& cp, size_t& consumed,
250 const bool need_swap) {
251 if (index >= len) {
252 cp = 0xFFFD;
253 consumed = 0;
254 return false;
255 }
256
257 const auto raw1 = static_cast<uint16_t>(data[index]);
258 const auto c1 = static_cast<uint32_t>(need_swap ? endian::byteswap16(raw1) : raw1);
259 consumed = 1;
260
261 if (is_high_surrogate(c1)) {
262 if (index + 1 < len) {
263 const auto raw2 = static_cast<uint16_t>(data[index + 1]);
264 const auto c2 = static_cast<uint32_t>(need_swap ? endian::byteswap16(raw2) : raw2);
265
266 if (is_low_surrogate(c2)) {
267 cp = combine_surrogates(c1, c2).value();
268 consumed = 2;
269 return true;
270 }
271 }
272
273 cp = 0xFFFD;
274 return false;
275 }
276
277 if (is_low_surrogate(c1)) {
278 cp = 0xFFFD;
279 return false;
280 }
281
282 cp = c1;
283 return true;
284 }
285
286public:
291 constexpr codepoint() noexcept = default;
292
299 constexpr explicit codepoint(const uint32_t value) noexcept :
301
308 constexpr explicit codepoint(const int32_t value) noexcept :
309 codepoint(static_cast<uint32_t>(value)) {}
310
315 constexpr codepoint(const char32_t value) noexcept :
316 codepoint(static_cast<uint32_t>(value)) {}
317
318 constexpr codepoint(const codepoint&) noexcept = default;
319 constexpr codepoint& operator=(const codepoint&) noexcept = default;
320 constexpr codepoint(codepoint&&) noexcept = default;
321 constexpr codepoint& operator=(codepoint&&) noexcept = default;
322
327 NEFORCE_NODISCARD constexpr uint32_t value() const noexcept { return value_; }
328
334 NEFORCE_NODISCARD int display_width() const noexcept;
335
340 NEFORCE_NODISCARD constexpr char32_t to_char32() const noexcept { return static_cast<char32_t>(value_); }
341
346 NEFORCE_NODISCARD constexpr bool is_replacement() const noexcept { return value_ == REPLACEMENT_VALUE; }
347
352 NEFORCE_NODISCARD constexpr bool is_ascii() const noexcept { return value_ <= 0x7F; }
353
358 NEFORCE_NODISCARD constexpr bool is_bmp() const noexcept { return value_ <= 0xFFFF; }
359
364 NEFORCE_NODISCARD constexpr bool is_supplementary() const noexcept {
365 return value_ > 0xFFFF && value_ <= MAX_VALUE;
366 }
367
372 NEFORCE_NODISCARD constexpr bool needs_surrogate_pair() const noexcept { return is_supplementary(); }
373
384 NEFORCE_NODISCARD constexpr size_t utf8_length() const noexcept {
385 if (value_ <= 0x7F) {
386 return 1;
387 }
388 if (value_ <= 0x7FF) {
389 return 2;
390 }
391 if (value_ <= 0xFFFF) {
392 return 3;
393 }
394 return 4;
395 }
396
403 NEFORCE_NODISCARD constexpr size_t utf16_length() const noexcept { return is_supplementary() ? 2U : 1U; }
404
411 void append_to(string& result) const;
412
413#ifdef NEFORCE_STANDARD_20
420 void append_to(u8string& result) const;
421#endif
422
430 void append_to(u16string& result) const;
431
438 void append_to(u32string& result) const { result.push_back(static_cast<char32_t>(value_)); }
439
444 void append_to(wstring& result) const;
445
446 constexpr bool operator==(const codepoint& other) const noexcept { return value_ == other.value_; }
447 constexpr bool operator!=(const codepoint& other) const noexcept { return value_ != other.value_; }
448 constexpr bool operator<(const codepoint& other) const noexcept { return value_ < other.value_; }
449 constexpr bool operator<=(const codepoint& other) const noexcept { return value_ <= other.value_; }
450 constexpr bool operator>(const codepoint& other) const noexcept { return value_ > other.value_; }
451 constexpr bool operator>=(const codepoint& other) const noexcept { return value_ >= other.value_; }
452
453 constexpr bool operator==(uint32_t v) const noexcept { return value_ == v; }
454 constexpr bool operator!=(uint32_t v) const noexcept { return value_ != v; }
455};
456 // CodePoint
458
459NEFORCE_END_NAMESPACE__
460#endif // NEFORCE_CORE_STRING_CODEPOINT_HPP__
constexpr void push_back(value_type value)
在末尾插入字符
Unicode码点包装类
void append_to(u16string &result) const
追加UTF-16编码到u16string
static constexpr codepoint replacement() noexcept
构造替换符U+FFFD
static constexpr uint32_t MAX_VALUE
Unicode 最大合法码点
constexpr bool needs_surrogate_pair() const noexcept
是否需要UTF-16代理对表示
static codepoint decode_utf16(const T *data, size_t &index, const size_t len, const bool need_swap) noexcept
从UTF-16序列解码一个码点,并推进索引
constexpr char32_t to_char32() const noexcept
获取码点的char32_t值
static constexpr bool is_low_surrogate(const char16_t c) noexcept
检查字符是否为低代理项
constexpr size_t utf16_length() const noexcept
UTF-16编码后的码元数
void append_to(u32string &result) const
追加UTF-32编码到u32string
constexpr bool is_bmp() const noexcept
是否位于基本多文种平面(BMP, U+0000 ~ U+FFFF)
constexpr bool is_replacement() const noexcept
是否为替换符U+FFFD
constexpr uint32_t value() const noexcept
获取码点的uint32_t值
static constexpr bool is_high_surrogate(const char16_t c) noexcept
检查字符是否为高代理项
constexpr bool is_supplementary() const noexcept
是否为辅助平面字符(需要UTF-16代理对)
static constexpr codepoint from_utf32(const char32_t value) noexcept
从UTF-32值直接构造码点
void append_to(wstring &result) const
追加编码到wstring
int display_width() const noexcept
获取码点在终端中的显示宽度
constexpr codepoint(const int32_t value) noexcept
从int32_t构造码点
constexpr size_t utf8_length() const noexcept
UTF-8编码后的字节数
void append_to(string &result) const
追加UTF-8编码到string
void append_to(u8string &result) const
追加UTF-8编码到u8string
constexpr codepoint() noexcept=default
默认构造函数
static constexpr bool is_valid_codepoint(const uint32_t v) noexcept
检查码点值是否合法
static codepoint decode_utf8(const byte_t *data, size_t &i, size_t len) noexcept
从UTF-8字节流解码一个码点,并推进索引
static constexpr uint32_t REPLACEMENT_VALUE
Unicode 替换符 U+FFFD
constexpr codepoint(const char32_t value) noexcept
从char32_t构造码点
static constexpr codepoint combine_surrogates(const char16_t high, const char16_t low) noexcept
组合高代理项和低代理项为完整的Unicode码点
static constexpr codepoint null() noexcept
构造空字符U+0000
constexpr bool is_ascii() const noexcept
是否为ASCII字符(U+0000 ~ U+007F)
端序转换工具
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
int int32_t
32位有符号整数类型
unsigned short uint16_t
16位无符号整数类型
bool operator!=(const function< Res(Args...)> &f, nullptr_t np) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t np) noexcept
等于空指针比较
basic_string< wchar_t > wstring
宽字符字符串
basic_string< char16_t > u16string
UTF-16字符串
basic_string< char32_t > u32string
UTF-32字符串
basic_string< char8_t > u8string
UTF-8字符串
constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
字符串类型别名和实用函数