diff --git a/include/wil/registry_helpers.h b/include/wil/registry_helpers.h index f796864f..1ebf0fd7 100644 --- a/include/wil/registry_helpers.h +++ b/include/wil/registry_helpers.h @@ -925,10 +925,16 @@ namespace reg static_assert(!wistd::is_same_v, "Unsupported type for get_value_type"); } - template - DWORD set_value_type() WI_NOEXCEPT + template + struct set_value_type_t { static_assert(!wistd::is_same_v, "Unsupported type for set_value_type"); + }; + + template + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return set_value_type_t>::value; } template <> @@ -937,10 +943,10 @@ namespace reg return get_value_flags_from_value_type(REG_DWORD); } template <> - constexpr DWORD set_value_type() WI_NOEXCEPT + struct set_value_type_t { - return REG_DWORD; - } + static constexpr DWORD value = REG_DWORD; + }; template <> constexpr DWORD get_value_type() WI_NOEXCEPT @@ -948,10 +954,10 @@ namespace reg return get_value_flags_from_value_type(REG_DWORD); } template <> - constexpr DWORD set_value_type() WI_NOEXCEPT + struct set_value_type_t { - return REG_DWORD; - } + static constexpr DWORD value = REG_DWORD; + }; template <> constexpr DWORD get_value_type() WI_NOEXCEPT @@ -959,10 +965,10 @@ namespace reg return get_value_flags_from_value_type(REG_DWORD); } template <> - constexpr DWORD set_value_type() WI_NOEXCEPT + struct set_value_type_t { - return REG_DWORD; - } + static constexpr DWORD value = REG_DWORD; + }; template <> constexpr DWORD get_value_type() WI_NOEXCEPT @@ -970,10 +976,10 @@ namespace reg return get_value_flags_from_value_type(REG_DWORD); } template <> - constexpr DWORD set_value_type() WI_NOEXCEPT + struct set_value_type_t { - return REG_DWORD; - } + static constexpr DWORD value = REG_DWORD; + }; template <> constexpr DWORD get_value_type() WI_NOEXCEPT @@ -981,10 +987,10 @@ namespace reg return get_value_flags_from_value_type(REG_QWORD); } template <> - constexpr DWORD set_value_type() WI_NOEXCEPT + struct set_value_type_t { - return REG_QWORD; - } + static constexpr DWORD value = REG_QWORD; + }; template <> constexpr DWORD get_value_type() WI_NOEXCEPT @@ -992,10 +998,10 @@ namespace reg return get_value_flags_from_value_type(REG_QWORD); } template <> - constexpr DWORD set_value_type() WI_NOEXCEPT + struct set_value_type_t { - return REG_QWORD; - } + static constexpr DWORD value = REG_QWORD; + }; template <> constexpr DWORD get_value_type() WI_NOEXCEPT @@ -1003,10 +1009,10 @@ namespace reg return get_value_flags_from_value_type(REG_SZ); } template <> - constexpr DWORD set_value_type() WI_NOEXCEPT + struct set_value_type_t { - return REG_SZ; - } + static constexpr DWORD value = REG_SZ; + }; #if (WIL_USE_STL && defined(WIL_ENABLE_EXCEPTIONS)) || defined(WIL_DOXYGEN) template <> @@ -1016,10 +1022,10 @@ namespace reg } template <> - constexpr DWORD set_value_type() WI_NOEXCEPT + struct set_value_type_t<::std::wstring> { - return REG_SZ; - } + static constexpr DWORD value = REG_SZ; + }; #endif #if defined(__WIL_OLEAUTO_H_) @@ -1035,16 +1041,16 @@ namespace reg } template <> - constexpr DWORD set_value_type() WI_NOEXCEPT + struct set_value_type_t { - return REG_SZ; - } + static constexpr DWORD value = REG_SZ; + }; template <> - constexpr DWORD set_value_type() 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) @@ -1056,10 +1062,10 @@ namespace reg } template <> - constexpr DWORD set_value_type() 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_) @@ -1070,10 +1076,10 @@ namespace reg } template <> - constexpr DWORD set_value_type() 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) @@ -1084,10 +1090,10 @@ namespace reg } template <> - constexpr DWORD set_value_type() 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 diff --git a/tests/RegistryTests.cpp b/tests/RegistryTests.cpp index f774e95c..abd0d727 100644 --- a/tests/RegistryTests.cpp +++ b/tests/RegistryTests.cpp @@ -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(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(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(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(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(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") {