diff --git a/include/plog/Record.h b/include/plog/Record.h index 5626043..c0c4e87 100644 --- a/include/plog/Record.h +++ b/include/plog/Record.h @@ -146,6 +146,17 @@ namespace plog plog::detail::operator<<(stream, data.c_str()); } +#ifdef __cpp_char8_t + inline void operator<<(util::nostringstream& stream, const char8_t* data) + { +# if PLOG_CHAR_IS_UTF8 + plog::detail::operator<<(stream, reinterpret_cast(data)); +# else + plog::detail::operator<<(stream, util::toWide(reinterpret_cast(data), codePage::kUTF8)); +# endif + } +#endif //__cpp_char8_t + // Print `std::pair` template inline void operator<<(util::nostringstream& stream, const std::pair& data) @@ -201,39 +212,36 @@ namespace plog #if defined(_WIN32) && (!defined(_MSC_VER) || _MSC_VER > 1400) // MSVC 2005 doesn't understand `enableIf`, so drop all `meta` namespace meta { + template + struct valueType { enum { value = Value }; }; + template inline No operator<<(Stream&, const T&); template - struct isStreamable - { - enum { value = sizeof(operator<<(meta::declval(), meta::declval())) != sizeof(No) }; - }; + struct isStreamable : valueType(), meta::declval())) != sizeof(No)> {}; template - struct isStreamable - { - enum { value = true }; - }; + struct isStreamable : valueType {}; template - struct isStreamable - { - enum { value = false }; - }; + struct isStreamable : valueType {}; template - struct isStreamable - { - enum { value = false }; - }; + struct isStreamable : valueType {}; // meta doesn't work well for deleted functions and C++20 has `operator<<(std::ostream&, const wchar_t*) = delete` so exlicitly define it template<> - struct isStreamable - { - enum { value = false }; - }; + struct isStreamable : valueType {}; + +# ifdef __cpp_char8_t + // meta doesn't work well for deleted functions and C++20 has `operator<<(std::ostream&, const char8_t*) = delete` so exlicitly define it + template + struct isStreamable : valueType {}; + + template + struct isStreamable : valueType {}; +# endif //__cpp_char8_t } template diff --git a/include/plog/Util.h b/include/plog/Util.h index f8678af..efce8fc 100644 --- a/include/plog/Util.h +++ b/include/plog/Util.h @@ -266,23 +266,23 @@ namespace plog #endif #ifdef _WIN32 - inline std::wstring toWide(const char* str) + inline std::wstring toWide(const char* str, UINT cp = codePage::kChar) { size_t len = ::strlen(str); std::wstring wstr(len, 0); if (!wstr.empty()) { - int wlen = MultiByteToWideChar(codePage::kChar, 0, str, static_cast(len), &wstr[0], static_cast(wstr.size())); + int wlen = MultiByteToWideChar(cp, 0, str, static_cast(len), &wstr[0], static_cast(wstr.size())); wstr.resize(wlen); } return wstr; } - inline std::wstring toWide(const std::string& str) + inline std::wstring toWide(const std::string& str, UINT cp = codePage::kChar) { - return toWide(str.c_str()); + return toWide(str.c_str(), cp); } inline const std::wstring& toWide(const std::wstring& str) // do nothing for already wide string diff --git a/samples/Demo/Main.cpp b/samples/Demo/Main.cpp index e96b51d..222fea9 100644 --- a/samples/Demo/Main.cpp +++ b/samples/Demo/Main.cpp @@ -87,14 +87,19 @@ int main() // Plog handles unicode and std::string/wstring. #ifndef _WIN32 // On Windows the following code produces a warning C4566 if the codepage is not Cyrillic. - PLOG_DEBUG << "Cat - котэ"; + PLOG_DEBUG << "test - тест"; PLOG_DEBUG << std::string("test - тест"); #endif #if PLOG_ENABLE_WCHAR_INPUT - PLOG_DEBUG << L"Cat - котэ"; + PLOG_DEBUG << L"test - тест"; PLOG_DEBUG << std::wstring(L"test - тест"); - PLOG_DEBUG << L'ы'; + PLOG_DEBUG << L'ж'; +#endif + +#ifdef __cpp_char8_t + PLOG_DEBUG << u8"Chinese: 中文"; + PLOG_DEBUG << const_cast(u8"Cyrillic: тест"); #endif // Multiline.