Add format_as for enums

This commit is contained in:
Victor Zverovich 2022-01-28 06:31:29 -08:00
parent b00a1eac75
commit 1557ab7644
2 changed files with 34 additions and 18 deletions

View File

@ -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 <typename... T> 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 <typename Char> 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 <typename Char> class basic_string_view {
template <typename Traits, typename Alloc>
FMT_CONSTEXPR basic_string_view(
const std::basic_string<Char, Traits, Alloc>& s) noexcept
: data_(s.data()),
size_(s.size()) {}
: data_(s.data()), size_(s.size()) {}
template <typename S, FMT_ENABLE_IF(std::is_same<
S, detail::std_string_view<Char>>::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 <typename T> 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 <typename Context> struct arg_mapper {
return map(static_cast<typename std::underlying_type<T>::type>(val));
}
template <typename T, typename U = decltype(format_as(T())),
FMT_ENABLE_IF(std::is_enum<T>::value&& std::is_integral<U>::value)>
FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
-> decltype(std::declval<arg_mapper>().map(U())) {
return map(format_as(val));
}
FMT_CONSTEXPR FMT_INLINE auto map(detail::byte val) -> unsigned {
return map(static_cast<unsigned char>(val));
}

View File

@ -755,7 +755,16 @@ template <> struct formatter<convertible_to_pointer_formattable> {
};
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<int(s::*)>::value, "");
static_assert(!fmt::is_formattable<int (s::*)()>::value, "");
static_assert(!fmt::is_formattable<test_scoped_enum>::value, "");
static_assert(!fmt::is_formattable<unformattable_scoped_enum>::value, "");
static_assert(fmt::is_formattable<test::formattable_scoped_enum>::value, "");
static_assert(!fmt::is_formattable<test::convertible_to_enum>::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; }
};