65 static_assert(
sizeof(MU8T) == 1,
"MU8T size must be at 1 byte");
66 static_assert(
sizeof(U16T) == 2,
"U16T size must be at 2 bytes");
67 static_assert(
sizeof(U8T) == 1,
"U8T size must be at 1 bytes");
69 MUTF8_Tool(
void) =
delete;
70 ~MUTF8_Tool(
void) =
delete;
73 static inline constexpr MU8T mu8FailChar[3]{ (MU8T)0xEF, (MU8T)0xBF, (MU8T)0xBD };
74 static inline constexpr U16T u16FailChar = (U16T)0xFFFD;
75 static inline constexpr U8T u8FailChar[3]{ (U8T)0xEF, (U8T)0xBF, (U8T)0xBD };
89 class FakeStringCounter
94 constexpr FakeStringCounter(
void) =
default;
95 constexpr ~FakeStringCounter(
void) =
default;
97 constexpr void clear(
void)
noexcept
102 constexpr FakeStringCounter &append(
const T *
const,
size_t szSize)
noexcept
109 constexpr FakeStringCounter &append_cvt(
const U *
const,
size_t szSize)
noexcept
115 constexpr void push_back(
const T &)
noexcept
120 constexpr const size_t &GetData(
void)
const noexcept
127 template<
typename T,
size_t N>
131 using ARRAY_TYPE = std::array<T, N>;
133 ARRAY_TYPE arrData{};
136 constexpr StaticString(
void) =
default;
137 constexpr ~StaticString(
void) =
default;
139 constexpr void clear(
void)
noexcept
144 constexpr StaticString &append(
const T *
const pData,
size_t szLength)
noexcept
146 if (szLength == 0 || szLength > arrData.size() - szIndex)
152 std::ranges::copy(&pData[0], &pData[szLength], &arrData[szIndex]);
159 constexpr StaticString &append_cvt(
const U *
const pData,
size_t szLength)
noexcept
161 if (std::is_constant_evaluated())
163 if (szLength == 0 || szLength > arrData.size() - szIndex)
169 std::ranges::transform(&pData[0], &pData[szLength], &arrData[szIndex],
180 return append((
const T *
const)pData, szLength);
184 constexpr void push_back(
const T &tData)
noexcept
186 if (1 > arrData.size() - szIndex)
191 arrData[szIndex] = tData;
195 constexpr const ARRAY_TYPE &GetData(
void)
const noexcept
202 template<
typename String>
203 class DynamicString :
public String
206 DynamicString(
size_t szReserve = 0) :
String({})
208 String::reserve(szReserve);
210 ~DynamicString(
void) =
default;
213 DynamicString &append_cvt(
const U *
const pData,
size_t szLength)
215 String::append((
const typename String::value_type *
const)pData, szLength);
219 constexpr const String &GetData(
void)
const noexcept
226 template<
size_t szBytes>
227 static constexpr void EncodeMUTF8Bmp(
const U16T u16Char, MU8T(&mu8CharArr)[szBytes])
229 if constexpr (szBytes == 1)
231 mu8CharArr[0] = (uint8_t)((((uint16_t)u16Char & (uint16_t)0b0000'0000'0111'1111) >> 0) | (uint16_t)0b0000'0000);
233 else if constexpr (szBytes == 2)
235 mu8CharArr[0] = (uint8_t)((((uint16_t)u16Char & (uint16_t)0b0000'0111'1100'0000) >> 6) | (uint16_t)0b1100'0000);
236 mu8CharArr[1] = (uint8_t)((((uint16_t)u16Char & (uint16_t)0b0000'0000'0011'1111) >> 0) | (uint16_t)0b1000'0000);
238 else if constexpr (szBytes == 3)
240 mu8CharArr[0] = (uint8_t)((((uint16_t)u16Char & (uint16_t)0b1111'0000'0000'0000) >> 12) | (uint16_t)0b1110'0000);
241 mu8CharArr[1] = (uint8_t)((((uint16_t)u16Char & (uint16_t)0b0000'1111'1100'0000) >> 6) | (uint16_t)0b1000'0000);
242 mu8CharArr[2] = (uint8_t)((((uint16_t)u16Char & (uint16_t)0b0000'0000'0011'1111) >> 0) | (uint16_t)0b1000'0000);
246 static_assert(
false,
"Error szBytes Size");
250 static constexpr void EncodeMUTF8Supplementary(
const U16T u16HighSurrogate,
const U16T u16LowSurrogate, MU8T(&mu8CharArr)[6])
254 uint32_t u32RawChar = ((uint32_t)((uint16_t)u16HighSurrogate & (uint16_t)0b0000'0011'1111'1111)) << 10 |
255 ((uint32_t)((uint16_t)u16LowSurrogate & (uint16_t)0b0000'0011'1111'1111)) << 0;
261 mu8CharArr[0] = (uint8_t)0b1110'1101;
262 mu8CharArr[1] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'1111'0000'0000'0000'0000) >> 16) | (uint32_t)0b1010'0000);
263 mu8CharArr[2] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'0000'1111'1100'0000'0000) >> 10) | (uint32_t)0b1000'0000);
265 mu8CharArr[3] = (uint8_t)0b1110'1101;
266 mu8CharArr[4] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'0000'0000'0011'1100'0000) >> 6) | (uint32_t)0b1011'0000);
267 mu8CharArr[5] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'0000'0000'0000'0011'1111) >> 0) | (uint32_t)0b1000'0000);
270 template<
size_t szBytes>
271 static constexpr void DecodeMUTF8Bmp(
const MU8T(&mu8CharArr)[szBytes], U16T &u16Char)
273 if constexpr (szBytes == 1)
275 u16Char = ((uint16_t)((uint8_t)mu8CharArr[0] & (uint8_t)0b0111'1111)) << 0;
277 else if constexpr (szBytes == 2)
279 u16Char = ((uint16_t)((uint8_t)mu8CharArr[0] & (uint8_t)0b0001'1111)) << 6 |
280 ((uint16_t)((uint8_t)mu8CharArr[1] & (uint8_t)0b0011'1111)) << 0;
282 else if constexpr (szBytes == 3)
284 u16Char = ((uint16_t)((uint8_t)mu8CharArr[0] & (uint8_t)0b0000'1111)) << 12 |
285 ((uint16_t)((uint8_t)mu8CharArr[1] & (uint8_t)0b0011'1111)) << 6 |
286 ((uint16_t)((uint8_t)mu8CharArr[2] & (uint8_t)0b0011'1111)) << 0;
290 static_assert(
false,
"Error szBytes Size");
294 static constexpr void DecodeMUTF8Supplementary(
const MU8T(&mu8CharArr)[6], U16T &u16HighSurrogate, U16T &u16LowSurrogate)
296 uint32_t u32RawChar =
297 ((uint32_t)((uint8_t)mu8CharArr[1] & (uint8_t)0b0000'1111)) << 16 |
298 ((uint32_t)((uint8_t)mu8CharArr[2] & (uint8_t)0b0011'1111)) << 10 |
300 ((uint32_t)((uint8_t)mu8CharArr[4] & (uint8_t)0b0000'1111)) << 6 |
301 ((uint32_t)((uint8_t)mu8CharArr[5] & (uint8_t)0b0011'1111)) << 0 ;
308 u16HighSurrogate = (uint32_t)((u32RawChar & (uint32_t)0b0000'0000'0000'1111'1111'1100'0000'0000) >> 10 | (uint32_t)0b1101'1000'0000'0000);
309 u16LowSurrogate = (uint32_t)((u32RawChar & (uint32_t)0b0000'0000'0000'0000'0000'0011'1111'1111) >> 0 | (uint32_t)0b1101'1100'0000'0000);
320 static constexpr void UTF8SupplementaryToMUTF8(
const U8T(&u8CharArr)[4], MU8T(&mu8CharArr)[6])
323 uint32_t u32RawChar = ((uint32_t)((uint8_t)u8CharArr[0] & (uint8_t)0b0000'0111)) << 18 |
324 ((uint32_t)((uint8_t)u8CharArr[1] & (uint8_t)0b0011'1111)) << 12 |
325 ((uint32_t)((uint8_t)u8CharArr[2] & (uint8_t)0b0011'1111)) << 6 |
326 ((uint32_t)((uint8_t)u8CharArr[3] & (uint8_t)0b0011'1111)) << 0;
329 u32RawChar -= (uint32_t)0b0000'0000'0000'0001'0000'0000'0000'0000;
332 mu8CharArr[0] = (uint8_t)0b1110'1101;
333 mu8CharArr[1] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'1111'0000'0000'0000'0000) >> 16) | (uint32_t)0b1010'0000);
334 mu8CharArr[2] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'0000'1111'1100'0000'0000) >> 10) | (uint32_t)0b1000'0000);
336 mu8CharArr[3] = (uint8_t)0b1110'1101;
337 mu8CharArr[4] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'0000'0000'0011'1100'0000) >> 6) | (uint32_t)0b1011'0000);
338 mu8CharArr[5] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'0000'0000'0000'0011'1111) >> 0) | (uint32_t)0b1000'0000);
341 static constexpr void MUTF8SupplementaryToUTF8(
const MU8T(&mu8CharArr)[6], U8T(&u8CharArr)[4])
344 uint32_t u32RawChar =
345 ((uint32_t)((uint8_t)mu8CharArr[1] & (uint8_t)0b0000'1111)) << 16 |
346 ((uint32_t)((uint8_t)mu8CharArr[2] & (uint8_t)0b0011'1111)) << 10 |
348 ((uint32_t)((uint8_t)mu8CharArr[4] & (uint8_t)0b0000'1111)) << 6 |
349 ((uint32_t)((uint8_t)mu8CharArr[5] & (uint8_t)0b0011'1111)) << 0 ;
352 u32RawChar += (uint32_t)0b0000'0000'0000'0001'0000'0000'0000'0000;
355 u8CharArr[0] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0001'1100'0000'0000'0000'0000) >> 18) | (uint32_t)0b1111'0000);
356 u8CharArr[1] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'0011'1111'0000'0000'0000) >> 12) | (uint32_t)0b1000'0000);
357 u8CharArr[2] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'0000'0000'1111'1100'0000) >> 6) | (uint32_t)0b1000'0000);
358 u8CharArr[3] = (uint8_t)(((u32RawChar & (uint32_t)0b0000'0000'0000'0000'0000'0000'0011'1111) >> 0) | (uint32_t)0b1000'0000);
365#define GET_NEXTCHAR(c,d) if (++it == end) { (d);break; } else { (c) = *it; }
367#define HAS_BITMASK(v,m,p) (((uint8_t)(v) & (uint8_t)(m)) == (uint8_t)(p))
368#define IS_BITS(v,t) ((uint8_t)(v) == (uint8_t)(t))
370#define IN_RANGE(v,b,e) (((uint16_t)(v) >= (uint16_t)(b)) && ((uint16_t)(v) <= (uint16_t)(e)))
374 template<
typename T = std::basic_
string<MU8T>>
375 static constexpr T U16ToMU8Impl(
const U16T *u16String,
size_t szStringLength, T mu8String = {})
378#define PUSH_FAIL_MU8CHAR mu8String.append(mu8FailChar, sizeof(mu8FailChar) / sizeof(MU8T))
384 for (
auto it = u16String, end = u16String + szStringLength; it != end; ++it)
387 if (IN_RANGE(u16Char, 0x0001, 0x007F))
390 EncodeMUTF8Bmp(u16Char, mu8Char);
391 mu8String.append(mu8Char,
sizeof(mu8Char) /
sizeof(MU8T));
393 else if (IN_RANGE(u16Char, 0x0080, 0x07FF) || u16Char == 0x0000)
396 EncodeMUTF8Bmp(u16Char, mu8Char);
397 mu8String.append(mu8Char,
sizeof(mu8Char) /
sizeof(MU8T));
399 else if (IN_RANGE(u16Char, 0x0800, 0xFFFF))
401 if (IN_RANGE(u16Char, 0xD800, 0xDBFF))
403 U16T u16HighSurrogate = u16Char;
404 U16T u16LowSurrogate{};
405 GET_NEXTCHAR(u16LowSurrogate, (PUSH_FAIL_MU8CHAR));
409 if (!IN_RANGE(u16LowSurrogate, 0xDC00, 0xDFFF))
418 EncodeMUTF8Supplementary(u16HighSurrogate, u16LowSurrogate, mu8Char);
419 mu8String.append(mu8Char,
sizeof(mu8Char) /
sizeof(MU8T));
423 if (IN_RANGE(u16Char, 0xDC00, 0xDFFF))
432 EncodeMUTF8Bmp(u16Char, mu8Char);
433 mu8String.append(mu8Char,
sizeof(mu8Char) /
sizeof(MU8T));
444#undef PUSH_FAIL_MU8CHAR
447 template<
typename T = std::basic_
string<U16T>>
448 static constexpr T MU8ToU16Impl(
const MU8T *mu8String,
size_t szStringLength, T u16String = {})
451#define PUSH_FAIL_U16CHAR u16String.push_back(u16FailChar)
457 for (
auto it = mu8String, end = mu8String + szStringLength; it != end; ++it)
461 if (HAS_BITMASK(mu8Char, 0b1000'0000, 0b0000'0000))
464 MU8T mu8CharArr[1] = { mu8Char };
468 DecodeMUTF8Bmp(mu8CharArr, u16Char);
469 u16String.push_back(u16Char);
471 else if (HAS_BITMASK(mu8Char, 0b1110'0000, 0b1100'0000))
474 MU8T mu8CharArr[2] = { mu8Char };
476 GET_NEXTCHAR(mu8CharArr[1], (PUSH_FAIL_U16CHAR));
478 if (!HAS_BITMASK(mu8CharArr[1], 0b1100'0000, 0b1000'0000))
487 DecodeMUTF8Bmp(mu8CharArr, u16Char);
488 u16String.push_back(u16Char);
490 else if (HAS_BITMASK(mu8Char, 0b1111'0000, 0b1110'0000))
494 GET_NEXTCHAR(mu8Next, (PUSH_FAIL_U16CHAR));
500 if (IS_BITS(mu8Char, 0b1110'1101) && HAS_BITMASK(mu8Next, 0b1111'0000, 0b1010'0000))
503 MU8T mu8CharArr[6] = { mu8Char,mu8Next };
508 GET_NEXTCHAR(mu8CharArr[2],
509 (PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR));
510 if (!HAS_BITMASK(mu8CharArr[2], 0b1100'0000, 0b1000'0000))
521 GET_NEXTCHAR(mu8CharArr[3],
522 (PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR));
523 if (!IS_BITS(mu8CharArr[3], 0b1110'1101))
535 GET_NEXTCHAR(mu8CharArr[4],
536 (PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR));
537 if (!HAS_BITMASK(mu8CharArr[4], 0b1111'0000, 0b1011'0000))
550 GET_NEXTCHAR(mu8CharArr[5],
551 (PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR));
552 if (!HAS_BITMASK(mu8CharArr[5], 0b1100'0000, 0b1000'0000))
566 U16T u16HighSurrogate{}, u16LowSurrogate{};
567 DecodeMUTF8Supplementary(mu8CharArr, u16HighSurrogate, u16LowSurrogate);
568 u16String.push_back(u16HighSurrogate);
569 u16String.push_back(u16LowSurrogate);
571 else if(HAS_BITMASK(mu8Next, 0b1100'0000, 0b1000'0000))
574 MU8T mu8CharArr[3] = { mu8Char,mu8Next };
577 GET_NEXTCHAR(mu8CharArr[2],
578 (PUSH_FAIL_U16CHAR, PUSH_FAIL_U16CHAR));
579 if (!HAS_BITMASK(mu8CharArr[2], 0b1100'0000, 0b1000'0000))
591 DecodeMUTF8Bmp(mu8CharArr, u16Char);
592 u16String.push_back(u16Char);
616#undef PUSH_FAIL_U16CHAR
629 template<
typename T = DynamicString<std::basic_
string<MU8T>>>
630 static constexpr T U8ToMU8Impl(
const U8T *u8String,
size_t szStringLength, T mu8String = {})
633#define PUSH_FAIL_MU8CHAR mu8String.append(mu8FailChar, sizeof(mu8FailChar) / sizeof(MU8T))
634#define INSERT_NORMAL(p) (mu8String.append_cvt((p) - szNormalLength, szNormalLength), szNormalLength = 0)
637 size_t szNormalLength = 0;
638 for (
auto it = u8String, end = u8String + szStringLength; it != end; ++it)
642 if (HAS_BITMASK(u8Char, 0b1111'1000, 0b1111'0000))
647 U8T u8CharArr[4]{ u8Char };
649 GET_NEXTCHAR(u8CharArr[1], (PUSH_FAIL_MU8CHAR));
650 if (!HAS_BITMASK(u8CharArr[1], 0b1100'0000, 0b1000'0000))
658 GET_NEXTCHAR(u8CharArr[2],
659 (PUSH_FAIL_MU8CHAR, PUSH_FAIL_MU8CHAR));
660 if (!HAS_BITMASK(u8CharArr[2], 0b1100'0000, 0b1000'0000))
669 GET_NEXTCHAR(u8CharArr[3],
670 (PUSH_FAIL_MU8CHAR, PUSH_FAIL_MU8CHAR, PUSH_FAIL_MU8CHAR));
671 if (!HAS_BITMASK(u8CharArr[3], 0b1100'0000, 0b1000'0000))
682 MU8T mu8CharArr[6]{};
683 UTF8SupplementaryToMUTF8(u8CharArr, mu8CharArr);
684 mu8String.append(mu8CharArr,
sizeof(mu8CharArr) /
sizeof(MU8T));
686 else if (IS_BITS(u8Char, 0b0000'0000))
690 MU8T mu8EmptyCharArr[2] = { (MU8T)0xC0,(MU8T)0x80 };
691 mu8String.append(mu8EmptyCharArr,
sizeof(mu8EmptyCharArr) /
sizeof(MU8T));
700 INSERT_NORMAL(u8String + szStringLength);
706#undef PUSH_FAIL_MU8CHAR
709 template<
typename T = DynamicString<std::basic_
string<U8T>>>
710 static constexpr T MU8ToU8Impl(
const MU8T *mu8String,
size_t szStringLength, T u8String = {})
713#define PUSH_FAIL_U8CHAR u8String.append(u8FailChar, sizeof(u8FailChar) / sizeof(U8T))
714#define INSERT_NORMAL(p) (u8String.append_cvt((p) - szNormalLength, szNormalLength), szNormalLength = 0)
717 size_t szNormalLength = 0;
718 for (
auto it = mu8String, end = mu8String + szStringLength; it != end; ++it)
722 if (HAS_BITMASK(mu8Char, 0b1111'0000, 0b1110'0000))
729 INSERT_NORMAL(it - 1);
737 if (!IS_BITS(mu8Char, 0b1110'1101) || !HAS_BITMASK(mu8Next, 0b1111'0000, 0b1010'0000))
744 INSERT_NORMAL(it - 1);
747 MU8T mu8CharArr[6] = { mu8Char, mu8Next };
750 GET_NEXTCHAR(mu8CharArr[2],
751 (PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR));
752 if (!HAS_BITMASK(mu8CharArr[2], 0b1100'0000, 0b1000'0000))
763 GET_NEXTCHAR(mu8CharArr[3],
764 (PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR));
765 if (!IS_BITS(mu8CharArr[3], 0b1110'1101))
777 GET_NEXTCHAR(mu8CharArr[4],
778 (PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR));
779 if (!HAS_BITMASK(mu8CharArr[4], 0b1111'0000, 0b1011'0000))
792 GET_NEXTCHAR(mu8CharArr[5],
793 (PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR, PUSH_FAIL_U8CHAR));
794 if (!HAS_BITMASK(mu8CharArr[5], 0b1100'0000, 0b1000'0000))
809 MUTF8SupplementaryToUTF8(mu8CharArr, u8CharArr);
810 u8String.append(u8CharArr,
sizeof(u8CharArr) /
sizeof(U8T));
812 else if (IS_BITS(mu8Char, 0xC0))
819 INSERT_NORMAL(it - 1);
825 if (!IS_BITS(mu8Next, 0x80))
832 INSERT_NORMAL(it - 1);
833 u8String.push_back((U8T)0x00);
842 INSERT_NORMAL(mu8String + szStringLength);
847#undef PUSH_FAIL_U8CHAR
857 static consteval size_t ContentLength(
const T &tStr)
859 return tStr.size() > 0 && tStr[tStr.size() - 1] == (
typename T::value_type)0x00
871 static constexpr size_t U16ToMU8Length(
const std::basic_string_view<U16T> &u16String)
873 return U16ToMU8Impl<FakeStringCounter<MU8T>>(u16String.data(), u16String.size()).GetData();
881 static constexpr size_t U16ToMU8Length(
const U16T *u16String,
size_t szStringLength)
883 return U16ToMU8Impl<FakeStringCounter<MU8T>>(u16String, szStringLength).GetData();
891 static std::basic_string<MU8T>
U16ToMU8(
const std::basic_string_view<U16T> &u16String,
size_t szReserve = 0)
893 return U16ToMU8Impl<DynamicString<std::basic_string<MU8T>>>(u16String.data(), u16String.size(), { szReserve }).GetData();
902 static std::basic_string<MU8T>
U16ToMU8(
const U16T *u16String,
size_t szStringLength,
size_t szReserve = 0)
904 return U16ToMU8Impl<DynamicString<std::basic_string<MU8T>>>(u16String, szStringLength, { szReserve }).GetData();
912 template<MUTF8_Tool_Internal::StringLiteral u16String>
913 requires std::is_same_v<
typename decltype(u16String)::value_type, U16T>
914 static consteval std::basic_string_view<MU8T>
U16ToMU8(
void)
916 constexpr size_t szStringLength = ContentLength(u16String);
917 constexpr size_t szNewLength = U16ToMU8Impl<FakeStringCounter<MU8T>>(u16String.data(), szStringLength).GetData();
921 U16ToMU8Impl<StaticString<MU8T, szNewLength>>(u16String.data(), szStringLength).GetData(),
922 std::basic_string_view<MU8T>
932 static constexpr size_t U8ToMU8Length(
const std::basic_string_view<U8T> &u8String)
934 return U8ToMU8Impl<FakeStringCounter<MU8T>>(u8String.data(), u8String.size()).GetData();
942 static constexpr size_t U8ToMU8Length(
const U8T *u8String,
size_t szStringLength)
944 return U8ToMU8Impl<FakeStringCounter<MU8T>>(u8String, szStringLength).GetData();
952 static std::basic_string<MU8T>
U8ToMU8(
const std::basic_string_view<U8T> &u8String,
size_t szReserve = 0)
954 return U8ToMU8Impl<DynamicString<std::basic_string<MU8T>>>(u8String.data(), u8String.size(), { szReserve }).GetData();
963 static std::basic_string<MU8T>
U8ToMU8(
const U8T *u8String,
size_t szStringLength,
size_t szReserve = 0)
965 return U8ToMU8Impl<DynamicString<std::basic_string<MU8T>>>(u8String, szStringLength, { szReserve }).GetData();
973 template<MUTF8_Tool_Internal::StringLiteral u8String>
974 requires std::is_same_v<
typename decltype(u8String)::value_type, U8T>
975 static consteval std::basic_string_view<MU8T>
U8ToMU8(
void)
977 constexpr size_t szStringLength = ContentLength(u8String);
978 constexpr size_t szNewLength = U8ToMU8Impl<FakeStringCounter<MU8T>>(u8String.data(), szStringLength).GetData();
982 StaticString<MU8T, szNewLength>>(u8String.data(), szStringLength).GetData(),
983 std::basic_string_view<MU8T>
994 static constexpr size_t MU8ToU16Length(
const std::basic_string_view<MU8T> &mu8String)
996 return MU8ToU16Impl<FakeStringCounter<U16T>>(mu8String.data(), mu8String.size()).GetData();
1006 return MU8ToU16Impl<FakeStringCounter<U16T>>(mu8String, szStringLength).GetData();
1014 static std::basic_string<U16T>
MU8ToU16(
const std::basic_string_view<MU8T> &mu8String,
size_t szReserve = 0)
1016 return MU8ToU16Impl<DynamicString<std::basic_string<U16T>>>(mu8String.data(), mu8String.size(), { szReserve }).GetData();
1025 static std::basic_string<U16T>
MU8ToU16(
const MU8T *mu8String,
size_t szStringLength,
size_t szReserve = 0)
1027 return MU8ToU16Impl<DynamicString<std::basic_string<U16T>>>(mu8String, szStringLength, { szReserve }).GetData();
1036 static constexpr size_t MU8ToU8Length(
const std::basic_string_view<MU8T> &mu8String)
1038 return MU8ToU8Impl<FakeStringCounter<U8T>>(mu8String.data(), mu8String.size()).GetData();
1046 static constexpr size_t MU8ToU8Length(
const MU8T *mu8String,
size_t szStringLength)
1048 return MU8ToU8Impl<FakeStringCounter<U8T>>(mu8String, szStringLength).GetData();
1056 static std::basic_string<U8T>
MU8ToU8(
const std::basic_string_view<MU8T> &mu8String,
size_t szReserve = 0)
1058 return MU8ToU8Impl<DynamicString<std::basic_string<U8T>>>(mu8String.data(), mu8String.size(), { szReserve }).GetData();
1067 static std::basic_string<U8T>
MU8ToU8(
const MU8T *mu8String,
size_t szStringLength,
size_t szReserve = 0)
1069 return MU8ToU8Impl<DynamicString<std::basic_string<U8T>>>(mu8String, szStringLength, { szReserve }).GetData();