refactor: continue refactor project from C++17 to 23
This commit is contained in:
@ -26,9 +26,6 @@ FILES
|
||||
# Headers
|
||||
yycc.hpp
|
||||
yycc/version.hpp
|
||||
yycc/primitive.hpp
|
||||
yycc/prelude/core.hpp
|
||||
yycc/prelude/rust.hpp
|
||||
yycc/macro/version_cmp.hpp
|
||||
yycc/macro/os_detector.hpp
|
||||
yycc/macro/endian_detector.hpp
|
||||
@ -38,6 +35,8 @@ FILES
|
||||
yycc/string/op.hpp
|
||||
yycc/num/parse.hpp
|
||||
yycc/num/stringify.hpp
|
||||
yycc/rust/prelude.hpp
|
||||
yycc/rust/primitive.hpp
|
||||
yycc/rust/panic.hpp
|
||||
yycc/rust/option.hpp
|
||||
yycc/rust/result.hpp
|
||||
|
@ -1,38 +1,26 @@
|
||||
#include "stlcvt.hpp"
|
||||
#include <locale>
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
#define NS_YYCC_PATCH_EXPECTED ::yycc::patch::expected
|
||||
|
||||
namespace yycc::encoding::stlcvt {
|
||||
|
||||
#pragma region Generic Converter
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* YYC MARK:
|
||||
* According to the documentation introduced in CppReference.
|
||||
* The standard library is guaranteed to provide several specific specializations of \c std::codecvt.
|
||||
* The UTF8 char type in UTF8 related specializations of \c std::codecvt is different.
|
||||
* It is also independend from we defined char type.
|
||||
* So it is essential define a type which can correctly trigger specific specializations of \c std::codecv in there.
|
||||
* The UTF8 char type in UTF8 related specializations of \c std::codecvt is different in different C++ standard.
|
||||
* But the oldest C++ version YYCC supported is C++ 23, char8_t is the only viable UTF8 char type for \c std::codecvt.
|
||||
* So we can simply and safely use it to correctly trigger specific specializations of \c std::codecv in there.
|
||||
*/
|
||||
|
||||
#if defined(YYCC_CPPFEAT_UTF8)
|
||||
using CodecvtUtf8Char = char8_t;
|
||||
#else
|
||||
using CodecvtUtf8Char = char;
|
||||
#endif
|
||||
template<typename TChar>
|
||||
requires(std::is_same_v<TChar, char16_t> || std::is_same_v<TChar, char32_t>)
|
||||
using CodecvtFacet = std::codecvt<TChar, char8_t, std::mbstate_t>;
|
||||
|
||||
template<typename TChar,
|
||||
std::enable_if_t<std::is_same_v<TChar, char16_t> || std::is_same_v<TChar, char32_t>, int>
|
||||
= 0>
|
||||
using CodecvtFacet = std::codecvt<TChar, CodecvtUtf8Char, std::mbstate_t>;
|
||||
|
||||
template<typename TChar,
|
||||
std::enable_if_t<std::is_same_v<TChar, char16_t> || std::is_same_v<TChar, char32_t>, int>
|
||||
= 0>
|
||||
static ConvResult<std::basic_string<TChar>> generic_to_utf_other(
|
||||
const NS_YYCC_STRING::u8string_view& src) {
|
||||
template<typename TChar>
|
||||
requires(std::is_same_v<TChar, char16_t> || std::is_same_v<TChar, char32_t>)
|
||||
static ConvResult<std::basic_string<TChar>> generic_to_utf_other(const std::u8string_view& src) {
|
||||
// Reference:
|
||||
// https://en.cppreference.com/w/cpp/locale/codecvt/in
|
||||
|
||||
@ -52,38 +40,27 @@ namespace yycc::encoding::stlcvt {
|
||||
// convertion preparation
|
||||
std::mbstate_t mb{};
|
||||
dst.resize(src.size());
|
||||
const CodecvtUtf8Char *intern_from = reinterpret_cast<const CodecvtUtf8Char*>(src.data()),
|
||||
*intern_from_end = reinterpret_cast<const CodecvtUtf8Char*>(
|
||||
src.data() + src.size()),
|
||||
*intern_from_next = nullptr;
|
||||
TChar *extern_to = dst.data(), *extern_to_end = dst.data() + dst.size(),
|
||||
*extern_to_next = nullptr;
|
||||
const char8_t *intern_from = reinterpret_cast<const char8_t*>(src.data()),
|
||||
*intern_from_end = reinterpret_cast<const char8_t*>(src.data() + src.size()), *intern_from_next = nullptr;
|
||||
TChar *extern_to = dst.data(), *extern_to_end = dst.data() + dst.size(), *extern_to_next = nullptr;
|
||||
// do convertion
|
||||
auto result = this_codecvt.in(mb,
|
||||
intern_from,
|
||||
intern_from_end,
|
||||
intern_from_next,
|
||||
extern_to,
|
||||
extern_to_end,
|
||||
extern_to_next);
|
||||
auto result = this_codecvt.in(mb, intern_from, intern_from_end, intern_from_next, extern_to, extern_to_end, extern_to_next);
|
||||
|
||||
// check result
|
||||
if (result != CodecvtFacet<TChar>::ok) return ConvError();
|
||||
if (result != CodecvtFacet<TChar>::ok) return std::unexpected(ConvError{});
|
||||
// resize result and return
|
||||
dst.resize(extern_to_next - dst.data());
|
||||
return dst;
|
||||
}
|
||||
|
||||
template<typename TChar,
|
||||
std::enable_if_t<std::is_same_v<TChar, char16_t> || std::is_same_v<TChar, char32_t>, int>
|
||||
= 0>
|
||||
static ConvResult<NS_YYCC_STRING::u8string> generic_to_utf8(
|
||||
const std::basic_string_view<TChar>& src) {
|
||||
template<typename TChar>
|
||||
requires(std::is_same_v<TChar, char16_t> || std::is_same_v<TChar, char32_t>)
|
||||
static ConvResult<std::u8string> generic_to_utf8(const std::basic_string_view<TChar>& src) {
|
||||
// Reference:
|
||||
// https://en.cppreference.com/w/cpp/locale/codecvt/out
|
||||
|
||||
// prepare return value
|
||||
NS_YYCC_STRING::u8string dst;
|
||||
std::u8string dst;
|
||||
|
||||
// if src is empty, return directly
|
||||
if (src.empty()) {
|
||||
@ -99,102 +76,43 @@ namespace yycc::encoding::stlcvt {
|
||||
// do convertion preparation
|
||||
std::mbstate_t mb{};
|
||||
dst.resize(src.size() * this_codecvt.max_length());
|
||||
const TChar *intern_from = src.data(), *intern_from_end = src.data() + src.size(),
|
||||
*intern_from_next = nullptr;
|
||||
CodecvtUtf8Char *extern_to = reinterpret_cast<CodecvtUtf8Char*>(dst.data()),
|
||||
*extern_to_end = reinterpret_cast<CodecvtUtf8Char*>(dst.data() + dst.size()),
|
||||
*extern_to_next = nullptr;
|
||||
const TChar *intern_from = src.data(), *intern_from_end = src.data() + src.size(), *intern_from_next = nullptr;
|
||||
char8_t *extern_to = reinterpret_cast<char8_t*>(dst.data()), *extern_to_end = reinterpret_cast<char8_t*>(dst.data() + dst.size()),
|
||||
*extern_to_next = nullptr;
|
||||
// do convertion
|
||||
auto result = this_codecvt.out(mb,
|
||||
intern_from,
|
||||
intern_from_end,
|
||||
intern_from_next,
|
||||
extern_to,
|
||||
extern_to_end,
|
||||
extern_to_next);
|
||||
auto result = this_codecvt.out(mb, intern_from, intern_from_end, intern_from_next, extern_to, extern_to_end, extern_to_next);
|
||||
|
||||
// check result
|
||||
if (result != CodecvtFacet<TChar>::ok) return ConvError();
|
||||
if (result != CodecvtFacet<TChar>::ok) return std::unexpected(ConvError{});
|
||||
// resize result and retuen
|
||||
dst.resize(extern_to_next - reinterpret_cast<CodecvtUtf8Char*>(dst.data()));
|
||||
dst.resize(extern_to_next - reinterpret_cast<char8_t*>(dst.data()));
|
||||
return dst;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
#pragma endregion Converter
|
||||
|
||||
#pragma region Help Macros
|
||||
#pragma region
|
||||
|
||||
#define CONVFN_TYPE1(fct_name, src_char_type, dst_char_type) \
|
||||
namespace expected = NS_YYCC_PATCH_EXPECTED; \
|
||||
auto rv = 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 (fct_name(src, rv)) return rv; \
|
||||
else throw std::runtime_error("fail to convert utf string");
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UTF8 -> UTF16
|
||||
|
||||
ConvResult<std::u16string> priv_to_utf16(const NS_YYCC_STRING::u8string_view& src) {
|
||||
ConvResult<std::u16string> to_utf16(const std::u8string_view& src) {
|
||||
// UTF8 -> UTF16
|
||||
return generic_to_utf_other<char16_t>(src);
|
||||
}
|
||||
bool to_utf16(const NS_YYCC_STRING::u8string_view& src, std::u16string& dst) {
|
||||
CONVFN_TYPE1(to_utf16, NS_YYCC_STRING::u8char, char16_t);
|
||||
}
|
||||
std::u16string to_utf16(const NS_YYCC_STRING::u8string_view& src) {
|
||||
CONVFN_TYPE2(to_utf16, NS_YYCC_STRING::u8char, char16_t);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UTF16 -> UTF8
|
||||
|
||||
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::u16string_view& src) {
|
||||
ConvResult<std::u8string> to_utf8(const std::u16string_view& src) {
|
||||
// UTF16 -> UTF8
|
||||
return generic_to_utf8<char16_t>(src);
|
||||
}
|
||||
bool 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 to_utf8(const std::u16string_view& src) {
|
||||
CONVFN_TYPE2(to_utf8, char16_t, NS_YYCC_STRING::u8char);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UTF8 -> UTF32
|
||||
|
||||
ConvResult<std::u32string> priv_to_utf32(const NS_YYCC_STRING::u8string_view& src) {
|
||||
ConvResult<std::u32string> to_utf32(const std::u8string_view& src) {
|
||||
// UTF8 -> UTF32
|
||||
return generic_to_utf_other<char32_t>(src);
|
||||
}
|
||||
bool to_utf32(const NS_YYCC_STRING::u8string_view& src, std::u32string& dst) {
|
||||
CONVFN_TYPE1(to_utf32, NS_YYCC_STRING::u8char, char32_t);
|
||||
}
|
||||
std::u32string to_utf32(const NS_YYCC_STRING::u8string_view& src) {
|
||||
CONVFN_TYPE2(to_utf32, NS_YYCC_STRING::u8char, char32_t);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UTF32 -> UTF8
|
||||
|
||||
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::u32string_view& src) {
|
||||
ConvResult<std::u8string> to_utf8(const std::u32string_view& src) {
|
||||
// UTF32 -> UTF8
|
||||
return generic_to_utf8<char32_t>(src);
|
||||
}
|
||||
bool 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 to_utf8(const std::u32string_view& src) {
|
||||
CONVFN_TYPE2(to_utf8, char32_t, NS_YYCC_STRING::u8char);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
} // namespace yycc::encoding::utf
|
||||
} // namespace yycc::encoding::stlcvt
|
||||
|
@ -1,40 +1,43 @@
|
||||
#pragma once
|
||||
#include "../string.hpp"
|
||||
#include "../patch/expected.hpp"
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
#define NS_YYCC_PATCH_EXPECTED ::yycc::patch::expected
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <expected>
|
||||
|
||||
namespace yycc::encoding::stlcvt {
|
||||
|
||||
/// @private
|
||||
/// @brief Possible convertion error occurs in this module.
|
||||
struct ConvError {};
|
||||
|
||||
/// @private
|
||||
/// @brief The result type of this module.
|
||||
template<typename T>
|
||||
using ConvResult = NS_YYCC_PATCH_EXPECTED::Expected<T, ConvError>;
|
||||
using ConvResult = std::expected<T, ConvError>;
|
||||
|
||||
// UTF8 -> UTF16
|
||||
ConvResult<std::u16string> priv_to_utf16(const NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief UTF8 -> UTF16
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u16string> to_utf16(const std::u8string_view& src);
|
||||
|
||||
// UTF16 -> UTF8
|
||||
ConvResult<NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief UTF16 -> UTF8
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u8string> to_utf8(const std::u16string_view& src);
|
||||
|
||||
// UTF8 -> UTF32
|
||||
ConvResult<std::u32string> priv_to_utf32(const NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief UTF8 -> UTF32
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u32string> to_utf32(const std::u8string_view& src);
|
||||
|
||||
// UTF32 -> UTF8
|
||||
ConvResult<NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief UTF32 -> UTF8
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u8string> utf8(const std::u32string_view& src);
|
||||
|
||||
}
|
||||
|
||||
#undef NS_YYCC_PATCH_EXPECTED
|
||||
#undef NS_YYCC_STRING
|
||||
|
@ -11,34 +11,14 @@
|
||||
#include <Windows.h>
|
||||
#include "../windows/import_guard_tail.hpp"
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
#define NS_YYCC_STRING_REINTERPRET ::yycc::string::reinterpret
|
||||
#define NS_YYCC_PATCH_EXPECTED ::yycc::patch::expected
|
||||
|
||||
namespace yycc::encoding::windows {
|
||||
|
||||
#pragma region Help Macros
|
||||
#pragma region WideCharToMultiByte and MultiByteToWideChar stuff
|
||||
|
||||
#define CONVFN_TYPE1(fct_name, src_char_type, dst_char_type, ...) \
|
||||
namespace expected = NS_YYCC_PATCH_EXPECTED; \
|
||||
auto rv = priv_##fct_name(src, ##__VA_ARGS__); \
|
||||
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 (fct_name(src, rv, ##__VA_ARGS__)) return rv; \
|
||||
else throw std::runtime_error("fail to convert string in Win32 function");
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region WChar -> Char
|
||||
|
||||
ConvResult<std::string> priv_to_char(const std::wstring_view& src, CodePage code_page) {
|
||||
// WChar -> Char
|
||||
ConvResult<std::string> to_char(const std::wstring_view& src, CodePage code_page) {
|
||||
// prepare result
|
||||
std::string dst;
|
||||
|
||||
@ -52,36 +32,25 @@ namespace yycc::encoding::windows {
|
||||
LPCWCH lpWideCharStr = reinterpret_cast<LPCWCH>(src.data());
|
||||
// check whether source string is too large.
|
||||
size_t cSrcSize = src.size();
|
||||
if (cSrcSize > std::numeric_limits<int>::max()) return ConvError::TooLargeLength;
|
||||
if (cSrcSize > std::numeric_limits<int>::max()) return std::unexpected(ConvError::TooLargeLength);
|
||||
int cchWideChar = static_cast<int>(src.size());
|
||||
|
||||
// do convertion
|
||||
// do a dry-run first to fetch desired size.
|
||||
int desired_size = WideCharToMultiByte(code_page, 0, lpWideCharStr, cchWideChar, NULL, 0, NULL, NULL);
|
||||
if (desired_size <= 0) return ConvError::NoDesiredSize;
|
||||
if (desired_size <= 0) return std::unexpected(ConvError::NoDesiredSize);
|
||||
// resize dest for receiving result
|
||||
dst.resize(static_cast<size_t>(desired_size));
|
||||
// do real convertion
|
||||
int write_result
|
||||
= WideCharToMultiByte(code_page, 0, lpWideCharStr, cchWideChar, reinterpret_cast<LPSTR>(dst.data()), desired_size, NULL, NULL);
|
||||
if (write_result <= 0) return ConvError::BadWrittenSize;
|
||||
if (write_result <= 0) return std::unexpected(ConvError::BadWrittenSize);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
bool to_char(const std::wstring_view& src, std::string& dst, CodePage code_page) {
|
||||
CONVFN_TYPE1(to_char, wchar_t, char, code_page);
|
||||
}
|
||||
|
||||
std::string to_char(const std::wstring_view& src, CodePage code_page) {
|
||||
CONVFN_TYPE2(to_char, wchar_t, char, code_page);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Char -> WChar
|
||||
|
||||
ConvResult<std::wstring> priv_to_wchar(const std::string_view& src, CodePage code_page) {
|
||||
// Char -> WChar
|
||||
ConvResult<std::wstring> to_wchar(const std::string_view& src, CodePage code_page) {
|
||||
// prepare result
|
||||
std::wstring dst;
|
||||
|
||||
@ -95,134 +64,53 @@ namespace yycc::encoding::windows {
|
||||
LPCCH lpMultiByteStr = reinterpret_cast<LPCCH>(src.data());
|
||||
// check whether source string is too large.
|
||||
size_t cSrcSize = src.size();
|
||||
if (cSrcSize > std::numeric_limits<int>::max()) return ConvError::TooLargeLength;
|
||||
if (cSrcSize > std::numeric_limits<int>::max()) return std::unexpected(ConvError::TooLargeLength);
|
||||
int cbMultiByte = static_cast<int>(src.size());
|
||||
|
||||
// do convertion
|
||||
// do a dry-run first to fetch desired size.
|
||||
int desired_size = MultiByteToWideChar(code_page, 0, lpMultiByteStr, cbMultiByte, NULL, 0);
|
||||
if (desired_size <= 0) return ConvError::NoDesiredSize;
|
||||
if (desired_size <= 0) return std::unexpected(ConvError::NoDesiredSize);
|
||||
// resize dest for receiving result
|
||||
dst.resize(static_cast<size_t>(desired_size));
|
||||
// do real convertion
|
||||
int write_result = MultiByteToWideChar(code_page, 0, lpMultiByteStr, cbMultiByte, reinterpret_cast<LPWSTR>(dst.data()), desired_size);
|
||||
if (write_result <= 0) return ConvError::BadWrittenSize;
|
||||
if (write_result <= 0) return std::unexpected(ConvError::BadWrittenSize);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
bool to_wchar(const std::string_view& src, std::wstring& dst, CodePage code_page) {
|
||||
CONVFN_TYPE1(to_wchar, char, wchar_t, code_page);
|
||||
// Char -> Char
|
||||
ConvResult<std::string> to_char(const std::string_view& src, CodePage src_code_page, CodePage dst_code_page) {
|
||||
auto first_rv = to_wchar(src, src_code_page);
|
||||
return first_rv.and_then([dst_code_page](const auto& src) { return to_char(src, dst_code_page); });
|
||||
}
|
||||
|
||||
std::wstring to_wchar(const std::string_view& src, CodePage code_page) {
|
||||
CONVFN_TYPE2(to_wchar, char, wchar_t, code_page);
|
||||
// WChar -> UTF8
|
||||
ConvResult<std::u8string> to_utf8(const std::wstring_view& src) {
|
||||
auto rv = to_char(src, CP_UTF8);
|
||||
return rv.transform([](const auto& dst) { return NS_YYCC_STRING_REINTERPRET::as_utf8(dst); });
|
||||
}
|
||||
|
||||
// UTF8 -> WChar
|
||||
ConvResult<std::wstring> to_wchar(const std::u8string_view& src) {
|
||||
return to_wchar(NS_YYCC_STRING_REINTERPRET::as_ordinary_view(src), CP_UTF8);
|
||||
}
|
||||
|
||||
// Char -> UTF8
|
||||
ConvResult<std::u8string> to_utf8(const std::string_view& src, CodePage code_page) {
|
||||
auto rv = to_char(src, code_page, CP_UTF8);
|
||||
return rv.transform([](const auto& dst) { return NS_YYCC_STRING_REINTERPRET::as_utf8(dst); });
|
||||
}
|
||||
|
||||
// UTF8 -> Char
|
||||
ConvResult<std::string> to_char(const std::u8string_view& src, CodePage code_page) {
|
||||
return to_char(NS_YYCC_STRING_REINTERPRET::as_ordinary_view(src), CP_UTF8, code_page);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Char -> Char
|
||||
|
||||
ConvResult<std::string> priv_to_char(const std::string_view& src, CodePage src_code_page, CodePage dst_code_page) {
|
||||
namespace expected = NS_YYCC_PATCH_EXPECTED;
|
||||
|
||||
// Perform first convertion
|
||||
auto first_rv = priv_to_wchar(src, src_code_page);
|
||||
if (expected::is_error(first_rv)) {
|
||||
return expected::get_error(first_rv);
|
||||
}
|
||||
// Perform second convertion
|
||||
auto second_rv = to_char(std::get<std::wstring>(first_rv), dst_code_page);
|
||||
return second_rv;
|
||||
}
|
||||
|
||||
bool to_char(const std::string_view& src, std::string& dst, CodePage src_code_page, CodePage dst_code_page) {
|
||||
CONVFN_TYPE1(to_char, char, char, src_code_page, dst_code_page);
|
||||
}
|
||||
|
||||
std::string to_char(const std::string_view& src, CodePage src_code_page, CodePage dst_code_page) {
|
||||
CONVFN_TYPE2(to_char, char, char, src_code_page, dst_code_page);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region WChar -> UTF8
|
||||
|
||||
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::wstring_view& src) {
|
||||
namespace expected = NS_YYCC_PATCH_EXPECTED;
|
||||
|
||||
auto rv = priv_to_char(src, CP_UTF8);
|
||||
if (expected::is_value(rv)) {
|
||||
return NS_YYCC_STRING_REINTERPRET::as_utf8(expected::get_value(rv));
|
||||
} else {
|
||||
return expected::get_error(rv);
|
||||
}
|
||||
}
|
||||
|
||||
bool 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 to_utf8(const std::wstring_view& src) {
|
||||
CONVFN_TYPE2(to_utf8, wchar_t, NS_YYCC_STRING::u8char);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UTF8 -> WChar
|
||||
|
||||
ConvResult<std::wstring> priv_to_wchar(const NS_YYCC_STRING::u8string_view& src) {
|
||||
return priv_to_wchar(NS_YYCC_STRING_REINTERPRET::as_ordinary_view(src), CP_UTF8);
|
||||
}
|
||||
|
||||
bool to_wchar(const NS_YYCC_STRING::u8string_view& src, std::wstring& dst) {
|
||||
CONVFN_TYPE1(to_wchar, NS_YYCC_STRING::u8char, wchar_t);
|
||||
}
|
||||
|
||||
std::wstring to_wchar(const NS_YYCC_STRING::u8string_view& src) {
|
||||
CONVFN_TYPE2(to_wchar, NS_YYCC_STRING::u8char, wchar_t);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Char -> UTF8
|
||||
|
||||
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::string_view& src, CodePage code_page) {
|
||||
namespace expected = NS_YYCC_PATCH_EXPECTED;
|
||||
|
||||
auto rv = priv_to_char(src, code_page, CP_UTF8);
|
||||
if (expected::is_value(rv)) {
|
||||
return NS_YYCC_STRING_REINTERPRET::as_utf8(expected::get_value(rv));
|
||||
} else {
|
||||
return expected::get_error(rv);
|
||||
}
|
||||
}
|
||||
|
||||
bool to_utf8(const std::string_view& src, NS_YYCC_STRING::u8string& dst, CodePage code_page) {
|
||||
CONVFN_TYPE1(to_utf8, char, NS_YYCC_STRING::u8char, code_page);
|
||||
}
|
||||
|
||||
NS_YYCC_STRING::u8string to_utf8(const std::string_view& src, CodePage code_page) {
|
||||
CONVFN_TYPE2(to_utf8, char, NS_YYCC_STRING::u8char, code_page);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UTF8 -> Char
|
||||
|
||||
ConvResult<std::string> priv_to_char(const NS_YYCC_STRING::u8string_view& src, CodePage code_page) {
|
||||
return priv_to_char(NS_YYCC_STRING_REINTERPRET::as_ordinary_view(src), CP_UTF8, code_page);
|
||||
}
|
||||
|
||||
bool to_char(const NS_YYCC_STRING::u8string_view& src, std::string& dst, CodePage code_page) {
|
||||
CONVFN_TYPE1(to_char, NS_YYCC_STRING::u8char, char, code_page);
|
||||
}
|
||||
|
||||
std::string to_char(const NS_YYCC_STRING::u8string_view& src, CodePage code_page) {
|
||||
CONVFN_TYPE2(to_char, NS_YYCC_STRING::u8char, char, code_page);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
#pragma region UTF stuff
|
||||
|
||||
// YYC MARK:
|
||||
// The convertion between UTF is implemented by c16rtomb, c32rtomb, mbrtoc16 and mbrtoc32.
|
||||
@ -239,9 +127,8 @@ namespace yycc::encoding::windows {
|
||||
constexpr size_t MULTIPLE_UTF8_TO_UTF32 = 1u;
|
||||
constexpr size_t MULTIPLE_UTF32_TO_UTF8 = 4u;
|
||||
|
||||
#pragma region UTF8 -> UTF16
|
||||
|
||||
ConvResult<std::u16string> priv_to_utf16(const NS_YYCC_STRING::u8string_view& src) {
|
||||
// UTF8 -> UTF16
|
||||
ConvResult<std::u16string> to_utf16(const std::u8string_view& src) {
|
||||
std::u16string dst;
|
||||
dst.reserve(src.size() * MULTIPLE_UTF8_TO_UTF16);
|
||||
|
||||
@ -253,8 +140,8 @@ namespace yycc::encoding::windows {
|
||||
while (ptr < end) {
|
||||
size_t rc = std::mbrtoc16(&c16, ptr, end - ptr, &state);
|
||||
|
||||
if (rc == (size_t) -1) return ConvError::EncodeUtf8;
|
||||
else if (rc == (size_t) -2) return ConvError::IncompleteUtf8;
|
||||
if (rc == (size_t) -1) return std::unexpected(ConvError::EncodeUtf8);
|
||||
else if (rc == (size_t) -2) return std::unexpected(ConvError::IncompleteUtf8);
|
||||
else if (rc != (size_t) -3) dst.push_back(c16); // from earlier surrogate pair
|
||||
else {
|
||||
dst.push_back(c16);
|
||||
@ -264,20 +151,9 @@ namespace yycc::encoding::windows {
|
||||
return dst;
|
||||
}
|
||||
|
||||
bool to_utf16(const NS_YYCC_STRING::u8string_view& src, std::u16string& dst) {
|
||||
CONVFN_TYPE1(to_utf16, NS_YYCC_STRING::u8char, char16_t);
|
||||
}
|
||||
|
||||
std::u16string to_utf16(const NS_YYCC_STRING::u8string_view& src) {
|
||||
CONVFN_TYPE2(to_utf16, NS_YYCC_STRING::u8char, char16_t);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UTF16 -> UTF8
|
||||
|
||||
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::u16string_view& src) {
|
||||
NS_YYCC_STRING::u8string dst;
|
||||
// UTF16 -> UTF8
|
||||
ConvResult<std::u8string> to_utf8(const std::u16string_view& src) {
|
||||
std::u8string dst;
|
||||
dst.reserve(src.size() * MULTIPLE_UTF16_TO_UTF8);
|
||||
|
||||
std::mbstate_t state{};
|
||||
@ -285,25 +161,14 @@ namespace yycc::encoding::windows {
|
||||
for (char16_t c : src) {
|
||||
size_t rc = std::c16rtomb(mbout, c, &state);
|
||||
|
||||
if (rc != (size_t) -1) dst.append(reinterpret_cast<NS_YYCC_STRING::u8char*>(mbout), rc);
|
||||
else return ConvError::InvalidUtf16;
|
||||
if (rc != (size_t) -1) dst.append(reinterpret_cast<char8_t*>(mbout), rc);
|
||||
else return std::unexpected(ConvError::InvalidUtf16);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
bool 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 to_utf8(const std::u16string_view& src) {
|
||||
CONVFN_TYPE2(to_utf8, char16_t, NS_YYCC_STRING::u8char);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UTF8 -> UTF32
|
||||
|
||||
ConvResult<std::u32string> priv_to_utf32(const NS_YYCC_STRING::u8string_view& src) {
|
||||
// UTF8 -> UTF32
|
||||
ConvResult<std::u32string> to_utf32(const std::u8string_view& src) {
|
||||
std::u32string dst;
|
||||
dst.reserve(src.size() * MULTIPLE_UTF8_TO_UTF32);
|
||||
|
||||
@ -315,8 +180,8 @@ namespace yycc::encoding::windows {
|
||||
while (ptr < end) {
|
||||
size_t rc = std::mbrtoc32(&c32, ptr, end - ptr, &state);
|
||||
|
||||
if (rc == (size_t) -1) return ConvError::EncodeUtf8;
|
||||
else if (rc == (size_t) -2) return ConvError::IncompleteUtf8;
|
||||
if (rc == (size_t) -1) return std::unexpected(ConvError::EncodeUtf8);
|
||||
else if (rc == (size_t) -2) return std::unexpected(ConvError::IncompleteUtf8);
|
||||
else if (rc != (size_t) -3) throw std::runtime_error("no surrogates in UTF-32");
|
||||
else dst.push_back(c32);
|
||||
|
||||
@ -325,20 +190,9 @@ namespace yycc::encoding::windows {
|
||||
return dst;
|
||||
}
|
||||
|
||||
bool to_utf32(const NS_YYCC_STRING::u8string_view& src, std::u32string& dst) {
|
||||
CONVFN_TYPE1(to_utf32, NS_YYCC_STRING::u8char, char32_t);
|
||||
}
|
||||
|
||||
std::u32string to_utf32(const NS_YYCC_STRING::u8string_view& src) {
|
||||
CONVFN_TYPE2(to_utf32, NS_YYCC_STRING::u8char, char32_t);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UTF32 -> UTF8
|
||||
|
||||
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::u32string_view& src) {
|
||||
NS_YYCC_STRING::u8string dst;
|
||||
// UTF32 -> UTF8
|
||||
ConvResult<std::u8string> to_utf8(const std::u32string_view& src) {
|
||||
std::u8string dst;
|
||||
dst.reserve(src.size() * MULTIPLE_UTF32_TO_UTF8);
|
||||
|
||||
std::mbstate_t state{};
|
||||
@ -346,25 +200,14 @@ namespace yycc::encoding::windows {
|
||||
for (char32_t c : src) {
|
||||
size_t rc = std::c32rtomb(mbout, c, &state);
|
||||
|
||||
if (rc != (size_t) -1) dst.append(reinterpret_cast<NS_YYCC_STRING::u8char*>(mbout), rc);
|
||||
else return ConvError::InvalidUtf32;
|
||||
if (rc != (size_t) -1) dst.append(reinterpret_cast<char8_t*>(mbout), rc);
|
||||
else return std::unexpected(ConvError::InvalidUtf32);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
bool 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 to_utf8(const std::u32string_view& src) {
|
||||
CONVFN_TYPE2(to_utf8, char32_t, NS_YYCC_STRING::u8char);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#undef CONVFN_TYPE1
|
||||
#undef CONVFN_TYPE2
|
||||
|
||||
} // namespace yycc::encoding::windows
|
||||
|
||||
#endif
|
||||
|
@ -3,18 +3,17 @@
|
||||
|
||||
#if defined(YYCC_OS_WINDOWS)
|
||||
|
||||
#include "../patch/expected.hpp"
|
||||
#include "../string.hpp"
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <expected>
|
||||
#include <cstdint>
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
#define NS_YYCC_PATCH_EXPECTED ::yycc::patch::expected
|
||||
|
||||
namespace yycc::encoding::windows {
|
||||
|
||||
/// @brief The type of Windows code page.
|
||||
using CodePage = uint32_t;
|
||||
|
||||
/// @private
|
||||
/// @brief The possible error kind occurs in this module.
|
||||
enum class ConvError {
|
||||
TooLargeLength, ///< The length of given string is too large exceeding the maximum capacity of Win32 function.
|
||||
NoDesiredSize, ///< Can not compute the desired size of result string.
|
||||
@ -25,73 +24,98 @@ namespace yycc::encoding::windows {
|
||||
IncompleteUtf8, ///< Given UTF8 string is incomplete.
|
||||
};
|
||||
|
||||
/// @private
|
||||
/// @brief The result type in this module.
|
||||
template<typename T>
|
||||
using ConvResult = NS_YYCC_PATCH_EXPECTED::Expected<T, ConvError>;
|
||||
using ConvResult = std::expected<T, ConvError>;
|
||||
|
||||
// WChar -> Char
|
||||
ConvResult<std::string> priv_to_char(const std::wstring_view& src, CodePage code_page);
|
||||
bool to_char(const std::wstring_view& src, std::string& dst, CodePage code_page);
|
||||
std::string to_char(const std::wstring_view& src, CodePage code_page);
|
||||
/**
|
||||
* @brief WChar -> Char
|
||||
* @param src
|
||||
* @param code_page
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::string> to_char(const std::wstring_view& src, CodePage code_page);
|
||||
|
||||
// Char -> WChar
|
||||
ConvResult<std::wstring> priv_to_wchar(const std::string_view& src, CodePage code_page);
|
||||
bool to_wchar(const std::string_view& src, std::wstring& dst, CodePage code_page);
|
||||
std::wstring to_wchar(const std::string_view& src, CodePage code_page);
|
||||
/**
|
||||
* @brief Char -> WChar
|
||||
* @param src
|
||||
* @param code_page
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::wstring> to_wchar(const std::string_view& src, CodePage code_page);
|
||||
|
||||
// Char -> Char
|
||||
// This is the combination of "WChar -> Char" and "Char -> WChar"
|
||||
ConvResult<std::string> priv_to_char(const std::string_view& src, CodePage src_code_page, CodePage dst_code_page);
|
||||
bool to_char(const std::string_view& src, std::string& dst, CodePage src_code_page, CodePage dst_code_page);
|
||||
std::string to_char(const std::string_view& src, CodePage src_code_page, CodePage dst_code_page);
|
||||
/**
|
||||
* @brief Char -> Char
|
||||
* @details This is the combination of "WChar -> Char" and "Char -> WChar"
|
||||
* @param src
|
||||
* @param src_code_page
|
||||
* @param dst_code_page
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::string> to_char(const std::string_view& src, CodePage src_code_page, CodePage dst_code_page);
|
||||
|
||||
// WChar -> UTF8
|
||||
// This is the specialization of "WChar -> Char"
|
||||
ConvResult<NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief WChar -> UTF8
|
||||
* @details This is the specialization of "WChar -> Char"
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u8string> to_utf8(const std::wstring_view& src);
|
||||
|
||||
// UTF8 -> WChar
|
||||
// This is the specialization of "Char -> WChar"
|
||||
ConvResult<std::wstring> priv_to_wchar(const NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief UTF8 -> WChar
|
||||
* @details This is the specialization of "Char -> WChar"
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::wstring> to_wchar(const std::u8string_view& src);
|
||||
|
||||
// Char -> UTF8
|
||||
// This is the specialization of "Char -> Char"
|
||||
ConvResult<NS_YYCC_STRING::u8string> priv_to_utf8(const std::string_view& src, CodePage code_page);
|
||||
bool to_utf8(const std::string_view& src, NS_YYCC_STRING::u8string& dst, CodePage code_page);
|
||||
NS_YYCC_STRING::u8string to_utf8(const std::string_view& src, CodePage code_page);
|
||||
/**
|
||||
* @brief Char -> UTF8
|
||||
* @details This is the specialization of "Char -> Char"
|
||||
* @param src
|
||||
* @param code_page
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u8string> to_utf8(const std::string_view& src, CodePage code_page);
|
||||
|
||||
// UTF8 -> Char
|
||||
// This is the specialization of "Char -> Char"
|
||||
ConvResult<std::string> priv_to_char(const NS_YYCC_STRING::u8string_view& src, CodePage code_page);
|
||||
bool to_char(const NS_YYCC_STRING::u8string_view& src, std::string& dst, CodePage code_page);
|
||||
std::string to_char(const NS_YYCC_STRING::u8string_view& src, CodePage code_page);
|
||||
/**
|
||||
* @brief UTF8 -> Char
|
||||
* @details This is the specialization of "Char -> Char"
|
||||
* @param src
|
||||
* @param code_page
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::string> to_char(const std::u8string_view& src, CodePage code_page);
|
||||
|
||||
// UTF8 -> UTF16
|
||||
ConvResult<std::u16string> priv_to_utf16(const NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief UTF8 -> UTF16
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u16string> to_utf16(const std::u8string_view& src);
|
||||
|
||||
// UTF16 -> UTF8
|
||||
ConvResult<NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief UTF16 -> UTF8
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u8string> to_utf8(const std::u16string_view& src);
|
||||
|
||||
// UTF8 -> UTF32
|
||||
ConvResult<std::u32string> priv_to_utf32(const NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief UTF8 -> UTF32
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u32string> to_utf32(const std::u8string_view& src);
|
||||
|
||||
// UTF32 -> UTF8
|
||||
ConvResult<NS_YYCC_STRING::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);
|
||||
/**
|
||||
* @brief UTF32 -> UTF8
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
ConvResult<std::u8string> to_utf8(const std::u32string_view& src);
|
||||
|
||||
} // namespace yycc::encoding::windows
|
||||
|
||||
#undef NS_YYCC_PATCH_EXPECTED
|
||||
#undef NS_YYCC_STRING
|
||||
|
||||
#endif
|
||||
|
@ -3,3 +3,28 @@
|
||||
#if (defined(YYCC_CC_MSVC) + defined(YYCC_CC_GCC) + defined(YYCC_CC_CLANG)) != 1
|
||||
#error "Current compiler is not supported!"
|
||||
#endif
|
||||
|
||||
namespace yycc::macro::compiler {
|
||||
|
||||
/// @brief The kind of compiler.
|
||||
enum class CompilerKind {
|
||||
Msvc, ///< MSVC
|
||||
Gcc, ///< GCC
|
||||
Clang, ///< Clang
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Fetch the compiler type.
|
||||
* @return The kind of compiler.
|
||||
*/
|
||||
inline constexpr CompilerKind get_compiler() {
|
||||
#if defined(YYCC_CC_MSVC)
|
||||
return CompilerKind::Msvc;
|
||||
#elif defined(YYCC_CC_GCC)
|
||||
return CompilerKind::Gcc;
|
||||
#else
|
||||
return CompilerKind::Clang;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace yycc::macro::compiler
|
||||
|
@ -5,3 +5,24 @@
|
||||
#error "Current system endian (byte order) is not supported!"
|
||||
#endif
|
||||
|
||||
namespace yycc::macro::endian {
|
||||
|
||||
/// @brief The endian kind of OS.
|
||||
enum class EndianKind {
|
||||
Little, ///< Little endian.
|
||||
Big, ///< Big endian.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Fetch the endian of OS.
|
||||
* @return The endian of OS.
|
||||
*/
|
||||
inline constexpr EndianKind get_endian() {
|
||||
#if defined(YYCC_ENDIAN_LITTLE)
|
||||
return EndianKind::Little;
|
||||
#else
|
||||
return EndianKind::Big;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace yycc::macro::endian
|
||||
|
@ -4,3 +4,25 @@
|
||||
#if (defined(YYCC_OS_WINDOWS) + defined(YYCC_OS_LINUX)) != 1
|
||||
#error "Current operating system is not supported!"
|
||||
#endif
|
||||
|
||||
namespace yycc::macro::os {
|
||||
|
||||
/// @brief The operating system kind.
|
||||
enum class OsKind {
|
||||
Windows, ///< Microsoft Windows
|
||||
Linux, ///< GNU/Linux
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Fetch the operating system
|
||||
* @return The kind of operating system.
|
||||
*/
|
||||
inline constexpr OsKind get_os() {
|
||||
#if defined(YYCC_OS_WINDOWS)
|
||||
return OsKind::Windows;
|
||||
#else
|
||||
return OsKind::Linux;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace yycc::macro::os
|
||||
|
@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// Suppress unsafe warning on Windows
|
||||
#include "../windows/unsafe_suppressor.hpp"
|
||||
|
||||
// Prelude section
|
||||
#include "../string.hpp"
|
||||
namespace yycc::prelude {
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
|
||||
using u8char = NS_YYCC_STRING::u8char;
|
||||
using u8string = NS_YYCC_STRING::u8string;
|
||||
using u8string_view = NS_YYCC_STRING::u8string_view;
|
||||
|
||||
#undef NS_YYCC_STRING
|
||||
|
||||
} // namespace yycc::prelude
|
||||
|
||||
// Expose all members
|
||||
using namespace yycc::prelude;
|
@ -1,10 +1,12 @@
|
||||
#pragma once
|
||||
#include <optional>
|
||||
|
||||
/// @brief The reproduction of Rust Option type.
|
||||
/// @details
|
||||
/// This namespace reproduce Rust Option type, and its members Some and None in C++.
|
||||
/// However Option is not important than Result, so its implementation is very casual.
|
||||
/**
|
||||
* @brief The reproduction of Rust Option type.
|
||||
* @details
|
||||
* This namespace reproduce Rust Option type, and its members Some and None in C++.
|
||||
* However Option is not important than Result, so its implementation is very casual.
|
||||
*/
|
||||
namespace yycc::rust::option {
|
||||
|
||||
template<typename T>
|
||||
|
@ -1,12 +1,9 @@
|
||||
#include "panic.hpp"
|
||||
#include "../macro/feature_probe.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#if defined(YYCC_CPPFEAT_STACKTRACE)
|
||||
#include <stacktrace>
|
||||
#endif
|
||||
|
||||
namespace yycc::rust::panic {
|
||||
|
||||
@ -24,12 +21,8 @@ namespace yycc::rust::panic {
|
||||
// User custom message
|
||||
dst << "note: " << msg << std::endl;
|
||||
// Stacktrace message if we support it.
|
||||
#if defined(YYCC_CPPFEAT_STACKTRACE)
|
||||
dst << "stacktrace: " << std::endl;
|
||||
dst << std::stacktrace::current() << std::endl;
|
||||
#else
|
||||
dst << "there is no stacktrace because your C++ runtime do not support it." << std::endl;
|
||||
#endif
|
||||
// // Restore color
|
||||
// dst << RESET;
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
#pragma once
|
||||
#include "../macro/feature_probe.hpp"
|
||||
#include <string_view>
|
||||
|
||||
#if defined(YYCC_CPPFEAT_FORMAT)
|
||||
#include <format>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Provides Rust-style panic functionality for immediate program termination on unrecoverable errors.
|
||||
@ -38,13 +34,7 @@ namespace yycc::rust::panic {
|
||||
* The macro parameters are the message to format and its arguments, following \c std::format syntax.
|
||||
* This macro essentially calls \c std::format internally.
|
||||
*/
|
||||
#if defined(YYCC_CPPFEAT_FORMAT)
|
||||
#if defined(YYCC_CPPFEAT_VA_OPT)
|
||||
#define RS_PANICF(msg, ...) RS_PANIC(std::format(msg __VA_OPT__(, ) __VA_ARGS__))
|
||||
#else
|
||||
#define RS_PANICF(msg, ...) RS_PANIC(std::format(msg, ##__VA_ARGS__))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Immediately crashes the entire program like Rust's \c panic! macro.
|
||||
|
@ -1,16 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
// Include YYCC prelude first
|
||||
#include "core.hpp"
|
||||
|
||||
// Rust prelude section
|
||||
#include "../rust/primitive.hpp"
|
||||
#include "../rust/result.hpp"
|
||||
#include "../rust/option.hpp"
|
||||
#include "../rust/panic.hpp"
|
||||
#include "primitive.hpp"
|
||||
#include "result.hpp"
|
||||
#include "option.hpp"
|
||||
#include "panic.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace yycc::prelude::rust {
|
||||
namespace yycc::rust::prelude {
|
||||
// Include primitive types
|
||||
|
||||
#define NS_RUST_PRIMITIVE ::yycc::rust::primitive
|
||||
@ -35,7 +32,7 @@ namespace yycc::prelude::rust {
|
||||
#undef NS_RUST_PRIMITIVE
|
||||
|
||||
// Other types
|
||||
using String = ::yycc::string::u8string;
|
||||
using String = std::u8string;
|
||||
template<typename T>
|
||||
using Vec = std::vector<T>;
|
||||
|
||||
@ -49,4 +46,4 @@ namespace yycc::prelude::rust {
|
||||
} // namespace yycc::prelude::rust
|
||||
|
||||
// Expose all members
|
||||
using namespace yycc::prelude::rust;
|
||||
using namespace ::yycc::rust::prelude;
|
@ -3,7 +3,7 @@
|
||||
#include <cstddef>
|
||||
#include <string_view>
|
||||
|
||||
namespace yycc::primitive {
|
||||
namespace yycc::rust::primitive {
|
||||
|
||||
// `bool` is keyword so should not declare it anymore.
|
||||
// `char` is keyword so should not declare it anymore.
|
@ -1,9 +1,5 @@
|
||||
#pragma once
|
||||
#include "../macro/feature_probe.hpp"
|
||||
|
||||
#if defined(YYCC_CPPFEAT_EXPECTED)
|
||||
#include <expected>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The reproduction of Rust Option type.
|
||||
@ -42,8 +38,6 @@
|
||||
*/
|
||||
namespace yycc::rust::result {
|
||||
|
||||
#if defined(YYCC_CPPFEAT_EXPECTED)
|
||||
|
||||
/**
|
||||
* @brief Equivalent Rust \c Result in C++
|
||||
* @tparam T The type of the expected value.
|
||||
@ -80,6 +74,4 @@ namespace yycc::rust::result {
|
||||
return ResultType(std::unexpect, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace yycc::rust::result
|
||||
|
@ -27,7 +27,7 @@ namespace yycc::string::op {
|
||||
// Check expected size.
|
||||
if (count < 0) {
|
||||
// Invalid length returned by vsnprintf.
|
||||
return std::unexpected(FormatError::NoExpSize);
|
||||
return std::unexpected(FormatError::NoDesiredSize);
|
||||
}
|
||||
va_end(args1);
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
namespace yycc::string::op {
|
||||
|
||||
enum class FormatError {
|
||||
NullFormat, ///< Given format string is nullptr.
|
||||
NoExpSize, ///< Fail to fetch the expected size of result.
|
||||
NullFormat, ///< Given format string is nullptr.
|
||||
NoDesiredSize, ///< Fail to fetch the expected size of result.
|
||||
BadWrittenSize, ///< The written size is different with expected size.
|
||||
};
|
||||
|
||||
|
@ -2,18 +2,8 @@
|
||||
// Because this header is the part of wrapper, not a real header.
|
||||
// #pragma once
|
||||
|
||||
#include "../macro/os_detector.hpp"
|
||||
|
||||
#if defined(YYCC_OS_WINDOWS)
|
||||
|
||||
// Define 2 macros to disallow Windows generate MIN and MAX macros
|
||||
// which cause std::min and std::max can not function as normal.
|
||||
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#if !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// YYC MARK:
|
||||
// Since YYCC 2.0 version, we use CMake to handle Windows shitty macros,
|
||||
// so we do not need declare WIN32_LEAN_AND_MEAN or NOMINMAX in there.
|
||||
// But for keep the pair of this guard, we still keep this header file,
|
||||
// although it do nothing.
|
||||
|
Reference in New Issue
Block a user