diff --git a/include/fmt/format.h b/include/fmt/format.h index 18175bd6..f3b438e2 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2102,21 +2102,21 @@ struct id_adapter { Handler &handler; }; -template -FMT_CONSTEXPR InputIt find(InputIt first, InputIt last, const T &value) { - for (; first != last; ++first) { - if (*first == value) - return first; +// Return the result via the out param to workaround gcc bug 77539. +template +FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out) { + for (out = first; out != last; ++out) { + if (*out == value) + return true; } - return last; + return false; } template <> -inline const char *find( - const char *first, const char *last, const char &value) { - auto result = static_cast( - std::memchr(first, value, last - first)); - return result ? result : last; +inline bool find( + const char *first, const char *last, char value, const char *&out) { + out = static_cast(std::memchr(first, value, last - first)); + return out != FMT_NULL; } template @@ -2125,8 +2125,8 @@ FMT_CONSTEXPR void parse_format_string( struct writer { FMT_CONSTEXPR void operator()(const Char *begin, const Char *end) { for (;;) { - auto p = find(begin, end, '}'); - if (p == end) { + const Char *p = FMT_NULL; + if (!find(begin, end, '}', p)) { handler_.on_text(begin, end); return; } @@ -2146,8 +2146,8 @@ FMT_CONSTEXPR void parse_format_string( for (;;) { // Doing two passes with memchr (one for '{' and another for '}') is up to // 2.5x faster than the naive one-pass implementation on long format strings. - auto p = find(begin, end, '{'); - if (p == end) { + const Char *p = FMT_NULL; + if (!find(begin, end, '{', p)) { if (begin != end) write(begin, end); return; @@ -2176,6 +2176,8 @@ FMT_CONSTEXPR void parse_format_string( return; } begin = pointer_from(it) + 1; + if (begin == end) + return; } }