-
Notifications
You must be signed in to change notification settings - Fork 239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
std::format support for hstring, IStringable and more #1018
Comments
On a related note: Shouldn't types like h string be implicitly convertible to a std::string_view (wither |
hstring already has a conversion to wstring_view |
Sorry, overlooked it in the documentation. Then why doesn't it (supposedly) work with |
I believe |
No idea, what the spec says, but this seems to work: https://godbolt.org/z/3zrWKEYc9 |
This does not: https://godbolt.org/z/M868GKv74 |
Stupid me. The first parameter is the format string and has nothing to do with std::formatter. Sorry for the noise |
Looking at it now, support for Support for hstring is rather trivial, on the other hand.
This is impossible as HSTRING is immutable. However, cppwinrt has |
As you noted about |
I actually have something working now, I was going to send a PR this afternoon |
Leaving this here for anybody that might be interested: you can directly format into an hstring with code like this template<std::size_t N, typename CharT, typename Traits = std::char_traits<CharT>>
struct basic_fixed_string
{
consteval basic_fixed_string(const CharT (&arr)[N + 1]) noexcept
{
for (std::size_t i = 0; i < N; ++i)
{
data[i] = arr[i];
}
}
constexpr operator std::basic_string_view<CharT, Traits>() const noexcept
{
return { data, N };
}
CharT data[N]{};
};
template<std::size_t N, typename CharT>
basic_fixed_string(const CharT (&)[N]) -> basic_fixed_string<N - 1, CharT, std::char_traits<CharT>>;
template<std::size_t N>
using fixed_string = basic_fixed_string<N, char>;
#ifdef __cpp_lib_char8_t
template<std::size_t N>
using fixed_u8string = basic_fixed_string<N, char8_t>;
#endif
template<std::size_t N>
using fixed_u16string = basic_fixed_string<N, char16_t>;
template<std::size_t N>
using fixed_u32string = basic_fixed_string<N, char32_t>;
template<std::size_t N>
using fixed_wstring = basic_fixed_string<N, wchar_t>;
template<fixed_wstring FormatString, typename... Args>
winrt::hstring hstring_format(Args&&... args)
{
const auto sizetSize = std::formatted_size(FormatString, args...);
uint32_t u32Size = 0;
winrt::check_hresult(SizeTToUInt32(sizetSize, &u32Size));
// requires wil. can be replaced by your RAII wrapper of preference calling WindowsDeleteStringBuffer
wil::unique_hstring_buffer bufHandle;
wchar_t* buf = nullptr;
winrt::check_hresult(WindowsPreallocateStringBuffer(u32Size, &buf, bufHandle.put()));
const auto result = std::format_to_n(buf, u32Size, FormatString, args...);
assert(result.size == u32Size);
winrt::hstring str;
winrt::check_hresult(WindowsPromoteStringBuffer(bufHandle.get(), reinterpret_cast<HSTRING*>(winrt::put_abi(str))));
bufHandle.release(); // we shouldn't free the HSTRING_BUFFER if WindowsPromoteStringBuffer succeeded.
return str;
}
const auto str = hstring_format<L"{}">(1); // L"1" The usage of If |
This could be revisited once microsoft/STL#2937 lands in VS. The idea would be similar to: template <typename... Args>
hstring format(std::wformat_string fmt, Args&&... args)
{
const auto sizetSize = std::formatted_size(FormatString, args...);
uint32_t u32Size = 0;
winrt::check_hresult(SizeTToUInt32(sizetSize, &u32Size)); // TODO: avoid using this Win32 API
impl::hstring_builder output(u32Size);
const auto result = std::format_to_n(buf, u32Size, FormatString, args...);
WINRT_ASSERT(result.size == u32Size);
return output.to_hstring();
} So |
C++ 20 introduces std::format however currently Windows Runtime types don't work directly with them. Consider providing support for directly passing hstring and IStringable to std::format and additionally I would like to see hstring work with std::format_to so you can avoid an extra copy from std::wstring.
The text was updated successfully, but these errors were encountered: