diff --git a/include/fmt/core.h b/include/fmt/core.h index f1561f8c..b2236b33 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -173,7 +173,7 @@ # if FMT_GCC_VERSION && FMT_USE_CONSTEXPR # define FMT_INLINE inline __attribute__((always_inline)) # else -# define FMT_INLINE +# define FMT_INLINE inline # endif #endif diff --git a/include/fmt/format.h b/include/fmt/format.h index 928227bd..45bcef12 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -288,6 +288,13 @@ template <> constexpr int num_bits() { std::numeric_limits::digits); } +FMT_INLINE void assume(bool condition) { + (void)condition; +#if FMT_HAS_BUILTIN(__builtin_assume) + __builtin_assume(condition); +#endif +} + // A workaround for gcc 4.8 to make void_t work in a SFINAE context. template struct void_t_impl { using type = void; }; @@ -2508,7 +2515,7 @@ template struct id_adapter { }; template -FMT_CONSTEXPR FMT_INLINE const Char* parse_replacement_field( +FMT_CONSTEXPR_DECL FMT_INLINE const Char* parse_replacement_field( const Char* begin, const Char* end, Handler&& handler) { ++begin; if (begin == end) return handler.on_error("invalid format string"), end; @@ -3349,7 +3356,9 @@ template inline std::wstring to_wstring(const T& value) { template std::basic_string to_string(const basic_memory_buffer& buf) { - return std::basic_string(buf.data(), buf.size()); + auto size = buf.size(); + detail::assume(size < std::basic_string().max_size()); + return std::basic_string(buf.data(), size); } template