Skip to content

Commit 464e591

Browse files
authored
Implement support for noexcept overridable methods (#910)
1 parent 07f5b9a commit 464e591

File tree

5 files changed

+45
-2
lines changed

5 files changed

+45
-2
lines changed

cppwinrt/code_writers.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,7 +1905,7 @@ namespace cppwinrt
19051905

19061906
static void write_dispatch_overridable_method(writer& w, MethodDef const& method)
19071907
{
1908-
auto format = R"( auto %(%)
1908+
auto format = R"( auto %(%)%
19091909
{
19101910
if (auto overridable = this->shim_overridable())
19111911
{
@@ -1921,6 +1921,7 @@ namespace cppwinrt
19211921
w.write(format,
19221922
get_name(method),
19231923
bind<write_implementation_params>(signature),
1924+
is_noexcept(method) ? " noexcept" : "",
19241925
get_name(method),
19251926
bind<write_consume_args>(signature),
19261927
get_name(method),
@@ -1950,7 +1951,7 @@ struct __declspec(empty_bases) produce_dispatch_to_overridable<T, D, %>
19501951

19511952
static void write_interface_override_method(writer& w, MethodDef const& method, std::string_view const& interface_name)
19521953
{
1953-
auto format = R"( template <typename D> WINRT_IMPL_AUTO(%) %T<D>::%(%) const
1954+
auto format = R"( template <typename D> WINRT_IMPL_AUTO(%) %T<D>::%(%) const%
19541955
{
19551956
return shim().template try_as<%>().%(%);
19561957
}
@@ -1964,6 +1965,7 @@ struct __declspec(empty_bases) produce_dispatch_to_overridable<T, D, %>
19641965
interface_name,
19651966
method_name,
19661967
bind<write_consume_params>(signature),
1968+
is_noexcept(method) ? " noexcept" : "",
19671969
interface_name,
19681970
method_name,
19691971
bind<write_consume_args>(signature));

test/old_tests/Composable/Base.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ namespace winrt::Composable::implementation
2121
return overridable().OverridableVirtualMethod();
2222
}
2323

24+
int32_t Base::CallOverridableNoexceptMethod() noexcept
25+
{
26+
return overridable().OverridableNoexceptMethod();
27+
}
28+
2429
hstring Base::OverridableMethod()
2530
{
2631
return L"Base::OverridableMethod";
@@ -31,6 +36,11 @@ namespace winrt::Composable::implementation
3136
return L"Base::OverridableVirtualMethod";
3237
}
3338

39+
int32_t Base::OverridableNoexceptMethod() noexcept
40+
{
41+
return 42;
42+
}
43+
3444
hstring Base::Name() const
3545
{
3646
return m_name;

test/old_tests/Composable/Base.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ namespace winrt::Composable::implementation
1414
virtual hstring VirtualMethod();
1515
hstring CallOverridableMethod();
1616
hstring CallOverridableVirtualMethod();
17+
int32_t CallOverridableNoexceptMethod() noexcept;
1718
hstring OverridableMethod() ;
1819
virtual hstring OverridableVirtualMethod();
20+
int32_t OverridableNoexceptMethod() noexcept;
1921

2022
hstring Name() const;
2123

test/old_tests/Composable/Composable.idl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import "Windows.Foundation.idl";
22

3+
namespace Windows.Foundation.Metadata
4+
{
5+
[attributeusage(target_method, target_property)]
6+
[attributename("noexcept2")]
7+
attribute NoExceptionAttribute
8+
{
9+
}
10+
}
11+
312
namespace Composable
413
{
514
runtimeclass Base;
@@ -11,6 +20,7 @@ namespace Composable
1120
HRESULT VirtualMethod([out, retval] HSTRING* value);
1221
HRESULT CallOverridableMethod([out, retval] HSTRING* value);
1322
HRESULT CallOverridableVirtualMethod([out, retval] HSTRING* value);
23+
[noexcept2] HRESULT CallOverridableNoexceptMethod([out, retval] int* value);
1424

1525
[propget] HRESULT Name([out, retval] HSTRING* value);
1626
};
@@ -27,6 +37,7 @@ namespace Composable
2737
{
2838
HRESULT OverridableMethod([out, retval] HSTRING* value);
2939
HRESULT OverridableVirtualMethod([out, retval] HSTRING* value);
40+
[noexcept2] HRESULT OverridableNoexceptMethod([out, retval] int* value);
3041
};
3142

3243
[version(1.0), uuid(5f3996e1-3cf7-4716-9a3d-11eb5d32caff), exclusiveto(Derived)]

test/old_tests/UnitTests/Composable.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ namespace
1313
constexpr auto Base_VirtualMethod{ L"Base::VirtualMethod"sv };
1414
constexpr auto Base_OverridableMethod{ L"Base::OverridableMethod"sv };
1515
constexpr auto Base_OverridableVirtualMethod{ L"Base::OverridableVirtualMethod"sv };
16+
constexpr auto Base_OverridableNoexceptMethod{ 42 };
1617

1718
constexpr auto Derived_VirtualMethod{ L"Derived::VirtualMethod"sv };
1819
constexpr auto Derived_OverridableVirtualMethod{ L"Derived::OverridableVirtualMethod"sv };
1920

2021
constexpr auto OverriddenBase_OverridableMethod{ L"OverriddenBase::OverridableMethod"sv };
2122
constexpr auto OverriddenBase_OverridableVirtualMethod{ L"OverriddenBase::OverridableVirtualMethod"sv };
23+
constexpr auto OverriddenBase_OverridableNoexceptMethod{ 1337 };
2224
}
2325

2426
TEST_CASE("Composable.Base")
@@ -27,6 +29,7 @@ TEST_CASE("Composable.Base")
2729
REQUIRE(base.VirtualMethod() == Base_VirtualMethod);
2830
REQUIRE(base.CallOverridableMethod() == Base_OverridableMethod);
2931
REQUIRE(base.CallOverridableVirtualMethod() == Base_OverridableVirtualMethod);
32+
REQUIRE(base.CallOverridableNoexceptMethod() == Base_OverridableNoexceptMethod);
3033
}
3134

3235
TEST_CASE("Composable.OverriddenBase")
@@ -39,6 +42,7 @@ TEST_CASE("Composable.OverriddenBase")
3942
REQUIRE(object.VirtualMethod() == Base_VirtualMethod);
4043
REQUIRE(object.CallOverridableMethod() == Base_OverridableMethod);
4144
REQUIRE(object.CallOverridableVirtualMethod() == Base_OverridableVirtualMethod);
45+
REQUIRE(object.CallOverridableNoexceptMethod() == Base_OverridableNoexceptMethod);
4246
}
4347
{
4448
struct OverriddenBase : BaseT<OverriddenBase>
@@ -52,15 +56,22 @@ TEST_CASE("Composable.OverriddenBase")
5256
{
5357
return hstring(OverriddenBase_OverridableVirtualMethod);
5458
}
59+
60+
int32_t OverridableNoexceptMethod() const noexcept
61+
{
62+
return OverriddenBase_OverridableNoexceptMethod;
63+
}
5564
};
5665
auto object = make<OverriddenBase>();
5766
REQUIRE(object.VirtualMethod() == Base_VirtualMethod);
5867
REQUIRE(object.CallOverridableMethod() == OverriddenBase_OverridableMethod);
5968
REQUIRE(object.CallOverridableVirtualMethod() == OverriddenBase_OverridableVirtualMethod);
69+
REQUIRE(object.CallOverridableNoexceptMethod() == OverriddenBase_OverridableNoexceptMethod);
6070
}
6171
{
6272
const std::wstring OverridableMethodResult = std::wstring(OverriddenBase_OverridableMethod) + L"=>" + Base_OverridableMethod.data();
6373
const std::wstring OverridableVirtualMethodResult = std::wstring(OverriddenBase_OverridableVirtualMethod) + L"=>" + Base_OverridableVirtualMethod.data();
74+
const int32_t OverridableNoexceptMethodResult = OverriddenBase_OverridableNoexceptMethod + Base_OverridableNoexceptMethod;
6475

6576
struct OverriddenBase : BaseT<OverriddenBase>
6677
{
@@ -73,11 +84,17 @@ TEST_CASE("Composable.OverriddenBase")
7384
{
7485
return OverriddenBase_OverridableVirtualMethod + L"=>" + BaseT<OverriddenBase>::OverridableVirtualMethod();
7586
}
87+
88+
int32_t OverridableNoexceptMethod() const noexcept
89+
{
90+
return OverriddenBase_OverridableNoexceptMethod + BaseT<OverriddenBase>::OverridableNoexceptMethod();
91+
}
7692
};
7793
auto object = make<OverriddenBase>();
7894
REQUIRE(object.VirtualMethod() == Base_VirtualMethod);
7995
REQUIRE(object.CallOverridableMethod() == OverridableMethodResult);
8096
REQUIRE(object.CallOverridableVirtualMethod() == OverridableVirtualMethodResult);
97+
REQUIRE(object.CallOverridableNoexceptMethod() == OverridableNoexceptMethodResult);
8198
}
8299
}
83100

@@ -88,6 +105,7 @@ TEST_CASE("Composable.Derived")
88105
REQUIRE(obj.VirtualMethod() == Derived_VirtualMethod);
89106
REQUIRE(obj.CallOverridableMethod() == Base_OverridableMethod);
90107
REQUIRE(obj.CallOverridableVirtualMethod() == Derived_OverridableVirtualMethod);
108+
REQUIRE(obj.CallOverridableNoexceptMethod() == Base_OverridableNoexceptMethod);
91109
}
92110

93111
namespace

0 commit comments

Comments
 (0)