diff --git a/include/fmt/format.h b/include/fmt/format.h index 8d422fbd..e14658da 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -184,7 +184,7 @@ namespace detail { # endif # endif -inline int clz(uint32_t x) { +inline auto clz(uint32_t x) -> int { unsigned long r = 0; _BitScanReverse(&r, x); FMT_ASSERT(x != 0, ""); @@ -196,7 +196,7 @@ inline int clz(uint32_t x) { } # define FMT_BUILTIN_CLZ(n) detail::clz(n) -inline int clzll(uint64_t x) { +inline auto clzll(uint64_t x) -> int { unsigned long r = 0; # ifdef _WIN64 _BitScanReverse64(&r, x); @@ -212,7 +212,7 @@ inline int clzll(uint64_t x) { } # define FMT_BUILTIN_CLZLL(n) detail::clzll(n) -inline int ctz(uint32_t x) { +inline auto ctz(uint32_t x) -> int { unsigned long r = 0; _BitScanForward(&r, x); FMT_ASSERT(x != 0, ""); @@ -221,7 +221,7 @@ inline int ctz(uint32_t x) { } # define FMT_BUILTIN_CTZ(n) detail::ctz(n) -inline int ctzll(uint64_t x) { +inline auto ctzll(uint64_t x) -> int { unsigned long r = 0; FMT_ASSERT(x != 0, ""); FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. @@ -258,14 +258,14 @@ namespace detail { // undefined behavior (e.g. due to type aliasing). // Example: uint64_t d = bit_cast(2.718); template -inline Dest bit_cast(const Source& source) { +inline auto bit_cast(const Source& source) -> Dest { static_assert(sizeof(Dest) == sizeof(Source), "size mismatch"); Dest dest; std::memcpy(&dest, &source, sizeof(dest)); return dest; } -inline bool is_big_endian() { +inline auto is_big_endian() -> bool { const auto u = 1u; struct bytes { char data[sizeof(u)]; @@ -288,26 +288,28 @@ struct fallback_uintptr { }; #ifdef UINTPTR_MAX using uintptr_t = ::uintptr_t; -inline uintptr_t to_uintptr(const void* p) { return bit_cast(p); } +inline auto to_uintptr(const void* p) -> uintptr_t { + return bit_cast(p); +} #else using uintptr_t = fallback_uintptr; -inline fallback_uintptr to_uintptr(const void* p) { +inline auto to_uintptr(const void* p) -> fallback_uintptr { return fallback_uintptr(p); } #endif // Returns the largest possible value for type T. Same as // std::numeric_limits::max() but shorter and not affected by the max macro. -template constexpr T max_value() { +template constexpr auto max_value() -> T { return (std::numeric_limits::max)(); } -template constexpr int num_bits() { +template constexpr auto num_bits() -> int { return std::numeric_limits::digits; } // std::numeric_limits::digits may return 0 for 128-bit ints. -template <> constexpr int num_bits() { return 128; } -template <> constexpr int num_bits() { return 128; } -template <> constexpr int num_bits() { +template <> constexpr auto num_bits() -> int { return 128; } +template <> constexpr auto num_bits() -> int { return 128; } +template <> constexpr auto num_bits() -> int { return static_cast(sizeof(void*) * std::numeric_limits::digits); } @@ -325,23 +327,24 @@ using iterator_t = decltype(std::begin(std::declval())); template using sentinel_t = decltype(std::end(std::declval())); // A workaround for std::string not having mutable data() until C++17. -template inline Char* get_data(std::basic_string& s) { +template +inline auto get_data(std::basic_string& s) -> Char* { return &s[0]; } template -inline typename Container::value_type* get_data(Container& c) { +inline auto get_data(Container& c) -> typename Container::value_type* { return c.data(); } #if defined(_SECURE_SCL) && _SECURE_SCL // Make a checked iterator to avoid MSVC warnings. template using checked_ptr = stdext::checked_array_iterator; -template checked_ptr make_checked(T* p, size_t size) { +template auto make_checked(T* p, size_t size) -> checked_ptr { return {p, size}; } #else template using checked_ptr = T*; -template inline T* make_checked(T* p, size_t) { return p; } +template inline auto make_checked(T* p, size_t) -> T* { return p; } #endif // Attempts to reserve space for n extra characters in the output range. @@ -350,8 +353,9 @@ template ::value)> #if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION __attribute__((no_sanitize("undefined"))) #endif -inline checked_ptr -reserve(std::back_insert_iterator it, size_t n) { +inline auto +reserve(std::back_insert_iterator it, size_t n) + -> checked_ptr { Container& c = get_container(it); size_t size = c.size(); c.resize(size + n); @@ -359,13 +363,14 @@ reserve(std::back_insert_iterator it, size_t n) { } template -inline buffer_appender reserve(buffer_appender it, size_t n) { +inline auto reserve(buffer_appender it, size_t n) -> buffer_appender { buffer& buf = get_container(it); buf.try_reserve(buf.size() + n); return it; } -template constexpr Iterator& reserve(Iterator& it, size_t) { +template +constexpr auto reserve(Iterator& it, size_t) -> Iterator& { return it; } @@ -374,10 +379,10 @@ using reserve_iterator = remove_reference_t(), 0))>; template -constexpr T* to_pointer(OutputIt, size_t) { +constexpr auto to_pointer(OutputIt, size_t) -> T* { return nullptr; } -template T* to_pointer(buffer_appender it, size_t n) { +template auto to_pointer(buffer_appender it, size_t n) -> T* { buffer& buf = get_container(it); auto size = buf.size(); if (buf.capacity() < size + n) return nullptr; @@ -386,26 +391,27 @@ template T* to_pointer(buffer_appender it, size_t n) { } template ::value)> -inline std::back_insert_iterator base_iterator( - std::back_insert_iterator& it, - checked_ptr) { +inline auto base_iterator(std::back_insert_iterator& it, + checked_ptr) + -> std::back_insert_iterator { return it; } template -constexpr Iterator base_iterator(Iterator, Iterator it) { +constexpr auto base_iterator(Iterator, Iterator it) -> Iterator { return it; } // is spectacularly slow to compile in C++20 so use a simple fill_n // instead (#1998). template -FMT_CONSTEXPR OutputIt fill_n(OutputIt out, Size count, const T& value) { +FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value) + -> OutputIt { for (Size i = 0; i < count; ++i) *out++ = value; return out; } template -FMT_CONSTEXPR20 T* fill_n(T* out, Size count, char value) { +FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* { if (is_constant_evaluated()) { return fill_n(out, count, value); } @@ -427,14 +433,16 @@ using needs_conversion = bool_constant< template ::value)> -FMT_CONSTEXPR OutputIt copy_str(InputIt begin, InputIt end, OutputIt out) { +FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out) + -> OutputIt { while (begin != end) *out++ = *begin++; return out; } template ::value)> -FMT_CONSTEXPR20 OutChar* copy_str(InputIt begin, InputIt end, OutChar* out) { +FMT_CONSTEXPR20 auto copy_str(InputIt begin, InputIt end, OutChar* out) + -> OutChar* { if (is_constant_evaluated()) { return copy_str(begin, end, out); } @@ -445,22 +453,21 @@ FMT_CONSTEXPR20 OutChar* copy_str(InputIt begin, InputIt end, OutChar* out) { template ::value)> -OutputIt copy_str(InputIt begin, InputIt end, OutputIt out) { +auto copy_str(InputIt begin, InputIt end, OutputIt out) -> OutputIt { while (begin != end) *out++ = static_cast(*begin++); return out; } template ::value)> -appender copy_str(InputIt begin, InputIt end, appender out) { +auto copy_str(InputIt begin, InputIt end, appender out) -> appender { get_container(out).append(begin, end); return out; } template -FMT_CONSTEXPR FMT_NOINLINE OutputIt copy_str_noinline(InputIt begin, - InputIt end, - OutputIt out) { +FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end, + OutputIt out) -> OutputIt { return copy_str(begin, end, out); } @@ -481,8 +488,8 @@ FMT_CONSTEXPR FMT_NOINLINE OutputIt copy_str_noinline(InputIt begin, * occurs, this pointer will be a guess that depends on the particular * error, but it will always advance at least one byte. */ -FMT_CONSTEXPR inline const char* utf8_decode(const char* s, uint32_t* c, - int* e) { +FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e) + -> const char* { constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07}; constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536}; constexpr const int shiftc[] = {0, 18, 12, 6, 0}; @@ -538,7 +545,7 @@ FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) { } template -inline size_t compute_width(basic_string_view s) { +inline auto compute_width(basic_string_view s) -> size_t { return s.size(); } @@ -575,19 +582,20 @@ FMT_CONSTEXPR inline size_t compute_width(string_view s) { return num_code_points; } -inline size_t compute_width(basic_string_view s) { +inline auto compute_width(basic_string_view s) -> size_t { return compute_width(basic_string_view( reinterpret_cast(s.data()), s.size())); } template -inline size_t code_point_index(basic_string_view s, size_t n) { +inline auto code_point_index(basic_string_view s, size_t n) -> size_t { size_t size = s.size(); return n < size ? n : size; } // Calculates the index of the nth code point in a UTF-8 string. -inline size_t code_point_index(basic_string_view s, size_t n) { +inline auto code_point_index(basic_string_view s, size_t n) + -> size_t { const char8_type* data = s.data(); size_t num_code_points = 0; for (size_t i = 0, size = s.size(); i != size; ++i) { @@ -724,7 +732,8 @@ class basic_memory_buffer final : public detail::buffer { Moves the content of the other ``basic_memory_buffer`` object to this one. \endrst */ - basic_memory_buffer& operator=(basic_memory_buffer&& other) FMT_NOEXCEPT { + auto operator=(basic_memory_buffer&& other) FMT_NOEXCEPT + -> basic_memory_buffer& { FMT_ASSERT(this != &other, ""); deallocate(); move(other); @@ -732,7 +741,7 @@ class basic_memory_buffer final : public detail::buffer { } // Returns a copy of the allocator associated with this buffer. - Allocator get_allocator() const { return alloc_; } + auto get_allocator() const -> Allocator { return alloc_; } /** Resizes the buffer to contain *count* elements. If T is a POD type new @@ -839,16 +848,16 @@ using is_signed = // Returns true if value is negative, false otherwise. // Same as `value < 0` but doesn't produce warnings if T is an unsigned type. template ::value)> -FMT_CONSTEXPR bool is_negative(T value) { +FMT_CONSTEXPR auto is_negative(T value) -> bool { return value < 0; } template ::value)> -FMT_CONSTEXPR bool is_negative(T) { +FMT_CONSTEXPR auto is_negative(T) -> bool { return false; } template ::value)> -FMT_CONSTEXPR bool is_supported_floating_point(T) { +FMT_CONSTEXPR auto is_supported_floating_point(T) -> uint16_t { return (std::is_same::value && FMT_USE_FLOAT) || (std::is_same::value && FMT_USE_DOUBLE) || (std::is_same::value && FMT_USE_LONG_DOUBLE); @@ -912,7 +921,7 @@ struct data : basic_data<> {}; // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)). // This is a function instead of an array to workaround a bug in GCC10 (#1810). -FMT_INLINE uint16_t bsr2log10(int bsr) { +FMT_INLINE auto bsr2log10(int bsr) -> uint16_t { static constexpr uint16_t data[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, @@ -921,7 +930,7 @@ FMT_INLINE uint16_t bsr2log10(int bsr) { return data[bsr]; } -template FMT_CONSTEXPR int count_digits_fallback(T n) { +template FMT_CONSTEXPR auto count_digits_fallback(T n) -> int { int count = 1; for (;;) { // Integer division is slow so do it for a group of four digits instead @@ -936,14 +945,14 @@ template FMT_CONSTEXPR int count_digits_fallback(T n) { } } #if FMT_USE_INT128 -FMT_CONSTEXPR inline int count_digits(uint128_t n) { +FMT_CONSTEXPR inline auto count_digits(uint128_t n) -> int { return count_digits_fallback(n); } #endif // Returns the number of decimal digits in n. Leading zeros are not counted // except for n == 0 in which case count_digits returns 1. -FMT_CONSTEXPR20 inline int count_digits(uint64_t n) { +FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int { if (is_constant_evaluated()) { return count_digits_fallback(n); } @@ -960,7 +969,8 @@ FMT_CONSTEXPR20 inline int count_digits(uint64_t n) { } // Counts the number of digits in n. BITS = log2(radix). -template FMT_CONSTEXPR int count_digits(UInt n) { +template +FMT_CONSTEXPR auto count_digits(UInt n) -> int { #ifdef FMT_BUILTIN_CLZ if (num_bits() == 32) return (FMT_BUILTIN_CLZ(static_cast(n) | 1) ^ 31) / BITS + 1; @@ -972,7 +982,7 @@ template FMT_CONSTEXPR int count_digits(UInt n) { return num_digits; } -template <> int count_digits<4>(detail::fallback_uintptr n); +template <> auto count_digits<4>(detail::fallback_uintptr n) -> int; #if FMT_GCC_VERSION || FMT_CLANG_VERSION # define FMT_ALWAYS_INLINE inline __attribute__((always_inline)) @@ -984,7 +994,7 @@ template <> int count_digits<4>(detail::fallback_uintptr n); #ifdef FMT_BUILTIN_CLZ // Optional version of count_digits for better performance on 32-bit platforms. -FMT_CONSTEXPR20 inline int count_digits(uint32_t n) { +FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int { if (is_constant_evaluated()) { return count_digits_fallback(n); } @@ -995,42 +1005,49 @@ FMT_CONSTEXPR20 inline int count_digits(uint32_t n) { } #endif -template constexpr int digits10() FMT_NOEXCEPT { +template constexpr auto digits10() FMT_NOEXCEPT -> int { return std::numeric_limits::digits10; } -template <> constexpr int digits10() FMT_NOEXCEPT { return 38; } -template <> constexpr int digits10() FMT_NOEXCEPT { return 38; } +template <> constexpr auto digits10() FMT_NOEXCEPT -> int { + return 38; +} +template <> constexpr auto digits10() FMT_NOEXCEPT -> int { + return 38; +} // DEPRECATED! grouping will be merged into thousands_sep. -template FMT_API std::string grouping_impl(locale_ref loc); -template inline std::string grouping(locale_ref loc) { +template +FMT_API auto grouping_impl(locale_ref loc) -> std::string; +template inline auto grouping(locale_ref loc) -> std::string { return grouping_impl(loc); } -template <> inline std::string grouping(locale_ref loc) { +template <> inline auto grouping(locale_ref loc) -> std::string { return grouping_impl(loc); } -template FMT_API Char thousands_sep_impl(locale_ref loc); -template inline Char thousands_sep(locale_ref loc) { +template +FMT_API auto thousands_sep_impl(locale_ref loc) -> Char; +template inline auto thousands_sep(locale_ref loc) -> Char { return Char(thousands_sep_impl(loc)); } -template <> inline wchar_t thousands_sep(locale_ref loc) { +template <> inline auto thousands_sep(locale_ref loc) -> wchar_t { return thousands_sep_impl(loc); } -template FMT_API Char decimal_point_impl(locale_ref loc); -template inline Char decimal_point(locale_ref loc) { +template +FMT_API auto decimal_point_impl(locale_ref loc) -> Char; +template inline auto decimal_point(locale_ref loc) -> Char { return Char(decimal_point_impl(loc)); } -template <> inline wchar_t decimal_point(locale_ref loc) { +template <> inline auto decimal_point(locale_ref loc) -> wchar_t { return decimal_point_impl(loc); } // Compares two characters for equality. -template bool equal2(const Char* lhs, const char* rhs) { +template auto equal2(const Char* lhs, const char* rhs) -> bool { return lhs[0] == rhs[0] && lhs[1] == rhs[1]; } -inline bool equal2(const char* lhs, const char* rhs) { +inline auto equal2(const char* lhs, const char* rhs) -> bool { return memcmp(lhs, rhs, 2) == 0; } @@ -1050,9 +1067,8 @@ template struct format_decimal_result { // buffer of specified size. The caller must ensure that the buffer is large // enough. template -FMT_CONSTEXPR20 format_decimal_result format_decimal(Char* out, - UInt value, - int size) { +FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size) + -> format_decimal_result { FMT_ASSERT(size >= count_digits(value), "invalid digit count"); out += size; Char* end = out; @@ -1083,8 +1099,8 @@ FMT_CONSTEXPR20 format_decimal_result format_decimal(Char* out, template >::value)> -inline format_decimal_result format_decimal(Iterator out, UInt value, - int size) { +inline auto format_decimal(Iterator out, UInt value, int size) + -> format_decimal_result { // Buffer is large enough to hold all digits (digits10 + 1). Char buffer[digits10() + 1]; auto end = format_decimal(buffer, value, size).end; @@ -1092,8 +1108,8 @@ inline format_decimal_result format_decimal(Iterator out, UInt value, } template -FMT_CONSTEXPR Char* format_uint(Char* buffer, UInt value, int num_digits, - bool upper = false) { +FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits, + bool upper = false) -> Char* { buffer += num_digits; Char* end = buffer; do { @@ -1106,8 +1122,8 @@ FMT_CONSTEXPR Char* format_uint(Char* buffer, UInt value, int num_digits, } template -Char* format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits, - bool = false) { +auto format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits, + bool = false) -> Char* { auto char_digits = std::numeric_limits::digits / 4; int start = (num_digits + char_digits - 1) / char_digits - 1; if (int start_digits = num_digits % char_digits) { @@ -1128,7 +1144,8 @@ Char* format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits, } template -inline It format_uint(It out, UInt value, int num_digits, bool upper = false) { +inline auto format_uint(It out, UInt value, int num_digits, bool upper = false) + -> It { if (auto ptr = to_pointer(out, to_unsigned(num_digits))) { format_uint(ptr, value, num_digits, upper); return out; @@ -1147,9 +1164,9 @@ class utf8_to_utf16 { public: FMT_API explicit utf8_to_utf16(string_view s); operator basic_string_view() const { return {&buffer_[0], size()}; } - size_t size() const { return buffer_.size() - 1; } - const wchar_t* c_str() const { return &buffer_[0]; } - std::wstring str() const { return {&buffer_[0], size()}; } + auto size() const -> size_t { return buffer_.size() - 1; } + auto c_str() const -> const wchar_t* { return &buffer_[0]; } + auto str() const -> std::wstring { return {&buffer_[0], size()}; } }; namespace dragonbox { @@ -1215,18 +1232,21 @@ template struct decimal_fp { int exponent; }; -template FMT_API decimal_fp to_decimal(T x) FMT_NOEXCEPT; +template +FMT_API auto to_decimal(T x) FMT_NOEXCEPT -> decimal_fp; } // namespace dragonbox template -constexpr typename dragonbox::float_info::carrier_uint exponent_mask() { +constexpr auto exponent_mask() -> + typename dragonbox::float_info::carrier_uint { using uint = typename dragonbox::float_info::carrier_uint; return ((uint(1) << dragonbox::float_info::exponent_bits) - 1) << dragonbox::float_info::significand_bits; } // Writes the exponent exp in the form "[+-]d{2,3}" to buffer. -template It write_exponent(int exp, It it) { +template +auto write_exponent(int exp, It it) -> It { FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range"); if (exp < 0) { *it++ = static_cast('-'); @@ -1247,19 +1267,22 @@ template It write_exponent(int exp, It it) { } template -int format_float(T value, int precision, float_specs specs, buffer& buf); +auto format_float(T value, int precision, float_specs specs, buffer& buf) + -> int; // Formats a floating-point number with snprintf. template -int snprintf_float(T value, int precision, float_specs specs, - buffer& buf); +auto snprintf_float(T value, int precision, float_specs specs, + buffer& buf) -> int; -template T promote_float(T value) { return value; } -inline double promote_float(float value) { return static_cast(value); } +template auto promote_float(T value) -> T { return value; } +inline auto promote_float(float value) -> double { + return static_cast(value); +} template -FMT_NOINLINE FMT_CONSTEXPR OutputIt fill(OutputIt it, size_t n, - const fill_t& fill) { +FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, + const fill_t& fill) -> OutputIt { auto fill_size = fill.size(); if (fill_size == 1) return detail::fill_n(it, n, fill[0]); auto data = fill.data(); @@ -1273,9 +1296,9 @@ FMT_NOINLINE FMT_CONSTEXPR OutputIt fill(OutputIt it, size_t n, // width: output display width in (terminal) column positions. template -FMT_CONSTEXPR OutputIt write_padded(OutputIt out, - const basic_format_specs& specs, - size_t size, size_t width, F&& f) { +FMT_CONSTEXPR auto write_padded(OutputIt out, + const basic_format_specs& specs, + size_t size, size_t width, F&& f) -> OutputIt { static_assert(align == align::left || align == align::right, ""); unsigned spec_width = to_unsigned(specs.width); size_t padding = spec_width > width ? spec_width - width : 0; @@ -1292,15 +1315,15 @@ FMT_CONSTEXPR OutputIt write_padded(OutputIt out, template -constexpr OutputIt write_padded(OutputIt out, - const basic_format_specs& specs, - size_t size, F&& f) { +constexpr auto write_padded(OutputIt out, const basic_format_specs& specs, + size_t size, F&& f) -> OutputIt { return write_padded(out, specs, size, size, f); } template -FMT_CONSTEXPR OutputIt write_bytes(OutputIt out, string_view bytes, - const basic_format_specs& specs) { +FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, + const basic_format_specs& specs) + -> OutputIt { return write_padded( out, specs, bytes.size(), [bytes](reserve_iterator it) { const char* data = bytes.data(); @@ -1309,8 +1332,8 @@ FMT_CONSTEXPR OutputIt write_bytes(OutputIt out, string_view bytes, } template -OutputIt write_ptr(OutputIt out, UIntPtr value, - const basic_format_specs* specs) { +auto write_ptr(OutputIt out, UIntPtr value, + const basic_format_specs* specs) -> OutputIt { int num_digits = count_digits<4>(value); auto size = to_unsigned(num_digits) + size_t(2); auto write = [=](reserve_iterator it) { @@ -1323,17 +1346,18 @@ OutputIt write_ptr(OutputIt out, UIntPtr value, } template -FMT_CONSTEXPR OutputIt write_char(OutputIt out, Char value, - const basic_format_specs& specs) { +FMT_CONSTEXPR auto write_char(OutputIt out, Char value, + const basic_format_specs& specs) + -> OutputIt { return write_padded(out, specs, 1, [=](reserve_iterator it) { *it++ = value; return it; }); } template -FMT_CONSTEXPR OutputIt write(OutputIt out, Char value, - const basic_format_specs& specs, - locale_ref loc = {}) { +FMT_CONSTEXPR auto write(OutputIt out, Char value, + const basic_format_specs& specs, + locale_ref loc = {}) -> OutputIt { return check_char_specs(specs) ? write_char(out, value, specs) : write(out, static_cast(value), specs, loc); @@ -1366,9 +1390,10 @@ template struct write_int_data { // where are written by write_digits(it). // prefix contains chars in three lower bytes and the size in the fourth byte. template -FMT_CONSTEXPR FMT_INLINE OutputIt -write_int(OutputIt out, int num_digits, unsigned prefix, - const basic_format_specs& specs, W write_digits) { +FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits, + unsigned prefix, + const basic_format_specs& specs, + W write_digits) -> OutputIt { // Slightly faster check for specs.width == 0 && specs.precision == -1. if ((specs.width | (specs.precision + 1)) == 0) { auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24)); @@ -1389,9 +1414,9 @@ write_int(OutputIt out, int num_digits, unsigned prefix, } template -bool write_int_localized(OutputIt& out, UInt value, unsigned prefix, - const basic_format_specs& specs, - locale_ref loc) { +auto write_int_localized(OutputIt& out, UInt value, unsigned prefix, + const basic_format_specs& specs, locale_ref loc) + -> bool { static_assert(std::is_same, UInt>::value, ""); const auto sep_size = 1; std::string groups = grouping(loc); @@ -1530,9 +1555,9 @@ template ::value && !std::is_same::value && std::is_same>::value)> -FMT_CONSTEXPR OutputIt write(OutputIt out, T value, - const basic_format_specs& specs, - locale_ref loc) { +FMT_CONSTEXPR auto write(OutputIt out, T value, + const basic_format_specs& specs, locale_ref loc) + -> OutputIt { return write_int(out, make_write_int_arg(value, specs.sign), specs, loc); } // An inlined version of write used in format string compilation. @@ -1540,15 +1565,15 @@ template ::value && !std::is_same::value && !std::is_same>::value)> -FMT_CONSTEXPR FMT_INLINE OutputIt write(OutputIt out, T value, - const basic_format_specs& specs, - locale_ref loc) { +FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, + const basic_format_specs& specs, + locale_ref loc) -> OutputIt { return write_int(out, make_write_int_arg(value, specs.sign), specs, loc); } template -FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view s, - const basic_format_specs& specs) { +FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, + const basic_format_specs& specs) -> OutputIt { auto data = s.data(); auto size = s.size(); if (specs.precision >= 0 && to_unsigned(specs.precision) < size) @@ -1561,25 +1586,24 @@ FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view s, }); } template -FMT_CONSTEXPR OutputIt write(OutputIt out, - basic_string_view> s, - const basic_format_specs& specs, - locale_ref) { +FMT_CONSTEXPR auto write(OutputIt out, + basic_string_view> s, + const basic_format_specs& specs, locale_ref) + -> OutputIt { return write(out, s, specs); } template -FMT_CONSTEXPR OutputIt write(OutputIt out, const Char* s, - const basic_format_specs& specs, - locale_ref) { +FMT_CONSTEXPR auto write(OutputIt out, const Char* s, + const basic_format_specs& specs, locale_ref) + -> OutputIt { return check_cstring_type_spec(specs.type) ? write(out, basic_string_view(s), specs, {}) : write_ptr(out, to_uintptr(s), &specs); } template -OutputIt write_nonfinite(OutputIt out, bool isinf, - basic_format_specs specs, - const float_specs& fspecs) { +auto write_nonfinite(OutputIt out, bool isinf, basic_format_specs specs, + const float_specs& fspecs) -> OutputIt { auto str = isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan"); constexpr size_t str_size = 3; @@ -1602,30 +1626,29 @@ struct big_decimal_fp { int exponent; }; -inline int get_significand_size(const big_decimal_fp& fp) { +inline auto get_significand_size(const big_decimal_fp& fp) -> int { return fp.significand_size; } template -inline int get_significand_size(const dragonbox::decimal_fp& fp) { +inline auto get_significand_size(const dragonbox::decimal_fp& fp) -> int { return count_digits(fp.significand); } template -inline OutputIt write_significand(OutputIt out, const char* significand, - int& significand_size) { +inline auto write_significand(OutputIt out, const char* significand, + int& significand_size) -> OutputIt { return copy_str(significand, significand + significand_size, out); } template -inline OutputIt write_significand(OutputIt out, UInt significand, - int significand_size) { +inline auto write_significand(OutputIt out, UInt significand, + int significand_size) -> OutputIt { return format_decimal(out, significand, significand_size).end; } template ::value)> -inline Char* write_significand(Char* out, UInt significand, - int significand_size, int integral_size, - Char decimal_point) { +inline auto write_significand(Char* out, UInt significand, int significand_size, + int integral_size, Char decimal_point) -> Char* { if (!decimal_point) return format_decimal(out, significand, significand_size).end; auto end = format_decimal(out + 1, significand, significand_size).end; @@ -1641,9 +1664,9 @@ inline Char* write_significand(Char* out, UInt significand, template >::value)> -inline OutputIt write_significand(OutputIt out, UInt significand, - int significand_size, int integral_size, - Char decimal_point) { +inline auto write_significand(OutputIt out, UInt significand, + int significand_size, int integral_size, + Char decimal_point) -> OutputIt { // Buffer is large enough to hold digits (digits10 + 1) and a decimal point. Char buffer[digits10() + 2]; auto end = write_significand(buffer, significand, significand_size, @@ -1652,9 +1675,9 @@ inline OutputIt write_significand(OutputIt out, UInt significand, } template -inline OutputIt write_significand(OutputIt out, const char* significand, - int significand_size, int integral_size, - Char decimal_point) { +inline auto write_significand(OutputIt out, const char* significand, + int significand_size, int integral_size, + Char decimal_point) -> OutputIt { out = detail::copy_str_noinline(significand, significand + integral_size, out); if (!decimal_point) return out; @@ -1664,9 +1687,9 @@ inline OutputIt write_significand(OutputIt out, const char* significand, } template -OutputIt write_float(OutputIt out, const DecimalFP& fp, - const basic_format_specs& specs, float_specs fspecs, - Char decimal_point) { +auto write_float(OutputIt out, const DecimalFP& fp, + const basic_format_specs& specs, float_specs fspecs, + Char decimal_point) -> OutputIt { auto significand = fp.significand; int significand_size = get_significand_size(fp); static const Char zero = static_cast('0'); @@ -1764,8 +1787,8 @@ OutputIt write_float(OutputIt out, const DecimalFP& fp, template ::value)> -OutputIt write(OutputIt out, T value, basic_format_specs specs, - locale_ref loc = {}) { +auto write(OutputIt out, T value, basic_format_specs specs, + locale_ref loc = {}) -> OutputIt { if (const_check(!is_supported_floating_point(value))) return out; float_specs fspecs = parse_float_type_spec(specs); fspecs.sign = specs.sign; @@ -1813,7 +1836,7 @@ OutputIt write(OutputIt out, T value, basic_format_specs specs, template ::value)> -OutputIt write(OutputIt out, T value) { +auto write(OutputIt out, T value) -> OutputIt { if (const_check(!is_supported_floating_point(value))) return out; using floaty = conditional_t::value, double, T>; @@ -1839,19 +1862,20 @@ OutputIt write(OutputIt out, T value) { template ::value && !is_fast_float::value)> -inline OutputIt write(OutputIt out, T value) { +inline auto write(OutputIt out, T value) -> OutputIt { return write(out, value, basic_format_specs()); } template -OutputIt write(OutputIt out, monostate, basic_format_specs = {}, - locale_ref = {}) { +auto write(OutputIt out, monostate, basic_format_specs = {}, + locale_ref = {}) -> OutputIt { FMT_ASSERT(false, ""); return out; } template -FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view value) { +FMT_CONSTEXPR auto write(OutputIt out, basic_string_view value) + -> OutputIt { auto it = reserve(out, value.size()); it = copy_str_noinline(value.begin(), value.end(), it); return base_iterator(out, it); @@ -1859,7 +1883,7 @@ FMT_CONSTEXPR OutputIt write(OutputIt out, basic_string_view value) { template ::value)> -constexpr OutputIt write(OutputIt out, const T& value) { +constexpr auto write(OutputIt out, const T& value) -> OutputIt { return write(out, to_string_view(value)); } @@ -1867,7 +1891,7 @@ template ::value && !std::is_same::value && !std::is_same::value)> -FMT_CONSTEXPR OutputIt write(OutputIt out, T value) { +FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { auto abs_value = static_cast>(value); bool negative = is_negative(value); // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer. @@ -1893,30 +1917,31 @@ template < mapped_type_constant>::value != type::custom_type, FMT_ENABLE_IF(check)> -FMT_CONSTEXPR OutputIt write(OutputIt out, T value) { +FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { return write( out, static_cast::type>(value)); } template ::value)> -FMT_CONSTEXPR OutputIt write(OutputIt out, T value, - const basic_format_specs& specs = {}, - locale_ref = {}) { +FMT_CONSTEXPR auto write(OutputIt out, T value, + const basic_format_specs& specs = {}, + locale_ref = {}) -> OutputIt { return specs.type && specs.type != 's' ? write(out, value ? 1 : 0, specs, {}) : write_bytes(out, value ? "true" : "false", specs); } template -FMT_CONSTEXPR OutputIt write(OutputIt out, Char value) { +FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt { auto it = reserve(out, 1); *it++ = value; return base_iterator(out, it); } template -FMT_CONSTEXPR_CHAR_TRAITS OutputIt write(OutputIt out, const Char* value) { +FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value) + -> OutputIt { if (!value) { FMT_THROW(format_error("string pointer is null")); } else { @@ -1928,8 +1953,9 @@ FMT_CONSTEXPR_CHAR_TRAITS OutputIt write(OutputIt out, const Char* value) { template ::value)> -OutputIt write(OutputIt out, const T* value, - const basic_format_specs& specs = {}, locale_ref = {}) { +auto write(OutputIt out, const T* value, + const basic_format_specs& specs = {}, locale_ref = {}) + -> OutputIt { check_pointer_type_spec(specs.type, error_handler()); return write_ptr(out, to_uintptr(value), &specs); } @@ -2011,13 +2037,13 @@ template class width_checker { explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {} template ::value)> - FMT_CONSTEXPR unsigned long long operator()(T value) { + FMT_CONSTEXPR auto operator()(T value) -> unsigned long long { if (is_negative(value)) handler_.on_error("negative width"); return static_cast(value); } template ::value)> - FMT_CONSTEXPR unsigned long long operator()(T) { + FMT_CONSTEXPR auto operator()(T) -> unsigned long long { handler_.on_error("width is not integer"); return 0; } @@ -2031,13 +2057,13 @@ template class precision_checker { explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {} template ::value)> - FMT_CONSTEXPR unsigned long long operator()(T value) { + FMT_CONSTEXPR auto operator()(T value) -> unsigned long long { if (is_negative(value)) handler_.on_error("negative precision"); return static_cast(value); } template ::value)> - FMT_CONSTEXPR unsigned long long operator()(T) { + FMT_CONSTEXPR auto operator()(T) -> unsigned long long { handler_.on_error("precision is not integer"); return 0; } @@ -2048,14 +2074,15 @@ template class precision_checker { template