Skip to content

Commit 72b30cc

Browse files
authored
Add a clang-specific impl->projection conversion operator (#1274)
1 parent abcdc75 commit 72b30cc

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

strings/base_implements.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,25 @@ namespace winrt::impl
110110
template <typename D, typename I, typename Enable>
111111
struct producer_convert : producer<D, typename default_interface<I>::type>
112112
{
113+
#ifdef __clang__
114+
// This is sub-optimal in that it requires an AddRef and Release of the
115+
// implementation type for every conversion, but it works around an
116+
// issue where Clang ignores the conversion of producer_ref<I> const
117+
// to I&& (an rvalue ref that cannot bind a const rvalue).
118+
// See CWG rev. 110 active issue 2077, "Overload resolution and invalid
119+
// rvalue-reference initialization"
120+
operator I() const noexcept
121+
{
122+
I result{ nullptr };
123+
copy_from_abi(result, (produce<D, typename default_interface<I>::type>*)this);
124+
return result;
125+
}
126+
#else
113127
operator producer_ref<I> const() const noexcept
114128
{
115129
return { (produce<D, typename default_interface<I>::type>*)this };
116130
}
131+
#endif
117132

118133
operator producer_vtable<I> const() const noexcept
119134
{

test/old_tests/UnitTests/as_implements.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,13 @@ TEST_CASE("as_implements_inheritance")
138138
REQUIRE(bar.get() == foo2.get());
139139
}
140140
}
141+
142+
TEST_CASE("convert_to_implements_via_uniform_initialization")
143+
{
144+
// uniform initialization relies on IStringable(IStringable&&),
145+
// which requires non-const rvalue semantics.
146+
com_ptr<Foo> foo = make_self<Foo>();
147+
IStringable stringable{ *foo };
148+
com_ptr<Foo> foo2 = stringable.as<Foo>();
149+
REQUIRE(foo.get() == foo2.get());
150+
}

0 commit comments

Comments
 (0)