refactor: finish iconv refactor

This commit is contained in:
2025-07-25 11:06:22 +08:00
parent b79df0c65e
commit 5372af79f8
3 changed files with 72 additions and 169 deletions

View File

@ -1,5 +1,13 @@
#pragma once #pragma once
/**
* @file
* When you use YYCCommonplace, please make sure that you include this header first,
* before including any other headers of YYCC.
* This header contain essential check macros and version infos.
* They are crucial before using YYCC.
*/
// Library Version and Comparison Macros // Library Version and Comparison Macros
#include "yycc/version.hpp" #include "yycc/version.hpp"
#include "yycc/macro/version_cmp.hpp" #include "yycc/macro/version_cmp.hpp"

View File

@ -2,18 +2,12 @@
#if YYCC_FEAT_ICONV || !defined(YYCC_OS_WINDOWS) #if YYCC_FEAT_ICONV || !defined(YYCC_OS_WINDOWS)
#include "../string/reinterpret.hpp"
#include "../macro/endian_detector.hpp" #include "../macro/endian_detector.hpp"
#include <cerrno> #include <cerrno>
#include <stdexcept> #include <stdexcept>
#include <cstdint> #include <cstdint>
#include <cstdlib> #include <cstdlib>
#include <vector> #include <vector>
#include <iconv.h>
#define NS_YYCC_STRING ::yycc::string
#define NS_YYCC_STRING_REINTERPRET ::yycc::string::reinterpret
#define NS_YYCC_PATCH_EXPECTED ::yycc::patch::expected
#pragma region Iconv Shit Fix #pragma region Iconv Shit Fix
@ -24,6 +18,8 @@
// So I can only write some definitions of functions and types here, and extract the functions and types I need before I declare the namespace. // So I can only write some definitions of functions and types here, and extract the functions and types I need before I declare the namespace.
// And at the same time remove those annoying macro definitions. Hopefully, the compiler will optimize these wrapper functions. // And at the same time remove those annoying macro definitions. Hopefully, the compiler will optimize these wrapper functions.
#include <iconv.h>
typedef iconv_t that_iconv_t; typedef iconv_t that_iconv_t;
static iconv_t that_iconv_open(const char* tocode, const char* fromcode) { static iconv_t that_iconv_open(const char* tocode, const char* fromcode) {
return iconv_open(tocode, fromcode); return iconv_open(tocode, fromcode);
@ -56,8 +52,8 @@ namespace yycc::encoding::iconv {
PrivToken(const CodeName& from_code, const CodeName& to_code) : inner(INVALID_ICONV_TOKEN) { PrivToken(const CodeName& from_code, const CodeName& to_code) : inner(INVALID_ICONV_TOKEN) {
// We must cast them into string container, not string view, // We must cast them into string container, not string view,
// because they may not have NULL terminator. // because they may not have NULL terminator.
std::string iconv_from_code = NS_YYCC_STRING_REINTERPRET::as_ordinary(from_code), std::string iconv_from_code(from_code);
iconv_to_code = NS_YYCC_STRING_REINTERPRET::as_ordinary(to_code); std::string iconv_to_code(to_code);
// Call iconv_t creator // Call iconv_t creator
that_iconv_t descriptor = that_iconv_open(iconv_to_code.c_str(), iconv_from_code.c_str()); that_iconv_t descriptor = that_iconv_open(iconv_to_code.c_str(), iconv_from_code.c_str());
if (descriptor == INVALID_ICONV_TOKEN) { if (descriptor == INVALID_ICONV_TOKEN) {
@ -131,12 +127,12 @@ namespace yycc::encoding::iconv {
// Unwrap and check iconv_t // Unwrap and check iconv_t
that_iconv_t cd = token.get_inner()->get_inner(); that_iconv_t cd = token.get_inner()->get_inner();
if (cd == INVALID_ICONV_TOKEN) return ConvError::InvalidCd; if (cd == INVALID_ICONV_TOKEN) return std::unexpected(ConvError::InvalidCd);
// Check empty input // Check empty input
if (str_from_len == 0u) return str_to; if (str_from_len == 0u) return str_to;
// Check nullptr input variables // Check nullptr input variables
if (str_from_buf == nullptr) return ConvError::NullPointer; if (str_from_buf == nullptr) return std::unexpected(ConvError::NullPointer);
// ===== Do Iconv ===== // ===== Do Iconv =====
// setup input variables // setup input variables
@ -168,9 +164,9 @@ namespace yycc::encoding::iconv {
// check error // check error
if (nchars == ICONV_ERR_RV) { if (nchars == ICONV_ERR_RV) {
if (errno == EILSEQ) { if (errno == EILSEQ) {
return ConvError::InvalidMbSeq; return std::unexpected(ConvError::InvalidMbSeq);
} else if (errno == EINVAL) { } else if (errno == EINVAL) {
return ConvError::IncompleteMbSeq; return std::unexpected(ConvError::IncompleteMbSeq);
} else { } else {
throw std::runtime_error("impossible errno when calling iconv_open()"); throw std::runtime_error("impossible errno when calling iconv_open()");
} }
@ -191,58 +187,40 @@ namespace yycc::encoding::iconv {
// That's not what we expected. // That's not what we expected.
// So we need manually check runtime endian and explicitly specify endian in code name. // So we need manually check runtime endian and explicitly specify endian in code name.
static const NS_YYCC_STRING::u8char* UTF8_CODENAME_LITERAL = YYCC_U8("UTF-8"); using namespace std::literals::string_view_literals;
static const NS_YYCC_STRING::u8char* WCHAR_CODENAME_LITERAL = YYCC_U8("WCHAR_T");
static const NS_YYCC_STRING::u8char* fetch_utf16_codename() { constexpr auto UTF8_CODENAME_LITERAL = "UTF-8"sv;
constexpr auto WCHAR_CODENAME_LITERAL = "WCHAR_T"sv;
constexpr auto UTF16_CODENAME_LITERAL =
#if defined(YYCC_ENDIAN_LITTLE) #if defined(YYCC_ENDIAN_LITTLE)
return YYCC_U8("UTF16LE"); "UTF16LE"sv;
#else #else
return YYCC_U8("UTF16BE"); "UTF16BE"sv;
#endif #endif
} constexpr auto UTF32_CODENAME_LITERAL =
static const NS_YYCC_STRING::u8char* UTF16_CODENAME_LITERAL = fetch_utf16_codename();
static const NS_YYCC_STRING::u8char* fetch_utf32_codename() {
#if defined(YYCC_ENDIAN_LITTLE) #if defined(YYCC_ENDIAN_LITTLE)
return YYCC_U8("UTF32LE"); "UTF32LE"sv;
#else #else
return YYCC_U8("UTF32BE"); "UTF32BE"sv;
#endif #endif
}
static const NS_YYCC_STRING::u8char* UTF32_CODENAME_LITERAL = fetch_utf32_codename();
// TODO: // TODO:
// There is a memory copy in this function. Consider optimizing it in future. // There is a memory copy in this function. Consider optimizing it in future.
// A possible solution is that create a std::vector-like wrapper for std::basic_string and std::basic_string_view. // A possible solution is that create a std::vector-like wrapper for std::basic_string and std::basic_string_view.
// We call them VecString and VecStringView, and use them in "iconv_kernel" instead of real std::vector. // We call them VecString and VecStringView, and use them in "iconv_kernel" instead of real std::vector.
// They exposed interface are std::vector-like but its inner is std::basic_string and std::basic_string_view. // They exposed interface are std::vector-like but its inner is std::basic_string and std::basic_string_view.
#define CONVFN_TYPE0(src_char_type, dst_char_type) \ #define USER_CONVFN(src_char_type, dst_char_type) \
namespace expected = NS_YYCC_PATCH_EXPECTED; \
auto rv = iconv_kernel(this->token, reinterpret_cast<const uint8_t*>(src.data()), src.size()); \ auto rv = iconv_kernel(this->token, reinterpret_cast<const uint8_t*>(src.data()), src.size()); \
if (expected::is_value(rv)) { \ if (rv.has_value()) { \
const auto& dst = expected::get_value(rv); \ const auto& dst = rv.value(); \
if constexpr (sizeof(dst_char_type) > 1u) { \ if constexpr (sizeof(dst_char_type) > 1u) { \
if (dst.size() % sizeof(dst_char_type) != 0u) return ConvError::BadRv; \ if (dst.size() % sizeof(dst_char_type) != 0u) return std::unexpected(ConvError::BadRv); \
} \ } \
return std::basic_string<dst_char_type>(reinterpret_cast<const dst_char_type*>(dst.data()), dst.size() / sizeof(dst_char_type)); \ return std::basic_string<dst_char_type>(reinterpret_cast<const dst_char_type*>(dst.data()), dst.size() / sizeof(dst_char_type)); \
} else { \ } else { \
return expected::get_error(rv); \ return std::unexpected(rv.error()); \
} }
#define CONVFN_TYPE1(fct_name, src_char_type, dst_char_type) \
namespace expected = NS_YYCC_PATCH_EXPECTED; \
auto rv = this->priv_##fct_name(src); \
if (expected::is_value(rv)) { \
dst = std::move(expected::get_value(rv)); \
return true; \
} else { \
return false; \
}
#define CONVFN_TYPE2(fct_name, src_char_type, dst_char_type) \
std::basic_string<dst_char_type> rv; \
if (this->fct_name(src, rv)) return rv; \
else throw std::runtime_error("fail to convert string in Win32 function");
#pragma endregion #pragma endregion
#pragma region Char -> UTF8 #pragma region Char -> UTF8
@ -251,16 +229,8 @@ namespace yycc::encoding::iconv {
CharToUtf8::~CharToUtf8() {} CharToUtf8::~CharToUtf8() {}
ConvResult<NS_YYCC_STRING::u8string> CharToUtf8::priv_to_utf8(const std::string_view& src) { ConvResult<std::u8string> CharToUtf8::priv_to_utf8(const std::string_view& src) {
CONVFN_TYPE0(char, NS_YYCC_STRING::u8char); USER_CONVFN(char, char8_t);
}
bool CharToUtf8::to_utf8(const std::string_view& src, NS_YYCC_STRING::u8string& dst) {
CONVFN_TYPE1(to_utf8, char, NS_YYCC_STRING::u8char);
}
NS_YYCC_STRING::u8string CharToUtf8::to_utf8(const std::string_view& src) {
CONVFN_TYPE2(to_utf8, char, NS_YYCC_STRING::u8char);
} }
#pragma endregion #pragma endregion
@ -271,16 +241,8 @@ namespace yycc::encoding::iconv {
Utf8ToChar::~Utf8ToChar() {} Utf8ToChar::~Utf8ToChar() {}
ConvResult<std::string> Utf8ToChar::priv_to_char(const NS_YYCC_STRING::u8string_view& src) { ConvResult<std::string> Utf8ToChar::priv_to_char(const std::u8string_view& src) {
CONVFN_TYPE0(NS_YYCC_STRING::u8char, char); USER_CONVFN(char8_t, char);
}
bool Utf8ToChar::to_char(const NS_YYCC_STRING::u8string_view& src, std::string& dst) {
CONVFN_TYPE1(to_char, NS_YYCC_STRING::u8char, char);
}
std::string Utf8ToChar::to_char(const NS_YYCC_STRING::u8string_view& src) {
CONVFN_TYPE2(to_char, NS_YYCC_STRING::u8char, char);
} }
#pragma endregion #pragma endregion
@ -291,16 +253,8 @@ namespace yycc::encoding::iconv {
WcharToUtf8::~WcharToUtf8() {} WcharToUtf8::~WcharToUtf8() {}
ConvResult<NS_YYCC_STRING::u8string> WcharToUtf8::priv_to_utf8(const std::wstring_view& src) { ConvResult<std::u8string> WcharToUtf8::priv_to_utf8(const std::wstring_view& src) {
CONVFN_TYPE0(wchar_t, NS_YYCC_STRING::u8char); USER_CONVFN(wchar_t, char8_t);
}
bool WcharToUtf8::to_utf8(const std::wstring_view& src, NS_YYCC_STRING::u8string& dst) {
CONVFN_TYPE1(to_utf8, wchar_t, NS_YYCC_STRING::u8char);
}
NS_YYCC_STRING::u8string WcharToUtf8::to_utf8(const std::wstring_view& src) {
CONVFN_TYPE2(to_utf8, wchar_t, NS_YYCC_STRING::u8char);
} }
#pragma endregion #pragma endregion
@ -311,16 +265,8 @@ namespace yycc::encoding::iconv {
Utf8ToWchar::~Utf8ToWchar() {} Utf8ToWchar::~Utf8ToWchar() {}
ConvResult<std::wstring> Utf8ToWchar::priv_to_wchar(const NS_YYCC_STRING::u8string_view& src) { ConvResult<std::wstring> Utf8ToWchar::priv_to_wchar(const std::u8string_view& src) {
CONVFN_TYPE0(NS_YYCC_STRING::u8char, wchar_t); USER_CONVFN(char8_t, wchar_t);
}
bool Utf8ToWchar::to_wchar(const NS_YYCC_STRING::u8string_view& src, std::wstring& dst) {
CONVFN_TYPE1(to_wchar, NS_YYCC_STRING::u8char, wchar_t);
}
std::wstring Utf8ToWchar::to_wchar(const NS_YYCC_STRING::u8string_view& src) {
CONVFN_TYPE2(to_wchar, NS_YYCC_STRING::u8char, wchar_t);
} }
#pragma endregion #pragma endregion
@ -331,16 +277,8 @@ namespace yycc::encoding::iconv {
Utf8ToUtf16::~Utf8ToUtf16() {} Utf8ToUtf16::~Utf8ToUtf16() {}
ConvResult<std::u16string> Utf8ToUtf16::priv_to_utf16(const NS_YYCC_STRING::u8string_view& src) { ConvResult<std::u16string> Utf8ToUtf16::priv_to_utf16(const std::u8string_view& src) {
CONVFN_TYPE0(NS_YYCC_STRING::u8char, char16_t); USER_CONVFN(char8_t, char16_t);
}
bool Utf8ToUtf16::to_utf16(const NS_YYCC_STRING::u8string_view& src, std::u16string& dst) {
CONVFN_TYPE1(to_utf16, NS_YYCC_STRING::u8char, char16_t);
}
std::u16string Utf8ToUtf16::to_utf16(const NS_YYCC_STRING::u8string_view& src) {
CONVFN_TYPE2(to_utf16, NS_YYCC_STRING::u8char, char16_t);
} }
#pragma endregion #pragma endregion
@ -351,16 +289,8 @@ namespace yycc::encoding::iconv {
Utf16ToUtf8::~Utf16ToUtf8() {} Utf16ToUtf8::~Utf16ToUtf8() {}
ConvResult<NS_YYCC_STRING::u8string> Utf16ToUtf8::priv_to_utf8(const std::u16string_view& src) { ConvResult<std::u8string> Utf16ToUtf8::priv_to_utf8(const std::u16string_view& src) {
CONVFN_TYPE0(char16_t, NS_YYCC_STRING::u8char); USER_CONVFN(char16_t, char8_t);
}
bool Utf16ToUtf8::to_utf8(const std::u16string_view& src, NS_YYCC_STRING::u8string& dst) {
CONVFN_TYPE1(to_utf8, char16_t, NS_YYCC_STRING::u8char);
}
NS_YYCC_STRING::u8string Utf16ToUtf8::to_utf8(const std::u16string_view& src) {
CONVFN_TYPE2(to_utf8, char16_t, NS_YYCC_STRING::u8char);
} }
#pragma endregion #pragma endregion
@ -371,16 +301,8 @@ namespace yycc::encoding::iconv {
Utf8ToUtf32::~Utf8ToUtf32() {} Utf8ToUtf32::~Utf8ToUtf32() {}
ConvResult<std::u32string> Utf8ToUtf32::priv_to_utf32(const NS_YYCC_STRING::u8string_view& src) { ConvResult<std::u32string> Utf8ToUtf32::priv_to_utf32(const std::u8string_view& src) {
CONVFN_TYPE0(NS_YYCC_STRING::u8char, char32_t); USER_CONVFN(char8_t, char32_t);
}
bool Utf8ToUtf32::to_utf32(const NS_YYCC_STRING::u8string_view& src, std::u32string& dst) {
CONVFN_TYPE1(to_utf32, NS_YYCC_STRING::u8char, char32_t);
}
std::u32string Utf8ToUtf32::to_utf32(const NS_YYCC_STRING::u8string_view& src) {
CONVFN_TYPE2(to_utf32, NS_YYCC_STRING::u8char, char32_t);
} }
#pragma endregion #pragma endregion
@ -391,16 +313,8 @@ namespace yycc::encoding::iconv {
Utf32ToUtf8::~Utf32ToUtf8() {} Utf32ToUtf8::~Utf32ToUtf8() {}
ConvResult<NS_YYCC_STRING::u8string> Utf32ToUtf8::priv_to_utf8(const std::u32string_view& src) { ConvResult<std::u8string> Utf32ToUtf8::priv_to_utf8(const std::u32string_view& src) {
CONVFN_TYPE0(char32_t, NS_YYCC_STRING::u8char); USER_CONVFN(char32_t, char8_t);
}
bool Utf32ToUtf8::to_utf8(const std::u32string_view& src, NS_YYCC_STRING::u8string& dst) {
CONVFN_TYPE1(to_utf8, char32_t, NS_YYCC_STRING::u8char);
}
NS_YYCC_STRING::u8string Utf32ToUtf8::to_utf8(const std::u32string_view& src) {
CONVFN_TYPE2(to_utf8, char32_t, NS_YYCC_STRING::u8char);
} }
#pragma endregion #pragma endregion

View File

@ -4,13 +4,11 @@
#if YYCC_FEAT_ICONV || !defined(YYCC_OS_WINDOWS) #if YYCC_FEAT_ICONV || !defined(YYCC_OS_WINDOWS)
#include "../macro/class_copy_move.hpp" #include "../macro/class_copy_move.hpp"
#include "../patch/expected.hpp" #include <string>
#include "../string.hpp" #include <string_view>
#include <expected>
#include <memory> #include <memory>
#define NS_YYCC_STRING ::yycc::string
#define NS_YYCC_PATCH_EXPECTED ::yycc::patch::expected
namespace yycc::encoding::iconv { namespace yycc::encoding::iconv {
// YYC MARK: // YYC MARK:
@ -19,11 +17,13 @@ namespace yycc::encoding::iconv {
// Another reason is that "iconv.h" defines some annoying macros which intervene some names in this files. // Another reason is that "iconv.h" defines some annoying macros which intervene some names in this files.
// So I introduce PIMPL design mode. Use a pointer to hide all details in class PrivToken. // So I introduce PIMPL design mode. Use a pointer to hide all details in class PrivToken.
using CodeName = NS_YYCC_STRING::u8string_view; /// @brief The code name type used by Iconv.
using CodeName = std::string_view;
/// @private /// @private
class PrivToken; class PrivToken;
/// @private
class Token { class Token {
public: public:
Token(const CodeName& from_code, const CodeName& to_code); Token(const CodeName& from_code, const CodeName& to_code);
@ -38,7 +38,7 @@ namespace yycc::encoding::iconv {
std::unique_ptr<PrivToken> inner; std::unique_ptr<PrivToken> inner;
}; };
/// @private /// @brief The possible error occurs in this module.
enum class ConvError { enum class ConvError {
InvalidCd, ///< Given token is invalid. InvalidCd, ///< Given token is invalid.
NullPointer, ///< Some of essential pointer in argument is nullptr. NullPointer, ///< Some of essential pointer in argument is nullptr.
@ -47,11 +47,11 @@ namespace yycc::encoding::iconv {
BadRv, ///< The size of encoding convertion is not matched with expected char type. BadRv, ///< The size of encoding convertion is not matched with expected char type.
}; };
/// @private /// @brief The result type in this module.
template<typename T> template<typename T>
using ConvResult = NS_YYCC_PATCH_EXPECTED::Expected<T, ConvError>; using ConvResult = std::expected<T, ConvError>;
// Char -> UTF8 /// @brief Char -> UTF8
class CharToUtf8 { class CharToUtf8 {
public: public:
CharToUtf8(const CodeName& code_name); CharToUtf8(const CodeName& code_name);
@ -60,15 +60,13 @@ namespace yycc::encoding::iconv {
YYCC_DEFAULT_MOVE(CharToUtf8) YYCC_DEFAULT_MOVE(CharToUtf8)
public: public:
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::string_view& src); ConvResult<std::u8string> priv_to_utf8(const std::string_view& src);
bool to_utf8(const std::string_view& src, NS_YYCC_STRING::u8string& dst);
NS_YYCC_STRING::u8string to_utf8(const std::string_view& src);
private: private:
Token token; Token token;
}; };
// UTF8 -> Char /// @brief UTF8 -> Char
class Utf8ToChar { class Utf8ToChar {
public: public:
Utf8ToChar(const CodeName& code_name); Utf8ToChar(const CodeName& code_name);
@ -77,15 +75,13 @@ namespace yycc::encoding::iconv {
YYCC_DEFAULT_MOVE(Utf8ToChar) YYCC_DEFAULT_MOVE(Utf8ToChar)
public: public:
ConvResult<std::string> priv_to_char(const NS_YYCC_STRING::u8string_view& src); ConvResult<std::string> priv_to_char(const std::u8string_view& src);
bool to_char(const NS_YYCC_STRING::u8string_view& src, std::string& dst);
std::string to_char(const NS_YYCC_STRING::u8string_view& src);
private: private:
Token token; Token token;
}; };
// WChar -> UTF8 /// @brief WChar -> UTF8
class WcharToUtf8 { class WcharToUtf8 {
public: public:
WcharToUtf8(); WcharToUtf8();
@ -94,15 +90,13 @@ namespace yycc::encoding::iconv {
YYCC_DEFAULT_MOVE(WcharToUtf8) YYCC_DEFAULT_MOVE(WcharToUtf8)
public: public:
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::wstring_view& src); ConvResult<std::u8string> priv_to_utf8(const std::wstring_view& src);
bool to_utf8(const std::wstring_view& src, NS_YYCC_STRING::u8string& dst);
NS_YYCC_STRING::u8string to_utf8(const std::wstring_view& src);
private: private:
Token token; Token token;
}; };
// UTF8 -> WChar /// @brief UTF8 -> WChar
class Utf8ToWchar { class Utf8ToWchar {
public: public:
Utf8ToWchar(); Utf8ToWchar();
@ -111,15 +105,13 @@ namespace yycc::encoding::iconv {
YYCC_DEFAULT_MOVE(Utf8ToWchar) YYCC_DEFAULT_MOVE(Utf8ToWchar)
public: public:
ConvResult<std::wstring> priv_to_wchar(const NS_YYCC_STRING::u8string_view& src); ConvResult<std::wstring> priv_to_wchar(const std::u8string_view& src);
bool to_wchar(const NS_YYCC_STRING::u8string_view& src, std::wstring& dst);
std::wstring to_wchar(const NS_YYCC_STRING::u8string_view& src);
private: private:
Token token; Token token;
}; };
// UTF8 -> UTF16 /// @brief UTF8 -> UTF16
class Utf8ToUtf16 { class Utf8ToUtf16 {
public: public:
Utf8ToUtf16(); Utf8ToUtf16();
@ -128,15 +120,13 @@ namespace yycc::encoding::iconv {
YYCC_DEFAULT_MOVE(Utf8ToUtf16) YYCC_DEFAULT_MOVE(Utf8ToUtf16)
public: public:
ConvResult<std::u16string> priv_to_utf16(const NS_YYCC_STRING::u8string_view& src); ConvResult<std::u16string> priv_to_utf16(const std::u8string_view& src);
bool to_utf16(const NS_YYCC_STRING::u8string_view& src, std::u16string& dst);
std::u16string to_utf16(const NS_YYCC_STRING::u8string_view& src);
private: private:
Token token; Token token;
}; };
// UTF16 -> UTF8 /// @brief UTF16 -> UTF8
class Utf16ToUtf8 { class Utf16ToUtf8 {
public: public:
Utf16ToUtf8(); Utf16ToUtf8();
@ -145,15 +135,13 @@ namespace yycc::encoding::iconv {
YYCC_DEFAULT_MOVE(Utf16ToUtf8) YYCC_DEFAULT_MOVE(Utf16ToUtf8)
public: public:
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::u16string_view& src); ConvResult<std::u8string> priv_to_utf8(const std::u16string_view& src);
bool to_utf8(const std::u16string_view& src, NS_YYCC_STRING::u8string& dst);
NS_YYCC_STRING::u8string to_utf8(const std::u16string_view& src);
private: private:
Token token; Token token;
}; };
// UTF8 -> UTF32 /// @brief UTF8 -> UTF32
class Utf8ToUtf32 { class Utf8ToUtf32 {
public: public:
Utf8ToUtf32(); Utf8ToUtf32();
@ -162,15 +150,13 @@ namespace yycc::encoding::iconv {
YYCC_DEFAULT_MOVE(Utf8ToUtf32) YYCC_DEFAULT_MOVE(Utf8ToUtf32)
public: public:
ConvResult<std::u32string> priv_to_utf32(const NS_YYCC_STRING::u8string_view& src); ConvResult<std::u32string> priv_to_utf32(const std::u8string_view& src);
bool to_utf32(const NS_YYCC_STRING::u8string_view& src, std::u32string& dst);
std::u32string to_utf32(const NS_YYCC_STRING::u8string_view& src);
private: private:
Token token; Token token;
}; };
// UTF32 -> UTF8 /// @brief UTF32 -> UTF8
class Utf32ToUtf8 { class Utf32ToUtf8 {
public: public:
Utf32ToUtf8(); Utf32ToUtf8();
@ -179,9 +165,7 @@ namespace yycc::encoding::iconv {
YYCC_DEFAULT_MOVE(Utf32ToUtf8) YYCC_DEFAULT_MOVE(Utf32ToUtf8)
public: public:
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::u32string_view& src); ConvResult<std::u8string> priv_to_utf8(const std::u32string_view& src);
bool to_utf8(const std::u32string_view& src, NS_YYCC_STRING::u8string& dst);
NS_YYCC_STRING::u8string to_utf8(const std::u32string_view& src);
private: private:
Token token; Token token;
@ -189,7 +173,4 @@ namespace yycc::encoding::iconv {
} // namespace yycc::encoding::iconv } // namespace yycc::encoding::iconv
#undef NS_YYCC_PATCH_EXPECTED
#undef NS_YYCC_STRING
#endif #endif