diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index f0b94e0d..06ca7851 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -481,10 +481,10 @@ struct formatter, Char> { auto out = std::back_inserter(buf); typedef output_range range; basic_writer w(range(ctx.out())); - internal::handle_dynamic_spec(spec.width_, - width_ref, ctx); + internal::handle_dynamic_spec( + spec.width_, width_ref, ctx, format_str.begin()); internal::handle_dynamic_spec( - precision, precision_ref, ctx); + precision, precision_ref, ctx, format_str.begin()); if (begin == end || *begin == '}') { out = internal::format_chrono_duration_value(out, d.count(), precision); internal::format_chrono_duration_unit(out); diff --git a/include/fmt/core.h b/include/fmt/core.h index d7807baa..29d28566 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -687,7 +687,7 @@ template class value { }; FMT_CONSTEXPR value(int val = 0) : int_value(val) {} - value(unsigned val) { uint_value = val; } + FMT_CONSTEXPR value(unsigned val) : uint_value(val) {} value(long long val) { long_long_value = val; } value(unsigned long long val) { ulong_long_value = val; } value(double val) { double_value = val; } @@ -936,7 +936,7 @@ template class basic_format_arg { FMT_CONSTEXPR basic_format_arg() : type_(internal::none_type) {} - FMT_EXPLICIT operator bool() const FMT_NOEXCEPT { + FMT_CONSTEXPR FMT_EXPLICIT operator bool() const FMT_NOEXCEPT { return type_ != internal::none_type; } @@ -1045,76 +1045,13 @@ class locale_ref { public: locale_ref() : locale_(FMT_NULL) {} - template explicit locale_ref(const Locale& loc); template Locale get() const; }; template -class context_base { - public: - typedef OutputIt iterator; - - private: - basic_parse_context parse_context_; - iterator out_; - basic_format_args args_; - locale_ref loc_; - - protected: - typedef Char char_type; - typedef basic_format_arg format_arg; - - context_base(OutputIt out, basic_string_view format_str, - basic_format_args ctx_args, - locale_ref loc = locale_ref()) - : parse_context_(format_str), out_(out), args_(ctx_args), loc_(loc) {} - - // Returns the argument with specified index. - format_arg do_get_arg(unsigned arg_id) { - format_arg arg = args_.get(arg_id); - if (!arg) parse_context_.on_error("argument index out of range"); - return arg; - } - - friend basic_parse_context& get_parse_context(context_base& ctx) { - return ctx.parse_context_; - } - - // Checks if manual indexing is used and returns the argument with - // specified index. - format_arg arg(unsigned arg_id) { - return parse_context_.check_arg_id(arg_id) ? this->do_get_arg(arg_id) - : format_arg(); - } - - public: - FMT_DEPRECATED basic_parse_context& parse_context() { - return parse_context_; - } - - // basic_format_context::arg() depends on this - // Cannot be marked as deprecated without causing warnings - /*FMT_DEPRECATED*/ basic_format_args args() const { return args_; } - - basic_format_arg arg(unsigned id) const { return args_.get(id); } - - internal::error_handler error_handler() { - return parse_context_.error_handler(); - } - - void on_error(const char* message) { parse_context_.on_error(message); } - - // Returns an iterator to the beginning of the output range. - iterator out() { return out_; } - FMT_DEPRECATED iterator begin() { return out_; } - - // Advances the begin iterator to ``it``. - void advance_to(iterator it) { out_ = it; } - - locale_ref locale() { return loc_; } -}; +class context_base {}; template struct get_type { typedef decltype( @@ -1153,54 +1090,54 @@ make_arg(const T& value) { } // namespace internal // Formatting context. -template -class basic_format_context - : public internal::context_base< - OutputIt, basic_format_context, Char> { +template class basic_format_context { public: /** The character type for the output. */ typedef Char char_type; + private: + OutputIt out_; + basic_format_args args_; + internal::arg_map map_; + internal::locale_ref loc_; + + basic_format_context(const basic_format_context&) = delete; + void operator=(const basic_format_context&) = delete; + + public: + typedef OutputIt iterator; + typedef basic_format_arg format_arg; + // using formatter_type = formatter; template struct formatter_type { typedef formatter type; }; - private: - internal::arg_map map_; - - basic_format_context(const basic_format_context&) = delete; - void operator=(const basic_format_context&) = delete; - - typedef internal::context_base base; - using base::arg; - - public: - using typename base::iterator; - typedef typename base::format_arg format_arg; - /** Constructs a ``basic_format_context`` object. References to the arguments are stored in the object so make sure they have appropriate lifetimes. */ - basic_format_context(OutputIt out, basic_string_view format_str, + basic_format_context(OutputIt out, basic_format_args ctx_args, internal::locale_ref loc = internal::locale_ref()) - : base(out, format_str, ctx_args, loc) {} + : out_(out), args_(ctx_args), loc_(loc) {} - format_arg next_arg() { - return this->do_get_arg(get_parse_context(*this).next_arg_id()); - } - format_arg arg(unsigned arg_id) { return this->do_get_arg(arg_id); } + format_arg arg(unsigned id) const { return args_.get(id); } // Checks if manual indexing is used and returns the argument with the // specified name. format_arg arg(basic_string_view name); - FMT_DEPRECATED format_arg get_arg(unsigned arg_id) { return arg(arg_id); } - FMT_DEPRECATED format_arg get_arg(basic_string_view name) { - return arg(name); - } + internal::error_handler error_handler() { return {}; } + void on_error(const char* message) { error_handler().on_error(message); } + + // Returns an iterator to the beginning of the output range. + iterator out() { return out_; } + + // Advances the begin iterator to ``it``. + void advance_to(iterator it) { out_ = it; } + + internal::locale_ref locale() { return loc_; } }; template struct buffer_context { @@ -1399,6 +1336,13 @@ struct char_t : std::enable_if::value, #endif namespace internal { +template +FMT_CONSTEXPR basic_format_arg get_arg(Context& ctx, unsigned id) { + auto arg = ctx.arg(id); + if (!arg) ctx.on_error("argument index out of range"); + return arg; +} + template struct named_arg_base { basic_string_view name; diff --git a/include/fmt/format.h b/include/fmt/format.h index 2507e68c..916e4441 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1567,16 +1567,20 @@ FMT_CONSTEXPR unsigned parse_nonnegative_int(const Char*& begin, return value; } -template -class custom_formatter : public function { +template class custom_formatter : public function { private: + typedef typename Context::char_type char_type; + + basic_parse_context& parse_ctx_; Context& ctx_; public: - explicit custom_formatter(Context& ctx) : ctx_(ctx) {} + explicit custom_formatter(basic_parse_context& parse_ctx, + Context& ctx) + : parse_ctx_(parse_ctx), ctx_(ctx) {} bool operator()(typename basic_format_arg::handle h) const { - h.format(get_parse_context(ctx_), ctx_); + h.format(parse_ctx_, ctx_); return true; } @@ -1769,7 +1773,9 @@ class specs_handler : public specs_setter { FMT_CONSTEXPR specs_handler(basic_format_specs& specs, ParseContext& parse_ctx, Context& ctx) - : specs_setter(specs), parse_ctx_(parse_ctx), context_(ctx) {} + : specs_setter(specs), + parse_context_(parse_ctx), + context_(ctx) {} template FMT_CONSTEXPR void on_dynamic_width(Id arg_id) { set_dynamic_spec(this->specs_.width_, get_arg(arg_id), @@ -1787,14 +1793,21 @@ class specs_handler : public specs_setter { // This is only needed for compatibility with gcc 4.4. typedef typename Context::format_arg format_arg; - FMT_CONSTEXPR format_arg get_arg(auto_id) { return context_.next_arg(); } + FMT_CONSTEXPR format_arg get_arg(auto_id) { + return internal::get_arg(context_, parse_context_.next_arg_id()); + } - template FMT_CONSTEXPR format_arg get_arg(Id arg_id) { - parse_ctx_.check_arg_id(arg_id); + FMT_CONSTEXPR format_arg get_arg(unsigned arg_id) { + parse_context_.check_arg_id(arg_id); + return internal::get_arg(context_, arg_id); + } + + FMT_CONSTEXPR format_arg get_arg(basic_string_view arg_id) { + parse_context_.check_arg_id(arg_id); return context_.arg(arg_id); } - ParseContext& parse_ctx_; + ParseContext& parse_context_; Context& context_; }; @@ -2264,7 +2277,8 @@ struct format_type template