#ifndef FMT_FORMAT_
#define FMT_FORMAT_
+#include <algorithm>
#include <cassert>
#include <variant>
#include "fmt/format.h"
template<class Out, class charT> class basic_format_context;
using format_context = basic_format_context<
- /* unspecified */ std::back_insert_iterator<fmt::internal::buffer<char>>, char>;
+ /* unspecified */ fmt::detail::buffer_appender<char>, char>;
using wformat_context = basic_format_context<
- /* unspecified */ std::back_insert_iterator<fmt::internal::buffer<wchar_t>>, wchar_t>;
+ /* unspecified */ fmt::detail::buffer_appender<wchar_t>, wchar_t>;
template<class T, class charT = char> struct formatter {
formatter() = delete;
// Implementation details:
using format_arg = basic_format_arg<basic_format_context>;
- basic_format_context(Out out, basic_format_args<basic_format_context> args, fmt::internal::locale_ref)
+ basic_format_context(Out out, basic_format_args<basic_format_context> args, fmt::detail::locale_ref)
: args_(args), out_(out) {}
detail::error_handler error_handler() const { return {}; }
basic_format_arg<basic_format_context> arg(fmt::basic_string_view<charT>) const {
namespace std {
namespace detail {
-template <typename Range>
+template <typename OutputIt, typename Char>
class arg_formatter
- : public fmt::internal::arg_formatter_base<Range, error_handler> {
+ : public fmt::detail::arg_formatter_base<OutputIt, Char, error_handler> {
private:
- using char_type = typename Range::value_type;
- using base = fmt::internal::arg_formatter_base<Range, error_handler>;
- using format_context = std::basic_format_context<typename base::iterator, char_type>;
- using parse_context = basic_format_parse_context<char_type>;
+ using char_type = Char;
+ using base = fmt::detail::arg_formatter_base<OutputIt, Char, error_handler>;
+ using format_context = std::basic_format_context<OutputIt, Char>;
+ using parse_context = basic_format_parse_context<Char>;
parse_context* parse_ctx_;
format_context& ctx_;
public:
- typedef Range range;
- typedef typename base::iterator iterator;
- typedef typename base::format_specs format_specs;
+ using iterator = OutputIt;
+ using format_specs = typename base::format_specs;
/**
\rst
\endrst
*/
arg_formatter(format_context& ctx, parse_context* parse_ctx = nullptr, fmt::format_specs* spec = nullptr)
- : base(Range(ctx.out()), spec, {}), parse_ctx_(parse_ctx), ctx_(ctx) {}
+ : base(ctx.out(), spec, {}), parse_ctx_(parse_ctx), ctx_(ctx) {}
using base::operator();
};
template <typename Context>
-inline fmt::internal::type get_type(basic_format_arg<Context> arg) {
+inline fmt::detail::type get_type(basic_format_arg<Context> arg) {
return visit_format_arg([&] (auto val) {
using char_type = typename Context::char_type;
using T = decltype(val);
if (std::is_same_v<T, monostate>)
- return fmt::internal::type::none_type;
+ return fmt::detail::type::none_type;
if (std::is_same_v<T, bool>)
- return fmt::internal::type::bool_type;
+ return fmt::detail::type::bool_type;
if (std::is_same_v<T, char_type>)
- return fmt::internal::type::char_type;
+ return fmt::detail::type::char_type;
if (std::is_same_v<T, int>)
- return fmt::internal::type::int_type;
+ return fmt::detail::type::int_type;
if (std::is_same_v<T, unsigned int>)
- return fmt::internal::type::uint_type;
+ return fmt::detail::type::uint_type;
if (std::is_same_v<T, long long int>)
- return fmt::internal::type::long_long_type;
+ return fmt::detail::type::long_long_type;
if (std::is_same_v<T, unsigned long long int>)
- return fmt::internal::type::ulong_long_type;
+ return fmt::detail::type::ulong_long_type;
if (std::is_same_v<T, double>)
- return fmt::internal::type::double_type;
+ return fmt::detail::type::double_type;
if (std::is_same_v<T, long double>)
- return fmt::internal::type::long_double_type;
+ return fmt::detail::type::long_double_type;
if (std::is_same_v<T, const char_type*>)
- return fmt::internal::type::cstring_type;
+ return fmt::detail::type::cstring_type;
if (std::is_same_v<T, basic_string_view<char_type>>)
- return fmt::internal::type::string_type;
+ return fmt::detail::type::string_type;
if (std::is_same_v<T, const void*>)
- return fmt::internal::type::pointer_type;
+ return fmt::detail::type::pointer_type;
assert(get_value(arg).index() == 12);
- return fmt::internal::type::custom_type;
+ return fmt::detail::type::custom_type;
}, arg);
}
template <typename ArgFormatter, typename Char, typename Context>
struct format_handler : detail::error_handler {
- typedef typename ArgFormatter::range range;
+ using iterator = typename ArgFormatter::iterator;
- format_handler(range r, basic_string_view<Char> str,
+ format_handler(iterator out, basic_string_view<Char> str,
basic_format_args<Context> format_args,
- fmt::internal::locale_ref loc)
- : parse_ctx(str), context(r.begin(), format_args, loc) {}
+ fmt::detail::locale_ref loc)
+ : parse_ctx(str), context(out, format_args, loc) {}
void on_text(const Char* begin, const Char* end) {
- auto size = fmt::internal::to_unsigned(end - begin);
+ auto size = fmt::detail::to_unsigned(end - begin);
auto out = context.out();
- auto&& it = fmt::internal::reserve(out, size);
+ auto&& it = fmt::detail::reserve(out, size);
it = std::copy_n(begin, size, it);
context.advance_to(out);
}
- void on_arg_id() {
- arg = context.arg(parse_ctx.next_arg_id());
- }
- void on_arg_id(unsigned id) {
- parse_ctx.check_arg_id(id);
- arg = context.arg(id);
- }
- void on_arg_id(fmt::basic_string_view<Char>) {}
+ int on_arg_id() { return parse_ctx.next_arg_id(); }
+ int on_arg_id(unsigned id) { return parse_ctx.check_arg_id(id), id; }
+ int on_arg_id(fmt::basic_string_view<Char>) { return 0; }
- void on_replacement_field(const Char* p) {
- parse_ctx.advance_to(parse_ctx.begin() + (p - &*parse_ctx.begin()));
+ void on_replacement_field(int id, const Char* p) {
+ auto arg = context.arg(id);
+ parse_ctx.advance_to(parse_ctx.begin() + (p - &*parse_ctx.begin()));
custom_formatter<Context> f(parse_ctx, context);
if (!visit_format_arg(f, arg))
context.advance_to(visit_format_arg(ArgFormatter(context, &parse_ctx), arg));
}
- const Char* on_format_specs(const Char* begin, const Char* end) {
+ const Char* on_format_specs(int id, const Char* begin, const Char* end) {
+ auto arg = context.arg(id);
parse_ctx.advance_to(parse_ctx.begin() + (begin - &*parse_ctx.begin()));
custom_formatter<Context> f(parse_ctx, context);
if (visit_format_arg(f, arg)) return &*parse_ctx.begin();
fmt::basic_format_specs<Char> specs;
- using fmt::internal::specs_handler;
+ using fmt::detail::specs_handler;
using parse_context = basic_format_parse_context<Char>;
- fmt::internal::specs_checker<specs_handler<parse_context, Context>> handler(
+ fmt::detail::specs_checker<specs_handler<parse_context, Context>> handler(
specs_handler<parse_context, Context>(specs, parse_ctx, context), get_type(arg));
begin = parse_format_specs(begin, end, handler);
if (begin == end || *begin != '}') on_error("missing '}' in format string");
basic_format_parse_context<Char> parse_ctx;
Context context;
- basic_format_arg<Context> arg;
};
template <typename T, typename Char>
// terminating '}'.
template <typename ParseContext>
FMT_CONSTEXPR typename ParseContext::iterator parse(ParseContext& ctx) {
- namespace internal = fmt::internal;
- typedef internal::dynamic_specs_handler<ParseContext> handler_type;
- auto type = internal::mapped_type_constant<T, fmt::buffer_context<Char>>::value;
- internal::specs_checker<handler_type> handler(handler_type(specs_, ctx),
+ namespace detail = fmt::detail;
+ typedef detail::dynamic_specs_handler<ParseContext> handler_type;
+ auto type = detail::mapped_type_constant<T, fmt::buffer_context<Char>>::value;
+ detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
type);
auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
auto type_spec = specs_.type;
auto eh = ctx.error_handler();
switch (type) {
- case internal::type::none_type:
+ case detail::type::none_type:
FMT_ASSERT(false, "invalid argument type");
break;
- case internal::type::int_type:
- case internal::type::uint_type:
- case internal::type::long_long_type:
- case internal::type::ulong_long_type:
- case internal::type::bool_type:
+ case detail::type::int_type:
+ case detail::type::uint_type:
+ case detail::type::long_long_type:
+ case detail::type::ulong_long_type:
+ case detail::type::bool_type:
handle_int_type_spec(type_spec,
- internal::int_type_checker<decltype(eh)>(eh));
+ detail::int_type_checker<decltype(eh)>(eh));
break;
- case internal::type::char_type:
+ case detail::type::char_type:
handle_char_specs(
- &specs_, internal::char_specs_checker<decltype(eh)>(type_spec, eh));
+ &specs_, detail::char_specs_checker<decltype(eh)>(type_spec, eh));
break;
- case internal::type::double_type:
- case internal::type::long_double_type:
- internal::parse_float_type_spec(specs_, eh);
+ case detail::type::double_type:
+ case detail::type::long_double_type:
+ detail::parse_float_type_spec(specs_, eh);
break;
- case internal::type::cstring_type:
- internal::handle_cstring_type_spec(
- type_spec, internal::cstring_type_checker<decltype(eh)>(eh));
+ case detail::type::cstring_type:
+ detail::handle_cstring_type_spec(
+ type_spec, detail::cstring_type_checker<decltype(eh)>(eh));
break;
- case internal::type::string_type:
- internal::check_string_type_spec(type_spec, eh);
+ case detail::type::string_type:
+ detail::check_string_type_spec(type_spec, eh);
break;
- case internal::type::pointer_type:
- internal::check_pointer_type_spec(type_spec, eh);
+ case detail::type::pointer_type:
+ detail::check_pointer_type_spec(type_spec, eh);
break;
- case internal::type::custom_type:
+ case detail::type::custom_type:
// Custom format specifiers should be checked in parse functions of
// formatter specializations.
break;
template <typename FormatContext>
auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
- fmt::internal::handle_dynamic_spec<fmt::internal::width_checker>(
+ fmt::detail::handle_dynamic_spec<fmt::detail::width_checker>(
specs_.width, specs_.width_ref, ctx);
- fmt::internal::handle_dynamic_spec<fmt::internal::precision_checker>(
+ fmt::detail::handle_dynamic_spec<fmt::detail::precision_checker>(
specs_.precision, specs_.precision_ref, ctx);
- using range_type = fmt::internal::output_range<typename FormatContext::iterator,
- typename FormatContext::char_type>;
- return visit_format_arg(arg_formatter<range_type>(ctx, nullptr, &specs_),
+ using af = arg_formatter<typename FormatContext::iterator,
+ typename FormatContext::char_type>;
+ return visit_format_arg(af(ctx, nullptr, &specs_),
basic_format_arg<FormatContext>(val));
}
private:
- fmt::internal::dynamic_format_specs<Char> specs_;
+ fmt::detail::dynamic_format_specs<Char> specs_;
};
} // namespace detail
string vformat(string_view fmt, format_args args) {
fmt::memory_buffer mbuf;
- fmt::internal::buffer<char>& buf = mbuf;
- using range = fmt::buffer_range<char>;
- detail::format_handler<detail::arg_formatter<range>, char, format_context>
- h(range(std::back_inserter(buf)), fmt, args, {});
- fmt::internal::parse_format_string<false>(fmt::to_string_view(fmt), h);
+ fmt::detail::buffer<char>& buf = mbuf;
+ using af = detail::arg_formatter<fmt::format_context::iterator, char>;
+ detail::format_handler<af, char, format_context>
+ h(fmt::detail::buffer_appender<char>(buf), fmt, args, {});
+ fmt::detail::parse_format_string<false>(fmt::to_string_view(fmt), h);
return to_string(mbuf);
}
template<class Out>
Out vformat_to(Out out, string_view fmt, format_args_t<fmt::type_identity_t<Out>, char> args) {
- using range = fmt::internal::output_range<Out, char>;
- detail::format_handler<detail::arg_formatter<range>, char, basic_format_context<Out, char>>
- h(range(out), fmt, args, {});
- fmt::internal::parse_format_string<false>(fmt::to_string_view(fmt), h);
+ using af = detail::arg_formatter<Out, char>;
+ detail::format_handler<af, char, basic_format_context<Out, char>>
+ h(out, fmt, args, {});
+ fmt::detail::parse_format_string<false>(fmt::to_string_view(fmt), h);
return h.context.out();
}