-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enum class support #391
Comments
Similar question is how best to add formatting support for a templated type like std::optional from the standard library that doesn't support the << operator. Thanks again. |
I'm glad you like the library =). To format a enum class you'll have to provide an overloaded enum class ErrorCode : int {
SOME_ERROR
};
std::ostream &operator<<(std::ostream& os, ErrorCode ec) {
return os << static_cast<int>(ec);
}
int main() {
fmt::print("{}", ErrorCode::SOME_ERROR);
} If you don't want to overload template <typename ArgFormatter>
void format_arg(fmt::BasicFormatter<char, ArgFormatter> &f,
const char *&format_str, ErrorCode e) {
f.writer() << (int)e;
} There is an example here: https://github.com/fmtlib/fmt/blob/master/fmt/time.h#L18. The same can be done for |
Okay got it thanks! Is it possible to template this? e.g.
When I use this with a stringstream it compiles fine, e.g.:
But if I do the same thing with fmt::format it doesn't resolve the template. |
It should be possible to do that, but keep in mind that overloaded |
Yes indeed - include order was my issue. Thank you for pointing me in the right direction. |
Updates most dependencies to latest version Fixes the store build by fixing python Enables pillow and pycryptodome again on windows Replaces easyhook with detours
We wanted to have something that "just work" for the whole project so based on the advice in this thread we ended up with this. #include <ostream>
#include <type_traits>
// clang-format off
// This is required to format enum classes with fmt as they're not implicitly
// convertible to int.
// This operator has to be declared before including format.h and ostream.h.
// We keep clang format disabled to avoid reordering and breaking things
// https://github.com/fmtlib/fmt/issues/391
template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
std::ostream& operator<<(std::ostream& os, const T& value)
{
return os << static_cast<int>(value);
}
#include <fmt/format.h>
#include <fmt/ostream.h>
// clang-format on Put this in a header file like |
In recent versions of {fmt} enum classes are formatted as integers by default (https://godbolt.org/z/3Z9sj4): #include <fmt/core.h>
enum class ErrorCode : int {
SOME_ERROR
};
int main() {
fmt::print("{}", ErrorCode::SOME_ERROR); // prints 0
} |
@vitaut unfortunately it didn't work for me with 8.1.1 or the most recent commit as of this post (ba6f89c) In order to avoid these errors:
I followed the link in the error and wrote a template which fixed the error: enum class OrderStatus {
open,
partial_fill,
filled,
cancelled,
};
template <> struct fmt::formatter<OrderStatus> : formatter<string_view> {
template <typename FormatContext> auto format(OrderStatus order_status, FormatContext &ctx) {
string_view name = "unknown";
switch (order_status) {
case OrderStatus::open:
name = "open";
break;
case OrderStatus::partial_fill:
name = "partial_fill";
break;
case OrderStatus::filled:
name = "filled";
break;
case OrderStatus::cancelled:
name = "cancelled";
break;
}
return formatter<string_view>::format(name, ctx);
}
}; That's very verbose to write for each enum though and I would be ok if |
Scoped enum are not implicitly convertible to integers in C++ but the current master supports a simplified API if you want to make an enum formattable as an underlying (integral) type: auto format_as(OrderStatus s) { return fmt::underlying(s); } |
Same Problem as [DominicTobias] with 8.1.1 But i have implemented the operator<< for my Enum-Class (and it works correctly before) So not possible anymore? MSVC 17.1.0, -std=C++20 |
ostream |
Thanks, i missed the template specialization. Thanks again for this amazing, performant lib of yours! |
Just in case I want write some template function like:
that should accept |
You can either provide formatter specializations or use |
@vitaut hi, is there any way to turn on the implicit conversion from enum to underlying integer? |
@Inori, no but you can define a single |
Ok,thanks for the reply. |
gcc13 based build failed with below errors. error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt Problem reported during enum type input is similar to fmtlib/fmt#391 Fix is to static_cast the "enum" type to "underlying_type" in fmt::format function. Problem related file descriptor input is to static_cast enum to "underlying_type". Change-Id: I587e4abfb4e188d40a0e4bfbdd57e6da6a77616d Signed-off-by: Jayanth Othayoth <[email protected]>
gcc13 based build failed with below error. error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt Problem looks similar to fmtlib/fmt#391 Fix is to convert the "enum" type to underlying_type in fmt::format function. Change-Id: I155fc854428492462dfec3b3818d08daa16e36bf Signed-off-by: Jayanth Othayoth <[email protected]>
gcc13 based build failed with below errors. error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt Problem reported during enum type input is similar to fmtlib/fmt#391 Fix is to static_cast the "enum" type to "underlying_type" in fmt::format function. Problem related file descriptor input is to static_cast enum to "underlying_type". Change-Id: I587e4abfb4e188d40a0e4bfbdd57e6da6a77616d Signed-off-by: Jayanth Othayoth <[email protected]>
gcc13 based build failed with below errors. error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt Problem reported during enum type input is similar to fmtlib/fmt#391 Fix is to static_cast the "enum" type to "underlying_type" in fmt::format function. Problem related file descriptor input is to static_cast enum to "underlying_type". Change-Id: I587e4abfb4e188d40a0e4bfbdd57e6da6a77616d Signed-off-by: Jayanth Othayoth <[email protected]>
Hello - this library is a godsend. Thank you. I'm working in a project that uses a number of enum classes, e.g:
enum class ErrorCode : int {
SOME_ERROR;
}
I'm interested in formatting these objects as ints, but the built-in support wants to treat them as custom objects. I can't change these classes to add ostream support. What is the easiest way to do this? I tried adding a templatized report_arg overload, which works if I add it to the C file generating the log statement, but not if I add it the header from which I'm including format.h
template<class T,class=typename std::enable_if< std::is_enum::value >::type>
void format_arg(fmt::BasicFormatter &f, const char *, const T &e) {
f.writer() << (int)e;
}
Any suggestions would be very appreciated.
Dave
The text was updated successfully, but these errors were encountered: