mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-25 11:40:06 +00:00
Add format_as for enums
This commit is contained in:
parent
b00a1eac75
commit
1557ab7644
@ -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));
|
||||
}
|
||||
|
@ -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; }
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user