From b5c02fceea3ca84632dba267e9700b689c0feeb9 Mon Sep 17 00:00:00 2001 From: Zach Toogood Date: Sat, 27 Aug 2022 20:59:47 +0300 Subject: [PATCH] Add formatter for std::exception Co-authored-by: fekir Co-authored-by: Alexey Ochapov --- include/fmt/std.h | 18 +++++++++++++++++- test/std-test.cc | 31 ++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/include/fmt/std.h b/include/fmt/std.h index 41d2b2838b6d7..39fa776244d06 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -8,6 +8,7 @@ #ifndef FMT_STD_H_ #define FMT_STD_H_ +#include #include #include #include @@ -166,6 +167,21 @@ struct formatter< } }; FMT_END_NAMESPACE -#endif + +#endif // __cpp_lib_variant + +FMT_BEGIN_NAMESPACE +template +struct formatter< + T, Char, + typename std::enable_if::value>::type> + : formatter { + template + auto format(const std::exception& ex, FormatContext& ctx) const -> + typename FormatContext::iterator { + return fmt::formatter::format(ex.what(), ctx); + } +}; +FMT_END_NAMESPACE #endif // FMT_STD_H_ diff --git a/test/std-test.cc b/test/std-test.cc index c22b3e38fb39b..d3008d6fd6f69 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -6,11 +6,11 @@ // For the license information refer to format.h. #include "fmt/std.h" -#include "fmt/ranges.h" #include #include +#include "fmt/ranges.h" #include "gtest/gtest.h" TEST(std_test, path) { @@ -77,3 +77,32 @@ TEST(std_test, variant) { EXPECT_EQ(fmt::format("{}", v5), "variant(\"yes, this is variant\")"); #endif } + +TEST(std_test, exception) { +#if (defined(__GNUC__) && __GNUC__ <= 8 ) || (defined(__clang__) && __clang__ <= 8) || defined(_APPLE__) + std::string str("vector"); +#elif defined(__clang__) || defined(__GNUC__) + std::string str("vector::_M_range_check: __n (which is 42) >= this->size() (which is 0)"); +#elif defined(_MSC_VER) && _MSC_VER > 1920 + std::string str("invalid vector subscript"); +#else + std::string str("invalid vector subscript"); +#endif + std::string escstr = fmt::format("\"{}\"", str); + + try { + std::vector vec; + std::ignore = vec.at(42); + } catch (const std::exception& ex) { + EXPECT_EQ(fmt::format("{}", ex), str); + EXPECT_EQ(fmt::format("{:?}", ex), escstr); + } + + try { + std::vector vec; + std::ignore = vec.at(42); + } catch (const std::out_of_range& ex) { + EXPECT_EQ(fmt::format("{}", ex), str); + EXPECT_EQ(fmt::format("{:?}", ex), escstr); + } +}