Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions cppwinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ namespace cppwinrt
}
}

[[nodiscard]] static finish_with wrap_ifdef(writer& w, std::string_view macro)
{
auto format = R"(#ifdef %
)";

w.write(format, macro);

return { w, write_endif };
}

static void write_parent_depends(writer& w, cache const& c, std::string_view const& type_namespace)
{
auto pos = type_namespace.rfind('.');
Expand Down Expand Up @@ -3216,6 +3226,18 @@ struct __declspec(empty_bases) produce_dispatch_to_overridable<T, D, %>
type);
}

static void write_std_formatter(writer& w, TypeDef const& type)
{
if (implements_interface(type, "Windows.Foundation.IStringable"))
{
auto generics = type.GenericParam();

w.write(" template<%> struct formatter<%, wchar_t> : formatter<winrt::Windows::Foundation::IStringable, wchar_t> {};\n",
bind<write_generic_typenames>(generics),
type);
}
}

static void write_namespace_special(writer& w, std::string_view const& namespace_name)
{
if (namespace_name == "Windows.Foundation")
Expand Down Expand Up @@ -3259,6 +3281,7 @@ struct __declspec(empty_bases) produce_dispatch_to_overridable<T, D, %>
if (namespace_name == "Windows.Foundation")
{
w.write(strings::base_reference_produce_1);
w.write(strings::base_stringable_format);
}
}
}
1 change: 1 addition & 0 deletions cppwinrt/cppwinrt.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
<ClInclude Include="..\strings\base_string.h" />
<ClInclude Include="..\strings\base_string_input.h" />
<ClInclude Include="..\strings\base_string_operators.h" />
<ClInclude Include="..\strings\base_stringable_format.h" />
<ClInclude Include="..\strings\base_types.h" />
<ClInclude Include="..\strings\base_version.h" />
<ClInclude Include="..\strings\base_version_odr.h" />
Expand Down
3 changes: 3 additions & 0 deletions cppwinrt/cppwinrt.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@
<ClInclude Include="..\strings\base_iterator.h">
<Filter>strings</Filter>
</ClInclude>
<ClInclude Include="..\strings\base_stringable_format.h">
<Filter>strings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="$(OutDir)version.rc" />
Expand Down
14 changes: 11 additions & 3 deletions cppwinrt/file_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,17 @@ namespace cppwinrt
}
{
auto wrap_std = wrap_std_namespace(w);
auto wrap_lean = wrap_lean_and_mean(w);
w.write_each<write_std_hash>(members.interfaces);
w.write_each<write_std_hash>(members.classes);

{
auto wrap_lean = wrap_lean_and_mean(w);
w.write_each<write_std_hash>(members.interfaces);
w.write_each<write_std_hash>(members.classes);
}
{
auto wrap_format = wrap_ifdef(w, "__cpp_lib_format");
w.write_each<write_std_formatter>(members.interfaces);
w.write_each<write_std_formatter>(members.classes);
}
}

write_namespace_special(w, ns);
Expand Down
21 changes: 21 additions & 0 deletions cppwinrt/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,27 @@ namespace cppwinrt
return result;
}

static bool implements_interface(TypeDef const& type, std::string_view const& name)
{
for (auto&& impl : type.InterfaceImpl())
{
const auto iface = impl.Interface();
if (iface.type() != TypeDefOrRef::TypeSpec && type_name(iface) == name)
{
return true;
}
}

if (auto base = get_base_class(type))
{
return implements_interface(base, name);
}
else
{
return false;
}
}

bool has_fastabi_tearoffs(writer& w, TypeDef const& type)
{
for (auto&& [name, info] : get_interfaces(w, type))
Expand Down
4 changes: 4 additions & 0 deletions strings/base_includes.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#include <directxmath.h>
#endif

#ifdef __cpp_lib_format
#include <format>
#endif

#ifdef __cpp_lib_coroutine

#include <coroutine>
Expand Down
7 changes: 6 additions & 1 deletion strings/base_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ WINRT_EXPORT namespace winrt
return rend();
}

#if __cpp_lib_starts_ends_with
#ifdef __cpp_lib_starts_ends_with
bool starts_with(wchar_t const value) const noexcept
{
return operator std::wstring_view().starts_with(value);
Expand Down Expand Up @@ -437,6 +437,11 @@ WINRT_EXPORT namespace winrt
}
}

#ifdef __cpp_lib_format
template<>
struct std::formatter<winrt::hstring, wchar_t> : std::formatter<std::wstring_view, wchar_t> {};
#endif

namespace winrt::impl
{
template <> struct abi<hstring>
Expand Down
12 changes: 12 additions & 0 deletions strings/base_stringable_format.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

#ifdef __cpp_lib_format
template<>
struct std::formatter<winrt::Windows::Foundation::IStringable, wchar_t> : std::formatter<winrt::hstring, wchar_t>
{
template<typename FormatContext>
auto format(winrt::Windows::Foundation::IStringable const& obj, FormatContext& fc)
{
return std::formatter<winrt::hstring, wchar_t>::format(obj.ToString(), fc);
}
};
#endif
28 changes: 28 additions & 0 deletions test/test_cpp20/format.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "pch.h"
#include <format>

struct stringable : winrt::implements<stringable, winrt::Windows::Foundation::IStringable>
{
winrt::hstring ToString()
{
return L"a stringable object";
}
};

TEST_CASE("format")
{
{
winrt::hstring str = L"World";
REQUIRE(std::format(L"Hello {}", str) == L"Hello World");
}

{
winrt::Windows::Foundation::IStringable obj = winrt::make<stringable>();
REQUIRE(std::format(L"This is {}", obj) == L"This is a stringable object");
}

{
winrt::Windows::Data::Json::JsonArray jsonArray;
REQUIRE(std::format(L"The contents of the array are: {}", jsonArray) == L"The contents of the array are: []");
}
}
2 changes: 1 addition & 1 deletion test/test_cpp20/hstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ TEST_CASE("hstring")
REQUIRE(text.ends_with(L"rocks!"));
REQUIRE(textView.ends_with(L"rocks!"));
REQUIRE(text.ends_with(L"rocks!") == textView.ends_with(L"rocks!"));
}
}
2 changes: 2 additions & 0 deletions test/test_cpp20/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#define WINRT_LEAN_AND_MEAN
#include <unknwn.h>
#include "winrt/Windows.Data.Json.h"
#include "winrt/Windows.Foundation.h"
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/Windows.Foundation.Numerics.h"
#include <winstring.h>
Expand Down
1 change: 1 addition & 0 deletions test/test_cpp20/test_cpp20.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="format.cpp" />
<ClCompile Include="hstring.cpp" />
<ClCompile Include="main.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
Expand Down