| 71 | |
| 72 | template<typename Utf32String> |
| 73 | static std::string convertUtf32ToUtf8(const Utf32String& utf32_str) { |
| 74 | std::string result; |
| 75 | result.reserve(utf32_str.size() * 4); |
| 76 | |
| 77 | for (auto character : utf32_str) { |
| 78 | if (character < 0x80) // ASCII character |
| 79 | result.push_back(static_cast<char>(character)); |
| 80 | else if (character < 0x800) { // 2 byte character |
| 81 | result.push_back(static_cast<char>((character >> 6) | 0xC0)); |
| 82 | result.push_back(static_cast<char>((character & 0x3F) | 0x80)); |
| 83 | } |
| 84 | else if (character < 0x10000) { // 3 byte character |
| 85 | result.push_back(static_cast<char>((character >> 12) | 0xE0)); |
| 86 | result.push_back(static_cast<char>(((character >> 6) & 0x3F) | 0x80)); |
| 87 | result.push_back(static_cast<char>((character & 0x3F) | 0x80)); |
| 88 | } |
| 89 | else if (character < 0x110000) { // 4 byte character |
| 90 | result.push_back(static_cast<char>((character >> 18) | 0xF0)); |
| 91 | result.push_back(static_cast<char>(((character >> 12) & 0x3F) | 0x80)); |
| 92 | result.push_back(static_cast<char>(((character >> 6) & 0x3F) | 0x80)); |
| 93 | result.push_back(static_cast<char>((character & 0x3F) | 0x80)); |
| 94 | } |
| 95 | else // Error |
| 96 | return result; |
| 97 | } |
| 98 | return result; |
| 99 | } |
| 100 | |
| 101 | template<typename T> |
| 102 | static T convertUtf32ToUtf16(const std::u32string& utf32_str) { |