7namespace Vkm::Engine::Utf8 {
10constexpr char32_t REPLACEMENT = 0xFFFD;
22inline char32_t next(std::string_view text, std::size_t& at) {
23 const unsigned char lead =
static_cast<unsigned char>(text[at]);
29 std::size_t length = 0;
32 if ((lead & 0xE0) == 0xC0) {
36 }
else if ((lead & 0xF0) == 0xE0) {
40 }
else if ((lead & 0xF8) == 0xF0) {
49 if (at + length > text.size()) {
53 for (std::size_t i = 1; i < length; ++i) {
54 const unsigned char byte =
static_cast<unsigned char>(text[at + i]);
55 if ((
byte & 0xC0) != 0x80) {
61 if (value < least || value > 0x10FFFF || (value >= 0xD800 && value <= 0xDFFF)) {
76inline void append(std::string& text,
char32_t codepoint) {
77 if (codepoint > 0x10FFFF || (codepoint >= 0xD800 && codepoint <= 0xDFFF)) codepoint = REPLACEMENT;
79 if (codepoint < 0x80) {
80 text.push_back(
static_cast<char>(codepoint));
81 }
else if (codepoint < 0x800) {
82 text.push_back(
static_cast<char>(0xC0 | (codepoint >> 6)));
83 text.push_back(
static_cast<char>(0x80 | (codepoint & 0x3F)));
84 }
else if (codepoint < 0x10000) {
85 text.push_back(
static_cast<char>(0xE0 | (codepoint >> 12)));
86 text.push_back(
static_cast<char>(0x80 | ((codepoint >> 6) & 0x3F)));
87 text.push_back(
static_cast<char>(0x80 | (codepoint & 0x3F)));
89 text.push_back(
static_cast<char>(0xF0 | (codepoint >> 18)));
90 text.push_back(
static_cast<char>(0x80 | ((codepoint >> 12) & 0x3F)));
91 text.push_back(
static_cast<char>(0x80 | ((codepoint >> 6) & 0x3F)));
92 text.push_back(
static_cast<char>(0x80 | (codepoint & 0x3F)));
106inline std::size_t previous(std::string_view text, std::size_t at) {
107 if (at == 0)
return 0;
108 if (at > text.size()) at = text.size();
110 std::size_t start = at - 1;
111 for (
int step = 0; step < 3 && start > 0; ++step) {
112 if ((
static_cast<unsigned char>(text[start]) & 0xC0) != 0x80)
break;
115 std::size_t end = start;
117 return end == at ? start : at - 1;
float value()
Uniform float in [0, 1), from the per-thread generator.
Definition random.h:126