Have you considered adding result_macros.h macros for C++23's new std::expected? This would make writing exception-free wrapper code a lot easier.
One discussion to have would be on the Unexpected type that is being returned (i.e. the second template parameter: std::expected<SuccessT, UnexpectedT>). The most straightforward choice would be to directly use HRESULT, BOOL, etc. However, that would loose crucial information when passed around. The THROW_XXX macros use the wil::ResultException for instance, in order to capture the source location, an optional message and other metadata. That's why I'd suggest using it as the unexpected type, too?
Another open question is how to name these macros (e.g. RETURN_UNEXPECTED_XXX, UNEXPECTED_XXX, etc.).
A possible implementation could look something like this:
#define RETURN_UNEXPECTED_IF_FAILED_MSG(hr, fmt, ...) \
do \
{ \
const auto __hrRet = wil::verify_hresult(hr); \
if (FAILED(__hrRet)) \
{ \
return std::unexpected<wil::ResultException>(std::in_place, __hrRet, _format_msg_(__VA_ARGS__), ...); \
} \
} \
while ((void)0, 0)
Related issues: #452
Have you considered adding
result_macros.hmacros for C++23's newstd::expected? This would make writing exception-free wrapper code a lot easier.One discussion to have would be on the Unexpected type that is being returned (i.e. the second template parameter:
std::expected<SuccessT, UnexpectedT>). The most straightforward choice would be to directly useHRESULT,BOOL, etc. However, that would loose crucial information when passed around. TheTHROW_XXXmacros use thewil::ResultExceptionfor instance, in order to capture the source location, an optional message and other metadata. That's why I'd suggest using it as the unexpected type, too?Another open question is how to name these macros (e.g.
RETURN_UNEXPECTED_XXX,UNEXPECTED_XXX, etc.).A possible implementation could look something like this:
Related issues: #452