Skip to content

Commit

Permalink
Add a formatter for float128
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Mar 22, 2024
1 parent aecec01 commit 5d63e87
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 37 deletions.
35 changes: 18 additions & 17 deletions include/fmt/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -2799,35 +2799,25 @@ FMT_API void vprint_mojibake(FILE*, string_view, format_args, bool = false);
#ifndef _WIN32
inline void vprint_mojibake(FILE*, string_view, format_args, bool) {}
#endif
} // namespace detail

FMT_BEGIN_EXPORT

// A formatter specialization for natively supported types.
template <typename T, typename Char>
struct formatter<T, Char,
enable_if_t<detail::type_constant<T, Char>::value !=
detail::type::custom_type>> {
template <typename T, typename Char, type TYPE> struct native_formatter {
private:
detail::dynamic_format_specs<Char> specs_;
dynamic_format_specs<Char> specs_;

public:
using nonlocking = void;

template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const Char* {
if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
auto type = detail::type_constant<T, Char>::value;
auto end =
detail::parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, type);
if (type == detail::type::char_type) detail::check_char_specs(specs_);
auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, TYPE);
if (TYPE == type::char_type) check_char_specs(specs_);
return end;
}

template <detail::type U = detail::type_constant<T, Char>::value,
FMT_ENABLE_IF(U == detail::type::string_type ||
U == detail::type::cstring_type ||
U == detail::type::char_type)>
template <type U = TYPE,
FMT_ENABLE_IF(U == type::string_type || U == type::cstring_type ||
U == type::char_type)>
FMT_CONSTEXPR void set_debug_format(bool set = true) {
specs_.type = set ? presentation_type::debug : presentation_type::none;
}
Expand All @@ -2836,6 +2826,17 @@ struct formatter<T, Char,
FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
-> decltype(ctx.out());
};
} // namespace detail

FMT_BEGIN_EXPORT

// A formatter specialization for natively supported types.
template <typename T, typename Char>
struct formatter<T, Char,
enable_if_t<detail::type_constant<T, Char>::value !=
detail::type::custom_type>>
: detail::native_formatter<T, Char, detail::type_constant<T, Char>::value> {
};

template <typename Char = char> struct runtime_format_string {
basic_string_view<Char> str;
Expand Down
39 changes: 19 additions & 20 deletions include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -4321,8 +4321,27 @@ extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
#endif // FMT_HEADER_ONLY

template <typename T, typename Char, type TYPE>
template <typename FormatContext>
FMT_CONSTEXPR FMT_INLINE auto native_formatter<T, Char, TYPE>::format(
const T& val, FormatContext& ctx) const -> decltype(ctx.out()) {
if (specs_.width_ref.kind == arg_id_kind::none &&
specs_.precision_ref.kind == arg_id_kind::none) {
return write<Char>(ctx.out(), val, specs_, ctx.locale());
}
auto specs = specs_;
handle_dynamic_spec<width_checker>(specs.width, specs.width_ref, ctx);
handle_dynamic_spec<precision_checker>(specs.precision, specs.precision_ref,
ctx);
return write<Char>(ctx.out(), val, specs, ctx.locale());
}
} // namespace detail

template <typename Char>
struct formatter<detail::float128, Char>
: detail::native_formatter<detail::float128, Char,
detail::type::float_type> {};

#if FMT_USE_USER_DEFINED_LITERALS
inline namespace literals {
/**
Expand Down Expand Up @@ -4412,26 +4431,6 @@ FMT_NODISCARD FMT_INLINE auto formatted_size(const Locale& loc,

FMT_END_EXPORT

template <typename T, typename Char>
template <typename FormatContext>
FMT_CONSTEXPR FMT_INLINE auto
formatter<T, Char,
enable_if_t<detail::type_constant<T, Char>::value !=
detail::type::custom_type>>::format(const T& val,
FormatContext& ctx)
const -> decltype(ctx.out()) {
if (specs_.width_ref.kind == detail::arg_id_kind::none &&
specs_.precision_ref.kind == detail::arg_id_kind::none) {
return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
}
auto specs = specs_;
detail::handle_dynamic_spec<detail::width_checker>(specs.width,
specs.width_ref, ctx);
detail::handle_dynamic_spec<detail::precision_checker>(
specs.precision, specs.precision_ref, ctx);
return detail::write<Char>(ctx.out(), val, specs, ctx.locale());
}

FMT_END_NAMESPACE

#ifdef FMT_HEADER_ONLY
Expand Down

0 comments on commit 5d63e87

Please sign in to comment.