Skip to content
Draft
Show file tree
Hide file tree
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
88 changes: 47 additions & 41 deletions include/wil/registry_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -925,10 +925,16 @@ namespace reg
static_assert(!wistd::is_same_v<T, T>, "Unsupported type for get_value_type");
}

template <typename T = void>
DWORD set_value_type() WI_NOEXCEPT
template <typename T>
struct set_value_type_t
{
static_assert(!wistd::is_same_v<T, T>, "Unsupported type for set_value_type");
};

template <typename T>
constexpr DWORD set_value_type() WI_NOEXCEPT
{
return set_value_type_t<wistd::remove_cv_t<T>>::value;
}

template <>
Expand All @@ -937,76 +943,76 @@ namespace reg
return get_value_flags_from_value_type(REG_DWORD);
}
template <>
constexpr DWORD set_value_type<int32_t>() WI_NOEXCEPT
struct set_value_type_t<int32_t>
{
return REG_DWORD;
}
static constexpr DWORD value = REG_DWORD;
};

template <>
constexpr DWORD get_value_type<uint32_t>() WI_NOEXCEPT
{
return get_value_flags_from_value_type(REG_DWORD);
}
template <>
constexpr DWORD set_value_type<uint32_t>() WI_NOEXCEPT
struct set_value_type_t<uint32_t>
{
return REG_DWORD;
}
static constexpr DWORD value = REG_DWORD;
};

template <>
constexpr DWORD get_value_type<long>() WI_NOEXCEPT
{
return get_value_flags_from_value_type(REG_DWORD);
}
template <>
constexpr DWORD set_value_type<long>() WI_NOEXCEPT
struct set_value_type_t<long>
{
return REG_DWORD;
}
static constexpr DWORD value = REG_DWORD;
};

template <>
constexpr DWORD get_value_type<unsigned long>() WI_NOEXCEPT
{
return get_value_flags_from_value_type(REG_DWORD);
}
template <>
constexpr DWORD set_value_type<unsigned long>() WI_NOEXCEPT
struct set_value_type_t<unsigned long>
{
return REG_DWORD;
}
static constexpr DWORD value = REG_DWORD;
};

template <>
constexpr DWORD get_value_type<int64_t>() WI_NOEXCEPT
{
return get_value_flags_from_value_type(REG_QWORD);
}
template <>
constexpr DWORD set_value_type<int64_t>() WI_NOEXCEPT
struct set_value_type_t<int64_t>
{
return REG_QWORD;
}
static constexpr DWORD value = REG_QWORD;
};

template <>
constexpr DWORD get_value_type<uint64_t>() WI_NOEXCEPT
{
return get_value_flags_from_value_type(REG_QWORD);
}
template <>
constexpr DWORD set_value_type<uint64_t>() WI_NOEXCEPT
struct set_value_type_t<uint64_t>
{
return REG_QWORD;
}
static constexpr DWORD value = REG_QWORD;
};

template <>
constexpr DWORD get_value_type<PCWSTR>() WI_NOEXCEPT
{
return get_value_flags_from_value_type(REG_SZ);
}
template <>
constexpr DWORD set_value_type<PCWSTR>() WI_NOEXCEPT
struct set_value_type_t<PCWSTR>
{
return REG_SZ;
}
static constexpr DWORD value = REG_SZ;
};

#if (WIL_USE_STL && defined(WIL_ENABLE_EXCEPTIONS)) || defined(WIL_DOXYGEN)
template <>
Expand All @@ -1016,10 +1022,10 @@ namespace reg
}

template <>
constexpr DWORD set_value_type<const ::std::wstring>() WI_NOEXCEPT
struct set_value_type_t<::std::wstring>
{
return REG_SZ;
}
static constexpr DWORD value = REG_SZ;
};
#endif

#if defined(__WIL_OLEAUTO_H_)
Expand All @@ -1035,16 +1041,16 @@ namespace reg
}

template <>
constexpr DWORD set_value_type<const BSTR>() WI_NOEXCEPT
struct set_value_type_t<BSTR>
{
return REG_SZ;
}
static constexpr DWORD value = REG_SZ;
};

template <>
constexpr DWORD set_value_type<const ::wil::unique_bstr>() WI_NOEXCEPT
struct set_value_type_t<::wil::unique_bstr>
{
return REG_SZ;
}
static constexpr DWORD value = REG_SZ;
};
#endif // #if defined(__WIL_OLEAUTO_H_)

#if defined(__WIL_OLEAUTO_H_STL)
Expand All @@ -1056,10 +1062,10 @@ namespace reg
}

template <>
constexpr DWORD set_value_type<const ::wil::shared_bstr>() WI_NOEXCEPT
struct set_value_type_t<::wil::shared_bstr>
{
return REG_SZ;
}
static constexpr DWORD value = REG_SZ;
};
#endif // #if defined(__WIL_OLEAUTO_H_STL)

#if defined(__WIL_OBJBASE_H_)
Expand All @@ -1070,10 +1076,10 @@ namespace reg
}

template <>
constexpr DWORD set_value_type<const ::wil::unique_cotaskmem_string>() WI_NOEXCEPT
struct set_value_type_t<::wil::unique_cotaskmem_string>
{
return REG_SZ;
}
static constexpr DWORD value = REG_SZ;
};
#endif // defined(__WIL_OBJBASE_H_)

#if defined(__WIL_OBJBASE_H_STL)
Expand All @@ -1084,10 +1090,10 @@ namespace reg
}

template <>
constexpr DWORD set_value_type<const ::wil::shared_cotaskmem_string>() WI_NOEXCEPT
struct set_value_type_t<::wil::shared_cotaskmem_string>
{
return REG_SZ;
}
static constexpr DWORD value = REG_SZ;
};
#endif // #if defined(__WIL_OBJBASE_H_STL)
} // namespace reg_value_type_info

Expand Down
37 changes: 37 additions & 0 deletions tests/RegistryTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2272,6 +2272,43 @@ TEST_CASE("BasicRegistryTests::string types", "[registry]")
#endif
}

SECTION("strings set_value with std::wstring lvalue: with opened key")
{
wil::unique_hkey hkey;
REQUIRE_SUCCEEDED(wil::reg::create_unique_key_nothrow(HKEY_CURRENT_USER, testSubkey, hkey, wil::reg::key_access::readwrite));

// verify non-const std::wstring lvalue works with set_value (issue #624)
std::wstring stringValue{L"wstring lvalue test"};
wil::reg::set_value(hkey.get(), stringValueName, stringValue);
auto result = wil::reg::get_value<std::wstring>(hkey.get(), stringValueName);
REQUIRE(result == stringValue);

// verify const std::wstring lvalue also works
const std::wstring constStringValue{L"const wstring test"};
wil::reg::set_value(hkey.get(), stringValueName, constStringValue);
result = wil::reg::get_value<std::wstring>(hkey.get(), stringValueName);
REQUIRE(result == constStringValue);

// verify empty std::wstring
std::wstring emptyValue;
wil::reg::set_value(hkey.get(), stringValueName, emptyValue);
result = wil::reg::get_value<std::wstring>(hkey.get(), stringValueName);
REQUIRE(result.empty());
}

SECTION("strings set_value with std::wstring lvalue: with string key")
{
std::wstring stringValue{L"wstring lvalue subkey test"};
wil::reg::set_value(HKEY_CURRENT_USER, testSubkey, stringValueName, stringValue);
auto result = wil::reg::get_value<std::wstring>(HKEY_CURRENT_USER, testSubkey, stringValueName);
REQUIRE(result == stringValue);

const std::wstring constStringValue{L"const wstring subkey test"};
wil::reg::set_value(HKEY_CURRENT_USER, testSubkey, stringValueName, constStringValue);
result = wil::reg::get_value<std::wstring>(HKEY_CURRENT_USER, testSubkey, stringValueName);
REQUIRE(result == constStringValue);
}

#if defined(__cpp_lib_optional)
SECTION("strings set_value_string/try_get_value_string: with open key")
{
Expand Down
Loading