75 lines
2.5 KiB
C++
75 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include <Windows.h>
|
|
|
|
#include <type_traits>
|
|
#include <string>
|
|
#include <locale>
|
|
#include <codecvt>
|
|
#include <cstring>
|
|
#include <stdexcept>
|
|
#include <cstddef>
|
|
|
|
#include "libipc/utility/concept.h"
|
|
#include "libipc/memory/resource.h"
|
|
#include "libipc/platform/detail.h"
|
|
|
|
namespace ipc {
|
|
namespace detail {
|
|
|
|
struct has_value_type_ {
|
|
template <typename T> static std::true_type check(typename T::value_type *);
|
|
template <typename T> static std::false_type check(...);
|
|
};
|
|
|
|
template <typename T, typename U, typename = decltype(has_value_type_::check<U>(nullptr))>
|
|
struct is_same_char : std::is_same<T, U> {};
|
|
|
|
template <typename T, typename U>
|
|
struct is_same_char<T, U, std::true_type> : std::is_same<T, typename U::value_type> {};
|
|
|
|
template <typename T, typename S, typename R = S>
|
|
using IsSameChar = ipc::require<is_same_char<T, S>::value, R>;
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
/// to_tchar implementation
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
template <typename T = TCHAR>
|
|
constexpr auto to_tchar(ipc::string &&str) -> IsSameChar<T, ipc::string, ipc::string &&> {
|
|
return std::move(str); // noconv
|
|
}
|
|
|
|
/**
|
|
* \remarks codecvt_utf8_utf16/std::wstring_convert is deprecated
|
|
* \see https://codingtidbit.com/2020/02/09/c17-codecvt_utf8-is-deprecated/
|
|
* https://stackoverflow.com/questions/42946335/deprecated-header-codecvt-replacement
|
|
* https://en.cppreference.com/w/cpp/locale/codecvt/in
|
|
* https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
|
|
*/
|
|
template <typename T = TCHAR>
|
|
auto to_tchar(ipc::string &&external) -> IsSameChar<T, ipc::wstring> {
|
|
if (external.empty()) {
|
|
return {}; // noconv
|
|
}
|
|
/**
|
|
* CP_ACP : The system default Windows ANSI code page.
|
|
* CP_MACCP : The current system Macintosh code page.
|
|
* CP_OEMCP : The current system OEM code page.
|
|
* CP_SYMBOL : Symbol code page (42).
|
|
* CP_THREAD_ACP: The Windows ANSI code page for the current thread.
|
|
* CP_UTF7 : UTF-7. Use this value only when forced by a 7-bit transport mechanism. Use of UTF-8 is preferred.
|
|
* CP_UTF8 : UTF-8.
|
|
*/
|
|
int size_needed = ::MultiByteToWideChar(CP_UTF8, 0, &external[0], (int)external.size(), NULL, 0);
|
|
if (size_needed <= 0) {
|
|
return {};
|
|
}
|
|
ipc::wstring internal(size_needed, L'\0');
|
|
::MultiByteToWideChar(CP_UTF8, 0, &external[0], (int)external.size(), &internal[0], size_needed);
|
|
return internal;
|
|
}
|
|
|
|
} // namespace detail
|
|
} // namespace ipc
|