mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-19 11:14:41 +00:00
Cleanup format_as handling
This commit is contained in:
parent
545dc4148a
commit
761d35f763
@ -1081,15 +1081,18 @@ enum { long_short = sizeof(long) == sizeof(int) };
|
||||
using long_type = conditional_t<long_short, int, long long>;
|
||||
using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
|
||||
|
||||
template <typename T> struct format_as_result {
|
||||
template <typename U,
|
||||
FMT_ENABLE_IF(std::is_enum<U>::value || std::is_class<U>::value)>
|
||||
static auto map(U*) -> remove_cvref_t<decltype(format_as(std::declval<U>()))>;
|
||||
static auto map(...) -> void;
|
||||
template <typename T>
|
||||
using format_as_result =
|
||||
remove_cvref_t<decltype(format_as(std::declval<const T&>()))>;
|
||||
|
||||
using type = decltype(map(static_cast<T*>(nullptr)));
|
||||
};
|
||||
template <typename T> using format_as_t = typename format_as_result<T>::type;
|
||||
template <typename T, typename Enable = std::true_type>
|
||||
struct use_format_as : std::false_type {};
|
||||
|
||||
// Only map owning types because mapping views can be unsafe.
|
||||
template <typename T>
|
||||
struct use_format_as<
|
||||
T, bool_constant<std::is_integral<format_as_result<T>>::value>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename Char, typename T>
|
||||
constexpr auto has_const_formatter_impl(T*)
|
||||
@ -1193,10 +1196,8 @@ template <typename Char> struct arg_mapper {
|
||||
return x;
|
||||
}
|
||||
|
||||
// Only map owning types because mapping views can be unsafe.
|
||||
template <typename T, typename U = format_as_t<T>,
|
||||
FMT_ENABLE_IF(std::is_arithmetic<U>::value)>
|
||||
FMT_MAP_API auto map(const T& x) -> decltype(map(U())) {
|
||||
template <typename T, FMT_ENABLE_IF(use_format_as<T>::value)>
|
||||
FMT_MAP_API auto map(const T& x) -> decltype(map(format_as(x))) {
|
||||
return map(format_as(x));
|
||||
}
|
||||
|
||||
@ -1222,7 +1223,7 @@ template <typename Char> struct arg_mapper {
|
||||
std::is_union<U>::value || std::is_fundamental<U>::value) &&
|
||||
!has_to_string_view<U>::value && !is_char<U>::value &&
|
||||
!is_named_arg<U>::value && !std::is_integral<U>::value &&
|
||||
!std::is_arithmetic<format_as_t<U>>::value)>
|
||||
!use_format_as<U>::value)>
|
||||
FMT_MAP_API auto map(T& x) -> decltype(do_map(x)) {
|
||||
return do_map(x);
|
||||
}
|
||||
|
@ -3826,10 +3826,6 @@ using fmt::report_error;
|
||||
FMT_API void report_error(format_func func, int error_code,
|
||||
const char* message) noexcept;
|
||||
|
||||
template <typename T>
|
||||
struct has_format_as
|
||||
: bool_constant<!std::is_same<format_as_t<T>, void>::value> {};
|
||||
|
||||
FMT_BEGIN_EXPORT
|
||||
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
@ -3859,13 +3855,13 @@ FMT_CONSTEXPR auto native_formatter<T, Char, TYPE>::format(
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename Char>
|
||||
struct formatter<T, Char, enable_if_t<detail::has_format_as<T>::value>>
|
||||
: formatter<detail::format_as_t<T>, Char> {
|
||||
struct formatter<T, Char, void_t<detail::format_as_result<T>>>
|
||||
: formatter<detail::format_as_result<T>, Char> {
|
||||
template <typename FormatContext>
|
||||
FMT_CONSTEXPR auto format(const T& value, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
auto&& val = format_as(value); // Make an lvalue reference for format.
|
||||
return formatter<detail::format_as_t<T>, Char>::format(val, ctx);
|
||||
return formatter<detail::format_as_result<T>, Char>::format(val, ctx);
|
||||
}
|
||||
};
|
||||
|
||||
@ -4303,20 +4299,19 @@ FMT_NODISCARD auto to_string(T value) -> std::string {
|
||||
return {buffer, detail::write<char>(begin, value)};
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(detail::use_format_as<T>::value)>
|
||||
FMT_NODISCARD auto to_string(const T& value) -> std::string {
|
||||
return to_string(format_as(value));
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
|
||||
!detail::has_format_as<T>::value)>
|
||||
!detail::use_format_as<T>::value)>
|
||||
FMT_NODISCARD auto to_string(const T& value) -> std::string {
|
||||
auto buffer = memory_buffer();
|
||||
detail::write<char>(appender(buffer), value);
|
||||
return {buffer.data(), buffer.size()};
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&
|
||||
detail::has_format_as<T>::value)>
|
||||
FMT_NODISCARD auto to_string(const T& value) -> std::string {
|
||||
return to_string(format_as(value));
|
||||
}
|
||||
|
||||
FMT_END_EXPORT
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user