mirror of
https://github.com/fmtlib/fmt.git
synced 2025-03-15 07:20:50 +00:00
Cleanup base API
This commit is contained in:
parent
5f438c967e
commit
c3344e21e2
@ -254,7 +254,8 @@
|
||||
#ifdef FMT_CLANG_PRAGMA
|
||||
// Use the provided definition.
|
||||
#elif FMT_CLANG_VERSION
|
||||
# define FMT_CLANG_PRAGMA(x) _Pragma(#x)
|
||||
# define FMT_CLANG_PRAGMA_IMPL(x) _Pragma(#x)
|
||||
# define FMT_CLANG_PRAGMA(x) FMT_CLANG_PRAGMA_IMPL(clang x)
|
||||
#else
|
||||
# define FMT_CLANG_PRAGMA(x)
|
||||
#endif
|
||||
@ -317,7 +318,7 @@ FMT_GCC_PRAGMA(GCC push_options)
|
||||
#if !defined(__OPTIMIZE__) && !defined(__CUDACC__)
|
||||
FMT_GCC_PRAGMA(GCC optimize("Og"))
|
||||
#endif
|
||||
FMT_CLANG_PRAGMA(clang diagnostic push)
|
||||
FMT_CLANG_PRAGMA(diagnostic push)
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
|
||||
@ -432,7 +433,7 @@ template <typename T> auto convert_for_visit(T) -> monostate { return {}; }
|
||||
#endif
|
||||
|
||||
#if FMT_USE_BITINT
|
||||
# pragma clang diagnostic ignored "-Wbit-int-extension"
|
||||
FMT_CLANG_PRAGMA(diagnostic ignored "-Wbit-int-extension")
|
||||
template <int N> using bitint = _BitInt(N);
|
||||
template <int N> using ubitint = unsigned _BitInt(N);
|
||||
#else
|
||||
@ -2431,7 +2432,7 @@ template <typename T, typename Char, type TYPE> struct native_formatter {
|
||||
specs_.set_type(set ? presentation_type::debug : presentation_type::none);
|
||||
}
|
||||
|
||||
FMT_CLANG_PRAGMA(clang diagnostic ignored "-Wundefined-inline")
|
||||
FMT_CLANG_PRAGMA(diagnostic ignored "-Wundefined-inline")
|
||||
template <typename FormatContext>
|
||||
FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
|
||||
-> decltype(ctx.out());
|
||||
@ -2452,17 +2453,8 @@ FMT_CONSTEXPR inline auto is_locking() -> bool {
|
||||
return locking<T1>::value || is_locking<T2, Tail...>();
|
||||
}
|
||||
|
||||
// Use vformat_args and avoid type_identity to keep symbols short.
|
||||
template <typename Char = char> struct vformat_args {
|
||||
using type = basic_format_args<buffered_context<Char>>;
|
||||
};
|
||||
template <> struct vformat_args<char> {
|
||||
using type = format_args;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
|
||||
typename vformat_args<Char>::type args, locale_ref loc = {});
|
||||
FMT_API void vformat_to(buffer<char>& buf, string_view fmt, format_args args,
|
||||
locale_ref loc = {});
|
||||
|
||||
#ifdef _WIN32
|
||||
FMT_API void vprint_mojibake(FILE*, string_view, format_args, bool);
|
||||
@ -2978,7 +2970,7 @@ template <typename... T>
|
||||
FMT_NODISCARD FMT_INLINE auto formatted_size(format_string<T...> fmt,
|
||||
T&&... args) -> size_t {
|
||||
auto buf = detail::counting_buffer<>();
|
||||
detail::vformat_to<char>(buf, fmt, fmt::make_format_args(args...), {});
|
||||
detail::vformat_to(buf, fmt, fmt::make_format_args(args...), {});
|
||||
return buf.count();
|
||||
}
|
||||
|
||||
@ -3036,7 +3028,7 @@ FMT_INLINE void println(format_string<T...> fmt, T&&... args) {
|
||||
}
|
||||
|
||||
FMT_END_EXPORT
|
||||
FMT_CLANG_PRAGMA(clang diagnostic pop)
|
||||
FMT_CLANG_PRAGMA(diagnostic pop)
|
||||
FMT_GCC_PRAGMA(GCC pop_options)
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
|
@ -1442,6 +1442,15 @@ FMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {
|
||||
|
||||
namespace detail {
|
||||
|
||||
FMT_FUNC void vformat_to(buffer<char>& buf, string_view fmt, format_args args,
|
||||
locale_ref loc) {
|
||||
auto out = appender(buf);
|
||||
if (fmt.size() == 2 && equal2(fmt.data(), "{}"))
|
||||
return args.get(0).visit(default_arg_formatter<char>{out});
|
||||
parse_format_string(
|
||||
fmt, format_handler<char>{parse_context<char>(fmt), {out, args, loc}});
|
||||
}
|
||||
|
||||
template <typename T> struct span {
|
||||
T* data;
|
||||
size_t size;
|
||||
|
@ -3808,6 +3808,71 @@ template <typename Char> struct udl_arg {
|
||||
# endif
|
||||
#endif // FMT_USE_USER_DEFINED_LITERALS
|
||||
|
||||
template <typename Char> struct format_handler {
|
||||
parse_context<Char> parse_ctx;
|
||||
buffered_context<Char> ctx;
|
||||
|
||||
void on_text(const Char* begin, const Char* end) {
|
||||
copy_noinline<Char>(begin, end, ctx.out());
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR auto on_arg_id() -> int { return parse_ctx.next_arg_id(); }
|
||||
FMT_CONSTEXPR auto on_arg_id(int id) -> int {
|
||||
parse_ctx.check_arg_id(id);
|
||||
return id;
|
||||
}
|
||||
FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
|
||||
parse_ctx.check_arg_id(id);
|
||||
int arg_id = ctx.arg_id(id);
|
||||
if (arg_id < 0) report_error("argument not found");
|
||||
return arg_id;
|
||||
}
|
||||
|
||||
FMT_INLINE void on_replacement_field(int id, const Char*) {
|
||||
ctx.arg(id).visit(default_arg_formatter<Char>{ctx.out()});
|
||||
}
|
||||
|
||||
auto on_format_specs(int id, const Char* begin, const Char* end)
|
||||
-> const Char* {
|
||||
auto arg = get_arg(ctx, id);
|
||||
// Not using a visitor for custom types gives better codegen.
|
||||
if (arg.format_custom(begin, parse_ctx, ctx)) return parse_ctx.begin();
|
||||
|
||||
auto specs = dynamic_format_specs<Char>();
|
||||
begin = parse_format_specs(begin, end, specs, parse_ctx, arg.type());
|
||||
if (specs.dynamic()) {
|
||||
handle_dynamic_spec(specs.dynamic_width(), specs.width, specs.width_ref,
|
||||
ctx);
|
||||
handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
|
||||
specs.precision_ref, ctx);
|
||||
}
|
||||
|
||||
arg.visit(arg_formatter<Char>{ctx.out(), specs, ctx.locale()});
|
||||
return begin;
|
||||
}
|
||||
|
||||
FMT_NORETURN void on_error(const char* message) { report_error(message); }
|
||||
};
|
||||
|
||||
// DEPRECATED!
|
||||
// Use vformat_args and avoid type_identity to keep symbols short.
|
||||
template <typename Char = char> struct vformat_args {
|
||||
using type = basic_format_args<buffered_context<Char>>;
|
||||
};
|
||||
template <> struct vformat_args<char> {
|
||||
using type = format_args;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
|
||||
typename vformat_args<Char>::type args, locale_ref loc = {}) {
|
||||
auto out = basic_appender<Char>(buf);
|
||||
if (fmt.size() == 2 && equal2(fmt.data(), "{}"))
|
||||
return args.get(0).visit(default_arg_formatter<Char>{out});
|
||||
parse_format_string(
|
||||
fmt, format_handler<Char>{parse_context<Char>(fmt), {out, args, loc}});
|
||||
}
|
||||
|
||||
template <typename Locale, typename Char>
|
||||
auto vformat(const Locale& loc, basic_string_view<Char> fmt,
|
||||
typename detail::vformat_args<Char>::type args)
|
||||
@ -4188,68 +4253,9 @@ FMT_END_EXPORT
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Char> struct format_handler {
|
||||
parse_context<Char> parse_ctx;
|
||||
buffered_context<Char> ctx;
|
||||
|
||||
void on_text(const Char* begin, const Char* end) {
|
||||
copy_noinline<Char>(begin, end, ctx.out());
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR auto on_arg_id() -> int { return parse_ctx.next_arg_id(); }
|
||||
FMT_CONSTEXPR auto on_arg_id(int id) -> int {
|
||||
parse_ctx.check_arg_id(id);
|
||||
return id;
|
||||
}
|
||||
FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
|
||||
parse_ctx.check_arg_id(id);
|
||||
int arg_id = ctx.arg_id(id);
|
||||
if (arg_id < 0) report_error("argument not found");
|
||||
return arg_id;
|
||||
}
|
||||
|
||||
FMT_INLINE void on_replacement_field(int id, const Char*) {
|
||||
ctx.arg(id).visit(default_arg_formatter<Char>{ctx.out()});
|
||||
}
|
||||
|
||||
auto on_format_specs(int id, const Char* begin, const Char* end)
|
||||
-> const Char* {
|
||||
auto arg = get_arg(ctx, id);
|
||||
// Not using a visitor for custom types gives better codegen.
|
||||
if (arg.format_custom(begin, parse_ctx, ctx)) return parse_ctx.begin();
|
||||
|
||||
auto specs = dynamic_format_specs<Char>();
|
||||
begin = parse_format_specs(begin, end, specs, parse_ctx, arg.type());
|
||||
if (specs.dynamic()) {
|
||||
handle_dynamic_spec(specs.dynamic_width(), specs.width, specs.width_ref,
|
||||
ctx);
|
||||
handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
|
||||
specs.precision_ref, ctx);
|
||||
}
|
||||
|
||||
arg.visit(arg_formatter<Char>{ctx.out(), specs, ctx.locale()});
|
||||
return begin;
|
||||
}
|
||||
|
||||
FMT_NORETURN void on_error(const char* message) { report_error(message); }
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
|
||||
typename vformat_args<Char>::type args, locale_ref loc) {
|
||||
auto out = basic_appender<Char>(buf);
|
||||
if (fmt.size() == 2 && equal2(fmt.data(), "{}"))
|
||||
return args.get(0).visit(default_arg_formatter<Char>{out});
|
||||
parse_format_string(
|
||||
fmt, format_handler<Char>{parse_context<Char>(fmt), {out, args, loc}});
|
||||
}
|
||||
|
||||
FMT_BEGIN_EXPORT
|
||||
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
extern template FMT_API void vformat_to(buffer<char>&, string_view,
|
||||
typename vformat_args<>::type,
|
||||
locale_ref);
|
||||
extern template FMT_API auto thousands_sep_impl<char>(locale_ref)
|
||||
-> thousands_sep_result<char>;
|
||||
extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)
|
||||
@ -4361,8 +4367,8 @@ FMT_NODISCARD FMT_INLINE auto formatted_size(const Locale& loc,
|
||||
format_string<T...> fmt,
|
||||
T&&... args) -> size_t {
|
||||
auto buf = detail::counting_buffer<>();
|
||||
detail::vformat_to<char>(buf, fmt, fmt::make_format_args(args...),
|
||||
detail::locale_ref(loc));
|
||||
detail::vformat_to(buf, fmt, fmt::make_format_args(args...),
|
||||
detail::locale_ref(loc));
|
||||
return buf.count();
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ template FMT_API auto decimal_point_impl(locale_ref) -> char;
|
||||
// DEPRECATED!
|
||||
template FMT_API void buffer<char>::append(const char*, const char*);
|
||||
|
||||
// DEPRECATED!
|
||||
template FMT_API void vformat_to(buffer<char>&, string_view,
|
||||
typename vformat_args<>::type, locale_ref);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user