diff --git a/src/Windows/libraries/formatters/include/CMakeLists.txt b/src/Windows/libraries/formatters/include/CMakeLists.txt index d3f5b0e3..78462e51 100644 --- a/src/Windows/libraries/formatters/include/CMakeLists.txt +++ b/src/Windows/libraries/formatters/include/CMakeLists.txt @@ -5,6 +5,7 @@ target_sources(m_formatters PUBLIC FILE_SET HEADERS FILES m/formatters/FILE_ACTION.h m/formatters/FILE_NOTIFY_EXTENDED_INFORMATION.h m/formatters/FILE_NOTIFY_INFORMATION.h + m/formatters/HKEY.h m/formatters/HRESULT.h m/formatters/NTSTATUS.h m/formatters/OVERLAPPED.h diff --git a/src/Windows/libraries/formatters/include/m/formatters/HKEY.h b/src/Windows/libraries/formatters/include/m/formatters/HKEY.h new file mode 100644 index 00000000..b14e385a --- /dev/null +++ b/src/Windows/libraries/formatters/include/m/formatters/HKEY.h @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. + +#pragma once + +#include +#include +#include +#include +#include + +#include + +using namespace std::string_view_literals; + +template +struct std::formatter +{ + template + constexpr ParseContext::iterator + parse(ParseContext& ctx) + { + auto it = ctx.begin(); + auto const end = ctx.end(); + + if (it != end && *it != '}') + throw std::format_error("Invalid format string"); + + return it; + } + + template + FormatContext::iterator + format(HKEY hkey, FormatContext& ctx) const + { + auto out = ctx.out(); + + // + // Macros are to be hated but they are to be tolerated here. + // + // There are a number of "named" HKEY values. + // + +#pragma push_macro("X") + +#undef X +#define X(p) \ + case reinterpret_cast(p): \ + { \ + constexpr auto lit = #p##sv; \ + return std::ranges::copy(lit.begin(), lit.end(), out).out; \ + } + + switch (reinterpret_cast(hkey)) + { + X(HKEY_CURRENT_USER) + X(HKEY_CLASSES_ROOT) + X(HKEY_LOCAL_MACHINE) + X(HKEY_USERS) + X(HKEY_PERFORMANCE_DATA) + X(HKEY_PERFORMANCE_TEXT) + X(HKEY_PERFORMANCE_NLSTEXT) + X(HKEY_CURRENT_CONFIG) + X(HKEY_DYN_DATA) + X(HKEY_CURRENT_USER_LOCAL_SETTINGS) + } + +#pragma pop_macro("X") + + if constexpr (std::is_same_v) + { + return std::format_to(out, "{{hkey 0x{:x}}}", reinterpret_cast(hkey)); + } + else if constexpr (std::is_same_v) + { + return std::format_to(out, L"{{hkey 0x{:x}}}", reinterpret_cast(hkey)); + } + else + { + throw std::runtime_error("Bad CharT"); + } + } +}; diff --git a/src/Windows/libraries/formatters/test/CMakeLists.txt b/src/Windows/libraries/formatters/test/CMakeLists.txt index d644c0fa..f3d880d0 100644 --- a/src/Windows/libraries/formatters/test/CMakeLists.txt +++ b/src/Windows/libraries/formatters/test/CMakeLists.txt @@ -9,11 +9,12 @@ add_executable(${TEST_EXE_NAME} test_FILE_ACTION.cpp test_FILE_NOTIFY_EXTENDED_INFORMATION.cpp test_FILE_NOTIFY_INFORMATION.cpp + test_HKEY.cpp test_HRESULT.cpp test_NTSTATUS.cpp test_OVERLAPPED.cpp test_Win32ErrorCode.cpp -) + ) target_compile_features(${TEST_EXE_NAME} PUBLIC ${M_CXX_STD}) diff --git a/src/Windows/libraries/formatters/test/test_HKEY.cpp b/src/Windows/libraries/formatters/test/test_HKEY.cpp new file mode 100644 index 00000000..81c8d1d9 --- /dev/null +++ b/src/Windows/libraries/formatters/test/test_HKEY.cpp @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include + +#include +#include +#include + +#include + +#include + +using namespace std::string_literals; +using namespace std::string_view_literals; + +TEST(HKEY, format_HKEY_CURRENT_USER) +{ + auto s = std::format(L"{}", HKEY_CURRENT_USER); + EXPECT_EQ(s, L"HKEY_CURRENT_USER"s); +} + +TEST(HKEY, format_HKEY_LOCAL_MACHINE) +{ + auto s = std::format(L"{}", HKEY_LOCAL_MACHINE); + EXPECT_EQ(s, L"HKEY_LOCAL_MACHINE"s); +} + +TEST(HKEY, format_default_hkey) +{ + auto s = std::format(L"{}", HKEY{}); + EXPECT_EQ(s, L"{hkey 0x0}"s); +} +