From d671bf524ea25f7f0311bd98e4aaefa10b002a07 Mon Sep 17 00:00:00 2001 From: theomegacarrot Date: Tue, 14 Mar 2023 20:29:17 -0400 Subject: [PATCH 1/7] fix case of variant which is valueless by exception --- include/fmt/std.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/include/fmt/std.h b/include/fmt/std.h index 24bf2c53b6d3..1583ca213296 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -218,11 +218,15 @@ struct formatter< auto out = ctx.out(); out = detail::write(out, "variant("); - std::visit( - [&](const auto& v) { - out = detail::write_variant_alternative(out, v); - }, - value); + try { + std::visit( + [&](const auto& v) { + out = detail::write_variant_alternative(out, v); + }, + value); + } catch (const std::bad_variant_access&) { + detail::write(out, "valueless by exception"); + } *out++ = ')'; return out; } From de942e757d526ee52ef1228fbae98eae6adc86f5 Mon Sep 17 00:00:00 2001 From: theomegacarrot Date: Thu, 16 Mar 2023 11:03:13 -0400 Subject: [PATCH 2/7] add test case for a std::variant which is valueless by exception --- CMakeLists.txt | 2 ++ test/std-test.cc | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b096e4e20436..ec7e14c3748f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required(VERSION 3.8...3.25) +set(CMAKE_EXPORT_COMPILE_COMMANDS YES) + # Fallback for using newer policies on CMake <3.12. if(${CMAKE_VERSION} VERSION_LESS 3.12) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) diff --git a/test/std-test.cc b/test/std-test.cc index d12dbf5d2cdd..81d365a08773 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -7,6 +7,7 @@ #include "fmt/std.h" +#include #include #include @@ -95,6 +96,28 @@ TEST(std_test, optional) { #endif } +// this struct exists only to force a variant to be +// valueless by exception +// NOLINTNEXTLINE +struct throws_on_move_t { + throws_on_move_t() = default; + + // NOLINTNEXTLINE + [[noreturn]] throws_on_move_t(throws_on_move_t&&) { + throw std::runtime_error{"Thrown by throws_on_move_t"}; + } + + throws_on_move_t(const throws_on_move_t&) = default; +}; + +template <> struct fmt::formatter : formatter { + template + auto format(const throws_on_move_t&, FormatContext& ctx) const { + string_view str{""}; + return formatter::format(str, ctx); + } +}; + TEST(std_test, variant) { #ifdef __cpp_lib_variant EXPECT_EQ(fmt::format("{}", std::monostate{}), "monostate"); @@ -126,6 +149,20 @@ TEST(std_test, variant) { volatile int i = 42; // Test compile error before GCC 11 described in #3068. EXPECT_EQ(fmt::format("{}", i), "42"); + + using V2 = std::variant; + + V2 v6{}; + + try { + throws_on_move_t thrower{}; + v6.emplace(std::move(thrower)); + } catch (const std::runtime_error&) { + } + // v6 is now valueless by exception + + EXPECT_EQ(fmt::format("{}", v6), "variant(valueless by exception)"); + #endif } From e1c72c4a880eeabc393f72162c94369874b96953 Mon Sep 17 00:00:00 2001 From: theomegacarrot Date: Thu, 16 Mar 2023 11:06:51 -0400 Subject: [PATCH 3/7] revert accidentally committed edit to CMakeLists.txt --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec7e14c3748f..b096e4e20436 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,5 @@ cmake_minimum_required(VERSION 3.8...3.25) -set(CMAKE_EXPORT_COMPILE_COMMANDS YES) - # Fallback for using newer policies on CMake <3.12. if(${CMAKE_VERSION} VERSION_LESS 3.12) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) From 0a328c01253f49f23f6e1095318c9223c8ae66d7 Mon Sep 17 00:00:00 2001 From: theomegacarrot Date: Fri, 17 Mar 2023 14:09:30 -0400 Subject: [PATCH 4/7] address requested changes --- test/std-test.cc | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/test/std-test.cc b/test/std-test.cc index 81d365a08773..278cef7780f8 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -96,24 +96,19 @@ TEST(std_test, optional) { #endif } -// this struct exists only to force a variant to be -// valueless by exception -// NOLINTNEXTLINE -struct throws_on_move_t { - throws_on_move_t() = default; - - // NOLINTNEXTLINE - [[noreturn]] throws_on_move_t(throws_on_move_t&&) { - throw std::runtime_error{"Thrown by throws_on_move_t"}; +struct throws_on_move { + throws_on_move() = default; + + [[noreturn]] throws_on_move(throws_on_move&&) { + throw std::runtime_error("Thrown by throws_on_move_t"); } - throws_on_move_t(const throws_on_move_t&) = default; + throws_on_move(const throws_on_move&) = default; }; -template <> struct fmt::formatter : formatter { - template - auto format(const throws_on_move_t&, FormatContext& ctx) const { - string_view str{""}; +template <> struct fmt::formatter : formatter { + auto format(const throws_on_move&, format_context& ctx) const { + string_view str(""); return formatter::format(str, ctx); } }; @@ -150,13 +145,11 @@ TEST(std_test, variant) { volatile int i = 42; // Test compile error before GCC 11 described in #3068. EXPECT_EQ(fmt::format("{}", i), "42"); - using V2 = std::variant; - - V2 v6{}; + std::variant v6; try { - throws_on_move_t thrower{}; - v6.emplace(std::move(thrower)); + throws_on_move thrower; + v6.emplace(std::move(thrower)); } catch (const std::runtime_error&) { } // v6 is now valueless by exception From 0b52517e1f401040d35cb602484f19a80ddac015 Mon Sep 17 00:00:00 2001 From: theomegacarrot Date: Fri, 17 Mar 2023 14:20:43 -0400 Subject: [PATCH 5/7] throws_on_move_t -> throws_on_move in strings --- test/std-test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/std-test.cc b/test/std-test.cc index 278cef7780f8..4e3c14eda1be 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -100,7 +100,7 @@ struct throws_on_move { throws_on_move() = default; [[noreturn]] throws_on_move(throws_on_move&&) { - throw std::runtime_error("Thrown by throws_on_move_t"); + throw std::runtime_error("Thrown by throws_on_move"); } throws_on_move(const throws_on_move&) = default; @@ -108,7 +108,7 @@ struct throws_on_move { template <> struct fmt::formatter : formatter { auto format(const throws_on_move&, format_context& ctx) const { - string_view str(""); + string_view str(""); return formatter::format(str, ctx); } }; From 00d3c6adf929e33927957ef5efe05fc0e7d7e00a Mon Sep 17 00:00:00 2001 From: theomegacarrot Date: Fri, 17 Mar 2023 14:50:47 -0400 Subject: [PATCH 6/7] fix return type in formatter for throws_on_move --- test/std-test.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/std-test.cc b/test/std-test.cc index 4e3c14eda1be..0fc1c148385b 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -107,7 +107,8 @@ struct throws_on_move { }; template <> struct fmt::formatter : formatter { - auto format(const throws_on_move&, format_context& ctx) const { + auto format(const throws_on_move&, format_context& ctx) const + -> decltype(ctx.out()) { string_view str(""); return formatter::format(str, ctx); } From fbfb08e340aa893b4447bdcf850f45571ab86c12 Mon Sep 17 00:00:00 2001 From: theomegacarrot Date: Fri, 17 Mar 2023 17:29:57 -0400 Subject: [PATCH 7/7] fix namespace issue --- test/std-test.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/std-test.cc b/test/std-test.cc index 0fc1c148385b..53c7620d8baf 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -106,13 +106,15 @@ struct throws_on_move { throws_on_move(const throws_on_move&) = default; }; -template <> struct fmt::formatter : formatter { +namespace fmt { +template <> struct formatter : formatter { auto format(const throws_on_move&, format_context& ctx) const -> decltype(ctx.out()) { string_view str(""); return formatter::format(str, ctx); } }; +} // namespace fmt TEST(std_test, variant) { #ifdef __cpp_lib_variant