From fe2bf32e17ac9ad0c2dab8c8c26ddd85d49899fd Mon Sep 17 00:00:00 2001 From: Mauricio Vargas Sepulveda Date: Thu, 18 Sep 2025 21:34:41 -0400 Subject: [PATCH] simplify three false conditions for r_vector string (fix #431) --- inst/include/cpp11/r_vector.hpp | 14 +- inst/include/fmt/core.h | 1262 +++++++++++++++---------------- inst/include/fmt/format-inl.h | 485 ++++++------ inst/include/fmt/format.h | 1000 ++++++++++++------------ 4 files changed, 1311 insertions(+), 1450 deletions(-) diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index 576f4fe6..601f5d5b 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -1392,18 +1392,14 @@ inline SEXP r_vector::resize_names(SEXP x, R_xlen_t size) { } // namespace writable -// TODO: is there a better condition we could use, e.g. assert something true -// rather than three things false? -template -using is_container_but_not_sexp_or_string = typename std::enable_if< +// Ensure that C is not constructible from SEXP, and neither C nor T is a std::string +template ::type::value_type> +typename std::enable_if< !std::is_constructible::value && !std::is_same::type, std::string>::value && !std::is_same::type, std::string>::value, - typename std::decay::type>::type; - -template ::type::value_type> -// typename T = typename C::value_type> -is_container_but_not_sexp_or_string as_cpp(SEXP from) { + C>::type +as_cpp(SEXP from) { auto obj = cpp11::r_vector(from); return {obj.begin(), obj.end()}; } diff --git a/inst/include/fmt/core.h b/inst/include/fmt/core.h index 4c1f5e2c..26084206 100644 --- a/inst/include/fmt/core.h +++ b/inst/include/fmt/core.h @@ -19,62 +19,62 @@ #define FMT_VERSION 80000 #ifdef __clang__ -# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) +#define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) #else -# define FMT_CLANG_VERSION 0 +#define FMT_CLANG_VERSION 0 #endif #if defined(__GNUC__) && !defined(__clang__) -# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -# define FMT_GCC_PRAGMA(arg) _Pragma(arg) +#define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#define FMT_GCC_PRAGMA(arg) _Pragma(arg) #else -# define FMT_GCC_VERSION 0 -# define FMT_GCC_PRAGMA(arg) +#define FMT_GCC_VERSION 0 +#define FMT_GCC_PRAGMA(arg) #endif #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) -# define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION +#define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION #else -# define FMT_HAS_GXX_CXX11 0 +#define FMT_HAS_GXX_CXX11 0 #endif #if defined(__INTEL_COMPILER) -# define FMT_ICC_VERSION __INTEL_COMPILER +#define FMT_ICC_VERSION __INTEL_COMPILER #else -# define FMT_ICC_VERSION 0 +#define FMT_ICC_VERSION 0 #endif #ifdef __NVCC__ -# define FMT_NVCC __NVCC__ +#define FMT_NVCC __NVCC__ #else -# define FMT_NVCC 0 +#define FMT_NVCC 0 #endif #ifdef _MSC_VER -# define FMT_MSC_VER _MSC_VER -# define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__)) +#define FMT_MSC_VER _MSC_VER +#define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__)) #else -# define FMT_MSC_VER 0 -# define FMT_MSC_WARNING(...) +#define FMT_MSC_VER 0 +#define FMT_MSC_WARNING(...) #endif #ifdef __has_feature -# define FMT_HAS_FEATURE(x) __has_feature(x) +#define FMT_HAS_FEATURE(x) __has_feature(x) #else -# define FMT_HAS_FEATURE(x) 0 +#define FMT_HAS_FEATURE(x) 0 #endif #if defined(__has_include) && !defined(__INTELLISENSE__) && \ (!FMT_ICC_VERSION || FMT_ICC_VERSION >= 1600) -# define FMT_HAS_INCLUDE(x) __has_include(x) +#define FMT_HAS_INCLUDE(x) __has_include(x) #else -# define FMT_HAS_INCLUDE(x) 0 +#define FMT_HAS_INCLUDE(x) 0 #endif #ifdef __has_cpp_attribute -# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) #else -# define FMT_HAS_CPP_ATTRIBUTE(x) 0 +#define FMT_HAS_CPP_ATTRIBUTE(x) 0 #endif #define FMT_HAS_CPP14_ATTRIBUTE(attribute) \ @@ -86,224 +86,218 @@ // Check if relaxed C++14 constexpr is supported. // GCC doesn't allow throw in constexpr until version 6 (bug 67371). #ifndef FMT_USE_CONSTEXPR -# define FMT_USE_CONSTEXPR \ - (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \ - (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) && \ - !FMT_NVCC && !FMT_ICC_VERSION +#define FMT_USE_CONSTEXPR \ + (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \ + (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) && \ + !FMT_NVCC && !FMT_ICC_VERSION #endif #if FMT_USE_CONSTEXPR -# define FMT_CONSTEXPR constexpr -# define FMT_CONSTEXPR_DECL constexpr +#define FMT_CONSTEXPR constexpr +#define FMT_CONSTEXPR_DECL constexpr #else -# define FMT_CONSTEXPR -# define FMT_CONSTEXPR_DECL +#define FMT_CONSTEXPR +#define FMT_CONSTEXPR_DECL #endif // Check if constexpr std::char_traits<>::compare,length is supported. #if defined(__GLIBCXX__) -# if __cplusplus >= 201703L && defined(_GLIBCXX_RELEASE) && \ - _GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE. -# define FMT_CONSTEXPR_CHAR_TRAITS constexpr -# endif -#elif defined(_LIBCPP_VERSION) && __cplusplus >= 201703L && \ - _LIBCPP_VERSION >= 4000 -# define FMT_CONSTEXPR_CHAR_TRAITS constexpr +#if __cplusplus >= 201703L && defined(_GLIBCXX_RELEASE) && \ + _GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE. +#define FMT_CONSTEXPR_CHAR_TRAITS constexpr +#endif +#elif defined(_LIBCPP_VERSION) && __cplusplus >= 201703L && _LIBCPP_VERSION >= 4000 +#define FMT_CONSTEXPR_CHAR_TRAITS constexpr #elif FMT_MSC_VER >= 1914 && _MSVC_LANG >= 201703L -# define FMT_CONSTEXPR_CHAR_TRAITS constexpr +#define FMT_CONSTEXPR_CHAR_TRAITS constexpr #endif #ifndef FMT_CONSTEXPR_CHAR_TRAITS -# define FMT_CONSTEXPR_CHAR_TRAITS +#define FMT_CONSTEXPR_CHAR_TRAITS #endif #ifndef FMT_OVERRIDE -# if FMT_HAS_FEATURE(cxx_override_control) || \ - (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 -# define FMT_OVERRIDE override -# else -# define FMT_OVERRIDE -# endif +#if FMT_HAS_FEATURE(cxx_override_control) || \ + (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 +#define FMT_OVERRIDE override +#else +#define FMT_OVERRIDE +#endif #endif // Check if exceptions are disabled. #ifndef FMT_EXCEPTIONS -# if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \ - FMT_MSC_VER && !_HAS_EXCEPTIONS -# define FMT_EXCEPTIONS 0 -# else -# define FMT_EXCEPTIONS 1 -# endif +#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || FMT_MSC_VER && !_HAS_EXCEPTIONS +#define FMT_EXCEPTIONS 0 +#else +#define FMT_EXCEPTIONS 1 +#endif #endif // Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature). #ifndef FMT_USE_NOEXCEPT -# define FMT_USE_NOEXCEPT 0 +#define FMT_USE_NOEXCEPT 0 #endif #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 -# define FMT_DETECTED_NOEXCEPT noexcept -# define FMT_HAS_CXX11_NOEXCEPT 1 +#define FMT_DETECTED_NOEXCEPT noexcept +#define FMT_HAS_CXX11_NOEXCEPT 1 #else -# define FMT_DETECTED_NOEXCEPT throw() -# define FMT_HAS_CXX11_NOEXCEPT 0 +#define FMT_DETECTED_NOEXCEPT throw() +#define FMT_HAS_CXX11_NOEXCEPT 0 #endif #ifndef FMT_NOEXCEPT -# if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT -# define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT -# else -# define FMT_NOEXCEPT -# endif +#if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT +#define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT +#else +#define FMT_NOEXCEPT +#endif #endif // [[noreturn]] is disabled on MSVC and NVCC because of bogus unreachable code // warnings. -#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER && \ - !FMT_NVCC -# define FMT_NORETURN [[noreturn]] +#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER && !FMT_NVCC +#define FMT_NORETURN [[noreturn]] #else -# define FMT_NORETURN +#define FMT_NORETURN #endif #ifndef FMT_MAYBE_UNUSED -# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused) -# define FMT_MAYBE_UNUSED [[maybe_unused]] -# else -# define FMT_MAYBE_UNUSED -# endif +#if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused) +#define FMT_MAYBE_UNUSED [[maybe_unused]] +#else +#define FMT_MAYBE_UNUSED +#endif #endif #if __cplusplus == 201103L || __cplusplus == 201402L -# if defined(__INTEL_COMPILER) || defined(__PGI) -# define FMT_FALLTHROUGH -# elif defined(__clang__) -# define FMT_FALLTHROUGH [[clang::fallthrough]] -# elif FMT_GCC_VERSION >= 700 && \ - (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520) -# define FMT_FALLTHROUGH [[gnu::fallthrough]] -# else -# define FMT_FALLTHROUGH -# endif +#if defined(__INTEL_COMPILER) || defined(__PGI) +#define FMT_FALLTHROUGH +#elif defined(__clang__) +#define FMT_FALLTHROUGH [[clang::fallthrough]] +#elif FMT_GCC_VERSION >= 700 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520) +#define FMT_FALLTHROUGH [[gnu::fallthrough]] +#else +#define FMT_FALLTHROUGH +#endif #elif FMT_HAS_CPP17_ATTRIBUTE(fallthrough) || \ (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -# define FMT_FALLTHROUGH [[fallthrough]] +#define FMT_FALLTHROUGH [[fallthrough]] #else -# define FMT_FALLTHROUGH +#define FMT_FALLTHROUGH #endif #ifndef FMT_USE_FLOAT -# define FMT_USE_FLOAT 1 +#define FMT_USE_FLOAT 1 #endif #ifndef FMT_USE_DOUBLE -# define FMT_USE_DOUBLE 1 +#define FMT_USE_DOUBLE 1 #endif #ifndef FMT_USE_LONG_DOUBLE -# define FMT_USE_LONG_DOUBLE 1 +#define FMT_USE_LONG_DOUBLE 1 #endif #ifndef FMT_INLINE -# if FMT_GCC_VERSION || FMT_CLANG_VERSION -# define FMT_INLINE inline __attribute__((always_inline)) -# else -# define FMT_INLINE inline -# endif +#if FMT_GCC_VERSION || FMT_CLANG_VERSION +#define FMT_INLINE inline __attribute__((always_inline)) +#else +#define FMT_INLINE inline +#endif #endif #ifndef FMT_USE_INLINE_NAMESPACES -# if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \ - (FMT_MSC_VER >= 1900 && (!defined(_MANAGED) || !_MANAGED)) -# define FMT_USE_INLINE_NAMESPACES 1 -# else -# define FMT_USE_INLINE_NAMESPACES 0 -# endif +#if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \ + (FMT_MSC_VER >= 1900 && (!defined(_MANAGED) || !_MANAGED)) +#define FMT_USE_INLINE_NAMESPACES 1 +#else +#define FMT_USE_INLINE_NAMESPACES 0 +#endif #endif #ifndef FMT_BEGIN_NAMESPACE -# if FMT_USE_INLINE_NAMESPACES -# define FMT_INLINE_NAMESPACE inline namespace -# define FMT_END_NAMESPACE \ - } \ - } -# else -# define FMT_INLINE_NAMESPACE namespace -# define FMT_END_NAMESPACE \ - } \ - using namespace v7; \ - } -# endif -# define FMT_BEGIN_NAMESPACE \ - namespace fmt { \ - FMT_INLINE_NAMESPACE v7 { +#if FMT_USE_INLINE_NAMESPACES +#define FMT_INLINE_NAMESPACE inline namespace +#define FMT_END_NAMESPACE \ + } \ + } +#else +#define FMT_INLINE_NAMESPACE namespace +#define FMT_END_NAMESPACE \ + } \ + using namespace v7; \ + } +#endif +#define FMT_BEGIN_NAMESPACE \ + namespace fmt { \ + FMT_INLINE_NAMESPACE v7 { #endif #ifndef FMT_MODULE_EXPORT -# define FMT_MODULE_EXPORT -# define FMT_MODULE_EXPORT_BEGIN -# define FMT_MODULE_EXPORT_END -# define FMT_BEGIN_DETAIL_NAMESPACE namespace detail { -# define FMT_END_DETAIL_NAMESPACE } +#define FMT_MODULE_EXPORT +#define FMT_MODULE_EXPORT_BEGIN +#define FMT_MODULE_EXPORT_END +#define FMT_BEGIN_DETAIL_NAMESPACE namespace detail { +#define FMT_END_DETAIL_NAMESPACE } #endif #if !defined(FMT_HEADER_ONLY) && defined(_WIN32) -# define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275) -# ifdef FMT_EXPORT -# define FMT_API __declspec(dllexport) -# elif defined(FMT_SHARED) -# define FMT_API __declspec(dllimport) -# endif +#define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275) +#ifdef FMT_EXPORT +#define FMT_API __declspec(dllexport) +#elif defined(FMT_SHARED) +#define FMT_API __declspec(dllimport) +#endif #else -# define FMT_CLASS_API -# if defined(FMT_EXPORT) || defined(FMT_SHARED) -# if defined(__GNUC__) || defined(__clang__) -# define FMT_API __attribute__((visibility("default"))) -# endif -# endif +#define FMT_CLASS_API +#if defined(FMT_EXPORT) || defined(FMT_SHARED) +#if defined(__GNUC__) || defined(__clang__) +#define FMT_API __attribute__((visibility("default"))) +#endif +#endif #endif #ifndef FMT_API -# define FMT_API +#define FMT_API #endif #if FMT_GCC_VERSION -# define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) +#define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) #else -# define FMT_GCC_VISIBILITY_HIDDEN +#define FMT_GCC_VISIBILITY_HIDDEN #endif // libc++ supports string_view in pre-c++17. #if (FMT_HAS_INCLUDE() && \ (__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \ (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) -# include -# define FMT_USE_STRING_VIEW +#include +#define FMT_USE_STRING_VIEW #elif FMT_HAS_INCLUDE("experimental/string_view") && __cplusplus >= 201402L -# include -# define FMT_USE_EXPERIMENTAL_STRING_VIEW +#include +#define FMT_USE_EXPERIMENTAL_STRING_VIEW #endif #ifndef FMT_UNICODE -# define FMT_UNICODE !FMT_MSC_VER +#define FMT_UNICODE !FMT_MSC_VER #endif #ifndef FMT_CONSTEVAL -# if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \ - __cplusplus > 201703L) || \ - (defined(__cpp_consteval) && \ - !FMT_MSC_VER) // consteval is broken in MSVC. -# define FMT_CONSTEVAL consteval -# define FMT_HAS_CONSTEVAL -# else -# define FMT_CONSTEVAL -# endif +#if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && __cplusplus > 201703L) || \ + (defined(__cpp_consteval) && !FMT_MSC_VER) // consteval is broken in MSVC. +#define FMT_CONSTEVAL consteval +#define FMT_HAS_CONSTEVAL +#else +#define FMT_CONSTEVAL +#endif #endif #ifndef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS -# if defined(__cpp_nontype_template_args) && \ - ((FMT_GCC_VERSION >= 903 && __cplusplus >= 201709L) || \ - __cpp_nontype_template_args >= 201911L) -# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 1 -# else -# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 0 -# endif +#if defined(__cpp_nontype_template_args) && \ + ((FMT_GCC_VERSION >= 903 && __cplusplus >= 201709L) || \ + __cpp_nontype_template_args >= 201911L) +#define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 1 +#else +#define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 0 +#endif #endif // Enable minimal optimizations for more compact code in debug mode. @@ -320,13 +314,18 @@ template using enable_if_t = typename std::enable_if::type; template using conditional_t = typename std::conditional::type; -template using bool_constant = std::integral_constant; +template +using bool_constant = std::integral_constant; template using remove_reference_t = typename std::remove_reference::type; template using remove_cvref_t = typename std::remove_cv>::type; -template struct type_identity { using type = T; }; -template using type_identity_t = typename type_identity::type; +template +struct type_identity { + using type = T; +}; +template +using type_identity_t = typename type_identity::type; struct monostate { constexpr monostate() {} @@ -336,9 +335,9 @@ struct monostate { // shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed // to workaround a bug in MSVC 2019 (see #1140 and #1186). #ifdef FMT_DOC -# define FMT_ENABLE_IF(...) +#define FMT_ENABLE_IF(...) #else -# define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0 +#define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0 #endif FMT_BEGIN_DETAIL_NAMESPACE @@ -352,58 +351,62 @@ constexpr FMT_INLINE auto is_constant_evaluated() FMT_NOEXCEPT -> bool { } // A function to suppress "conditional expression is constant" warnings. -template constexpr auto const_check(T value) -> T { return value; } +template +constexpr auto const_check(T value) -> T { + return value; +} -FMT_NORETURN FMT_API void assert_fail(const char* file, int line, - const char* message); +FMT_NORETURN FMT_API void assert_fail(const char* file, int line, const char* message); #ifndef FMT_ASSERT -# ifdef NDEBUG +#ifdef NDEBUG // FMT_ASSERT is not empty to avoid -Werror=empty-body. -# define FMT_ASSERT(condition, message) ((void)0) -# else -# define FMT_ASSERT(condition, message) \ - ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \ - ? (void)0 \ - : ::fmt::detail::assert_fail(__FILE__, __LINE__, (message))) -# endif +#define FMT_ASSERT(condition, message) ((void)0) +#else +#define FMT_ASSERT(condition, message) \ + ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \ + ? (void)0 \ + : ::fmt::detail::assert_fail(__FILE__, __LINE__, (message))) +#endif #endif #if defined(FMT_USE_STRING_VIEW) -template using std_string_view = std::basic_string_view; +template +using std_string_view = std::basic_string_view; #elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW) template using std_string_view = std::experimental::basic_string_view; #else -template struct std_string_view {}; +template +struct std_string_view {}; #endif #ifdef FMT_USE_INT128 // Do nothing. -#elif defined(__SIZEOF_INT128__) && !FMT_NVCC && \ - !(FMT_CLANG_VERSION && FMT_MSC_VER) -# define FMT_USE_INT128 1 +#elif defined(__SIZEOF_INT128__) && !FMT_NVCC && !(FMT_CLANG_VERSION && FMT_MSC_VER) +#define FMT_USE_INT128 1 using int128_t = __int128_t; using uint128_t = __uint128_t; -template inline auto convert_for_visit(T value) -> T { +template +inline auto convert_for_visit(T value) -> T { return value; } #else -# define FMT_USE_INT128 0 +#define FMT_USE_INT128 0 #endif #if !FMT_USE_INT128 enum class int128_t {}; enum class uint128_t {}; // Reduce template instantiations. -template inline auto convert_for_visit(T) -> monostate { +template +inline auto convert_for_visit(T) -> monostate { return {}; } #endif // Casts a nonnegative integer to unsigned. template -FMT_CONSTEXPR auto to_unsigned(Int value) -> - typename std::make_unsigned::type { +FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned::type { FMT_ASSERT(value >= 0, "negative value"); return static_cast::type>(value); } @@ -414,8 +417,8 @@ constexpr auto is_utf8() -> bool { // Avoid buggy sign extensions in MSVC's constant evaluation mode. // https://developercommunity.visualstudio.com/t/C-difference-in-behavior-for-unsigned/1233612 using uchar = unsigned char; - return FMT_UNICODE || (sizeof(micro) == 3 && uchar(micro[0]) == 0xC2 && - uchar(micro[1]) == 0xB5); + return FMT_UNICODE || + (sizeof(micro) == 3 && uchar(micro[0]) == 0xC2 && uchar(micro[1]) == 0xB5); } FMT_END_DETAIL_NAMESPACE @@ -426,7 +429,8 @@ FMT_END_DETAIL_NAMESPACE compiled with a different ``-std`` option than the client code (which is not recommended). */ -template class basic_string_view { +template +class basic_string_view { private: const Char* data_; size_t size_; @@ -438,9 +442,8 @@ template class basic_string_view { constexpr basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {} /** Constructs a string reference object from a C string and a size. */ - constexpr basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT - : data_(s), - size_(count) {} + constexpr basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT : data_(s), + size_(count) {} /** \rst @@ -460,15 +463,13 @@ template class basic_string_view { /** Constructs a string reference from a ``std::basic_string`` object. */ template - FMT_CONSTEXPR basic_string_view( - const std::basic_string& s) FMT_NOEXCEPT - : data_(s.data()), - size_(s.size()) {} + FMT_CONSTEXPR basic_string_view(const std::basic_string& s) + FMT_NOEXCEPT : data_(s.data()), + size_(s.size()) {} - template >::value)> - FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT : data_(s.data()), - size_(s.size()) {} + template >::value)> + FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT : data_(s.data()), size_(s.size()) {} /** Returns a pointer to the string data. */ constexpr auto data() const -> const Char* { return data_; } @@ -479,9 +480,7 @@ template class basic_string_view { constexpr auto begin() const -> iterator { return data_; } constexpr auto end() const -> iterator { return data_ + size_; } - constexpr auto operator[](size_t pos) const -> const Char& { - return data_[pos]; - } + constexpr auto operator[](size_t pos) const -> const Char& { return data_[pos]; } FMT_CONSTEXPR void remove_prefix(size_t n) { data_ += n; @@ -492,14 +491,12 @@ template class basic_string_view { FMT_CONSTEXPR_CHAR_TRAITS auto compare(basic_string_view other) const -> int { size_t str_size = size_ < other.size_ ? size_ : other.size_; int result = std::char_traits::compare(data_, other.data_, str_size); - if (result == 0) - result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); + if (result == 0) result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); return result; } FMT_CONSTEXPR_CHAR_TRAITS friend auto operator==(basic_string_view lhs, - basic_string_view rhs) - -> bool { + basic_string_view rhs) -> bool { return lhs.compare(rhs) == 0; } friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool { @@ -522,8 +519,10 @@ template class basic_string_view { using string_view = basic_string_view; /** Specifies if ``T`` is a character type. Can be specialized by users. */ -template struct is_char : std::false_type {}; -template <> struct is_char : std::true_type {}; +template +struct is_char : std::false_type {}; +template <> +struct is_char : std::true_type {}; /** \rst @@ -553,15 +552,13 @@ inline auto to_string_view(const std::basic_string& s) } template -constexpr auto to_string_view(basic_string_view s) - -> basic_string_view { +constexpr auto to_string_view(basic_string_view s) -> basic_string_view { return s; } template >::value)> -inline auto to_string_view(detail::std_string_view s) - -> basic_string_view { +inline auto to_string_view(detail::std_string_view s) -> basic_string_view { return s; } @@ -573,8 +570,7 @@ template struct is_compile_string : std::is_base_of {}; template ::value)> -constexpr auto to_string_view(const S& s) - -> basic_string_view { +constexpr auto to_string_view(const S& s) -> basic_string_view { return basic_string_view(s); } @@ -587,11 +583,12 @@ using fmt::v7::to_string_view; // It should be a constexpr function but MSVC 2017 fails to compile it in // enable_if and MSVC 2015 fails to compile it as an alias template. template -struct is_string : std::is_class()))> { -}; +struct is_string : std::is_class()))> {}; -template struct char_t_impl {}; -template struct char_t_impl::value>> { +template +struct char_t_impl {}; +template +struct char_t_impl::value>> { using result = decltype(to_string_view(std::declval())); using type = typename result::value_type; }; @@ -618,7 +615,8 @@ struct error_handler { FMT_END_DETAIL_NAMESPACE /** String's character type. */ -template using char_t = typename detail::char_t_impl::type; +template +using char_t = typename detail::char_t_impl::type; /** \rst @@ -637,25 +635,20 @@ class basic_format_parse_context : private ErrorHandler { using char_type = Char; using iterator = typename basic_string_view::iterator; - explicit constexpr basic_format_parse_context( - basic_string_view format_str, ErrorHandler eh = {}, - int next_arg_id = 0) + explicit constexpr basic_format_parse_context(basic_string_view format_str, + ErrorHandler eh = {}, int next_arg_id = 0) : ErrorHandler(eh), format_str_(format_str), next_arg_id_(next_arg_id) {} /** Returns an iterator to the beginning of the format string range being parsed. */ - constexpr auto begin() const FMT_NOEXCEPT -> iterator { - return format_str_.begin(); - } + constexpr auto begin() const FMT_NOEXCEPT -> iterator { return format_str_.begin(); } /** Returns an iterator past the end of the format string range being parsed. */ - constexpr auto end() const FMT_NOEXCEPT -> iterator { - return format_str_.end(); - } + constexpr auto end() const FMT_NOEXCEPT -> iterator { return format_str_.end(); } /** Advances the begin iterator to ``it``. */ FMT_CONSTEXPR void advance_to(iterator it) { @@ -687,18 +680,19 @@ class basic_format_parse_context : private ErrorHandler { FMT_CONSTEXPR void check_arg_id(basic_string_view) {} - FMT_CONSTEXPR void on_error(const char* message) { - ErrorHandler::on_error(message); - } + FMT_CONSTEXPR void on_error(const char* message) { ErrorHandler::on_error(message); } constexpr auto error_handler() const -> ErrorHandler { return *this; } }; using format_parse_context = basic_format_parse_context; -template class basic_format_arg; -template class basic_format_args; -template class dynamic_format_arg_store; +template +class basic_format_arg; +template +class basic_format_args; +template +class dynamic_format_arg_store; // A formatter for objects of type T. template @@ -710,11 +704,11 @@ struct formatter { // Specifies if T has an enabled formatter specialization. A type can be // formattable even if it doesn't have a formatter e.g. via a conversion. template -using has_formatter = - std::is_constructible>; +using has_formatter = std::is_constructible>; // Checks whether T is a container with contiguous storage. -template struct is_contiguous : std::false_type {}; +template +struct is_contiguous : std::false_type {}; template struct is_contiguous> : std::true_type {}; @@ -724,8 +718,7 @@ FMT_BEGIN_DETAIL_NAMESPACE // Extracts a reference to the container from back_insert_iterator. template -inline auto get_container(std::back_insert_iterator it) - -> Container& { +inline auto get_container(std::back_insert_iterator it) -> Container& { using bi_iterator = std::back_insert_iterator; struct accessor : bi_iterator { accessor(bi_iterator iter) : bi_iterator(iter) {} @@ -735,17 +728,14 @@ inline auto get_container(std::back_insert_iterator it) } template -FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out) - -> OutputIt { +FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out) -> OutputIt { while (begin != end) *out++ = static_cast(*begin++); return out; } template ::value)> -FMT_CONSTEXPR auto copy_str(const Char* begin, const Char* end, Char* out) - -> Char* { - if (is_constant_evaluated()) - return copy_str(begin, end, out); +FMT_CONSTEXPR auto copy_str(const Char* begin, const Char* end, Char* out) -> Char* { + if (is_constant_evaluated()) return copy_str(begin, end, out); auto size = to_unsigned(end - begin); memcpy(out, begin, size); return out + size; @@ -757,7 +747,8 @@ FMT_CONSTEXPR auto copy_str(const Char* begin, const Char* end, Char* out) class and shouldn't be used directly, only via `~fmt::basic_memory_buffer`. \endrst */ -template class buffer { +template +class buffer { private: T* ptr_; size_t size_; @@ -768,10 +759,9 @@ template class buffer { FMT_MSC_WARNING(suppress : 26495) buffer(size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {} - buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) FMT_NOEXCEPT - : ptr_(p), - size_(sz), - capacity_(cap) {} + buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) FMT_NOEXCEPT : ptr_(p), + size_(sz), + capacity_(cap) {} ~buffer() = default; buffer(buffer&&) = default; @@ -834,10 +824,15 @@ template class buffer { } /** Appends data to the end of the buffer. */ - template void append(const U* begin, const U* end); + template + void append(const U* begin, const U* end); - template auto operator[](I index) -> T& { return ptr_[index]; } - template auto operator[](I index) const -> const T& { + template + auto operator[](I index) -> T& { + return ptr_[index]; + } + template + auto operator[](I index) const -> const T& { return ptr_[index]; } }; @@ -896,7 +891,8 @@ class iterator_buffer final : public Traits, public buffer { auto count() const -> size_t { return Traits::count() + this->size(); } }; -template class iterator_buffer final : public buffer { +template +class iterator_buffer final : public buffer { protected: void grow(size_t) final FMT_OVERRIDE {} @@ -908,9 +904,9 @@ template class iterator_buffer final : public buffer { // A buffer that writes to a container with the contiguous storage. template -class iterator_buffer, - enable_if_t::value, - typename Container::value_type>> +class iterator_buffer< + std::back_insert_iterator, + enable_if_t::value, typename Container::value_type>> final : public buffer { private: Container& container_; @@ -932,7 +928,8 @@ class iterator_buffer, }; // A buffer that counts the number of code units written discarding the output. -template class counting_buffer final : public buffer { +template +class counting_buffer final : public buffer { private: enum { buffer_size = 256 }; T data_[buffer_size]; @@ -965,7 +962,8 @@ template auto get_iterator(Buffer& buf) -> decltype(buf.out()) { return buf.out(); } -template auto get_iterator(buffer& buf) -> buffer_appender { +template +auto get_iterator(buffer& buf) -> buffer_appender { return buffer_appender(buf); } @@ -976,18 +974,19 @@ struct fallback_formatter { // Specifies if T has an enabled fallback_formatter specialization. template -using has_fallback_formatter = - std::is_constructible>; +using has_fallback_formatter = std::is_constructible>; struct view {}; -template struct named_arg : view { +template +struct named_arg : view { const Char* name; const T& value; named_arg(const Char* n, const T& v) : name(n), value(v) {} }; -template struct named_arg_info { +template +struct named_arg_info { const Char* name; int id; }; @@ -1014,45 +1013,49 @@ struct arg_data { template FMT_CONSTEXPR FMT_INLINE arg_data(const U&... init) : args_{init...} {} FMT_CONSTEXPR FMT_INLINE auto args() const -> const T* { return args_; } - FMT_CONSTEXPR FMT_INLINE auto named_args() -> std::nullptr_t { - return nullptr; - } + FMT_CONSTEXPR FMT_INLINE auto named_args() -> std::nullptr_t { return nullptr; } }; template inline void init_named_args(named_arg_info*, int, int) {} -template struct is_named_arg : std::false_type {}; -template struct is_statically_named_arg : std::false_type {}; +template +struct is_named_arg : std::false_type {}; +template +struct is_statically_named_arg : std::false_type {}; template struct is_named_arg> : std::true_type {}; template ::value)> -void init_named_args(named_arg_info* named_args, int arg_count, - int named_arg_count, const T&, const Tail&... args) { +void init_named_args(named_arg_info* named_args, int arg_count, int named_arg_count, + const T&, const Tail&... args) { init_named_args(named_args, arg_count + 1, named_arg_count, args...); } template ::value)> -void init_named_args(named_arg_info* named_args, int arg_count, - int named_arg_count, const T& arg, const Tail&... args) { +void init_named_args(named_arg_info* named_args, int arg_count, int named_arg_count, + const T& arg, const Tail&... args) { named_args[named_arg_count++] = {arg.name, arg_count}; init_named_args(named_args, arg_count + 1, named_arg_count, args...); } template -FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int, - const Args&...) {} +FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int, const Args&...) {} -template constexpr auto count() -> size_t { return B ? 1 : 0; } -template constexpr auto count() -> size_t { +template +constexpr auto count() -> size_t { + return B ? 1 : 0; +} +template +constexpr auto count() -> size_t { return (B1 ? 1 : 0) + count(); } -template constexpr auto count_named_args() -> size_t { +template +constexpr auto count_named_args() -> size_t { return count::value...>(); } @@ -1085,8 +1088,7 @@ struct type_constant : std::integral_constant {}; #define FMT_TYPE_CONSTANT(Type, constant) \ template \ - struct type_constant \ - : std::integral_constant {} + struct type_constant : std::integral_constant {} FMT_TYPE_CONSTANT(int, int_type); FMT_TYPE_CONSTANT(unsigned, uint_type); @@ -1111,24 +1113,28 @@ constexpr bool is_arithmetic_type(type t) { return t > type::none_type && t <= type::last_numeric_type; } -template struct string_value { +template +struct string_value { const Char* data; size_t size; }; -template struct named_arg_value { +template +struct named_arg_value { const named_arg_info* data; size_t size; }; -template struct custom_value { +template +struct custom_value { using parse_context = typename Context::parse_context_type; const void* value; void (*format)(const void* arg, parse_context& parse_ctx, Context& ctx); }; // A formatting argument value. -template class value { +template +class value { public: using char_type = typename Context::char_type; @@ -1175,15 +1181,16 @@ template class value { FMT_INLINE value(const named_arg_info* args, size_t size) : named_args{args, size} {} - template FMT_CONSTEXPR FMT_INLINE value(const T& val) { + template + FMT_CONSTEXPR FMT_INLINE value(const T& val) { custom.value = &val; // Get the formatter type through the context to allow different contexts // have different extension points, e.g. `formatter` for `format` and // `printf_formatter` for `printf`. - custom.format = format_custom_arg< - T, conditional_t::value, - typename Context::template formatter_type, - fallback_formatter>>; + custom.format = + format_custom_arg::value, + typename Context::template formatter_type, + fallback_formatter>>; } private: @@ -1210,26 +1217,20 @@ using ulong_type = conditional_t; struct unformattable {}; // Maps formatting arguments to core types. -template struct arg_mapper { +template +struct arg_mapper { using char_type = typename Context::char_type; FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int { return val; } - FMT_CONSTEXPR FMT_INLINE auto map(unsigned char val) -> unsigned { - return val; - } + FMT_CONSTEXPR FMT_INLINE auto map(unsigned char val) -> unsigned { return val; } FMT_CONSTEXPR FMT_INLINE auto map(short val) -> int { return val; } - FMT_CONSTEXPR FMT_INLINE auto map(unsigned short val) -> unsigned { - return val; - } + FMT_CONSTEXPR FMT_INLINE auto map(unsigned short val) -> unsigned { return val; } FMT_CONSTEXPR FMT_INLINE auto map(int val) -> int { return val; } FMT_CONSTEXPR FMT_INLINE auto map(unsigned val) -> unsigned { return val; } FMT_CONSTEXPR FMT_INLINE auto map(long val) -> long_type { return val; } - FMT_CONSTEXPR FMT_INLINE auto map(unsigned long val) -> ulong_type { - return val; - } + FMT_CONSTEXPR FMT_INLINE auto map(unsigned long val) -> ulong_type { return val; } FMT_CONSTEXPR FMT_INLINE auto map(long long val) -> long long { return val; } - FMT_CONSTEXPR FMT_INLINE auto map(unsigned long long val) - -> unsigned long long { + FMT_CONSTEXPR FMT_INLINE auto map(unsigned long long val) -> unsigned long long { return val; } FMT_CONSTEXPR FMT_INLINE auto map(int128_t val) -> int128_t { return val; } @@ -1238,49 +1239,39 @@ template struct arg_mapper { template ::value)> FMT_CONSTEXPR FMT_INLINE auto map(T val) -> char_type { - static_assert( - std::is_same::value || std::is_same::value, - "mixing character types is disallowed"); + static_assert(std::is_same::value || std::is_same::value, + "mixing character types is disallowed"); return val; } FMT_CONSTEXPR FMT_INLINE auto map(float val) -> float { return val; } FMT_CONSTEXPR FMT_INLINE auto map(double val) -> double { return val; } - FMT_CONSTEXPR FMT_INLINE auto map(long double val) -> long double { - return val; - } + FMT_CONSTEXPR FMT_INLINE auto map(long double val) -> long double { return val; } - FMT_CONSTEXPR FMT_INLINE auto map(char_type* val) -> const char_type* { - return val; - } + FMT_CONSTEXPR FMT_INLINE auto map(char_type* val) -> const char_type* { return val; } FMT_CONSTEXPR FMT_INLINE auto map(const char_type* val) -> const char_type* { return val; } template ::value)> - FMT_CONSTEXPR FMT_INLINE auto map(const T& val) - -> basic_string_view { + FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> basic_string_view { static_assert(std::is_same>::value, "mixing character types is disallowed"); return to_string_view(val); } template , T>::value && - !is_string::value && !has_formatter::value && - !has_fallback_formatter::value)> - FMT_CONSTEXPR FMT_INLINE auto map(const T& val) - -> basic_string_view { + FMT_ENABLE_IF(std::is_constructible, T>::value && + !is_string::value && !has_formatter::value && + !has_fallback_formatter::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> basic_string_view { return basic_string_view(val); } template < typename T, - FMT_ENABLE_IF( - std::is_constructible, T>::value && - !std::is_constructible, T>::value && - !is_string::value && !has_formatter::value && - !has_fallback_formatter::value)> - FMT_CONSTEXPR FMT_INLINE auto map(const T& val) - -> basic_string_view { + FMT_ENABLE_IF(std::is_constructible, T>::value && + !std::is_constructible, T>::value && + !is_string::value && !has_formatter::value && + !has_fallback_formatter::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> basic_string_view { return std_string_view(val); } FMT_CONSTEXPR FMT_INLINE auto map(const signed char* val) -> const char* { @@ -1301,12 +1292,8 @@ template struct arg_mapper { } FMT_CONSTEXPR FMT_INLINE auto map(void* val) -> const void* { return val; } - FMT_CONSTEXPR FMT_INLINE auto map(const void* val) -> const void* { - return val; - } - FMT_CONSTEXPR FMT_INLINE auto map(std::nullptr_t val) -> const void* { - return val; - } + FMT_CONSTEXPR FMT_INLINE auto map(const void* val) -> const void* { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(std::nullptr_t val) -> const void* { return val; } // We use SFINAE instead of a const T* parameter to avoid conflicting with // the C array overload. @@ -1326,18 +1313,16 @@ template struct arg_mapper { } template ::value && - !has_formatter::value && + FMT_ENABLE_IF(std::is_enum::value && !has_formatter::value && !has_fallback_formatter::value)> FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> decltype(std::declval().map( static_cast::type>(val))) { return map(static_cast::type>(val)); } - template ::value && !is_char::value && - (has_formatter::value || - has_fallback_formatter::value))> + template ::value && !is_char::value && + (has_formatter::value || + has_fallback_formatter::value))> FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> const T& { return val; } @@ -1394,7 +1379,8 @@ class appender : public std::back_insert_iterator> { // A formatting argument. It is a trivially copyable/constructible type to // allow storage in basic_memory_buffer. -template class basic_format_arg { +template +class basic_format_arg { private: detail::value value_; detail::type type_; @@ -1424,8 +1410,7 @@ template class basic_format_arg { public: explicit handle(detail::custom_value custom) : custom_(custom) {} - void format(typename Context::parse_context_type& parse_ctx, - Context& ctx) const { + void format(typename Context::parse_context_type& parse_ctx, Context& ctx) const { custom_.format(custom_.value, parse_ctx, ctx); } @@ -1442,9 +1427,7 @@ template class basic_format_arg { auto type() const -> detail::type { return type_; } auto is_integral() const -> bool { return detail::is_integral_type(type_); } - auto is_arithmetic() const -> bool { - return detail::is_arithmetic_type(type_); - } + auto is_arithmetic() const -> bool { return detail::is_arithmetic_type(type_); } }; /** @@ -1455,42 +1438,43 @@ template class basic_format_arg { \endrst */ template -FMT_CONSTEXPR FMT_INLINE auto visit_format_arg( - Visitor&& vis, const basic_format_arg& arg) -> decltype(vis(0)) { +FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(Visitor&& vis, + const basic_format_arg& arg) + -> decltype(vis(0)) { switch (arg.type_) { - case detail::type::none_type: - break; - case detail::type::int_type: - return vis(arg.value_.int_value); - case detail::type::uint_type: - return vis(arg.value_.uint_value); - case detail::type::long_long_type: - return vis(arg.value_.long_long_value); - case detail::type::ulong_long_type: - return vis(arg.value_.ulong_long_value); - case detail::type::int128_type: - return vis(detail::convert_for_visit(arg.value_.int128_value)); - case detail::type::uint128_type: - return vis(detail::convert_for_visit(arg.value_.uint128_value)); - case detail::type::bool_type: - return vis(arg.value_.bool_value); - case detail::type::char_type: - return vis(arg.value_.char_value); - case detail::type::float_type: - return vis(arg.value_.float_value); - case detail::type::double_type: - return vis(arg.value_.double_value); - case detail::type::long_double_type: - return vis(arg.value_.long_double_value); - case detail::type::cstring_type: - return vis(arg.value_.string.data); - case detail::type::string_type: - using sv = basic_string_view; - return vis(sv(arg.value_.string.data, arg.value_.string.size)); - case detail::type::pointer_type: - return vis(arg.value_.pointer); - case detail::type::custom_type: - return vis(typename basic_format_arg::handle(arg.value_.custom)); + case detail::type::none_type: + break; + case detail::type::int_type: + return vis(arg.value_.int_value); + case detail::type::uint_type: + return vis(arg.value_.uint_value); + case detail::type::long_long_type: + return vis(arg.value_.long_long_value); + case detail::type::ulong_long_type: + return vis(arg.value_.ulong_long_value); + case detail::type::int128_type: + return vis(detail::convert_for_visit(arg.value_.int128_value)); + case detail::type::uint128_type: + return vis(detail::convert_for_visit(arg.value_.uint128_value)); + case detail::type::bool_type: + return vis(arg.value_.bool_value); + case detail::type::char_type: + return vis(arg.value_.char_value); + case detail::type::float_type: + return vis(arg.value_.float_value); + case detail::type::double_type: + return vis(arg.value_.double_value); + case detail::type::long_double_type: + return vis(arg.value_.long_double_value); + case detail::type::cstring_type: + return vis(arg.value_.string.data); + case detail::type::string_type: + using sv = basic_string_view; + return vis(sv(arg.value_.string.data, arg.value_.string.size)); + case detail::type::pointer_type: + return vis(arg.value_.pointer); + case detail::type::custom_type: + return vis(typename basic_format_arg::handle(arg.value_.custom)); } return vis(monostate()); } @@ -1505,28 +1489,30 @@ auto copy_str(InputIt begin, InputIt end, appender out) -> appender { #if FMT_GCC_VERSION && FMT_GCC_VERSION < 500 // A workaround for gcc 4.8 to make void_t work in a SFINAE context. -template struct void_t_impl { using type = void; }; +template +struct void_t_impl { + using type = void; +}; template using void_t = typename detail::void_t_impl::type; #else -template using void_t = void; +template +using void_t = void; #endif template struct is_output_iterator : std::false_type {}; template -struct is_output_iterator< - It, T, - void_t::iterator_category, - decltype(*std::declval() = std::declval())>> +struct is_output_iterator::iterator_category, + decltype(*std::declval() = std::declval())>> : std::true_type {}; template struct is_back_insert_iterator : std::false_type {}; template -struct is_back_insert_iterator> - : std::true_type {}; +struct is_back_insert_iterator> : std::true_type {}; template struct is_contiguous_back_insert_iterator : std::false_type {}; @@ -1543,14 +1529,17 @@ class locale_ref { public: constexpr locale_ref() : locale_(nullptr) {} - template explicit locale_ref(const Locale& loc); + template + explicit locale_ref(const Locale& loc); explicit operator bool() const FMT_NOEXCEPT { return locale_ != nullptr; } - template auto get() const -> Locale; + template + auto get() const -> Locale; }; -template constexpr auto encode_types() -> unsigned long long { +template +constexpr auto encode_types() -> unsigned long long { return 0; } @@ -1571,26 +1560,24 @@ FMT_CONSTEXPR auto make_arg(const T& value) -> basic_format_arg { // The type template parameter is there to avoid an ODR violation when using // a fallback formatter in one translation unit and an implicit conversion in // another (not recommended). -template +template FMT_CONSTEXPR FMT_INLINE auto make_arg(const T& val) -> value { const auto& arg = arg_mapper().map(val); - static_assert( - !std::is_same::value, - "Cannot format an argument. To make type T formattable provide a " - "formatter specialization: https://fmt.dev/latest/api.html#udt"); + static_assert(!std::is_same::value, + "Cannot format an argument. To make type T formattable provide a " + "formatter specialization: https://fmt.dev/latest/api.html#udt"); return {arg}; } -template +template inline auto make_arg(const T& value) -> basic_format_arg { return make_arg(value); } FMT_END_DETAIL_NAMESPACE // Formatting context. -template class basic_format_context { +template +class basic_format_context { public: /** The character type for the output. */ using char_type = Char; @@ -1604,7 +1591,8 @@ template class basic_format_context { using iterator = OutputIt; using format_arg = basic_format_arg; using parse_context_type = basic_format_parse_context; - template using formatter_type = formatter; + template + using formatter_type = formatter; basic_format_context(basic_format_context&&) = default; basic_format_context(const basic_format_context&) = delete; @@ -1613,9 +1601,9 @@ template class basic_format_context { Constructs a ``basic_format_context`` object. References to the arguments are stored in the object so make sure they have appropriate lifetimes. */ - constexpr basic_format_context( - OutputIt out, basic_format_args ctx_args, - detail::locale_ref loc = detail::locale_ref()) + constexpr basic_format_context(OutputIt out, + basic_format_args ctx_args, + detail::locale_ref loc = detail::locale_ref()) : out_(out), args_(ctx_args), loc_(loc) {} constexpr auto arg(int id) const -> format_arg { return args_.get(id); } @@ -1625,9 +1613,7 @@ template class basic_format_context { FMT_CONSTEXPR auto arg_id(basic_string_view name) -> int { return args_.get_id(name); } - auto args() const -> const basic_format_args& { - return args_; - } + auto args() const -> const basic_format_args& { return args_; } FMT_CONSTEXPR auto error_handler() -> detail::error_handler { return {}; } void on_error(const char* message) { error_handler().on_error(message); } @@ -1644,20 +1630,18 @@ template class basic_format_context { }; template -using buffer_context = - basic_format_context, Char>; +using buffer_context = basic_format_context, Char>; using format_context = buffer_context; // Workaround an alias issue: https://stackoverflow.com/q/62767544/471164. -#define FMT_BUFFER_CONTEXT(Char) \ - basic_format_context, Char> +#define FMT_BUFFER_CONTEXT(Char) basic_format_context, Char> template -using is_formattable = bool_constant< - !std::is_same>().map( - std::declval())), - detail::unformattable>::value && - !detail::has_fallback_formatter::value>; +using is_formattable = + bool_constant>().map( + std::declval())), + detail::unformattable>::value && + !detail::has_fallback_formatter::value>; /** \rst @@ -1678,11 +1662,10 @@ class format_arg_store static const size_t num_named_args = detail::count_named_args(); static const bool is_packed = num_args <= detail::max_packed_args; - using value_type = conditional_t, - basic_format_arg>; + using value_type = + conditional_t, basic_format_arg>; - detail::arg_data + detail::arg_data data_; friend class basic_format_args; @@ -1690,9 +1673,8 @@ class format_arg_store static constexpr unsigned long long desc = (is_packed ? detail::encode_types() : detail::is_unpacked_bit | num_args) | - (num_named_args != 0 - ? static_cast(detail::has_named_args_bit) - : 0); + (num_named_args != 0 ? static_cast(detail::has_named_args_bit) + : 0); public: FMT_CONSTEXPR FMT_INLINE format_arg_store(const Args&... args) @@ -1700,9 +1682,9 @@ class format_arg_store #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 basic_format_args(*this), #endif - data_{detail::make_arg< - is_packed, Context, - detail::mapped_type_constant::value>(args)...} { + data_{detail::make_arg::value>( + args)...} { detail::init_named_args(data_.named_args(), 0, 0, args...); } }; @@ -1748,7 +1730,8 @@ inline auto arg(const Char* name, const T& arg) -> detail::named_arg { format_args args = make_format_args(42); // Error: dangling reference \endrst */ -template class basic_format_args { +template +class basic_format_args { public: using size_type = int; using format_arg = basic_format_arg; @@ -1797,10 +1780,8 @@ template class basic_format_args { \endrst */ template - constexpr FMT_INLINE basic_format_args( - const format_arg_store& store) - : basic_format_args(format_arg_store::desc, - store.data_.args()) {} + constexpr FMT_INLINE basic_format_args(const format_arg_store& store) + : basic_format_args(format_arg_store::desc, store.data_.args()) {} /** \rst @@ -1808,8 +1789,7 @@ template class basic_format_args { `~fmt::dynamic_format_arg_store`. \endrst */ - constexpr FMT_INLINE basic_format_args( - const dynamic_format_arg_store& store) + constexpr FMT_INLINE basic_format_args(const dynamic_format_arg_store& store) : basic_format_args(store.get_types(), store.data()) {} /** @@ -1818,8 +1798,7 @@ template class basic_format_args { \endrst */ constexpr basic_format_args(const format_arg* args, int count) - : basic_format_args(detail::is_unpacked_bit | detail::to_unsigned(count), - args) {} + : basic_format_args(detail::is_unpacked_bit | detail::to_unsigned(count), args) {} /** Returns the argument with the specified id. */ FMT_CONSTEXPR auto get(int id) const -> format_arg { @@ -1844,8 +1823,7 @@ template class basic_format_args { template auto get_id(basic_string_view name) const -> int { if (!has_named_args()) return -1; - const auto& named_args = - (is_packed() ? values_[-1] : args_[-1].value_).named_args; + const auto& named_args = (is_packed() ? values_[-1] : args_[-1].value_).named_args; for (size_t i = 0; i < named_args.size; ++i) { if (named_args.data[i].name == name) return named_args.data[i].id; } @@ -1854,8 +1832,7 @@ template class basic_format_args { auto max_size() const -> int { unsigned long long max_packed = detail::max_packed_args; - return static_cast(is_packed() ? max_packed - : desc_ & ~detail::is_unpacked_bit); + return static_cast(is_packed() ? max_packed : desc_ & ~detail::is_unpacked_bit); } }; @@ -1880,7 +1857,8 @@ FMT_BEGIN_DETAIL_NAMESPACE void throw_format_error(const char* message); // Workaround an array initialization issue in gcc 4.8. -template struct fill_t { +template +struct fill_t { private: enum { max_size = 4 }; Char data_[max_size] = {Char(' '), Char(0), Char(0), Char(0)}; @@ -1905,7 +1883,8 @@ template struct fill_t { FMT_END_DETAIL_NAMESPACE // Format specifiers for built-in and string types. -template struct basic_format_specs { +template +struct basic_format_specs { int width; int precision; char type; @@ -1932,11 +1911,11 @@ FMT_BEGIN_DETAIL_NAMESPACE enum class arg_id_kind { none, index, name }; // An argument reference. -template struct arg_ref { +template +struct arg_ref { FMT_CONSTEXPR arg_ref() : kind(arg_id_kind::none), val() {} - FMT_CONSTEXPR explicit arg_ref(int index) - : kind(arg_id_kind::index), val(index) {} + FMT_CONSTEXPR explicit arg_ref(int index) : kind(arg_id_kind::index), val(index) {} FMT_CONSTEXPR explicit arg_ref(basic_string_view name) : kind(arg_id_kind::name), val(name) {} @@ -1968,21 +1947,18 @@ struct dynamic_format_specs : basic_format_specs { struct auto_id {}; // A format specifier handler that sets fields in basic_format_specs. -template class specs_setter { +template +class specs_setter { protected: basic_format_specs& specs_; public: - explicit FMT_CONSTEXPR specs_setter(basic_format_specs& specs) - : specs_(specs) {} + explicit FMT_CONSTEXPR specs_setter(basic_format_specs& specs) : specs_(specs) {} - FMT_CONSTEXPR specs_setter(const specs_setter& other) - : specs_(other.specs_) {} + FMT_CONSTEXPR specs_setter(const specs_setter& other) : specs_(other.specs_) {} FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; } - FMT_CONSTEXPR void on_fill(basic_string_view fill) { - specs_.fill = fill; - } + FMT_CONSTEXPR void on_fill(basic_string_view fill) { specs_.fill = fill; } FMT_CONSTEXPR void on_sign(sign_t s) { specs_.sign = s; } FMT_CONSTEXPR void on_hash() { specs_.alt = true; } FMT_CONSTEXPR void on_localized() { specs_.localized = true; } @@ -1993,21 +1969,16 @@ template class specs_setter { } FMT_CONSTEXPR void on_width(int width) { specs_.width = width; } - FMT_CONSTEXPR void on_precision(int precision) { - specs_.precision = precision; - } + FMT_CONSTEXPR void on_precision(int precision) { specs_.precision = precision; } FMT_CONSTEXPR void end_precision() {} - FMT_CONSTEXPR void on_type(Char type) { - specs_.type = static_cast(type); - } + FMT_CONSTEXPR void on_type(Char type) { specs_.type = static_cast(type); } }; // Format spec handler that saves references to arguments representing dynamic // width and precision to be resolved at formatting time. template -class dynamic_specs_handler - : public specs_setter { +class dynamic_specs_handler : public specs_setter { public: using char_type = typename ParseContext::char_type; @@ -2016,21 +1987,19 @@ class dynamic_specs_handler : specs_setter(specs), specs_(specs), context_(ctx) {} FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler& other) - : specs_setter(other), - specs_(other.specs_), - context_(other.context_) {} + : specs_setter(other), specs_(other.specs_), context_(other.context_) {} - template FMT_CONSTEXPR void on_dynamic_width(Id arg_id) { + template + FMT_CONSTEXPR void on_dynamic_width(Id arg_id) { specs_.width_ref = make_arg_ref(arg_id); } - template FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) { + template + FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) { specs_.precision_ref = make_arg_ref(arg_id); } - FMT_CONSTEXPR void on_error(const char* message) { - context_.on_error(message); - } + FMT_CONSTEXPR void on_error(const char* message) { context_.on_error(message); } private: dynamic_format_specs& specs_; @@ -2047,8 +2016,7 @@ class dynamic_specs_handler return arg_ref_type(context_.next_arg_id()); } - FMT_CONSTEXPR auto make_arg_ref(basic_string_view arg_id) - -> arg_ref_type { + FMT_CONSTEXPR auto make_arg_ref(basic_string_view arg_id) -> arg_ref_type { context_.check_arg_id(arg_id); basic_string_view format_str( context_.begin(), to_unsigned(context_.end() - context_.begin())); @@ -2056,7 +2024,8 @@ class dynamic_specs_handler } }; -template constexpr bool is_ascii_letter(Char c) { +template +constexpr bool is_ascii_letter(Char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } @@ -2066,8 +2035,7 @@ constexpr auto to_ascii(Char value) -> Char { return value; } template ::value)> -constexpr auto to_ascii(Char value) -> - typename std::underlying_type::type { +constexpr auto to_ascii(Char value) -> typename std::underlying_type::type { return value; } @@ -2096,8 +2064,7 @@ FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool { template <> inline auto find(const char* first, const char* last, char value, const char*& out) -> bool { - out = static_cast( - std::memchr(first, value, to_unsigned(last - first))); + out = static_cast(std::memchr(first, value, to_unsigned(last - first))); return out != nullptr; } @@ -2116,8 +2083,7 @@ FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end, } while (p != end && '0' <= *p && *p <= '9'); auto num_digits = p - begin; begin = p; - if (num_digits <= std::numeric_limits::digits10) - return static_cast(value); + if (num_digits <= std::numeric_limits::digits10) return static_cast(value); // Check for overflow. const unsigned max = to_unsigned((std::numeric_limits::max)()); return num_digits == std::numeric_limits::digits10 + 1 && @@ -2128,31 +2094,30 @@ FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end, // Parses fill and alignment. template -FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, - Handler&& handler) -> const Char* { +FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, Handler&& handler) + -> const Char* { FMT_ASSERT(begin != end, ""); auto align = align::none; auto p = begin + code_point_length(begin); if (p >= end) p = begin; for (;;) { switch (to_ascii(*p)) { - case '<': - align = align::left; - break; - case '>': - align = align::right; - break; - case '^': - align = align::center; - break; - default: - break; + case '<': + align = align::left; + break; + case '>': + align = align::right; + break; + case '^': + align = align::center; + break; + default: + break; } if (align != align::none) { if (p != begin) { auto c = *begin; - if (c == '{') - return handler.on_error("invalid fill character '{'"), begin; + if (c == '{') return handler.on_error("invalid fill character '{'"), begin; handler.on_fill(basic_string_view(begin, to_unsigned(p - begin))); begin = p + 1; } else @@ -2167,7 +2132,8 @@ FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, return begin; } -template FMT_CONSTEXPR bool is_name_start(Char c) { +template +FMT_CONSTEXPR bool is_name_start(Char c) { return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; } @@ -2179,8 +2145,7 @@ FMT_CONSTEXPR auto do_parse_arg_id(const Char* begin, const Char* end, if (c >= '0' && c <= '9') { int index = 0; if (c != '0') - index = - parse_nonnegative_int(begin, end, (std::numeric_limits::max)()); + index = parse_nonnegative_int(begin, end, (std::numeric_limits::max)()); else ++begin; if (begin == end || (*begin != '}' && *begin != ':')) @@ -2211,8 +2176,8 @@ FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char* begin, const Char* end, } template -FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end, - Handler&& handler) -> const Char* { +FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end, Handler&& handler) + -> const Char* { using detail::auto_id; struct width_adapter { Handler& handler; @@ -2245,8 +2210,8 @@ FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end, } template -FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end, - Handler&& handler) -> const Char* { +FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end, Handler&& handler) + -> const Char* { using detail::auto_id; struct precision_adapter { Handler& handler; @@ -2271,8 +2236,7 @@ FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end, handler.on_error("number is too big"); } else if (c == '{') { ++begin; - if (begin != end) - begin = parse_arg_id(begin, end, precision_adapter{handler}); + if (begin != end) begin = parse_arg_id(begin, end, precision_adapter{handler}); if (begin == end || *begin++ != '}') return handler.on_error("invalid format string"), begin; } else { @@ -2285,12 +2249,9 @@ FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end, // Parses standard format specifiers and sends notifications about parsed // components to handler. template -FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char* begin, - const Char* end, - SpecHandler&& handler) - -> const Char* { - if (begin + 1 < end && begin[1] == '}' && is_ascii_letter(*begin) && - *begin != 'L') { +FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char* begin, const Char* end, + SpecHandler&& handler) -> const Char* { + if (begin + 1 < end && begin[1] == '}' && is_ascii_letter(*begin) && *begin != 'L') { handler.on_type(*begin++); return begin; } @@ -2302,20 +2263,20 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char* begin, // Parse sign. switch (to_ascii(*begin)) { - case '+': - handler.on_sign(sign::plus); - ++begin; - break; - case '-': - handler.on_sign(sign::minus); - ++begin; - break; - case ' ': - handler.on_sign(sign::space); - ++begin; - break; - default: - break; + case '+': + handler.on_sign(sign::plus); + ++begin; + break; + case '-': + handler.on_sign(sign::minus); + ++begin; + break; + case ' ': + handler.on_sign(sign::space); + ++begin; + break; + default: + break; } if (begin == end) return begin; @@ -2390,8 +2351,8 @@ FMT_CONSTEXPR auto parse_replacement_field(const Char* begin, const Char* end, } template -FMT_CONSTEXPR FMT_INLINE void parse_format_string( - basic_string_view format_str, Handler&& handler) { +FMT_CONSTEXPR FMT_INLINE void parse_format_string(basic_string_view format_str, + Handler&& handler) { // this is most likely a name-lookup defect in msvc's modules implementation using detail::find; @@ -2443,13 +2404,12 @@ FMT_CONSTEXPR FMT_INLINE void parse_format_string( } template -FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx) - -> decltype(ctx.begin()) { +FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx) -> decltype(ctx.begin()) { using char_type = typename ParseContext::char_type; using context = buffer_context; - using mapped_type = conditional_t< - mapped_type_constant::value != type::custom_type, - decltype(arg_mapper().map(std::declval())), T>; + using mapped_type = + conditional_t::value != type::custom_type, + decltype(arg_mapper().map(std::declval())), T>; auto f = conditional_t::value, formatter, fallback_formatter>(); @@ -2461,8 +2421,7 @@ FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx) // and would be redundant since argument ids are checked when arguments are // retrieved anyway. template -class compile_parse_context - : public basic_format_parse_context { +class compile_parse_context : public basic_format_parse_context { private: int num_args_; using base = basic_format_parse_context; @@ -2489,18 +2448,18 @@ class compile_parse_context template FMT_CONSTEXPR void check_int_type_spec(char spec, ErrorHandler&& eh) { switch (spec) { - case 0: - case 'd': - case 'x': - case 'X': - case 'b': - case 'B': - case 'o': - case 'c': - break; - default: - eh.on_error("invalid type specifier"); - break; + case 0: + case 'd': + case 'x': + case 'X': + case 'b': + case 'B': + case 'o': + case 'c': + break; + default: + eh.on_error("invalid type specifier"); + break; } } @@ -2538,51 +2497,49 @@ struct float_specs { template FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs& specs, - ErrorHandler&& eh = {}) - -> float_specs { + ErrorHandler&& eh = {}) -> float_specs { auto result = float_specs(); result.showpoint = specs.alt; result.locale = specs.localized; switch (specs.type) { - case 0: - result.format = float_format::general; - break; - case 'G': - result.upper = true; - FMT_FALLTHROUGH; - case 'g': - result.format = float_format::general; - break; - case 'E': - result.upper = true; - FMT_FALLTHROUGH; - case 'e': - result.format = float_format::exp; - result.showpoint |= specs.precision != 0; - break; - case 'F': - result.upper = true; - FMT_FALLTHROUGH; - case 'f': - result.format = float_format::fixed; - result.showpoint |= specs.precision != 0; - break; - case 'A': - result.upper = true; - FMT_FALLTHROUGH; - case 'a': - result.format = float_format::hex; - break; - default: - eh.on_error("invalid type specifier"); - break; + case 0: + result.format = float_format::general; + break; + case 'G': + result.upper = true; + FMT_FALLTHROUGH; + case 'g': + result.format = float_format::general; + break; + case 'E': + result.upper = true; + FMT_FALLTHROUGH; + case 'e': + result.format = float_format::exp; + result.showpoint |= specs.precision != 0; + break; + case 'F': + result.upper = true; + FMT_FALLTHROUGH; + case 'f': + result.format = float_format::fixed; + result.showpoint |= specs.precision != 0; + break; + case 'A': + result.upper = true; + FMT_FALLTHROUGH; + case 'a': + result.format = float_format::hex; + break; + default: + eh.on_error("invalid type specifier"); + break; } return result; } template -FMT_CONSTEXPR auto check_cstring_type_spec(Char spec, ErrorHandler&& eh = {}) - -> bool { +FMT_CONSTEXPR auto check_cstring_type_spec(Char spec, ErrorHandler&& eh = {}) -> bool { if (spec == 0 || spec == 's') return true; if (spec != 'p') eh.on_error("invalid type specifier"); return false; @@ -2600,7 +2557,8 @@ FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler&& eh) { // A parse_format_specs handler that checks if specifiers are consistent with // the argument type. -template class specs_checker : public Handler { +template +class specs_checker : public Handler { private: detail::type arg_type_; @@ -2656,8 +2614,7 @@ constexpr auto get_arg_index_by_name(basic_string_view name) -> int { if constexpr (detail::is_statically_named_arg()) { if (name == T::name) return N; } - if constexpr (sizeof...(Args) > 0) - return get_arg_index_by_name(name); + if constexpr (sizeof...(Args) > 0) return get_arg_index_by_name(name); (void)name; // Workaround an MSVC bug about "unused" parameter. return invalid_arg_index; } @@ -2666,8 +2623,7 @@ constexpr auto get_arg_index_by_name(basic_string_view name) -> int { template FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view name) -> int { #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS - if constexpr (sizeof...(Args) > 0) - return get_arg_index_by_name<0, Args...>(name); + if constexpr (sizeof...(Args) > 0) return get_arg_index_by_name<0, Args...>(name); #endif (void)name; return invalid_arg_index; @@ -2686,17 +2642,15 @@ class format_string_checker { parse_func parse_funcs_[num_args > 0 ? num_args : 1]; public: - explicit FMT_CONSTEXPR format_string_checker( - basic_string_view format_str, ErrorHandler eh) + explicit FMT_CONSTEXPR format_string_checker(basic_string_view format_str, + ErrorHandler eh) : context_(format_str, num_args, eh), parse_funcs_{&parse_format_specs...} {} FMT_CONSTEXPR void on_text(const Char*, const Char*) {} FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); } - FMT_CONSTEXPR auto on_arg_id(int id) -> int { - return context_.check_arg_id(id), id; - } + FMT_CONSTEXPR auto on_arg_id(int id) -> int { return context_.check_arg_id(id), id; } FMT_CONSTEXPR auto on_arg_id(basic_string_view id) -> int { #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS auto index = get_arg_index_by_name(id); @@ -2718,13 +2672,10 @@ class format_string_checker { return id >= 0 && id < num_args ? parse_funcs_[id](context_) : begin; } - FMT_CONSTEXPR void on_error(const char* message) { - context_.on_error(message); - } + FMT_CONSTEXPR void on_error(const char* message) { context_.on_error(message); } }; -template ::value), int>> +template ::value), int>> void check_format_string(S format_str) { FMT_CONSTEXPR auto s = to_string_view(format_str); using checker = format_string_checker -void vformat_to( - buffer& buf, basic_string_view fmt, - basic_format_args)> args, - detail::locale_ref loc = {}); +void vformat_to(buffer& buf, basic_string_view fmt, + basic_format_args)> args, + detail::locale_ref loc = {}); FMT_API void vprint_mojibake(std::FILE*, string_view, format_args); #ifndef _WIN32 @@ -2749,9 +2699,9 @@ FMT_END_DETAIL_NAMESPACE // A formatter specialization for the core types corresponding to detail::type // constants. template -struct formatter::value != - detail::type::custom_type>> { +struct formatter< + T, Char, + enable_if_t::value != detail::type::custom_type>> { private: detail::dynamic_format_specs specs_; @@ -2764,59 +2714,58 @@ struct formatter; auto type = detail::type_constant::value; - auto checker = - detail::specs_checker(handler_type(specs_, ctx), type); + auto checker = detail::specs_checker(handler_type(specs_, ctx), type); auto it = detail::parse_format_specs(begin, end, checker); auto eh = ctx.error_handler(); switch (type) { - case detail::type::none_type: - FMT_ASSERT(false, "invalid argument type"); - break; - case detail::type::bool_type: - if (!specs_.type || specs_.type == 's') break; - FMT_FALLTHROUGH; - case detail::type::int_type: - case detail::type::uint_type: - case detail::type::long_long_type: - case detail::type::ulong_long_type: - case detail::type::int128_type: - case detail::type::uint128_type: - detail::check_int_type_spec(specs_.type, eh); - break; - case detail::type::char_type: - detail::check_char_specs(specs_, eh); - break; - case detail::type::float_type: - if (detail::const_check(FMT_USE_FLOAT)) - detail::parse_float_type_spec(specs_, eh); - else - FMT_ASSERT(false, "float support disabled"); - break; - case detail::type::double_type: - if (detail::const_check(FMT_USE_DOUBLE)) - detail::parse_float_type_spec(specs_, eh); - else - FMT_ASSERT(false, "double support disabled"); - break; - case detail::type::long_double_type: - if (detail::const_check(FMT_USE_LONG_DOUBLE)) - detail::parse_float_type_spec(specs_, eh); - else - FMT_ASSERT(false, "long double support disabled"); - break; - case detail::type::cstring_type: - detail::check_cstring_type_spec(specs_.type, eh); - break; - case detail::type::string_type: - detail::check_string_type_spec(specs_.type, eh); - break; - case detail::type::pointer_type: - detail::check_pointer_type_spec(specs_.type, eh); - break; - case detail::type::custom_type: - // Custom format specifiers are checked in parse functions of - // formatter specializations. - break; + case detail::type::none_type: + FMT_ASSERT(false, "invalid argument type"); + break; + case detail::type::bool_type: + if (!specs_.type || specs_.type == 's') break; + FMT_FALLTHROUGH; + case detail::type::int_type: + case detail::type::uint_type: + case detail::type::long_long_type: + case detail::type::ulong_long_type: + case detail::type::int128_type: + case detail::type::uint128_type: + detail::check_int_type_spec(specs_.type, eh); + break; + case detail::type::char_type: + detail::check_char_specs(specs_, eh); + break; + case detail::type::float_type: + if (detail::const_check(FMT_USE_FLOAT)) + detail::parse_float_type_spec(specs_, eh); + else + FMT_ASSERT(false, "float support disabled"); + break; + case detail::type::double_type: + if (detail::const_check(FMT_USE_DOUBLE)) + detail::parse_float_type_spec(specs_, eh); + else + FMT_ASSERT(false, "double support disabled"); + break; + case detail::type::long_double_type: + if (detail::const_check(FMT_USE_LONG_DOUBLE)) + detail::parse_float_type_spec(specs_, eh); + else + FMT_ASSERT(false, "long double support disabled"); + break; + case detail::type::cstring_type: + detail::check_cstring_type_spec(specs_.type, eh); + break; + case detail::type::string_type: + detail::check_string_type_spec(specs_.type, eh); + break; + case detail::type::pointer_type: + detail::check_pointer_type_spec(specs_.type, eh); + break; + case detail::type::custom_type: + // Custom format specifiers are checked in parse functions of + // formatter specializations. + break; } return it; } @@ -2826,21 +2775,23 @@ struct formatter decltype(ctx.out()); }; -template struct basic_runtime { basic_string_view str; }; +template +struct basic_runtime { + basic_string_view str; +}; -template class basic_format_string { +template +class basic_format_string { private: basic_string_view str_; public: template >::value)> + FMT_ENABLE_IF(std::is_convertible>::value)> FMT_CONSTEVAL basic_format_string(const S& s) : str_(s) { static_assert( - detail::count< - (std::is_base_of>::value && - std::is_reference::value)...>() == 0, + detail::count<(std::is_base_of>::value && + std::is_reference::value)...>() == 0, "passing views as lvalues is disallowed"); #ifdef FMT_HAS_CONSTEVAL if constexpr (detail::count_named_args() == 0) { @@ -2859,15 +2810,18 @@ template class basic_format_string { #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 // Workaround broken conversion on older gcc. -template using format_string = string_view; -template auto runtime(const S& s) -> basic_string_view> { +template +using format_string = string_view; +template +auto runtime(const S& s) -> basic_string_view> { return s; } #else template using format_string = basic_format_string...>; // Creates a runtime format string. -template auto runtime(const S& s) -> basic_runtime> { +template +auto runtime(const S& s) -> basic_runtime> { return {{s}}; } #endif @@ -2919,7 +2873,8 @@ FMT_INLINE auto format_to(OutputIt out, format_string fmt, T&&... args) return vformat_to(out, fmt, fmt::make_format_args(args...)); } -template struct format_to_n_result { +template +struct format_to_n_result { /** Iterator past the end of the output range. */ OutputIt out; /** Total (not truncated) output size. */ @@ -2930,8 +2885,7 @@ template ::value)> auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args) -> format_to_n_result { - using buffer = - detail::iterator_buffer; + using buffer = detail::iterator_buffer; auto buf = buffer(out, n); detail::vformat_to(buf, fmt, args); return {buf.out(), buf.count()}; @@ -3001,6 +2955,6 @@ FMT_GCC_PRAGMA("GCC pop_options") FMT_END_NAMESPACE #ifdef FMT_HEADER_ONLY -# include "format.h" +#include "format.h" #endif #endif // FMT_CORE_H_ diff --git a/inst/include/fmt/format-inl.h b/inst/include/fmt/format-inl.h index a802aea5..5e10ae2a 100644 --- a/inst/include/fmt/format-inl.h +++ b/inst/include/fmt/format-inl.h @@ -19,11 +19,11 @@ #include #ifndef FMT_STATIC_THOUSANDS_SEPARATOR -# include +#include #endif #ifdef _WIN32 -# include // _isatty +#include // _isatty #endif #include "format.h" @@ -41,7 +41,7 @@ FMT_FUNC void assert_fail(const char* file, int line, const char* message) { } #ifndef _MSC_VER -# define FMT_SNPRINTF snprintf +#define FMT_SNPRINTF snprintf #else // _MSC_VER inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) { va_list args; @@ -50,7 +50,7 @@ inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) { va_end(args); return result; } -# define FMT_SNPRINTF fmt_snprintf +#define FMT_SNPRINTF fmt_snprintf #endif // _MSC_VER FMT_FUNC void format_error_code(detail::buffer& out, int error_code, @@ -86,8 +86,7 @@ FMT_FUNC void report_error(format_func func, int error_code, } // A wrapper around fwrite that throws on error. -inline void fwrite_fully(const void* ptr, size_t size, size_t count, - FILE* stream) { +inline void fwrite_fully(const void* ptr, size_t size, size_t count, FILE* stream) { size_t written = std::fwrite(ptr, size, count, stream); if (written < count) FMT_THROW(system_error(errno, "cannot write to file")); } @@ -98,7 +97,8 @@ locale_ref::locale_ref(const Locale& loc) : locale_(&loc) { static_assert(std::is_same::value, ""); } -template Locale locale_ref::get() const { +template +Locale locale_ref::get() const { static_assert(std::is_same::value, ""); return locale_ ? *static_cast(locale_) : std::locale(); } @@ -110,16 +110,17 @@ FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result { auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep(); return {std::move(grouping), thousands_sep}; } -template FMT_FUNC Char decimal_point_impl(locale_ref loc) { - return std::use_facet>(loc.get()) - .decimal_point(); +template +FMT_FUNC Char decimal_point_impl(locale_ref loc) { + return std::use_facet>(loc.get()).decimal_point(); } #else template FMT_FUNC auto thousands_sep_impl(locale_ref) -> thousands_sep_result { return {"\03", FMT_STATIC_THOUSANDS_SEPARATOR}; } -template FMT_FUNC Char decimal_point_impl(locale_ref) { +template +FMT_FUNC Char decimal_point_impl(locale_ref) { return '.'; } #endif @@ -137,7 +138,8 @@ FMT_FUNC std::system_error vsystem_error(int error_code, string_view format_str, namespace detail { -template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) { +template <> +FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) { // fallback_uintptr is always stored in little endian. int i = static_cast(sizeof(void*)) - 1; while (i > 0 && n.value[i] == 0) --i; @@ -146,22 +148,29 @@ template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) { } #if __cplusplus < 201703L -template constexpr const char basic_data::digits[][2]; -template constexpr const char basic_data::hex_digits[]; -template constexpr const char basic_data::signs[]; -template constexpr const unsigned basic_data::prefixes[]; -template constexpr const char basic_data::left_padding_shifts[]; +template +constexpr const char basic_data::digits[][2]; +template +constexpr const char basic_data::hex_digits[]; +template +constexpr const char basic_data::signs[]; +template +constexpr const unsigned basic_data::prefixes[]; +template +constexpr const char basic_data::left_padding_shifts[]; template constexpr const char basic_data::right_padding_shifts[]; #endif -template struct bits { +template +struct bits { static FMT_CONSTEXPR_DECL const int value = static_cast(sizeof(T) * std::numeric_limits::digits); }; class fp; -template fp normalize(fp value); +template +fp normalize(fp value); // Lower (upper) boundary is a value half way between a floating-point value // and its predecessor (successor). Boundaries have the same exponent as the @@ -189,17 +198,18 @@ class fp { // normalized form. static FMT_CONSTEXPR_DECL const int double_significand_size = std::numeric_limits::digits - 1; - static FMT_CONSTEXPR_DECL const uint64_t implicit_bit = - 1ULL << double_significand_size; - static FMT_CONSTEXPR_DECL const int significand_size = - bits::value; + static FMT_CONSTEXPR_DECL const uint64_t implicit_bit = 1ULL << double_significand_size; + static FMT_CONSTEXPR_DECL const int significand_size = bits::value; fp() : f(0), e(0) {} fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {} // Constructs fp from an IEEE754 double. It is a template to prevent compile // errors on platforms where double is not IEEE754. - template explicit fp(Double d) { assign(d); } + template + explicit fp(Double d) { + assign(d); + } // Assigns d to this and return true iff predecessor is closer than successor. template ::value)> @@ -216,8 +226,7 @@ class fp { constexpr bool is_double = sizeof(Float) == sizeof(uint64_t); auto u = bit_cast>(d); f = u & significand_mask; - int biased_e = - static_cast((u & exponent_mask) >> float_significand_size); + int biased_e = static_cast((u & exponent_mask) >> float_significand_size); // Predecessor is closer if d is a normalized power of 2 (f == 0) other than // the smallest normalized number (biased_e > 1). bool is_predecessor_closer = f == 0 && biased_e > 1; @@ -237,7 +246,8 @@ class fp { }; // Normalizes the value converted from double and multiplied by (1 << SHIFT). -template fp normalize(fp value) { +template +fp normalize(fp value) { // Handle subnormals. const auto shifted_implicit_bit = fp::implicit_bit << SHIFT; while ((value.f & shifted_implicit_bit) == 0) { @@ -245,8 +255,7 @@ template fp normalize(fp value) { --value.e; } // Subtract 1 to account for hidden bit. - const auto offset = - fp::significand_size - fp::double_significand_size - SHIFT - 1; + const auto offset = fp::significand_size - fp::double_significand_size - SHIFT - 1; value.f <<= offset; value.e -= offset; return value; @@ -280,34 +289,27 @@ inline fp get_cached_power(int min_exponent, int& pow10_exponent) { // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340. // These are generated by support/compute-powers.py. static constexpr const uint64_t pow10_significands[] = { - 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76, - 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df, - 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c, - 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5, - 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57, - 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7, - 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e, - 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996, - 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126, - 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053, - 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f, - 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b, - 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06, - 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb, - 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000, - 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984, - 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068, - 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8, - 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758, - 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85, - 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d, - 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25, - 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2, - 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a, - 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410, - 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129, - 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85, - 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841, + 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76, 0xcf42894a5dce35ea, + 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df, 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, + 0xbe5691ef416bd60c, 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5, + 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57, 0xc21094364dfb5637, + 0x9096ea6f3848984f, 0xd77485cb25823ac7, 0xa086cfcd97bf97f4, 0xef340a98172aace5, + 0xb23867fb2a35b28e, 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996, + 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126, 0xb5b5ada8aaff80b8, + 0x87625f056c7c4a8b, 0xc9bcff6034c13053, 0x964e858c91ba2655, 0xdff9772470297ebd, + 0xa6dfbd9fb8e5b88f, 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b, + 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06, 0xaa242499697392d3, + 0xfd87b5f28300ca0e, 0xbce5086492111aeb, 0x8cbccc096f5088cc, 0xd1b71758e219652c, + 0x9c40000000000000, 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984, + 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068, 0x9f4f2726179a2245, + 0xed63a231d4c4fb27, 0xb0de65388cc8ada8, 0x83c7088e1aab65db, 0xc45d1df942711d9a, + 0x924d692ca61be758, 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85, + 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d, 0x952ab45cfa97a0b3, + 0xde469fbd99a05fe3, 0xa59bc234db398c25, 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, + 0x88fcf317f22241e2, 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a, + 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410, 0x8bab8eefb6409c1a, + 0xd01fef10a657842c, 0x9b10a4e5e9913129, 0xe7109bfba19c0c9d, 0xac2820d9623bf429, + 0x80444b5e7aa7cf85, 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841, 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b, }; @@ -419,8 +421,7 @@ class bigint { double_bigit carry = 0; for (size_t i = 0, n = bigits_.size(); i < n; ++i) { double_bigit result = bigits_[i] * lower + (carry & mask); - carry = - bigits_[i] * upper + (result >> bigit_bits) + (carry >> bigit_bits); + carry = bigits_[i] * upper + (result >> bigit_bits) + (carry >> bigit_bits); bigits_[i] = static_cast(result); } while (carry != 0) { @@ -472,7 +473,8 @@ class bigint { return *this; } - template bigint& operator*=(Int value) { + template + bigint& operator*=(Int value) { FMT_ASSERT(value > 0, ""); multiply(uint32_or_64_or_128_t(value)); return *this; @@ -480,8 +482,7 @@ class bigint { friend int compare(const bigint& lhs, const bigint& rhs) { int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits(); - if (num_lhs_bigits != num_rhs_bigits) - return num_lhs_bigits > num_rhs_bigits ? 1 : -1; + if (num_lhs_bigits != num_rhs_bigits) return num_lhs_bigits > num_rhs_bigits ? 1 : -1; int i = static_cast(lhs.bigits_.size()) - 1; int j = static_cast(rhs.bigits_.size()) - 1; int end = i - j; @@ -495,8 +496,7 @@ class bigint { } // Returns compare(lhs1 + lhs2, rhs). - friend int add_compare(const bigint& lhs1, const bigint& lhs2, - const bigint& rhs) { + friend int add_compare(const bigint& lhs1, const bigint& lhs2, const bigint& rhs) { int max_lhs_bigits = (std::max)(lhs1.num_bigits(), lhs2.num_bigits()); int num_rhs_bigits = rhs.num_bigits(); if (max_lhs_bigits + 1 < num_rhs_bigits) return -1; @@ -556,8 +556,7 @@ class bigint { sum >>= bits::value; // Compute the carry. } // Do the same for the top half. - for (int bigit_index = num_bigits; bigit_index < num_result_bigits; - ++bigit_index) { + for (int bigit_index = num_bigits; bigit_index < num_result_bigits; ++bigit_index) { for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;) sum += static_cast(n[i++]) * n[j--]; (*this)[bigit_index] = static_cast(sum); @@ -605,15 +604,14 @@ enum class round_direction { unknown, up, down }; // error should be less than divisor / 2. inline round_direction get_round_direction(uint64_t divisor, uint64_t remainder, uint64_t error) { - FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow. - FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow. + FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow. + FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow. FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow. // Round down if (remainder + error) * 2 <= divisor. if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2) return round_direction::down; // Round up if (remainder - error) * 2 >= divisor. - if (remainder >= error && - remainder - error >= divisor - (remainder - error)) { + if (remainder >= error && remainder - error >= divisor - (remainder - error)) { return round_direction::up; } return round_direction::unknown; @@ -628,9 +626,8 @@ enum result { } inline uint64_t power_of_10_64(int exp) { - static constexpr const uint64_t data[] = {1, FMT_POWERS_OF_10(1), - FMT_POWERS_OF_10(1000000000ULL), - 10000000000000000000ULL}; + static constexpr const uint64_t data[] = { + 1, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL), 10000000000000000000ULL}; return data[exp]; } @@ -651,8 +648,8 @@ FMT_INLINE digits::result grisu_gen_digits(fp value, uint64_t error, int& exp, uint64_t fractional = value.f & (one.f - 1); exp = count_digits(integral); // kappa in Grisu. // Divide by 10 to prevent overflow. - auto result = handler.on_start(power_of_10_64(exp - 1) << -one.e, - value.f / 10, error * 10, exp); + auto result = + handler.on_start(power_of_10_64(exp - 1) << -one.e, value.f / 10, error * 10, exp); if (result != digits::more) return result; // Generate digits for the integral part. This can produce up to 10 digits. do { @@ -664,45 +661,44 @@ FMT_INLINE digits::result grisu_gen_digits(fp value, uint64_t error, int& exp, // This optimization by Milo Yip reduces the number of integer divisions by // one per iteration. switch (exp) { - case 10: - divmod_integral(1000000000); - break; - case 9: - divmod_integral(100000000); - break; - case 8: - divmod_integral(10000000); - break; - case 7: - divmod_integral(1000000); - break; - case 6: - divmod_integral(100000); - break; - case 5: - divmod_integral(10000); - break; - case 4: - divmod_integral(1000); - break; - case 3: - divmod_integral(100); - break; - case 2: - divmod_integral(10); - break; - case 1: - digit = integral; - integral = 0; - break; - default: - FMT_ASSERT(false, "invalid number of digits"); + case 10: + divmod_integral(1000000000); + break; + case 9: + divmod_integral(100000000); + break; + case 8: + divmod_integral(10000000); + break; + case 7: + divmod_integral(1000000); + break; + case 6: + divmod_integral(100000); + break; + case 5: + divmod_integral(10000); + break; + case 4: + divmod_integral(1000); + break; + case 3: + divmod_integral(100); + break; + case 2: + divmod_integral(10); + break; + case 1: + digit = integral; + integral = 0; + break; + default: + FMT_ASSERT(false, "invalid number of digits"); } --exp; auto remainder = (static_cast(integral) << -one.e) + fractional; result = handler.on_digit(static_cast('0' + digit), - power_of_10_64(exp) << -one.e, remainder, error, - exp, true); + power_of_10_64(exp) << -one.e, remainder, error, exp, true); if (result != digits::more) return result; } while (exp > 0); // Generate digits for the fractional part. @@ -783,14 +779,11 @@ struct uint128_wrapper { uint128_t internal_; constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT - : internal_{static_cast(low) | - (static_cast(high) << 64)} {} + : internal_{static_cast(low) | (static_cast(high) << 64)} {} constexpr uint128_wrapper(uint128_t u) : internal_{u} {} - constexpr uint64_t high() const FMT_NOEXCEPT { - return uint64_t(internal_ >> 64); - } + constexpr uint64_t high() const FMT_NOEXCEPT { return uint64_t(internal_ >> 64); } constexpr uint64_t low() const FMT_NOEXCEPT { return uint64_t(internal_); } uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT { @@ -801,24 +794,23 @@ struct uint128_wrapper { uint64_t high_; uint64_t low_; - constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT - : high_{high}, - low_{low} {} + constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT : high_{high}, + low_{low} {} constexpr uint64_t high() const FMT_NOEXCEPT { return high_; } constexpr uint64_t low() const FMT_NOEXCEPT { return low_; } uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT { -# if defined(_MSC_VER) && defined(_M_X64) +#if defined(_MSC_VER) && defined(_M_X64) unsigned char carry = _addcarry_u64(0, low_, n, &low_); _addcarry_u64(carry, high_, 0, &high_); return *this; -# else +#else uint64_t sum = low_ + n; high_ += (sum < low_ ? 1 : 0); low_ = sum; return *this; -# endif +#endif } #endif }; @@ -889,17 +881,14 @@ inline uint64_t umul192_middle64(uint64_t x, uint128_wrapper y) FMT_NOEXCEPT { // Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a // 64-bit unsigned integer. -inline uint64_t umul96_lower64(uint32_t x, uint64_t y) FMT_NOEXCEPT { - return x * y; -} +inline uint64_t umul96_lower64(uint32_t x, uint64_t y) FMT_NOEXCEPT { return x * y; } // Computes floor(log10(pow(2, e))) for e in [-1700, 1700] using the method from // https://fmt.dev/papers/Grisu-Exact.pdf#page=5, section 3.4. inline int floor_log10_pow2(int e) FMT_NOEXCEPT { FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent"); const int shift = 22; - return (e * static_cast(data::log10_2_significand >> (64 - shift))) >> - shift; + return (e * static_cast(data::log10_2_significand >> (64 - shift))) >> shift; } // Various fast log computations. @@ -908,19 +897,16 @@ inline int floor_log2_pow10(int e) FMT_NOEXCEPT { const uint64_t log2_10_integer_part = 3; const uint64_t log2_10_fractional_digits = 0x5269e12f346e2bf9; const int shift_amount = 19; - return (e * static_cast( - (log2_10_integer_part << shift_amount) | - (log2_10_fractional_digits >> (64 - shift_amount)))) >> + return (e * static_cast((log2_10_integer_part << shift_amount) | + (log2_10_fractional_digits >> (64 - shift_amount)))) >> shift_amount; } inline int floor_log10_pow2_minus_log10_4_over_3(int e) FMT_NOEXCEPT { FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent"); const uint64_t log10_4_over_3_fractional_digits = 0x1ffbfc2bbc780375; const int shift_amount = 22; - return (e * static_cast(data::log10_2_significand >> - (64 - shift_amount)) - - static_cast(log10_4_over_3_fractional_digits >> - (64 - shift_amount))) >> + return (e * static_cast(data::log10_2_significand >> (64 - shift_amount)) - + static_cast(log10_4_over_3_fractional_digits >> (64 - shift_amount))) >> shift_amount; } @@ -945,7 +931,8 @@ inline bool divisible_by_power_of_2(uint64_t x, int exp) FMT_NOEXCEPT { } // Table entry type for divisibility test. -template struct divtest_table_entry { +template +struct divtest_table_entry { T mod_inv; T max_quotient; }; @@ -954,41 +941,27 @@ template struct divtest_table_entry { inline bool divisible_by_power_of_5(uint32_t x, int exp) FMT_NOEXCEPT { FMT_ASSERT(exp <= 10, "too large exponent"); static constexpr const divtest_table_entry divtest_table[] = { - {0x00000001, 0xffffffff}, {0xcccccccd, 0x33333333}, - {0xc28f5c29, 0x0a3d70a3}, {0x26e978d5, 0x020c49ba}, - {0x3afb7e91, 0x0068db8b}, {0x0bcbe61d, 0x0014f8b5}, - {0x68c26139, 0x000431bd}, {0xae8d46a5, 0x0000d6bf}, - {0x22e90e21, 0x00002af3}, {0x3a2e9c6d, 0x00000897}, - {0x3ed61f49, 0x000001b7}}; + {0x00000001, 0xffffffff}, {0xcccccccd, 0x33333333}, {0xc28f5c29, 0x0a3d70a3}, + {0x26e978d5, 0x020c49ba}, {0x3afb7e91, 0x0068db8b}, {0x0bcbe61d, 0x0014f8b5}, + {0x68c26139, 0x000431bd}, {0xae8d46a5, 0x0000d6bf}, {0x22e90e21, 0x00002af3}, + {0x3a2e9c6d, 0x00000897}, {0x3ed61f49, 0x000001b7}}; return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient; } inline bool divisible_by_power_of_5(uint64_t x, int exp) FMT_NOEXCEPT { FMT_ASSERT(exp <= 23, "too large exponent"); static constexpr const divtest_table_entry divtest_table[] = { - {0x0000000000000001, 0xffffffffffffffff}, - {0xcccccccccccccccd, 0x3333333333333333}, - {0x8f5c28f5c28f5c29, 0x0a3d70a3d70a3d70}, - {0x1cac083126e978d5, 0x020c49ba5e353f7c}, - {0xd288ce703afb7e91, 0x0068db8bac710cb2}, - {0x5d4e8fb00bcbe61d, 0x0014f8b588e368f0}, - {0x790fb65668c26139, 0x000431bde82d7b63}, - {0xe5032477ae8d46a5, 0x0000d6bf94d5e57a}, - {0xc767074b22e90e21, 0x00002af31dc46118}, - {0x8e47ce423a2e9c6d, 0x0000089705f4136b}, - {0x4fa7f60d3ed61f49, 0x000001b7cdfd9d7b}, - {0x0fee64690c913975, 0x00000057f5ff85e5}, - {0x3662e0e1cf503eb1, 0x000000119799812d}, - {0xa47a2cf9f6433fbd, 0x0000000384b84d09}, - {0x54186f653140a659, 0x00000000b424dc35}, - {0x7738164770402145, 0x0000000024075f3d}, - {0xe4a4d1417cd9a041, 0x000000000734aca5}, - {0xc75429d9e5c5200d, 0x000000000170ef54}, - {0xc1773b91fac10669, 0x000000000049c977}, - {0x26b172506559ce15, 0x00000000000ec1e4}, - {0xd489e3a9addec2d1, 0x000000000002f394}, - {0x90e860bb892c8d5d, 0x000000000000971d}, - {0x502e79bf1b6f4f79, 0x0000000000001e39}, - {0xdcd618596be30fe5, 0x000000000000060b}}; + {0x0000000000000001, 0xffffffffffffffff}, {0xcccccccccccccccd, 0x3333333333333333}, + {0x8f5c28f5c28f5c29, 0x0a3d70a3d70a3d70}, {0x1cac083126e978d5, 0x020c49ba5e353f7c}, + {0xd288ce703afb7e91, 0x0068db8bac710cb2}, {0x5d4e8fb00bcbe61d, 0x0014f8b588e368f0}, + {0x790fb65668c26139, 0x000431bde82d7b63}, {0xe5032477ae8d46a5, 0x0000d6bf94d5e57a}, + {0xc767074b22e90e21, 0x00002af31dc46118}, {0x8e47ce423a2e9c6d, 0x0000089705f4136b}, + {0x4fa7f60d3ed61f49, 0x000001b7cdfd9d7b}, {0x0fee64690c913975, 0x00000057f5ff85e5}, + {0x3662e0e1cf503eb1, 0x000000119799812d}, {0xa47a2cf9f6433fbd, 0x0000000384b84d09}, + {0x54186f653140a659, 0x00000000b424dc35}, {0x7738164770402145, 0x0000000024075f3d}, + {0xe4a4d1417cd9a041, 0x000000000734aca5}, {0xc75429d9e5c5200d, 0x000000000170ef54}, + {0xc1773b91fac10669, 0x000000000049c977}, {0x26b172506559ce15, 0x00000000000ec1e4}, + {0xd489e3a9addec2d1, 0x000000000002f394}, {0x90e860bb892c8d5d, 0x000000000000971d}, + {0x502e79bf1b6f4f79, 0x0000000000001e39}, {0xdcd618596be30fe5, 0x000000000000060b}}; return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient; } @@ -1013,7 +986,8 @@ bool check_divisibility_and_divide_by_pow5(uint32_t& n) FMT_NOEXCEPT { // Computes floor(n / pow(10, N)) for small n and N. // Precondition: n <= pow(10, N + 1). -template uint32_t small_division_by_pow10(uint32_t n) FMT_NOEXCEPT { +template +uint32_t small_division_by_pow10(uint32_t n) FMT_NOEXCEPT { static constexpr struct { uint32_t magic_number; int shift_amount; @@ -1034,9 +1008,11 @@ inline uint64_t divide_by_10_to_kappa_plus_1(uint64_t n) FMT_NOEXCEPT { } // Various subroutines using pow10 cache -template struct cache_accessor; +template +struct cache_accessor; -template <> struct cache_accessor { +template <> +struct cache_accessor { using carrier_uint = float_info::carrier_uint; using cache_entry_type = uint64_t; @@ -1044,32 +1020,26 @@ template <> struct cache_accessor { FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, "k is out of range"); constexpr const uint64_t pow10_significands[] = { - 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f, - 0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb, - 0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28, - 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb, - 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a, - 0xe69594bec44de15c, 0x901d7cf73ab0acda, 0xb424dc35095cd810, - 0xe12e13424bb40e14, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff, - 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd, - 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424, - 0xd1b71758e219652c, 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b, - 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000, - 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, - 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, - 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000, - 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000, - 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000, - 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, - 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000, - 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0, - 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984, - 0xa18f07d736b90be5, 0xc9f2c9cd04674ede, 0xfc6f7c4045812296, - 0x9dc5ada82b70b59d, 0xc5371912364ce305, 0xf684df56c3e01bc6, - 0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20, - 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd, - 0x92efd1b8d0cf37be, 0xb7abc627050305ad, 0xe596b7b0c643c719, - 0x8f7e32ce7bea5c6f, 0xb35dbf821ae4f38b, 0xe0352f62a19e306e}; + 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f, 0xfd87b5f28300ca0e, + 0x9e74d1b791e07e49, 0xc612062576589ddb, 0xf79687aed3eec552, 0x9abe14cd44753b53, + 0xc16d9a0095928a28, 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb, + 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a, 0xe69594bec44de15c, + 0x901d7cf73ab0acda, 0xb424dc35095cd810, 0xe12e13424bb40e14, 0x8cbccc096f5088cc, + 0xafebff0bcb24aaff, 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd, + 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424, 0xd1b71758e219652c, + 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b, 0xcccccccccccccccd, 0x8000000000000000, + 0xa000000000000000, 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, + 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, 0xbebc200000000000, + 0xee6b280000000000, 0x9502f90000000000, 0xba43b74000000000, 0xe8d4a51000000000, + 0x9184e72a00000000, 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000, + 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, 0xad78ebc5ac620000, + 0xd8d726b7177a8000, 0x878678326eac9000, 0xa968163f0a57b400, 0xd3c21bcecceda100, + 0x84595161401484a0, 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984, + 0xa18f07d736b90be5, 0xc9f2c9cd04674ede, 0xfc6f7c4045812296, 0x9dc5ada82b70b59d, + 0xc5371912364ce305, 0xf684df56c3e01bc6, 0x9a130b963a6c115c, 0xc097ce7bc90715b3, + 0xf0bdc21abb48db20, 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd, + 0x92efd1b8d0cf37be, 0xb7abc627050305ad, 0xe596b7b0c643c719, 0x8f7e32ce7bea5c6f, + 0xb35dbf821ae4f38b, 0xe0352f62a19e306e}; return pow10_significands[k - float_info::min_k]; } @@ -1083,8 +1053,7 @@ template <> struct cache_accessor { return static_cast(cache >> (64 - 1 - beta_minus_1)); } - static bool compute_mul_parity(carrier_uint two_f, - const cache_entry_type& cache, + static bool compute_mul_parity(carrier_uint two_f, const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { FMT_ASSERT(beta_minus_1 >= 1, ""); FMT_ASSERT(beta_minus_1 < 64, ""); @@ -1109,14 +1078,14 @@ template <> struct cache_accessor { static carrier_uint compute_round_up_for_shorter_interval_case( const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { return (static_cast( - cache >> - (64 - float_info::significand_bits - 2 - beta_minus_1)) + + cache >> (64 - float_info::significand_bits - 2 - beta_minus_1)) + 1) / 2; } }; -template <> struct cache_accessor { +template <> +struct cache_accessor { using carrier_uint = float_info::carrier_uint; using cache_entry_type = uint128_wrapper; @@ -1778,14 +1747,12 @@ template <> struct cache_accessor { return pow10_significands[k - float_info::min_k]; #else static constexpr const uint64_t powers_of_5_64[] = { - 0x0000000000000001, 0x0000000000000005, 0x0000000000000019, - 0x000000000000007d, 0x0000000000000271, 0x0000000000000c35, - 0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1, - 0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd, - 0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9, - 0x000000071afd498d, 0x0000002386f26fc1, 0x000000b1a2bc2ec5, - 0x000003782dace9d9, 0x00001158e460913d, 0x000056bc75e2d631, - 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed, + 0x0000000000000001, 0x0000000000000005, 0x0000000000000019, 0x000000000000007d, + 0x0000000000000271, 0x0000000000000c35, 0x0000000000003d09, 0x000000000001312d, + 0x000000000005f5e1, 0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd, + 0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9, 0x000000071afd498d, + 0x0000002386f26fc1, 0x000000b1a2bc2ec5, 0x000003782dace9d9, 0x00001158e460913d, + 0x000056bc75e2d631, 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed, 0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9}; static constexpr const uint32_t pow10_recovery_errors[] = { @@ -1815,25 +1782,23 @@ template <> struct cache_accessor { // Try to recover the real cache. uint64_t pow5 = powers_of_5_64[offset]; uint128_wrapper recovered_cache = umul128(base_cache.high(), pow5); - uint128_wrapper middle_low = - umul128(base_cache.low() - (kb < 0 ? 1u : 0u), pow5); + uint128_wrapper middle_low = umul128(base_cache.low() - (kb < 0 ? 1u : 0u), pow5); recovered_cache += middle_low.high(); uint64_t high_to_middle = recovered_cache.high() << (64 - alpha); uint64_t middle_to_low = recovered_cache.low() << (64 - alpha); - recovered_cache = - uint128_wrapper{(recovered_cache.low() >> alpha) | high_to_middle, - ((middle_low.low() >> alpha) | middle_to_low)}; + recovered_cache = uint128_wrapper{(recovered_cache.low() >> alpha) | high_to_middle, + ((middle_low.low() >> alpha) | middle_to_low)}; if (kb < 0) recovered_cache += 1; // Get error. int error_idx = (k - float_info::min_k) / 16; - uint32_t error = (pow10_recovery_errors[error_idx] >> - ((k - float_info::min_k) % 16) * 2) & - 0x3; + uint32_t error = + (pow10_recovery_errors[error_idx] >> ((k - float_info::min_k) % 16) * 2) & + 0x3; // Add the error back. FMT_ASSERT(recovered_cache.low() + error >= recovered_cache.low(), ""); @@ -1851,8 +1816,7 @@ template <> struct cache_accessor { return static_cast(cache.high() >> (64 - 1 - beta_minus_1)); } - static bool compute_mul_parity(carrier_uint two_f, - const cache_entry_type& cache, + static bool compute_mul_parity(carrier_uint two_f, const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { FMT_ASSERT(beta_minus_1 >= 1, ""); FMT_ASSERT(beta_minus_1 < 64, ""); @@ -1886,15 +1850,12 @@ template <> struct cache_accessor { // Various integer checks template bool is_left_endpoint_integer_shorter_interval(int exponent) FMT_NOEXCEPT { - return exponent >= - float_info< - T>::case_shorter_interval_left_endpoint_lower_threshold && - exponent <= - float_info::case_shorter_interval_left_endpoint_upper_threshold; + return exponent >= float_info::case_shorter_interval_left_endpoint_lower_threshold && + exponent <= float_info::case_shorter_interval_left_endpoint_upper_threshold; } template -bool is_endpoint_integer(typename float_info::carrier_uint two_f, - int exponent, int minus_k) FMT_NOEXCEPT { +bool is_endpoint_integer(typename float_info::carrier_uint two_f, int exponent, + int minus_k) FMT_NOEXCEPT { if (exponent < float_info::case_fc_pm_half_lower_threshold) return false; // For k >= 0. if (exponent <= float_info::case_fc_pm_half_upper_threshold) return true; @@ -2061,23 +2022,22 @@ FMT_INLINE decimal_fp shorter_interval_case(int exponent) FMT_NOEXCEPT { // Otherwise, compute the round-up of y ret_value.significand = - cache_accessor::compute_round_up_for_shorter_interval_case( - cache, beta_minus_1); + cache_accessor::compute_round_up_for_shorter_interval_case(cache, beta_minus_1); ret_value.exponent = minus_k; // When tie occurs, choose one of them according to the rule if (exponent >= float_info::shorter_interval_tie_lower_threshold && exponent <= float_info::shorter_interval_tie_upper_threshold) { - ret_value.significand = ret_value.significand % 2 == 0 - ? ret_value.significand - : ret_value.significand - 1; + ret_value.significand = ret_value.significand % 2 == 0 ? ret_value.significand + : ret_value.significand - 1; } else if (ret_value.significand < xi) { ++ret_value.significand; } return ret_value; } -template decimal_fp to_decimal(T x) FMT_NOEXCEPT { +template +decimal_fp to_decimal(T x) FMT_NOEXCEPT { // Step 1: integer promotion & Schubfach multiplier calculation. using carrier_uint = typename float_info::carrier_uint; @@ -2088,8 +2048,8 @@ template decimal_fp to_decimal(T x) FMT_NOEXCEPT { const carrier_uint significand_mask = (static_cast(1) << float_info::significand_bits) - 1; carrier_uint significand = (br & significand_mask); - int exponent = static_cast((br & exponent_mask()) >> - float_info::significand_bits); + int exponent = + static_cast((br & exponent_mask()) >> float_info::significand_bits); if (exponent != 0) { // Check if normal. exponent += float_info::exponent_bias - float_info::significand_bits; @@ -2097,8 +2057,7 @@ template decimal_fp to_decimal(T x) FMT_NOEXCEPT { // Shorter interval case; proceed like Schubfach. if (significand == 0) return shorter_interval_case(exponent); - significand |= - (static_cast(1) << float_info::significand_bits); + significand |= (static_cast(1) << float_info::significand_bits); } else { // Subnormal case; the interval is always regular. if (significand == 0) return {0, 0}; @@ -2118,8 +2077,7 @@ template decimal_fp to_decimal(T x) FMT_NOEXCEPT { const uint32_t deltai = cache_accessor::compute_delta(cache, beta_minus_1); const carrier_uint two_fc = significand << 1; const carrier_uint two_fr = two_fc | 1; - const carrier_uint zi = - cache_accessor::compute_mul(two_fr << beta_minus_1, cache); + const carrier_uint zi = cache_accessor::compute_mul(two_fr << beta_minus_1, cache); // Step 2: Try larger divisor; remove trailing zeros if necessary @@ -2127,8 +2085,8 @@ template decimal_fp to_decimal(T x) FMT_NOEXCEPT { // better than the compiler; we are computing zi / big_divisor here decimal_fp ret_value; ret_value.significand = divide_by_10_to_kappa_plus_1(zi); - uint32_t r = static_cast(zi - float_info::big_divisor * - ret_value.significand); + uint32_t r = + static_cast(zi - float_info::big_divisor * ret_value.significand); if (r > deltai) { goto small_divisor_case_label; @@ -2145,8 +2103,7 @@ template decimal_fp to_decimal(T x) FMT_NOEXCEPT { // Check conditions in the order different from the paper // to take advantage of short-circuiting const carrier_uint two_fl = two_fc - 1; - if ((!include_left_endpoint || - !is_endpoint_integer(two_fl, exponent, minus_k)) && + if ((!include_left_endpoint || !is_endpoint_integer(two_fl, exponent, minus_k)) && !cache_accessor::compute_mul_parity(two_fl, cache, beta_minus_1)) { goto small_divisor_case_label; } @@ -2168,8 +2125,7 @@ template decimal_fp to_decimal(T x) FMT_NOEXCEPT { // Is dist divisible by 2^kappa? if ((dist & mask) == 0) { - const bool approx_y_parity = - ((dist ^ (float_info::small_divisor / 2)) & 1) != 0; + const bool approx_y_parity = ((dist ^ (float_info::small_divisor / 2)) & 1) != 0; dist >>= float_info::kappa; // Is dist divisible by 5^kappa? @@ -2204,8 +2160,7 @@ template decimal_fp to_decimal(T x) FMT_NOEXCEPT { else { // Since we know dist is small, we might be able to optimize the division // better than the compiler; we are computing dist / small_divisor here - ret_value.significand += - small_division_by_pow10::kappa>(dist); + ret_value.significand += small_division_by_pow10::kappa>(dist); } return ret_value; } @@ -2283,8 +2238,7 @@ void fallback_format(Double d, int num_digits, bool binary32, buffer& buf, } else if (high) { int result = add_compare(numerator, numerator, denominator); // Round half to even. - if (result > 0 || (result == 0 && (digit % 2) != 0)) - ++data[num_digits - 1]; + if (result > 0 || (result == 0 && (digit % 2) != 0)) ++data[num_digits - 1]; } buf.try_resize(to_unsigned(num_digits)); exp10 -= num_digits - 1; @@ -2367,8 +2321,8 @@ int format_float(T value, int precision, float_specs specs, buffer& buf) { const int min_exp = -60; // alpha in Grisu. int cached_exp10 = 0; // K in Grisu. fp normalized = normalize(fp(value)); - const auto cached_pow = get_cached_power( - min_exp - (normalized.e + fp::significand_size), cached_exp10); + const auto cached_pow = + get_cached_power(min_exp - (normalized.e + fp::significand_size), cached_exp10); normalized = normalized * cached_pow; // Limit precision to the maximum possible number of significant digits in an // IEEE754 double because we don't need to generate zeros. @@ -2395,16 +2349,14 @@ int format_float(T value, int precision, float_specs specs, buffer& buf) { } // namespace detail template -int snprintf_float(T value, int precision, float_specs specs, - buffer& buf) { +int snprintf_float(T value, int precision, float_specs specs, buffer& buf) { // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail. FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer"); static_assert(!std::is_same::value, ""); // Subtract 1 to account for the difference in precision since we use %e for // both general and exponent format. - if (specs.format == float_format::general || - specs.format == float_format::exp) + if (specs.format == float_format::general || specs.format == float_format::exp) precision = (precision >= 0 ? precision : 6) - 1; // Build the format string. @@ -2430,15 +2382,13 @@ int snprintf_float(T value, int precision, float_specs specs, auto capacity = buf.capacity() - offset; #ifdef FMT_FUZZ if (precision > 100000) - throw std::runtime_error( - "fuzz mode - avoid large allocation inside snprintf"); + throw std::runtime_error("fuzz mode - avoid large allocation inside snprintf"); #endif // Suppress the warning about a nonliteral format string. // Cannot use auto because of a bug in MinGW (#1532). int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF; - int result = precision >= 0 - ? snprintf_ptr(begin, capacity, format, precision, value) - : snprintf_ptr(begin, capacity, format, value); + int result = precision >= 0 ? snprintf_ptr(begin, capacity, format, precision, value) + : snprintf_ptr(begin, capacity, format, value); if (result < 0) { // The buffer will grow exponentially. buf.try_reserve(buf.capacity() + 1); @@ -2499,14 +2449,13 @@ int snprintf_float(T value, int precision, float_specs specs, } } // namespace detail -template <> struct formatter { - FMT_CONSTEXPR format_parse_context::iterator parse( - format_parse_context& ctx) { +template <> +struct formatter { + FMT_CONSTEXPR format_parse_context::iterator parse(format_parse_context& ctx) { return ctx.begin(); } - format_context::iterator format(const detail::bigint& n, - format_context& ctx) { + format_context::iterator format(const detail::bigint& n, format_context& ctx) { auto out = ctx.out(); bool first = true; for (auto i = n.bigits_.size(); i > 0; --i) { @@ -2519,8 +2468,7 @@ template <> struct formatter { out = format_to(out, FMT_STRING("{:08x}"), value); } if (n.exp_ > 0) - out = format_to(out, FMT_STRING("p{}"), - n.exp_ * detail::bigint::bigit_bits); + out = format_to(out, FMT_STRING("p{}"), n.exp_ * detail::bigint::bigit_bits); return out; } }; @@ -2554,8 +2502,7 @@ FMT_FUNC void detail::error_handler::on_error(const char* message) { FMT_THROW(format_error(message)); } -FMT_FUNC void report_system_error(int error_code, - const char* message) FMT_NOEXCEPT { +FMT_FUNC void report_system_error(int error_code, const char* message) FMT_NOEXCEPT { report_error(format_system_error, error_code, message); } @@ -2582,9 +2529,8 @@ FMT_FUNC void print(std::FILE* f, string_view text) { if (_isatty(fd)) { detail::utf8_to_utf16 u16(string_view(text.data(), text.size())); auto written = detail::dword(); - if (detail::WriteConsoleW(reinterpret_cast(_get_osfhandle(fd)), - u16.c_str(), static_cast(u16.size()), - &written, nullptr)) { + if (detail::WriteConsoleW(reinterpret_cast(_get_osfhandle(fd)), u16.c_str(), + static_cast(u16.size()), &written, nullptr)) { return; } // Fallback to fwrite on failure. It can happen if the output has been @@ -2606,8 +2552,7 @@ FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) { FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str, format_args args) { memory_buffer buffer; - detail::vformat_to(buffer, format_str, - basic_format_args>(args)); + detail::vformat_to(buffer, format_str, basic_format_args>(args)); fwrite_fully(buffer.data(), 1, buffer.size(), f); } #endif diff --git a/inst/include/fmt/format.h b/inst/include/fmt/format.h index 44bb39b3..01d8365e 100644 --- a/inst/include/fmt/format.h +++ b/inst/include/fmt/format.h @@ -44,43 +44,44 @@ #include "core.h" #ifdef __INTEL_COMPILER -# define FMT_ICC_VERSION __INTEL_COMPILER +#define FMT_ICC_VERSION __INTEL_COMPILER #elif defined(__ICL) -# define FMT_ICC_VERSION __ICL +#define FMT_ICC_VERSION __ICL #else -# define FMT_ICC_VERSION 0 +#define FMT_ICC_VERSION 0 #endif #ifdef __NVCC__ -# define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__) +#define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__) #else -# define FMT_CUDA_VERSION 0 +#define FMT_CUDA_VERSION 0 #endif #ifdef __has_builtin -# define FMT_HAS_BUILTIN(x) __has_builtin(x) +#define FMT_HAS_BUILTIN(x) __has_builtin(x) #else -# define FMT_HAS_BUILTIN(x) 0 +#define FMT_HAS_BUILTIN(x) 0 #endif #if FMT_GCC_VERSION || FMT_CLANG_VERSION -# define FMT_NOINLINE __attribute__((noinline)) +#define FMT_NOINLINE __attribute__((noinline)) #else -# define FMT_NOINLINE +#define FMT_NOINLINE #endif #if FMT_MSC_VER -# define FMT_MSC_DEFAULT = default +#define FMT_MSC_DEFAULT = default #else -# define FMT_MSC_DEFAULT +#define FMT_MSC_DEFAULT #endif #ifndef FMT_THROW -# if FMT_EXCEPTIONS -# if FMT_MSC_VER || FMT_NVCC +#if FMT_EXCEPTIONS +#if FMT_MSC_VER || FMT_NVCC FMT_BEGIN_NAMESPACE namespace detail { -template inline void do_throw(const Exception& x) { +template +inline void do_throw(const Exception& x) { // Silence unreachable code warnings in MSVC and NVCC because these // are nearly impossible to fix in a generic code. volatile bool b = true; @@ -88,56 +89,56 @@ template inline void do_throw(const Exception& x) { } } // namespace detail FMT_END_NAMESPACE -# define FMT_THROW(x) detail::do_throw(x) -# else -# define FMT_THROW(x) throw x -# endif -# else -# define FMT_THROW(x) \ - do { \ - FMT_ASSERT(false, (x).what()); \ - } while (false) -# endif +#define FMT_THROW(x) detail::do_throw(x) +#else +#define FMT_THROW(x) throw x +#endif +#else +#define FMT_THROW(x) \ + do { \ + FMT_ASSERT(false, (x).what()); \ + } while (false) +#endif #endif #if FMT_EXCEPTIONS -# define FMT_TRY try -# define FMT_CATCH(x) catch (x) +#define FMT_TRY try +#define FMT_CATCH(x) catch (x) #else -# define FMT_TRY if (true) -# define FMT_CATCH(x) if (false) +#define FMT_TRY if (true) +#define FMT_CATCH(x) if (false) #endif #ifndef FMT_DEPRECATED -# if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900 -# define FMT_DEPRECATED [[deprecated]] -# else -# if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__) -# define FMT_DEPRECATED __attribute__((deprecated)) -# elif FMT_MSC_VER -# define FMT_DEPRECATED __declspec(deprecated) -# else -# define FMT_DEPRECATED /* deprecated */ -# endif -# endif +#if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900 +#define FMT_DEPRECATED [[deprecated]] +#else +#if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__) +#define FMT_DEPRECATED __attribute__((deprecated)) +#elif FMT_MSC_VER +#define FMT_DEPRECATED __declspec(deprecated) +#else +#define FMT_DEPRECATED /* deprecated */ +#endif +#endif #endif // Workaround broken [[deprecated]] in the Intel, PGI and NVCC compilers. #if FMT_ICC_VERSION || defined(__PGI) || FMT_NVCC -# define FMT_DEPRECATED_ALIAS +#define FMT_DEPRECATED_ALIAS #else -# define FMT_DEPRECATED_ALIAS FMT_DEPRECATED +#define FMT_DEPRECATED_ALIAS FMT_DEPRECATED #endif #ifndef FMT_USE_USER_DEFINED_LITERALS // EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs. -# if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ - FMT_MSC_VER >= 1900) && \ - (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480) -# define FMT_USE_USER_DEFINED_LITERALS 1 -# else -# define FMT_USE_USER_DEFINED_LITERALS 0 -# endif +#if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ + FMT_MSC_VER >= 1900) && \ + (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480) +#define FMT_USE_USER_DEFINED_LITERALS 1 +#else +#define FMT_USE_USER_DEFINED_LITERALS 0 +#endif #endif // Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of @@ -145,26 +146,26 @@ FMT_END_NAMESPACE // largest integer type. This results in a reduction in binary size but will // cause a decrease in integer formatting performance. #if !defined(FMT_REDUCE_INT_INSTANTIATIONS) -# define FMT_REDUCE_INT_INSTANTIATIONS 0 +#define FMT_REDUCE_INT_INSTANTIATIONS 0 #endif // __builtin_clz is broken in clang with Microsoft CodeGen: // https://github.com/fmtlib/fmt/issues/519 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER -# define FMT_BUILTIN_CLZ(n) __builtin_clz(n) +#define FMT_BUILTIN_CLZ(n) __builtin_clz(n) #endif #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER -# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) +#define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) #endif #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctz)) -# define FMT_BUILTIN_CTZ(n) __builtin_ctz(n) +#define FMT_BUILTIN_CTZ(n) __builtin_ctz(n) #endif #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctzll)) -# define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n) +#define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n) #endif #if FMT_MSC_VER -# include // _BitScanReverse[64], _BitScanForward[64], _umul128 +#include // _BitScanReverse[64], _BitScanForward[64], _umul128 #endif // Some compilers masquerade as both MSVC and GCC-likes or otherwise support @@ -174,15 +175,15 @@ FMT_END_NAMESPACE FMT_BEGIN_NAMESPACE namespace detail { // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning. -# if !defined(__clang__) -# pragma managed(push, off) -# pragma intrinsic(_BitScanForward) -# pragma intrinsic(_BitScanReverse) -# if defined(_WIN64) -# pragma intrinsic(_BitScanForward64) -# pragma intrinsic(_BitScanReverse64) -# endif -# endif +#if !defined(__clang__) +#pragma managed(push, off) +#pragma intrinsic(_BitScanForward) +#pragma intrinsic(_BitScanReverse) +#if defined(_WIN64) +#pragma intrinsic(_BitScanForward64) +#pragma intrinsic(_BitScanReverse64) +#endif +#endif inline auto clz(uint32_t x) -> int { unsigned long r = 0; @@ -194,23 +195,23 @@ inline auto clz(uint32_t x) -> int { FMT_MSC_WARNING(suppress : 6102) return 31 ^ static_cast(r); } -# define FMT_BUILTIN_CLZ(n) detail::clz(n) +#define FMT_BUILTIN_CLZ(n) detail::clz(n) inline auto clzll(uint64_t x) -> int { unsigned long r = 0; -# ifdef _WIN64 +#ifdef _WIN64 _BitScanReverse64(&r, x); -# else +#else // Scan the high 32 bits. if (_BitScanReverse(&r, static_cast(x >> 32))) return 63 ^ (r + 32); // Scan the low 32 bits. _BitScanReverse(&r, static_cast(x)); -# endif +#endif FMT_ASSERT(x != 0, ""); FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. return 63 ^ static_cast(r); } -# define FMT_BUILTIN_CLZLL(n) detail::clzll(n) +#define FMT_BUILTIN_CLZLL(n) detail::clzll(n) inline auto ctz(uint32_t x) -> int { unsigned long r = 0; @@ -219,27 +220,27 @@ inline auto ctz(uint32_t x) -> int { FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning. return static_cast(r); } -# define FMT_BUILTIN_CTZ(n) detail::ctz(n) +#define FMT_BUILTIN_CTZ(n) detail::ctz(n) 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. -# ifdef _WIN64 +#ifdef _WIN64 _BitScanForward64(&r, x); -# else +#else // Scan the low 32 bits. if (_BitScanForward(&r, static_cast(x))) return static_cast(r); // Scan the high 32 bits. _BitScanForward(&r, static_cast(x >> 32)); r += 32; -# endif +#endif return static_cast(r); } -# define FMT_BUILTIN_CTZLL(n) detail::ctzll(n) -# if !defined(__clang__) -# pragma managed(pop) -# endif +#define FMT_BUILTIN_CTZLL(n) detail::ctzll(n) +#if !defined(__clang__) +#pragma managed(pop) +#endif } // namespace detail FMT_END_NAMESPACE #endif @@ -247,11 +248,10 @@ FMT_END_NAMESPACE FMT_BEGIN_NAMESPACE namespace detail { -#if __cplusplus >= 202002L || \ - (__cplusplus >= 201709L && FMT_GCC_VERSION >= 1002) -# define FMT_CONSTEXPR20 constexpr +#if __cplusplus >= 202002L || (__cplusplus >= 201709L && FMT_GCC_VERSION >= 1002) +#define FMT_CONSTEXPR20 constexpr #else -# define FMT_CONSTEXPR20 +#define FMT_CONSTEXPR20 #endif // An equivalent of `*reinterpret_cast(&source)` that doesn't have @@ -288,30 +288,34 @@ struct fallback_uintptr { }; #ifdef UINTPTR_MAX using uintptr_t = ::uintptr_t; -inline auto to_uintptr(const void* p) -> uintptr_t { - return bit_cast(p); -} +inline auto to_uintptr(const void* p) -> uintptr_t { return bit_cast(p); } #else using uintptr_t = fallback_uintptr; -inline auto to_uintptr(const void* p) -> fallback_uintptr { - return fallback_uintptr(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 auto max_value() -> T { +template +constexpr auto max_value() -> T { return (std::numeric_limits::max)(); } -template constexpr auto num_bits() -> int { +template +constexpr auto num_bits() -> int { return std::numeric_limits::digits; } // std::numeric_limits::digits may return 0 for 128-bit ints. -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); +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); } FMT_INLINE void assume(bool condition) { @@ -324,7 +328,8 @@ FMT_INLINE void assume(bool condition) { // An approximation of iterator_t for pre-C++20 systems. template using iterator_t = decltype(std::begin(std::declval())); -template using sentinel_t = decltype(std::end(std::declval())); +template +using sentinel_t = decltype(std::end(std::declval())); // A workaround for std::string not having mutable data() until C++17. template @@ -338,13 +343,19 @@ inline auto get_data(Container& c) -> typename Container::value_type* { #if defined(_SECURE_SCL) && _SECURE_SCL // Make a checked iterator to avoid MSVC warnings. -template using checked_ptr = stdext::checked_array_iterator; -template auto make_checked(T* p, size_t size) -> checked_ptr { +template +using checked_ptr = stdext::checked_array_iterator; +template +auto make_checked(T* p, size_t size) -> checked_ptr { return {p, size}; } #else -template using checked_ptr = T*; -template inline auto make_checked(T* p, size_t) -> T* { return p; } +template +using checked_ptr = T*; +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. @@ -382,7 +393,8 @@ template constexpr auto to_pointer(OutputIt, size_t) -> T* { return nullptr; } -template auto to_pointer(buffer_appender it, size_t n) -> T* { +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; @@ -405,8 +417,7 @@ constexpr auto base_iterator(Iterator, Iterator it) -> Iterator { // is spectacularly slow to compile in C++20 so use a simple fill_n // instead (#1998). template -FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value) - -> OutputIt { +FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value) -> OutputIt { for (Size i = 0; i < count; ++i) *out++ = value; return out; } @@ -448,8 +459,7 @@ FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end, * 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 auto utf8_decode(const char* s, uint32_t* c, int* e) - -> const char* { +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}; @@ -517,25 +527,24 @@ FMT_CONSTEXPR inline size_t compute_width(string_view s) { size_t* count; FMT_CONSTEXPR void operator()(uint32_t cp, int error) const { *count += detail::to_unsigned( - 1 + - (error == 0 && cp >= 0x1100 && - (cp <= 0x115f || // Hangul Jamo init. consonants - cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET〈 - cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET 〉 - // CJK ... Yi except Unicode Character “〿”: - (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) || - (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables - (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs - (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms - (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms - (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms - (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms - (cp >= 0x20000 && cp <= 0x2fffd) || // CJK - (cp >= 0x30000 && cp <= 0x3fffd) || - // Miscellaneous Symbols and Pictographs + Emoticons: - (cp >= 0x1f300 && cp <= 0x1f64f) || - // Supplemental Symbols and Pictographs: - (cp >= 0x1f900 && cp <= 0x1f9ff)))); + 1 + (error == 0 && cp >= 0x1100 && + (cp <= 0x115f || // Hangul Jamo init. consonants + cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET〈 + cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET 〉 + // CJK ... Yi except Unicode Character “〿”: + (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) || + (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables + (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs + (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms + (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms + (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms + (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms + (cp >= 0x20000 && cp <= 0x2fffd) || // CJK + (cp >= 0x30000 && cp <= 0x3fffd) || + // Miscellaneous Symbols and Pictographs + Emoticons: + (cp >= 0x1f300 && cp <= 0x1f64f) || + // Supplemental Symbols and Pictographs: + (cp >= 0x1f900 && cp <= 0x1f9ff)))); } }; for_each_codepoint(s, count_code_points{&num_code_points}); @@ -543,8 +552,8 @@ FMT_CONSTEXPR inline size_t compute_width(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())); + return compute_width( + basic_string_view(reinterpret_cast(s.data()), s.size())); } template @@ -554,8 +563,7 @@ inline auto code_point_index(basic_string_view s, size_t n) -> size_t { } // Calculates the index of the nth code point in a UTF-8 string. -inline auto code_point_index(basic_string_view s, size_t n) - -> size_t { +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) { @@ -565,11 +573,11 @@ inline auto code_point_index(basic_string_view s, size_t n) } template -using is_fast_float = bool_constant::is_iec559 && - sizeof(T) <= sizeof(double)>; +using is_fast_float = + bool_constant::is_iec559 && sizeof(T) <= sizeof(double)>; #ifndef FMT_USE_FULL_CACHE_DRAGONBOX -# define FMT_USE_FULL_CACHE_DRAGONBOX 0 +#define FMT_USE_FULL_CACHE_DRAGONBOX 0 #endif template @@ -641,8 +649,7 @@ class basic_memory_buffer final : public detail::buffer { using value_type = T; using const_reference = const T&; - explicit basic_memory_buffer(const Allocator& alloc = Allocator()) - : alloc_(alloc) { + explicit basic_memory_buffer(const Allocator& alloc = Allocator()) : alloc_(alloc) { this->set(store_, SIZE); } ~basic_memory_buffer() { deallocate(); } @@ -680,8 +687,7 @@ class basic_memory_buffer final : public detail::buffer { Moves the content of the other ``basic_memory_buffer`` object to this one. \endrst */ - auto operator=(basic_memory_buffer&& other) FMT_NOEXCEPT - -> basic_memory_buffer& { + auto operator=(basic_memory_buffer&& other) FMT_NOEXCEPT -> basic_memory_buffer& { FMT_ASSERT(this != &other, ""); deallocate(); move(other); @@ -721,8 +727,7 @@ void basic_memory_buffer::grow(size_t size) { else if (new_capacity > max_size) new_capacity = size > max_size ? size : max_size; T* old_data = this->data(); - T* new_data = - std::allocator_traits::allocate(alloc_, new_capacity); + T* new_data = std::allocator_traits::allocate(alloc_, new_capacity); // The following code doesn't throw, so the raw pointer above doesn't leak. std::uninitialized_copy(old_data, old_data + this->size(), detail::make_checked(new_data, new_capacity)); @@ -736,8 +741,7 @@ void basic_memory_buffer::grow(size_t size) { using memory_buffer = basic_memory_buffer; template -struct is_contiguous> : std::true_type { -}; +struct is_contiguous> : std::true_type {}; namespace detail { FMT_API void print(std::FILE*, string_view); @@ -748,8 +752,7 @@ FMT_CLASS_API class FMT_API format_error : public std::runtime_error { public: explicit format_error(const char* message) : std::runtime_error(message) {} - explicit format_error(const std::string& message) - : std::runtime_error(message) {} + explicit format_error(const std::string& message) : std::runtime_error(message) {} format_error(const format_error&) = default; format_error& operator=(const format_error&) = default; format_error(format_error&&) = default; @@ -766,13 +769,11 @@ class FMT_API format_error : public std::runtime_error { \endrst */ template > -FMT_INLINE auto make_args_checked(const S& fmt, - const remove_reference_t&... args) +FMT_INLINE auto make_args_checked(const S& fmt, const remove_reference_t&... args) -> format_arg_store, remove_reference_t...> { static_assert( - detail::count<( - std::is_base_of>::value && - std::is_reference::value)...>() == 0, + detail::count<(std::is_base_of>::value && + std::is_reference::value)...>() == 0, "passing views as lvalues is disallowed"); detail::check_format_string(fmt); return {args...}; @@ -781,10 +782,11 @@ FMT_INLINE auto make_args_checked(const S& fmt, // compile-time support namespace detail_exported { #if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS -template struct fixed_string { +template +struct fixed_string { constexpr fixed_string(const Char (&str)[N]) { - detail::copy_str(static_cast(str), - str + N, data); + detail::copy_str(static_cast(str), str + N, + data); } Char data[N]{}; }; @@ -792,8 +794,7 @@ template struct fixed_string { // Converts a compile-time string to basic_string_view. template -constexpr auto compile_string_to_view(const Char (&s)[N]) - -> basic_string_view { +constexpr auto compile_string_to_view(const Char (&s)[N]) -> basic_string_view { // Remove trailing NUL character if needed. Won't be present if this is used // with a raw character array (i.e. not defined as a string). return {s, N - (std::char_traits::to_int_type(s[N - 1]) == 0 ? 1 : 0)}; @@ -807,18 +808,18 @@ constexpr auto compile_string_to_view(detail::std_string_view s) FMT_BEGIN_DETAIL_NAMESPACE -inline void throw_format_error(const char* message) { - FMT_THROW(format_error(message)); -} +inline void throw_format_error(const char* message) { FMT_THROW(format_error(message)); } -template struct is_integral : std::is_integral {}; -template <> struct is_integral : std::true_type {}; -template <> struct is_integral : std::true_type {}; +template +struct is_integral : std::is_integral {}; +template <> +struct is_integral : std::true_type {}; +template <> +struct is_integral : std::true_type {}; template -using is_signed = - std::integral_constant::is_signed || - std::is_same::value>; +using is_signed = std::integral_constant::is_signed || + std::is_same::value>; // Returns true if value is negative, false otherwise. // Same as `value < 0` but doesn't produce warnings if T is an unsigned type. @@ -842,41 +843,38 @@ FMT_CONSTEXPR auto is_supported_floating_point(T) -> uint16_t { // represent all values of an integral type T. template using uint32_or_64_or_128_t = - conditional_t() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS, - uint32_t, + conditional_t() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS, uint32_t, conditional_t() <= 64, uint64_t, uint128_t>>; template using uint64_or_128_t = conditional_t() <= 64, uint64_t, uint128_t>; #define FMT_POWERS_OF_10(factor) \ factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \ - (factor)*1000000, (factor)*10000000, (factor)*100000000, \ - (factor)*1000000000 + (factor)*1000000, (factor)*10000000, (factor)*100000000, (factor)*1000000000 // Static data is placed in this class template for the header-only config. -template struct basic_data { +template +struct basic_data { // log10(2) = 0x0.4d104d427de7fbcc... static const uint64_t log10_2_significand = 0x4d104d427de7fbcc; // GCC generates slightly better code for pairs than chars. FMT_API static constexpr const char digits[100][2] = { - {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'}, - {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'}, - {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'}, - {'1', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'}, - {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'}, - {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'}, - {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'}, - {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'}, - {'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, - {'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'}, - {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'}, - {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'}, - {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'}, - {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, - {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'}, - {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'}, - {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}}; + {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'}, {'0', '6'}, + {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'}, {'1', '2'}, {'1', '3'}, + {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'}, {'1', '8'}, {'1', '9'}, {'2', '0'}, + {'2', '1'}, {'2', '2'}, {'2', '3'}, {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, + {'2', '8'}, {'2', '9'}, {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, + {'3', '5'}, {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'}, + {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'}, {'4', '8'}, + {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, {'5', '4'}, {'5', '5'}, + {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'}, {'6', '0'}, {'6', '1'}, {'6', '2'}, + {'6', '3'}, {'6', '4'}, {'6', '5'}, {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, + {'7', '0'}, {'7', '1'}, {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, + {'7', '7'}, {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, + {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'}, {'9', '0'}, + {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'}, {'9', '6'}, {'9', '7'}, + {'9', '8'}, {'9', '9'}}; FMT_API static constexpr const char hex_digits[] = "0123456789abcdef"; FMT_API static constexpr const char signs[4] = {0, '-', '+', ' '}; @@ -894,7 +892,8 @@ extern template struct basic_data; // This is a struct rather than an alias to avoid shadowing warnings in gcc. struct data : basic_data<> {}; -template FMT_CONSTEXPR auto count_digits_fallback(T n) -> int { +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 @@ -921,15 +920,15 @@ FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int { if (!is_constant_evaluated()) { // https://github.com/fmtlib/format-benchmark/blob/master/digits10 // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)). - constexpr uint16_t bsr2log10[] = { - 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, - 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, - 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20}; + constexpr uint16_t bsr2log10[] = {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, 10, 11, 11, 11, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, + 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20}; auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63]; - constexpr const uint64_t zero_or_powers_of_10[] = { - 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL), - 10000000000000000000ULL}; + constexpr const uint64_t zero_or_powers_of_10[] = {0, 0, FMT_POWERS_OF_10(1U), + FMT_POWERS_OF_10(1000000000ULL), + 10000000000000000000ULL}; return t - (n < zero_or_powers_of_10[t]); } #endif @@ -950,7 +949,8 @@ FMT_CONSTEXPR auto count_digits(UInt n) -> int { return num_digits; } -template <> auto count_digits<4>(detail::fallback_uintptr n) -> int; +template <> +auto count_digits<4>(detail::fallback_uintptr n) -> int; // It is a separate function rather than a part of count_digits to workaround // the lack of static constexpr in constexpr functions. @@ -985,17 +985,21 @@ FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int { return count_digits_fallback(n); } -template constexpr auto digits10() FMT_NOEXCEPT -> int { +template +constexpr auto digits10() FMT_NOEXCEPT -> int { return std::numeric_limits::digits10; } -template <> constexpr auto digits10() FMT_NOEXCEPT -> int { +template <> +constexpr auto digits10() FMT_NOEXCEPT -> int { return 38; } -template <> constexpr auto digits10() FMT_NOEXCEPT -> int { +template <> +constexpr auto digits10() FMT_NOEXCEPT -> int { return 38; } -template struct thousands_sep_result { +template +struct thousands_sep_result { std::string grouping; Char thousands_sep; }; @@ -1014,15 +1018,18 @@ inline auto thousands_sep(locale_ref loc) -> thousands_sep_result { template FMT_API auto decimal_point_impl(locale_ref loc) -> Char; -template inline auto decimal_point(locale_ref loc) -> Char { +template +inline auto decimal_point(locale_ref loc) -> Char { return Char(decimal_point_impl(loc)); } -template <> inline auto decimal_point(locale_ref loc) -> wchar_t { +template <> +inline auto decimal_point(locale_ref loc) -> wchar_t { return decimal_point_impl(loc); } // Compares two characters for equality. -template auto equal2(const Char* lhs, const char* rhs) -> bool { +template +auto equal2(const Char* lhs, const char* rhs) -> bool { return lhs[0] == rhs[0] && lhs[1] == rhs[1]; } inline auto equal2(const char* lhs, const char* rhs) -> bool { @@ -1030,13 +1037,15 @@ inline auto equal2(const char* lhs, const char* rhs) -> bool { } // Copies two characters from src to dst. -template void copy2(Char* dst, const char* src) { +template +void copy2(Char* dst, const char* src) { *dst++ = static_cast(*src++); *dst = static_cast(*src); } FMT_INLINE void copy2(char* dst, const char* src) { memcpy(dst, src, 2); } -template struct format_decimal_result { +template +struct format_decimal_result { Iterator begin; Iterator end; }; @@ -1093,15 +1102,15 @@ FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits, do { const char* digits = upper ? "0123456789ABCDEF" : data::hex_digits; unsigned digit = (value & ((1 << BASE_BITS) - 1)); - *--buffer = static_cast(BASE_BITS < 4 ? static_cast('0' + digit) - : digits[digit]); + *--buffer = + static_cast(BASE_BITS < 4 ? static_cast('0' + digit) : digits[digit]); } while ((value >>= BASE_BITS) != 0); return end; } template -auto format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits, - bool = false) -> Char* { +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) { @@ -1122,8 +1131,7 @@ auto format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits, } template -inline auto format_uint(It out, UInt value, int num_digits, bool upper = false) - -> It { +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; @@ -1150,9 +1158,11 @@ class utf8_to_utf16 { namespace dragonbox { // Type-specific information that Dragonbox uses. -template struct float_info; +template +struct float_info; -template <> struct float_info { +template <> +struct float_info { using carrier_uint = uint32_t; static const int significand_bits = 23; static const int exponent_bits = 8; @@ -1178,7 +1188,8 @@ template <> struct float_info { static const int max_trailing_zeros = 7; }; -template <> struct float_info { +template <> +struct float_info { using carrier_uint = uint64_t; static const int significand_bits = 52; static const int exponent_bits = 11; @@ -1204,7 +1215,8 @@ template <> struct float_info { static const int max_trailing_zeros = 16; }; -template struct decimal_fp { +template +struct decimal_fp { using significand_type = typename float_info::carrier_uint; significand_type significand; int exponent; @@ -1215,8 +1227,7 @@ FMT_API auto to_decimal(T x) FMT_NOEXCEPT -> decimal_fp; } // namespace dragonbox template -constexpr auto exponent_mask() -> - typename dragonbox::float_info::carrier_uint { +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; @@ -1245,43 +1256,39 @@ auto write_exponent(int exp, It it) -> It { } template -auto format_float(T value, int precision, float_specs specs, buffer& buf) - -> int; +auto format_float(T value, int precision, float_specs specs, buffer& buf) -> int; // Formats a floating-point number with snprintf. template -auto snprintf_float(T value, int precision, float_specs specs, - buffer& buf) -> int; +auto snprintf_float(T value, int precision, float_specs specs, buffer& buf) -> int; -template auto promote_float(T value) -> T { return value; } -inline auto promote_float(float value) -> double { - 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 auto fill(OutputIt it, size_t n, - const fill_t& fill) -> OutputIt { +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(); - for (size_t i = 0; i < n; ++i) - it = copy_str(data, data + fill_size, it); + for (size_t i = 0; i < n; ++i) it = copy_str(data, data + fill_size, it); return it; } // Writes the output of f, padded according to format specifications in specs. // size: output size in code units. // width: output display width in (terminal) column positions. -template -FMT_CONSTEXPR auto write_padded(OutputIt out, - const basic_format_specs& specs, +template +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; - auto* shifts = align == align::left ? data::left_padding_shifts - : data::right_padding_shifts; + auto* shifts = + align == align::left ? data::left_padding_shifts : data::right_padding_shifts; size_t left_padding = padding >> shifts[specs.align]; size_t right_padding = padding - left_padding; auto it = reserve(out, size + padding * specs.fill.size()); @@ -1291,8 +1298,7 @@ FMT_CONSTEXPR auto write_padded(OutputIt out, return base_iterator(out, it); } -template +template 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); @@ -1300,18 +1306,17 @@ constexpr auto write_padded(OutputIt out, const basic_format_specs& specs, template 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(); - return copy_str(data, data + bytes.size(), it); - }); + const basic_format_specs& specs) -> OutputIt { + return write_padded(out, specs, bytes.size(), + [bytes](reserve_iterator it) { + const char* data = bytes.data(); + return copy_str(data, data + bytes.size(), it); + }); } template -auto write_ptr(OutputIt out, UIntPtr value, - const basic_format_specs* specs) -> OutputIt { +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) { @@ -1325,25 +1330,23 @@ auto write_ptr(OutputIt out, UIntPtr value, template FMT_CONSTEXPR auto write_char(OutputIt out, Char value, - const basic_format_specs& specs) - -> OutputIt { + const basic_format_specs& specs) -> OutputIt { return write_padded(out, specs, 1, [=](reserve_iterator it) { *it++ = value; return it; }); } template -FMT_CONSTEXPR auto write(OutputIt out, Char value, - const basic_format_specs& specs, +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); + return check_char_specs(specs) ? write_char(out, value, specs) + : write(out, static_cast(value), specs, loc); } // Data for write_int that doesn't depend on output iterator type. It is used to // avoid template code bloat. -template struct write_int_data { +template +struct write_int_data { size_t size; size_t padding; @@ -1368,8 +1371,7 @@ 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 auto write_int(OutputIt out, int num_digits, - unsigned prefix, +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. @@ -1393,8 +1395,7 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits, template auto write_int_localized(OutputIt& out, UInt value, unsigned prefix, - const basic_format_specs& specs, locale_ref loc) - -> bool { + const basic_format_specs& specs, locale_ref loc) -> bool { static_assert(std::is_same, UInt>::value, ""); const auto sep_size = 1; auto ts = thousands_sep(loc); @@ -1423,24 +1424,22 @@ auto write_int_localized(OutputIt& out, UInt value, unsigned prefix, auto p = buffer.data() + size - 1; for (int i = num_digits - 1; i > 0; --i) { *p-- = static_cast(digits[i]); - if (*group <= 0 || ++digit_index % *group != 0 || - *group == max_value()) + if (*group <= 0 || ++digit_index % *group != 0 || *group == max_value()) continue; if (group + 1 != groups.cend()) { digit_index = 0; ++group; } - std::uninitialized_copy(s.data(), s.data() + s.size(), - make_checked(p, s.size())); + std::uninitialized_copy(s.data(), s.data() + s.size(), make_checked(p, s.size())); p -= s.size(); } *p-- = static_cast(*digits); if (prefix != 0) *p = static_cast(prefix); auto data = buffer.data(); - out = write_padded( - out, specs, usize, usize, [=](reserve_iterator it) { - return copy_str(data, data + size, it); - }); + out = write_padded(out, specs, usize, usize, + [=](reserve_iterator it) { + return copy_str(data, data + size, it); + }); return true; } @@ -1449,7 +1448,8 @@ FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) { prefix += (1u + (value > 0xff ? 1 : 0)) << 24; } -template struct write_int_arg { +template +struct write_int_arg { UInt abs_value; unsigned prefix; }; @@ -1477,74 +1477,71 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg arg, auto prefix = arg.prefix; auto utype = static_cast(specs.type); switch (specs.type) { - case 0: - case 'd': { - if (specs.localized && - write_int_localized(out, static_cast>(abs_value), - prefix, specs, loc)) { - return out; + case 0: + case 'd': { + if (specs.localized && + write_int_localized(out, static_cast>(abs_value), prefix, + specs, loc)) { + return out; + } + auto num_digits = count_digits(abs_value); + return write_int(out, num_digits, prefix, specs, + [=](reserve_iterator it) { + return format_decimal(it, abs_value, num_digits).end; + }); } - auto num_digits = count_digits(abs_value); - return write_int( - out, num_digits, prefix, specs, [=](reserve_iterator it) { - return format_decimal(it, abs_value, num_digits).end; - }); - } - case 'x': - case 'X': { - if (specs.alt) prefix_append(prefix, (utype << 8) | '0'); - bool upper = specs.type != 'x'; - int num_digits = count_digits<4>(abs_value); - return write_int( - out, num_digits, prefix, specs, [=](reserve_iterator it) { - return format_uint<4, Char>(it, abs_value, num_digits, upper); - }); - } - case 'b': - case 'B': { - if (specs.alt) prefix_append(prefix, (utype << 8) | '0'); - int num_digits = count_digits<1>(abs_value); - return write_int(out, num_digits, prefix, specs, - [=](reserve_iterator it) { - return format_uint<1, Char>(it, abs_value, num_digits); - }); - } - case 'o': { - int num_digits = count_digits<3>(abs_value); - if (specs.alt && specs.precision <= num_digits && abs_value != 0) { - // Octal prefix '0' is counted as a digit, so only add it if precision - // is not greater than the number of digits. - prefix_append(prefix, '0'); + case 'x': + case 'X': { + if (specs.alt) prefix_append(prefix, (utype << 8) | '0'); + bool upper = specs.type != 'x'; + int num_digits = count_digits<4>(abs_value); + return write_int(out, num_digits, prefix, specs, + [=](reserve_iterator it) { + return format_uint<4, Char>(it, abs_value, num_digits, upper); + }); } - return write_int(out, num_digits, prefix, specs, - [=](reserve_iterator it) { - return format_uint<3, Char>(it, abs_value, num_digits); - }); - } - case 'c': - return write_char(out, static_cast(abs_value), specs); - default: - FMT_THROW(format_error("invalid type specifier")); + case 'b': + case 'B': { + if (specs.alt) prefix_append(prefix, (utype << 8) | '0'); + int num_digits = count_digits<1>(abs_value); + return write_int(out, num_digits, prefix, specs, + [=](reserve_iterator it) { + return format_uint<1, Char>(it, abs_value, num_digits); + }); + } + case 'o': { + int num_digits = count_digits<3>(abs_value); + if (specs.alt && specs.precision <= num_digits && abs_value != 0) { + // Octal prefix '0' is counted as a digit, so only add it if precision + // is not greater than the number of digits. + prefix_append(prefix, '0'); + } + return write_int(out, num_digits, prefix, specs, + [=](reserve_iterator it) { + return format_uint<3, Char>(it, abs_value, num_digits); + }); + } + case 'c': + return write_char(out, static_cast(abs_value), specs); + default: + FMT_THROW(format_error("invalid type specifier")); } return out; } template ::value && - !std::is_same::value && + FMT_ENABLE_IF(is_integral::value && !std::is_same::value && std::is_same>::value)> -FMT_CONSTEXPR auto write(OutputIt out, T value, - const basic_format_specs& specs, locale_ref loc) - -> OutputIt { +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. template ::value && - !std::is_same::value && + FMT_ENABLE_IF(is_integral::value && !std::is_same::value && !std::is_same>::value)> FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, - const basic_format_specs& specs, - locale_ref loc) -> OutputIt { + const basic_format_specs& specs, locale_ref loc) + -> OutputIt { return write_int(out, make_write_int_arg(value, specs.sign), specs, loc); } @@ -1555,24 +1552,19 @@ FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, auto size = s.size(); if (specs.precision >= 0 && to_unsigned(specs.precision) < size) size = code_point_index(s, to_unsigned(specs.precision)); - auto width = - specs.width != 0 ? compute_width(basic_string_view(data, size)) : 0; - return write_padded(out, specs, size, width, - [=](reserve_iterator it) { - return copy_str(data, data + size, it); - }); + auto width = specs.width != 0 ? compute_width(basic_string_view(data, size)) : 0; + return write_padded(out, specs, size, width, [=](reserve_iterator it) { + return copy_str(data, data + size, it); + }); } template -FMT_CONSTEXPR auto write(OutputIt out, - basic_string_view> s, - const basic_format_specs& specs, locale_ref) - -> OutputIt { +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 auto write(OutputIt out, const Char* s, - const basic_format_specs& specs, locale_ref) - -> OutputIt { + 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); @@ -1581,8 +1573,7 @@ FMT_CONSTEXPR auto write(OutputIt out, const Char* s, template 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"); + auto str = isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan"); constexpr size_t str_size = 3; auto sign = fspecs.sign; auto size = str_size + (sign ? 1 : 0); @@ -1617,17 +1608,15 @@ inline auto write_significand(OutputIt out, const char* significand, return copy_str(significand, significand + significand_size, out); } template -inline auto write_significand(OutputIt out, UInt significand, - int significand_size) -> OutputIt { +inline auto write_significand(OutputIt out, UInt significand, int significand_size) + -> OutputIt { return format_decimal(out, significand, significand_size).end; } -template ::value)> +template ::value)> 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; + if (!decimal_point) return format_decimal(out, significand, significand_size).end; auto end = format_decimal(out + 1, significand, significand_size).end; if (integral_size == 1) { out[0] = out[1]; @@ -1641,22 +1630,19 @@ inline auto write_significand(Char* out, UInt significand, int significand_size, template >::value)> -inline auto write_significand(OutputIt out, UInt significand, - int significand_size, int integral_size, - Char decimal_point) -> OutputIt { +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, - integral_size, decimal_point); + auto end = write_significand(buffer, significand, significand_size, integral_size, + decimal_point); return detail::copy_str_noinline(buffer, end, out); } template -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); +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; *out++ = decimal_point; return detail::copy_str_noinline(significand + integral_size, @@ -1664,9 +1650,8 @@ inline auto write_significand(OutputIt out, const char* significand, } template -auto write_float(OutputIt out, const DecimalFP& fp, - const basic_format_specs& specs, float_specs fspecs, - Char decimal_point) -> OutputIt { +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'); @@ -1702,8 +1687,7 @@ auto write_float(OutputIt out, const DecimalFP& fp, auto write = [=](iterator it) { if (sign) *it++ = static_cast(data::signs[sign]); // Insert a decimal point after the first digit and add an exponent. - it = write_significand(it, significand, significand_size, 1, - decimal_point); + it = write_significand(it, significand, significand_size, 1, decimal_point); if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero); *it++ = static_cast(exp_char); return write_exponent(output_exp, it); @@ -1739,15 +1723,13 @@ auto write_float(OutputIt out, const DecimalFP& fp, size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0); return write_padded(out, specs, size, [&](iterator it) { if (sign) *it++ = static_cast(data::signs[sign]); - it = write_significand(it, significand, significand_size, exp, - decimal_point); + it = write_significand(it, significand, significand_size, exp, decimal_point); return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it; }); } // 1234e-6 -> 0.001234 int num_zeros = -exp; - if (significand_size == 0 && fspecs.precision >= 0 && - fspecs.precision < num_zeros) { + if (significand_size == 0 && fspecs.precision >= 0 && fspecs.precision < num_zeros) { num_zeros = fspecs.precision; } bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint; @@ -1764,8 +1746,8 @@ auto write_float(OutputIt out, const DecimalFP& fp, template ::value)> -auto write(OutputIt out, T value, basic_format_specs specs, - locale_ref loc = {}) -> OutputIt { +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; @@ -1791,8 +1773,7 @@ auto write(OutputIt out, T value, basic_format_specs specs, if (fspecs.format == float_format::hex) { if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]); snprintf_float(promote_float(value), specs.precision, fspecs, buffer); - return write_bytes(out, {buffer.data(), buffer.size()}, - specs); + return write_bytes(out, {buffer.data(), buffer.size()}, specs); } int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6; if (fspecs.format == float_format::exp) { @@ -1805,8 +1786,7 @@ auto write(OutputIt out, T value, basic_format_specs specs, fspecs.use_grisu = is_fast_float(); int exp = format_float(promote_float(value), precision, fspecs, buffer); fspecs.precision = precision; - Char point = - fspecs.locale ? decimal_point(loc) : static_cast('.'); + Char point = fspecs.locale ? decimal_point(loc) : static_cast('.'); auto fp = big_decimal_fp{buffer.data(), static_cast(buffer.size()), exp}; return write_float(out, fp, specs, fspecs, point); } @@ -1837,22 +1817,20 @@ auto write(OutputIt out, T value) -> OutputIt { } template ::value && - !is_fast_float::value)> + FMT_ENABLE_IF(std::is_floating_point::value && !is_fast_float::value)> inline auto write(OutputIt out, T value) -> OutputIt { return write(out, value, basic_format_specs()); } template -auto write(OutputIt out, monostate, basic_format_specs = {}, - locale_ref = {}) -> OutputIt { +auto write(OutputIt out, monostate, basic_format_specs = {}, locale_ref = {}) + -> OutputIt { FMT_ASSERT(false, ""); return out; } template -FMT_CONSTEXPR auto write(OutputIt out, basic_string_view value) - -> OutputIt { +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); @@ -1865,8 +1843,7 @@ constexpr auto write(OutputIt out, const T& value) -> OutputIt { } template ::value && - !std::is_same::value && + FMT_ENABLE_IF(is_integral::value && !std::is_same::value && !std::is_same::value)> FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { auto abs_value = static_cast>(value); @@ -1889,21 +1866,19 @@ FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { // FMT_ENABLE_IF() condition separated to workaround MSVC bug template < typename Char, typename OutputIt, typename T, - bool check = - std::is_enum::value && !std::is_same::value && - mapped_type_constant>::value != - type::custom_type, + bool check = std::is_enum::value && !std::is_same::value && + mapped_type_constant>::value != + type::custom_type, FMT_ENABLE_IF(check)> FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { - return write( - out, static_cast::type>(value)); + return write(out, static_cast::type>(value)); } template ::value)> FMT_CONSTEXPR auto write(OutputIt out, T value, - const basic_format_specs& specs = {}, - locale_ref = {}) -> OutputIt { + 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); @@ -1917,8 +1892,7 @@ FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt { } template -FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value) - -> OutputIt { +FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value) -> OutputIt { if (!value) { FMT_THROW(format_error("string pointer is null")); } else { @@ -1930,31 +1904,29 @@ FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value) template ::value)> -auto write(OutputIt out, const T* value, - const basic_format_specs& specs = {}, locale_ref = {}) - -> OutputIt { +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); } template -FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> - typename std::enable_if< - mapped_type_constant>::value == - type::custom_type, - OutputIt>::type { +FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> typename std::enable_if< + mapped_type_constant>::value == + type::custom_type, + OutputIt>::type { using context_type = basic_format_context; - using formatter_type = - conditional_t::value, - typename context_type::template formatter_type, - fallback_formatter>; + using formatter_type = conditional_t::value, + typename context_type::template formatter_type, + fallback_formatter>; context_type ctx(out, {}, {}); return formatter_type().format(value, ctx); } // An argument visitor that formats the argument and writes it via the output // iterator. It's a class and not a generic lambda for compatibility with C++11. -template struct default_arg_formatter { +template +struct default_arg_formatter { using iterator = buffer_appender; using context = buffer_context; @@ -1962,7 +1934,8 @@ template struct default_arg_formatter { basic_format_args args; locale_ref loc; - template auto operator()(T value) -> iterator { + template + auto operator()(T value) -> iterator { return write(out, value); } auto operator()(typename basic_format_arg::handle h) -> iterator { @@ -1973,7 +1946,8 @@ template struct default_arg_formatter { } }; -template struct arg_formatter { +template +struct arg_formatter { using iterator = buffer_appender; using context = buffer_context; @@ -1992,24 +1966,25 @@ template struct arg_formatter { } }; -template struct custom_formatter { +template +struct custom_formatter { basic_format_parse_context& parse_ctx; buffer_context& ctx; - void operator()( - typename basic_format_arg>::handle h) const { + void operator()(typename basic_format_arg>::handle h) const { h.format(parse_ctx, ctx); } - template void operator()(T) const {} + template + void operator()(T) const {} }; template using is_integer = bool_constant::value && !std::is_same::value && - !std::is_same::value && - !std::is_same::value>; + !std::is_same::value && !std::is_same::value>; -template class width_checker { +template +class width_checker { public: explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {} @@ -2029,7 +2004,8 @@ template class width_checker { ErrorHandler& handler_; }; -template class precision_checker { +template +class precision_checker { public: explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {} @@ -2049,8 +2025,7 @@ template class precision_checker { ErrorHandler& handler_; }; -template