From 1557ab764422d5087619fea3994012066644a11e Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Fri, 28 Jan 2022 06:31:29 -0800 Subject: [PATCH] Add format_as for enums --- include/fmt/core.h | 33 +++++++++++++++++---------------- test/core-test.cc | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index e27578ed..2da3dc62 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -51,7 +51,7 @@ #ifdef __NVCOMPILER # define FMT_NVCOMPILER_VERSION \ - (__NVCOMPILER_MAJOR__ * 100 + __NVCOMPILER_MINOR__) + (__NVCOMPILER_MAJOR__ * 100 + __NVCOMPILER_MINOR__) #else # define FMT_NVCOMPILER_VERSION 0 #endif @@ -336,8 +336,8 @@ FMT_BEGIN_DETAIL_NAMESPACE // (void)var does not work on many Intel compilers. template FMT_CONSTEXPR void ignore_unused(const T&...) {} -constexpr FMT_INLINE auto is_constant_evaluated(bool default_value = false) - noexcept -> bool { +constexpr FMT_INLINE auto is_constant_evaluated( + bool default_value = false) noexcept -> bool { #ifdef __cpp_lib_is_constant_evaluated ignore_unused(default_value); return std::is_constant_evaluated(); @@ -443,8 +443,7 @@ template class basic_string_view { /** Constructs a string reference object from a C string and a size. */ constexpr basic_string_view(const Char* s, size_t count) noexcept - : data_(s), - size_(count) {} + : data_(s), size_(count) {} /** \rst @@ -465,13 +464,12 @@ template class basic_string_view { template FMT_CONSTEXPR basic_string_view( const std::basic_string& s) noexcept - : data_(s.data()), - size_(s.size()) {} + : data_(s.data()), size_(s.size()) {} template >::value)> - FMT_CONSTEXPR basic_string_view(S s) noexcept : data_(s.data()), - size_(s.size()) {} + FMT_CONSTEXPR basic_string_view(S s) noexcept + : data_(s.data()), size_(s.size()) {} /** Returns a pointer to the string data. */ constexpr auto data() const noexcept -> const Char* { return data_; } @@ -640,9 +638,7 @@ class basic_format_parse_context : private ErrorHandler { /** Returns an iterator past the end of the format string range being parsed. */ - constexpr auto end() const noexcept -> iterator { - return format_str_.end(); - } + constexpr auto end() const noexcept -> iterator { return format_str_.end(); } /** Advances the begin iterator to ``it``. */ FMT_CONSTEXPR void advance_to(iterator it) { @@ -771,10 +767,8 @@ template class buffer { FMT_MSC_WARNING(suppress : 26495) buffer(size_t sz) noexcept : size_(sz), capacity_(sz) {} - FMT_CONSTEXPR20 buffer(T* p = nullptr, size_t sz = 0, - size_t cap = 0) noexcept : ptr_(p), - size_(sz), - capacity_(cap) {} + FMT_CONSTEXPR20 buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) noexcept + : ptr_(p), size_(sz), capacity_(cap) {} FMT_CONSTEXPR20 ~buffer() = default; buffer(buffer&&) = default; @@ -1428,6 +1422,13 @@ template struct arg_mapper { return map(static_cast::type>(val)); } + template ::value&& std::is_integral::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& val) + -> decltype(std::declval().map(U())) { + return map(format_as(val)); + } + FMT_CONSTEXPR FMT_INLINE auto map(detail::byte val) -> unsigned { return map(static_cast(val)); } diff --git a/test/core-test.cc b/test/core-test.cc index c9eea8ff..fc874071 100644 --- a/test/core-test.cc +++ b/test/core-test.cc @@ -755,7 +755,16 @@ template <> struct formatter { }; FMT_END_NAMESPACE -enum class test_scoped_enum {}; +enum class unformattable_scoped_enum {}; + +namespace test { +enum class formattable_scoped_enum {}; +auto format_as(formattable_scoped_enum) -> int { return 42; } + +struct convertible_to_enum { + operator formattable_scoped_enum() const { return {}; } +}; +} // namespace test TEST(core_test, is_formattable) { #if 0 @@ -796,7 +805,9 @@ TEST(core_test, is_formattable) { struct s; static_assert(!fmt::is_formattable::value, ""); static_assert(!fmt::is_formattable::value, ""); - static_assert(!fmt::is_formattable::value, ""); + static_assert(!fmt::is_formattable::value, ""); + static_assert(fmt::is_formattable::value, ""); + static_assert(!fmt::is_formattable::value, ""); } TEST(core_test, format) { EXPECT_EQ(fmt::format("{}", 42), "42"); } @@ -807,6 +818,10 @@ TEST(core_test, format_to) { EXPECT_EQ(s, "42"); } +TEST(core_test, format_as) { + EXPECT_EQ(fmt::format("{}", test::formattable_scoped_enum()), "42"); +} + struct convertible_to_int { operator int() const { return 42; } };