diff --git a/doc/api.rst b/doc/api.rst index 46070ed6..cc17effe 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -493,7 +493,9 @@ System APIs ======================== ``fmt/ostream.h`` provides ``std::ostream`` support including formatting of -user-defined types that have an overloaded insertion operator (``operator<<``):: +user-defined types that have an overloaded insertion operator (``operator<<``). +In order to make a type formattable via ``std::ostream`` you should provide a +``formatter`` specialization inherited from ``ostream_formatter``: #include @@ -507,14 +509,11 @@ user-defined types that have an overloaded insertion operator (``operator<<``):: } }; - template <> struct fmt::formatter : ostream_formatter {}; + template <> struct fmt::formatter : ostream_formatter {}; std::string s = fmt::format("The date is {}", date(2012, 12, 9)); // s == "The date is 2012-12-9" -{fmt} only supports insertion operators that are defined in the same namespaces -as the types they format and can be found with the argument-dependent lookup. - .. doxygenfunction:: print(std::basic_ostream &os, const S &format_str, Args&&... args) .. _printf-api: diff --git a/include/fmt/core.h b/include/fmt/core.h index 4dc83ddf..ffc2ff3d 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1431,8 +1431,8 @@ template struct arg_mapper { !std::is_const>::value || has_fallback_formatter::value> {}; -#if FMT_MSC_VER != 0 && FMT_MSC_VER < 1910 - // Workaround a bug in MSVC. +#if (FMT_MSC_VER != 0 && FMT_MSC_VER < 1910) || FMT_ICC_VERSION != 0 + // Workaround a bug in MSVC and Intel (Issue 2746). template FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& { return val; } @@ -2282,7 +2282,7 @@ FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, FMT_ASSERT(begin != end, ""); auto align = align::none; auto p = begin + code_point_length(begin); - if (p >= end) p = begin; + if (end - p <= 0) p = begin; for (;;) { switch (to_ascii(*p)) { case '<': diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 9fdfabc0..2de95610 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -304,7 +304,8 @@ struct formatter::value>> { } template - auto format(const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) { + auto format(const TupleT& values, FormatContext& ctx) const + -> decltype(ctx.out()) { auto out = ctx.out(); *out++ = '('; detail::for_each(values, format_each{0, out}); @@ -385,7 +386,7 @@ struct formatter< FMT_ENABLE_IF( std::is_same::value, const R, R>>::value)> - auto format(U& range, FormatContext& ctx) -> decltype(ctx.out()) { + auto format(U& range, FormatContext& ctx) const -> decltype(ctx.out()) { #ifdef FMT_DEPRECATED_BRACED_RANGES Char prefix = '{'; Char postfix = '}'; @@ -435,7 +436,7 @@ struct formatter< FMT_ENABLE_IF( std::is_same::value, const T, T>>::value)> - auto format(U& map, FormatContext& ctx) -> decltype(ctx.out()) { + auto format(U& map, FormatContext& ctx) const -> decltype(ctx.out()) { auto out = ctx.out(); *out++ = '{'; int i = 0;