Skip to content

Commit 050fa7a

Browse files
committed
Address hresult comments by adding tests and removing source_locatoin, special-cased further by checking the typename.
1 parent 2ee9368 commit 050fa7a

File tree

5 files changed

+72
-14
lines changed

5 files changed

+72
-14
lines changed

cppwinrt/code_writers.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,7 +1903,7 @@ namespace cppwinrt
19031903
}
19041904
}
19051905

1906-
static void write_produce_method(writer& w, MethodDef const& method)
1906+
static void write_produce_method(writer& w, MethodDef const& method, TypeDef const& type)
19071907
{
19081908
std::string_view format;
19091909

@@ -1934,11 +1934,12 @@ namespace cppwinrt
19341934
std::string upcall = "this->shim().";
19351935
auto name = get_name(method);
19361936
upcall += name;
1937-
// if (type_name == "Windows.Foundation.Collections.IMapView`2")
1938-
if (name == "Lookup")
1937+
1938+
auto typeName = type.TypeName();
1939+
if (((typeName == "IMapView`2") || (typeName == "IMap`2"))
1940+
&& (name == "Lookup"))
19391941
{
1940-
// Special-case Lookup to look for a TryLookup here, to avoid a throw/originate
1941-
// and add a small performance improvement.
1942+
// Special-case IMap*::Lookup to look for a TryLookup here, to avoid extranous throw/originates
19421943
std::string tryLookupUpCall = "this->shim().TryLookup";
19431944
format = R"( int32_t __stdcall %(%) noexcept final try
19441945
{
@@ -2012,7 +2013,7 @@ namespace cppwinrt
20122013
break;
20132014
}
20142015

2015-
w.write_each<write_produce_method>(info.type.MethodList());
2016+
w.write_each<write_produce_method>(info.type.MethodList(), info.type);
20162017
}
20172018
}
20182019

@@ -2034,7 +2035,7 @@ namespace cppwinrt
20342035
bind<write_comma_generic_typenames>(generics),
20352036
type,
20362037
type,
2037-
bind_each<write_produce_method>(type.MethodList()),
2038+
bind_each<write_produce_method>(type.MethodList(), type),
20382039
bind<write_fast_produce_methods>(type));
20392040
}
20402041

strings/base_collections_base.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,10 +514,10 @@ WINRT_EXPORT namespace winrt
514514

515515
if (pair == static_cast<D const&>(*this).get_container().end())
516516
{
517-
return { std::nullopt };
517+
return std::nullopt;
518518
}
519519

520-
return { static_cast<D const&>(*this).unwrap_value(pair->second) };
520+
return static_cast<D const&>(*this).unwrap_value(pair->second);
521521
}
522522

523523
V Lookup(K const& key) const

strings/base_error.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ WINRT_EXPORT namespace winrt
112112
originate(code, nullptr, sourceInformation);
113113
}
114114

115-
explicit hresult_error(hresult const code, no_originate_t, [[maybe_unused]] winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : m_code(verify_error(code))
115+
explicit hresult_error(hresult const code, no_originate_t) noexcept : m_code(verify_error(code))
116116
{
117117
}
118118

strings/base_meta.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,7 @@ namespace winrt::impl
308308
{
309309
template <typename U, typename = decltype(std::declval<U>().TryLookup(std::declval<K>(), trylookup_from_abi))> static constexpr bool get_value(int) { return true; }
310310
template <typename> static constexpr bool get_value(...) { return false; }
311-
312311
public:
313-
314312
static constexpr bool value = get_value<D>(0);
315313
};
316314

test/test_cpp20/custom_error.cpp

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ namespace
3737

3838
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 170000
3939
// <source_location> not available in libc++ before LLVM 16
40-
TEST_CASE("custom_error_logger", "[!shouldfail]")
40+
TEST_CASE("custom_error_logger_on_throw", "[!shouldfail]")
4141
#else
42-
TEST_CASE("custom_error_logger")
42+
TEST_CASE("custom_error_logger_on_throw")
4343
#endif
4444
{
4545
// Set up global handler
@@ -72,3 +72,62 @@ TEST_CASE("custom_error_logger")
7272
winrt_throw_hresult_handler = nullptr;
7373
s_loggerCalled = false;
7474
}
75+
template<typename... Args>
76+
void HresultOnLine80(Args... args)
77+
{
78+
// Validate that handler translated on creating an HRESULT
79+
#line 80 // Force next line to be reported as line number 80
80+
winrt::hresult_canceled(std::forward<Args>(args)...);
81+
}
82+
83+
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 170000
84+
// <source_location> not available in libc++ before LLVM 16
85+
TEST_CASE("custom_error_logger_on_originate", "[!shouldfail]")
86+
#else
87+
TEST_CASE("custom_error_logger_on_originate")
88+
#endif
89+
{
90+
// Set up global handler
91+
REQUIRE(!s_loggerCalled);
92+
REQUIRE(!winrt_throw_hresult_handler);
93+
winrt_throw_hresult_handler = logger;
94+
95+
HresultOnLine80();
96+
REQUIRE(s_loggerCalled);
97+
// In C++20 these fields should be filled in by std::source_location
98+
REQUIRE(s_loggerArgs.lineNumber == 80);
99+
const auto fileNameSv = std::string_view(s_loggerArgs.fileName);
100+
REQUIRE(!fileNameSv.empty());
101+
REQUIRE(fileNameSv.find("custom_error.cpp") != std::string::npos);
102+
#ifdef _DEBUG
103+
const auto functionNameSv = std::string_view(s_loggerArgs.functionName);
104+
REQUIRE(!functionNameSv.empty());
105+
// Every compiler has a slightly different naming approach for this function, and even the same
106+
// compiler can change its mind over time. Instead of matching the entire function name just
107+
// match against the part we care about.
108+
REQUIRE((functionNameSv.find("HresultOnLine80") != std::string_view::npos));
109+
#else
110+
REQUIRE(s_loggerArgs.functionName == nullptr);
111+
#endif // _DEBUG
112+
113+
REQUIRE(s_loggerArgs.returnAddress);
114+
REQUIRE(s_loggerArgs.result == HRESULT_FROM_WIN32(ERROR_CANCELLED)); // E_ILLEGAL_DELEGATE_ASSIGNMENT)
115+
116+
s_loggerCalled = false;
117+
s_loggerArgs.lineNumber = 0;
118+
// verify HRESULT with a custom message
119+
HresultOnLine80(L"with custom message");
120+
REQUIRE(s_loggerCalled);
121+
REQUIRE(s_loggerArgs.lineNumber == 80);
122+
123+
s_loggerCalled = false;
124+
s_loggerArgs.lineNumber = 0;
125+
// verify that no_originate does _not_ call the logger.
126+
HresultOnLine80(winrt::hresult_error::no_originate);
127+
REQUIRE(!s_loggerCalled);
128+
REQUIRE(s_loggerArgs.lineNumber == 0);
129+
130+
// Remove global handler
131+
winrt_throw_hresult_handler = nullptr;
132+
s_loggerCalled = false;
133+
}

0 commit comments

Comments
 (0)