Skip to content
Open
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
22 changes: 22 additions & 0 deletions include/wil/stl.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,28 @@ inline PCWSTR str_raw_ptr(const std::wstring& str)
return str.c_str();
}

#if defined(__WIL_OLEAUTO_H_)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stl.h is not like resource.h and cannot be included multiple times to pick up new definitions, so this will be fragile and subject to include order dependencies. That said, trying to put this in resource.h may not be the best option either. In theory, there could be a _STRING_VIEW_ check, however I'm not a fan of these since (1) this is an implementation detail and might change, (2) might break if someone uses something other than the MSVC STL, and (3) isn't compatible with modules. We could also add a conditional include such as:

#if WIL_USE_STL && (__WI_LIBCPP_STD_VER >= 17) && WI_HAS_INCLUDE(<string_view>, 1)
#include <string_view>
#endif

and then later

#if WIL_USE_STL && (__cpp_lib_string_view >= 201606L)
// definition goes here
#endif

which eliminates the "is string_view included already" check (the purpose of WIL_USE_STL), however given how widely used resource.h is used, the probability of unintentional side effects is high.

Another option is to add a function to resource.h that accepts a template argument that is constrained on is_string_view_like , so you don't have to bother with proper guards.

#if defined(_STRING_VIEW_) || defined(__cpp_lib_string_view)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the general case, this is a problematic check because <version> also defines __cpp_lib_string_view even though <string_view> may not have been included. That said, this is the stl.h header, so it already (1) assumes STL use and (2) already includes <string_view> with the correct guards, so this concern is moot, but it does make the _STRING_VIEW_ check unnecessary. Better yet if you compare to a specific release. E.g. this could ideally become:

Suggested change
#if defined(_STRING_VIEW_) || defined(__cpp_lib_string_view)
#if __cpp_lib_string_view >= 201606L

... which means you can just move this definition a few lines lower since this check is already present.

// Create wil::unique_bstr from std::wstring_view (regardless if not null terminated, or if it contains embedded nulls)
inline wil::unique_bstr make_bstr_nothrow(std::wstring_view source) noexcept
Copy link
Copy Markdown
Collaborator

@dmachaj dmachaj May 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For bonus points - there is also the wil::zwstring_view overloads that enforce null termination but are ortherwise just a string_view.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can basic_zstring_view decay to basic_string_view? Or is there something special preventing object slicing?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might. I didn't actually check and just assumed a specialization would be needed.

{
return wil::unique_bstr(::SysAllocStringLen(source.data(), static_cast<UINT>(source.size())));
}
inline wil::unique_bstr make_bstr_failfast(std::wstring_view source) noexcept
{
return wil::unique_bstr(FAIL_FAST_IF_NULL_ALLOC(::SysAllocStringLen(source.data(), static_cast<UINT>(source.size()))));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider implementing this in terms of the nothrow variant, rather than repeating it here.

}
#ifdef WIL_ENABLE_EXCEPTIONS
inline wil::unique_bstr make_bstr(std::wstring_view source)
{
wil::unique_bstr result(make_bstr_nothrow(source));
THROW_IF_NULL_ALLOC(result);
return result;
}
#endif // WIL_ENABLE_EXCEPTIONS
#endif // defined(_STRING_VIEW_) || defined(__cpp_lib_string_view)
#endif // defined(__WIL_OLEAUTO_H_)

#if __cpp_lib_string_view >= 201606L

/**
Expand Down
Loading