From acdcf618a727d8653a98bf554ef11a5b74356969 Mon Sep 17 00:00:00 2001 From: Mauricio Vargas Sepulveda Date: Mon, 15 Sep 2025 09:51:36 -0400 Subject: [PATCH 1/2] clang format --- inst/include/cpp11/list_of.hpp | 56 +++++++++++++++------------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/inst/include/cpp11/list_of.hpp b/inst/include/cpp11/list_of.hpp index 7edcc0b9..c8ed1fa0 100644 --- a/inst/include/cpp11/list_of.hpp +++ b/inst/include/cpp11/list_of.hpp @@ -1,57 +1,51 @@ #pragma once -#include // for string, basic_string +#include // for string, basic_string -#include "cpp11/R.hpp" // for R_xlen_t, SEXP, SEXPREC, LONG_VECTOR_SUPPORT -#include "cpp11/list.hpp" // for list +#include "cpp11/R.hpp" // for R_xlen_t, SEXP, SEXPREC, LONG_VECTOR_SUPPORT +#include "cpp11/list.hpp" // for list namespace cpp11 { -template class list_of : public list { -public: - list_of(const list &data) : list(data) {} +template +class list_of : public list { + public: + list_of(const list& data) : list(data) {} #ifdef LONG_VECTOR_SUPPORT - T operator[](const int pos) const { - return operator[](static_cast(pos)); - } + T operator[](const int pos) const { return operator[](static_cast(pos)); } #endif T operator[](const R_xlen_t pos) const { return list::operator[](pos); } - T operator[](const char *pos) const { return list::operator[](pos); } + T operator[](const char* pos) const { return list::operator[](pos); } - T operator[](const std::string &pos) const { - return list::operator[](pos.c_str()); - } + T operator[](const std::string& pos) const { return list::operator[](pos.c_str()); } }; namespace writable { -template class list_of : public writable::list { -public: - list_of(const list &data) : writable::list(data) {} +template +class list_of : public writable::list { + public: + list_of(const list& data) : writable::list(data) {} list_of(R_xlen_t n) : writable::list(n) {} class proxy { - private: + private: writable::list::proxy data_; - public: - proxy(const writable::list::proxy &data) : data_(data) {} + public: + proxy(const writable::list::proxy& data) : data_(data) {} operator T() const { return static_cast(*this); } operator SEXP() const { return static_cast(data_); } #ifdef LONG_VECTOR_SUPPORT typename T::proxy operator[](int pos) { return static_cast(data_)[pos]; } #endif - typename T::proxy operator[](R_xlen_t pos) { - return static_cast(data_)[pos]; - } - proxy operator[](const char *pos) { static_cast(data_)[pos]; } - proxy operator[](const std::string &pos) { - return static_cast(data_)[pos]; - } - proxy &operator=(const T &rhs) { + typename T::proxy operator[](R_xlen_t pos) { return static_cast(data_)[pos]; } + proxy operator[](const char* pos) { static_cast(data_)[pos]; } + proxy operator[](const std::string& pos) { return static_cast(data_)[pos]; } + proxy& operator=(const T& rhs) { data_ = rhs; return *this; @@ -66,14 +60,14 @@ template class list_of : public writable::list { proxy operator[](R_xlen_t pos) { return writable::list::operator[](pos); } - proxy operator[](const char *pos) { + proxy operator[](const char* pos) { return { writable::list::operator[](pos) }; } - proxy operator[](const std::string &pos) { + proxy operator[](const std::string& pos) { return writable::list::operator[](pos.c_str()); } }; -} // namespace writable +} // namespace writable -} // namespace cpp11 +} // namespace cpp11 From e340f78e0b8a4e0ce2eaddaa9a29ef5a95ec59af Mon Sep 17 00:00:00 2001 From: Mauricio Vargas Sepulveda Date: Mon, 15 Sep 2025 10:40:48 -0400 Subject: [PATCH 2/2] clang format 12 --- README.md | 10 + inst/include/cpp11/list_of.hpp | 6 +- inst/include/fmt/core.h | 1262 +++++++++++++++---------------- inst/include/fmt/format-inl.h | 485 ++++++------ inst/include/fmt/format.h | 1000 ++++++++++++------------ tests/testthat/single_error.cpp | 2 +- 6 files changed, 1319 insertions(+), 1446 deletions(-) diff --git a/README.md b/README.md index d6f37dae..b5947fd4 100644 --- a/README.md +++ b/README.md @@ -78,3 +78,13 @@ Please note that the cpp11 project is released with a [Contributor Code of Condu cpp11 would not exist without Rcpp. Thanks to the Rcpp authors, Dirk Eddelbuettel, Romain Francois, JJ Allaire, Kevin Ushey, Qiang Kou, Nathan Russell, Douglas Bates and John Chambers for their work writing and maintaining Rcpp. + +## Clang format + +To match GHA, use clang-format-12 to format C++ code. With systems that provide clang-format-14 or newer, you can use Docker: + +```bash +docker run --rm -v "$PWD":/work -w /work ubuntu:22.04 bash -lc "\ + apt-get update && apt-get install -y clang-format-12 && \ + find . -name '*.cpp' -o -name '*.hpp' -o -name '*.h' | xargs -r clang-format-12 -i" +``` diff --git a/inst/include/cpp11/list_of.hpp b/inst/include/cpp11/list_of.hpp index c8ed1fa0..86c39acb 100644 --- a/inst/include/cpp11/list_of.hpp +++ b/inst/include/cpp11/list_of.hpp @@ -54,15 +54,13 @@ class list_of : public writable::list { #ifdef LONG_VECTOR_SUPPORT proxy operator[](int pos) { - return { writable::list::operator[](static_cast(pos)) }; + return {writable::list::operator[](static_cast(pos))}; } #endif proxy operator[](R_xlen_t pos) { return writable::list::operator[](pos); } - proxy operator[](const char* pos) { - return { writable::list::operator[](pos) }; - } + proxy operator[](const char* pos) { return {writable::list::operator[](pos)}; } proxy operator[](const std::string& pos) { return writable::list::operator[](pos.c_str()); 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