Skip to content
Chris Guzak edited this page Dec 28, 2023 · 16 revisions

WIL string helpers perform basic string manipulations. They augment the RAII resource types such as unique_cotaskmem_string, documented in WIL Resource Wrappers (RAII). To support a given string type, the definitions of those must precede the inclusion of wil/resource.h. For example #include <wil/stl.h> to get support for std::wstring and #include <winstring.h> to get wil::unique_hstring.

wil::make_something_string

The string maker functions accept a raw Unicode string pointer (or in rare cases, an ANSI string pointer) and an optional length. They return a suitably-specialized unique_any wrapper.

The string maker functions follow this pattern:

unique_something_string make_something_string         (PCWSTR source, size_t length = -1);
unique_something_string make_something_string_nothrow (PCWSTR source, size_t length = -1);
unique_something_string make_something_string_failfast(PCWSTR source, size_t length = -1);

If source is nullptr, then the functions return a zero-length string in a buffer with a capacity of length + 1.

If source is not nullptr, then the functions return a string buffer of capacity length + 1 consisting of the first length characters of source, followed by a null terminator. The source must be readable up to length characters.

If length is -1, then the function behaves as if length = wcslen(source). (In this case, source may not be nullptr.)

  • The plain version throws if unable to allocate memory.
  • The nothrow version returns an empty unique_something_string if unable to allocate memory.
  • The failfast version fails fast if unable to allocate memory.

Available functions:

String type Maker functions Remarks
unique_hlocal_string make_hlocal_string, etc. Frees with LocalFree
unique_hlocal_ansistring make_hlocal_ansistring, etc. Frees with LocalFree, ANSI version
unique_hlocal_string_secure make_hlocal_string_secure, etc. Frees with ZeroMemory + LocalFree
unique_process_heap_string make_process_heap_string, etc. Frees with HeapFree
unique_cotaskmem_string make_cotaskmem_string, etc. Frees with CoTaskMemFree
unique_bstr make_bstr, etc. Frees with SysFreeString
unique_hglobal_string None Frees with GlobalFree
unique_hglobal_ansistring None Frees with GlobalFree, ANSI version
unique_hstring None Frees with WindowsDeleteString
template: string_type make_unique_string<string_type>, etc. Frees with the appropriate method for the given string type

Examples:

auto string = wil::make_cotaskmem_string(L"sample string");

auto string = wil::make_cotaskmem_string(L"sample string", 3); // result is "sam"

auto string = wil::make_cotaskmem_string(nullptr, 5); // room for 5 characters + terminating null

auto string = wil::make_cotaskmem_string_nothrow(L"sample string");
RETURN_IF_NULL_ALLOC(string);

auto string = wil::make_unique_string<wil::unique_cotaskmem_string>(L"sample string");

auto string = wil::make_unique_string<wil::unique_hstring>(L"sample string");

HSTRING_BUFFERs

WIL also provides methods to assist with two-phase creation of an HSTRING via an HSTRING_BUFFER:

// Definition:
HRESULT make_hstring_from_buffer_nothrow(unique_hstring_buffer&& source, _Out_ HSTRING* promoted);
unique_hstring make_hstring_from_buffer_failfast(unique_hstring_buffer&& source);
unique_hstring make_hstring_from_buffer(unique_hstring_buffer&& source);

// Usage:
HRESULT Type::MakePath(_Out_ HSTRING* path)
{
    wchar_t* bufferStorage = nullptr;
    wil::unique_hstring_buffer theBuffer;
    RETURN_IF_FAILED(::WindowsPreallocateStringBuffer(65, &bufferStorage, &theBuffer));
    RETURN_IF_FAILED(::PathCchCombine(bufferStorage, 65, m_foo, m_bar));
    RETURN_IF_FAILED(wil::make_hstring_from_buffer_nothrow(wistd::move(theBuffer), path)));
    return S_OK;
}

wil::str_raw_ptr

This helper function unwraps a smart object until it finds a raw null-terminated Unicode string pointer (PCWSTR).

PCWSTR str_raw_ptr(anything);

The "anything" parameter can be

  • PCWSTR (returns itself)
  • HSTRING (returns WindowsGetStringRawBuffer)
  • const std::wstring& (returns c_str(), requires wil/stl.h)
  • unique_any_t<T> (recursively unwraps the T)

The last rule means that you can pass, for example, a unique_hstring or unique_cotaskmem_string, and the str_raw_ptr will unwrap the unique_ptr to the inner object (HSTRING or PCWSTR) and then try to get a raw string pointer from the inner object.

wil::string_get_not_null

This helper function returns the string wrapped by the smart pointer type, or the empty string L"" if the smart pointer is empty. In other words, it converts nullptr to L"".

PCWSTR string_get_not_null(anything);

The anything can be anything that has a get() method which returns a PWSTR or PCWSTR.

wil::str_concat

These functions take any number of strings and concatenates them.

  • string_type str_concat<string_type>(...): Returns the concatenated string, or throws on failure.
  • string_type str_concat_failfast<string_type>(...): Returns the concatenated string, or fails fast on failure.
  • HRESULT str_concat_nothrow(buffer, ...): Concatenates the strings to any existing contents of buffer. Returns an HRESULT indicating success or failure.

Remarks:

  • The strings can be a mix of objects, as long as each one can be resolved to a raw pointer by str_raw_ptr.
  • You must pass at least one string. Null pointers are permitted and treated the same as an empty string.
  • The string_type can be anything supported by string_maker.
  • If using a string_type of std::string or std::wstring and compilation fails with 'get': is not a member of std::basic_string<...> then ensure that you have an #include <wil/stl.h> in your sources.

wil::str_printf

These functions take a printf-style format string followed by a corresponding parameter list. The result is allocated by wil::details::string_maker.

  • string_type str_printf<string_type>(PCWSTR formatString, ...): Returns the formatted string, or throws on failure.
  • string_type str_printf_failfast<string_type>(PCWSTR formatString, ...): Returns the formatted string, or fails fast on failure.
  • HRESULT str_printf_nothrow(buffer, ...): Assigns the formatted string to buffer. (Any existing contents of buffer are overwritten.) Returns an HRESULT indicating success or failure.

Examples:

auto fullName = wil::str_printf<wil::unique_cotaskmem_string>(L"%ls %ls", firstName.get(), lastName.get());

auto fullName = wil::str_printf_failfast<wil::unique_cotaskmem_string>(L"%ls %ls", firstName.get(), lastName.get());

wil::unique_cotaskmem_string fullName;
RETURN_IF_FAILED(wil::str_printf_nothrow(fullName, L"%ls %ls", firstName.get(), lastName.get()));

wil::zstring_view

When C++17 is available and stl.h is included, WIL provides this helper class. A zstring_view is identical to a std::string_view except it is always null-terminated (unless empty).

  • zstring_view can be used for storing string literals without "forgetting" the length or that it is null-terminated.
  • A zstring_view can be converted implicitly to a std::string_view because it is always safe to use a null-terminated string_view as a plain string view.
  • A zstring_view can be constructed from a std::string because the data in std::string is null-terminated.

See also