Skip to content

Commit

Permalink
Add support for char8_t strings
Browse files Browse the repository at this point in the history
  • Loading branch information
SergiusTheBest committed Mar 19, 2023
1 parent c12efd0 commit d60df3a
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 27 deletions.
48 changes: 28 additions & 20 deletions include/plog/Record.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<const char*>(data));
# else
plog::detail::operator<<(stream, util::toWide(reinterpret_cast<const char*>(data), codePage::kUTF8));
# endif
}
#endif //__cpp_char8_t

// Print `std::pair`
template<class T1, class T2>
inline void operator<<(util::nostringstream& stream, const std::pair<T1, T2>& data)
Expand Down Expand Up @@ -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<bool Value>
struct valueType { enum { value = Value }; };

template<class T, class Stream>
inline No operator<<(Stream&, const T&);

template<class T, class Stream>
struct isStreamable
{
enum { value = sizeof(operator<<(meta::declval<Stream>(), meta::declval<const T>())) != sizeof(No) };
};
struct isStreamable : valueType<sizeof(operator<<(meta::declval<Stream>(), meta::declval<const T>())) != sizeof(No)> {};

template<class Stream>
struct isStreamable<std::ios_base& PLOG_CDECL (std::ios_base&), Stream>
{
enum { value = true };
};
struct isStreamable<std::ios_base& PLOG_CDECL (std::ios_base&), Stream> : valueType<true> {};

template<class Stream, size_t N>
struct isStreamable<wchar_t[N], Stream>
{
enum { value = false };
};
struct isStreamable<wchar_t[N], Stream> : valueType<false> {};

template<class Stream, size_t N>
struct isStreamable<const wchar_t[N], Stream>
{
enum { value = false };
};
struct isStreamable<const wchar_t[N], Stream> : valueType<false> {};

// 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<const wchar_t*, std::ostream>
{
enum { value = false };
};
struct isStreamable<const wchar_t*, std::ostream> : valueType<false> {};

# 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<class Stream, size_t N>
struct isStreamable<char8_t[N], Stream> : valueType<false> {};

template<class Stream>
struct isStreamable<const char8_t*, Stream> : valueType<false> {};
# endif //__cpp_char8_t
}

template<class T>
Expand Down
8 changes: 4 additions & 4 deletions include/plog/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int>(len), &wstr[0], static_cast<int>(wstr.size()));
int wlen = MultiByteToWideChar(cp, 0, str, static_cast<int>(len), &wstr[0], static_cast<int>(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
Expand Down
11 changes: 8 additions & 3 deletions samples/Demo/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<const char8_t*>(u8"Cyrillic: тест");
#endif

// Multiline.
Expand Down

0 comments on commit d60df3a

Please sign in to comment.