From 0515e41d8969df55613dc42f7be9d1ded667e874 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 9 Jul 2021 11:00:08 +0200 Subject: [PATCH] Poorformance improvements for fmt lib compile time --- Source/ThirdParty/fmt/core.h | 32 ---- Source/ThirdParty/fmt/format-inl.h | 76 --------- Source/ThirdParty/fmt/format.h | 247 +---------------------------- 3 files changed, 6 insertions(+), 349 deletions(-) diff --git a/Source/ThirdParty/fmt/core.h b/Source/ThirdParty/fmt/core.h index 93ecb910e..7de04519f 100644 --- a/Source/ThirdParty/fmt/core.h +++ b/Source/ThirdParty/fmt/core.h @@ -44,7 +44,6 @@ namespace fmt { } }; #else -#include namespace fmt { // std::back_insert_iterator impl to not include template @@ -403,19 +402,6 @@ FMT_CONSTEXPR typename std::make_unsigned::type to_unsigned(Int value) { FMT_ASSERT(value >= 0, "negative value"); return static_cast::type>(value); } - -constexpr unsigned char micro[] = "\u00B5"; - -template constexpr bool is_unicode() { - return FMT_UNICODE || sizeof(Char) != 1 || - (sizeof(micro) == 3 && micro[0] == 0xC2 && micro[1] == 0xB5); -} - -#ifdef __cpp_char8_t -using char8_type = char8_t; -#else -enum char8_type : unsigned char {}; -#endif } // namespace internal template @@ -434,7 +420,6 @@ template class basic_string_view { size_t size_; public: - using char_type FMT_DEPRECATED_ALIAS = Char; using value_type = Char; using iterator = const Char*; @@ -520,16 +505,10 @@ template class basic_string_view { using string_view = basic_string_view; using wstring_view = basic_string_view; -#ifndef __cpp_char8_t -// char8_t is deprecated; use char instead. -using char8_t FMT_DEPRECATED_ALIAS = internal::char8_type; -#endif - /** 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::true_type {}; -template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; @@ -696,12 +675,6 @@ class basic_format_parse_context : private ErrorHandler { using format_parse_context = basic_format_parse_context; using wformat_parse_context = basic_format_parse_context; -template -using basic_parse_context FMT_DEPRECATED_ALIAS = - basic_format_parse_context; -using parse_context FMT_DEPRECATED_ALIAS = basic_format_parse_context; -using wparse_context FMT_DEPRECATED_ALIAS = basic_format_parse_context; - template class basic_format_arg; template class basic_format_args; @@ -712,11 +685,6 @@ struct formatter { formatter() = delete; }; -template -struct FMT_DEPRECATED convert_to_int - : bool_constant::value && - std::is_convertible::value> {}; - // 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 diff --git a/Source/ThirdParty/fmt/format-inl.h b/Source/ThirdParty/fmt/format-inl.h index c763a0e46..8cbf30c41 100644 --- a/Source/ThirdParty/fmt/format-inl.h +++ b/Source/ThirdParty/fmt/format-inl.h @@ -55,82 +55,6 @@ inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) { # define FMT_SNPRINTF fmt_snprintf #endif // _MSC_VER -// A portable thread-safe version of strerror. -// Sets buffer to point to a string describing the error code. -// This can be either a pointer to a string stored in buffer, -// or a pointer to some static immutable string. -// Returns one of the following values: -// 0 - success -// ERANGE - buffer is not large enough to store the error message -// other - failure -// Buffer should be at least of size 1. -FMT_FUNC int safe_strerror(int error_code, char*& buffer, - std::size_t buffer_size) FMT_NOEXCEPT { - FMT_ASSERT(buffer != nullptr && buffer_size != 0, "invalid buffer"); - - class dispatcher { - private: - int error_code_; - char*& buffer_; - std::size_t buffer_size_; - - // A noop assignment operator to avoid bogus warnings. - void operator=(const dispatcher&) {} - - // Handle the result of XSI-compliant version of strerror_r. - int handle(int result) { - // glibc versions before 2.13 return result in errno. - return result == -1 ? errno : result; - } - - // Handle the result of GNU-specific version of strerror_r. - FMT_MAYBE_UNUSED - int handle(char* message) { - // If the buffer is full then the message is probably truncated. - if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1) - return ERANGE; - buffer_ = message; - return 0; - } - - // Handle the case when strerror_r is not available. - FMT_MAYBE_UNUSED - int handle(internal::null<>) { - return fallback(strerror_s(buffer_, buffer_size_, error_code_)); - } - - // Fallback to strerror_s when strerror_r is not available. - FMT_MAYBE_UNUSED - int fallback(int result) { - // If the buffer is full then the message is probably truncated. - return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? ERANGE - : result; - } - -#if !FMT_MSC_VER - // Fallback to strerror if strerror_r and strerror_s are not available. - int fallback(internal::null<>) { - errno = 0; - buffer_ = strerror(error_code_); - return errno; - } -#endif - - public: - dispatcher(int err_code, char*& buf, std::size_t buf_size) - : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} - - int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); } - }; - return dispatcher(error_code, buffer, buffer_size).run(); -} - -// A wrapper around fwrite that throws on error. -FMT_FUNC 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_FORMAT_ERROR("cannot write to file"); -} } // namespace internal #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) diff --git a/Source/ThirdParty/fmt/format.h b/Source/ThirdParty/fmt/format.h index b2cb88a24..cd8d385ab 100644 --- a/Source/ThirdParty/fmt/format.h +++ b/Source/ThirdParty/fmt/format.h @@ -35,6 +35,7 @@ #include #include +#include #include "core.h" @@ -221,11 +222,6 @@ FMT_END_NAMESPACE # define FMT_NUMERIC_ALIGN 1 #endif -// Enable the deprecated percent specifier. -#ifndef FMT_DEPRECATED_PERCENT -# define FMT_DEPRECATED_PERCENT 0 -#endif - FMT_BEGIN_NAMESPACE namespace internal { @@ -284,43 +280,6 @@ template <> constexpr int num_bits() { std::numeric_limits::digits); } -// An approximation of iterator_t for pre-C++20 systems. -template -using iterator_t = decltype(std::begin(std::declval())); - -// Detect the iterator category of *any* given type in a SFINAE-friendly way. -// Unfortunately, older implementations of std::iterator_traits are not safe -// for use in a SFINAE-context. -template -struct iterator_category : std::false_type {}; - -template struct iterator_category { - using type = std::random_access_iterator_tag; -}; - -template -struct iterator_category> { - using type = typename It::iterator_category; -}; - -// Detect if *any* given type models the OutputIterator concept. -template class is_output_iterator { - // Check for mutability because all iterator categories derived from - // std::input_iterator_tag *may* also meet the requirements of an - // OutputIterator, thereby falling into the category of 'mutable iterators' - // [iterator.requirements.general] clause 4. The compiler reveals this - // property only at the point of *actually dereferencing* the iterator! - template - static decltype(*(std::declval())) test(std::input_iterator_tag); - template static char& test(std::output_iterator_tag); - template static const char& test(...); - - using type = decltype(test(typename iterator_category::type{})); - - public: - enum { value = !std::is_const>::value }; -}; - #if FMT_USE_STRING // A workaround for std::string not having mutable data() until C++17. template inline Char* get_data(std::basic_string& s) { @@ -332,24 +291,13 @@ inline typename Container::value_type* get_data(Container& c) { return c.data(); } -#if defined(_SECURE_SCL) && _SECURE_SCL -// Make a checked iterator to avoid MSVC warnings. -template using checked_ptr = stdext::checked_array_iterator; -template checked_ptr make_checked(T* p, std::size_t size) { - return {p, size}; -} -#else -template using checked_ptr = T*; -template inline T* make_checked(T* p, std::size_t) { return p; } -#endif - template ::value)> -inline checked_ptr reserve( +inline typename Container::value_type* reserve( fmt::back_insert_iterator& it, std::size_t n) { Container& c = get_container(it); std::size_t size = c.size(); c.resize(size + n); - return make_checked(get_data(c) + size, n); + return get_data(c) + size; } template @@ -364,7 +312,6 @@ class counting_iterator { std::size_t count_; public: - using iterator_category = std::output_iterator_tag; using difference_type = std::ptrdiff_t; using pointer = void; using reference = void; @@ -392,79 +339,6 @@ class counting_iterator { value_type operator*() const { return {}; } }; -template class truncating_iterator_base { - protected: - OutputIt out_; - std::size_t limit_; - std::size_t count_; - - truncating_iterator_base(OutputIt out, std::size_t limit) - : out_(out), limit_(limit), count_(0) {} - - public: - using iterator_category = std::output_iterator_tag; - using value_type = typename std::iterator_traits::value_type; - using difference_type = void; - using pointer = void; - using reference = void; - using _Unchecked_type = - truncating_iterator_base; // Mark iterator as checked. - - OutputIt base() const { return out_; } - std::size_t count() const { return count_; } -}; - -// An output iterator that truncates the output and counts the number of objects -// written to it. -template ::value_type>::type> -class truncating_iterator; - -template -class truncating_iterator - : public truncating_iterator_base { - mutable typename truncating_iterator_base::value_type blackhole_; - - public: - using value_type = typename truncating_iterator_base::value_type; - - truncating_iterator(OutputIt out, std::size_t limit) - : truncating_iterator_base(out, limit) {} - - truncating_iterator& operator++() { - if (this->count_++ < this->limit_) ++this->out_; - return *this; - } - - truncating_iterator operator++(int) { - auto it = *this; - ++*this; - return it; - } - - value_type& operator*() const { - return this->count_ < this->limit_ ? *this->out_ : blackhole_; - } -}; - -template -class truncating_iterator - : public truncating_iterator_base { - public: - truncating_iterator(OutputIt out, std::size_t limit) - : truncating_iterator_base(out, limit) {} - - template truncating_iterator& operator=(T val) { - if (this->count_++ < this->limit_) *this->out_++ = val; - return *this; - } - - truncating_iterator& operator++() { return *this; } - truncating_iterator& operator++(int) { return *this; } - truncating_iterator& operator*() { return *this; } -}; - // A range with the specified output iterator and value type. template class output_range { @@ -496,29 +370,12 @@ inline size_t count_code_points(basic_string_view s) { return num_code_points; } -inline size_t count_code_points(basic_string_view s) { - return count_code_points(basic_string_view( - reinterpret_cast(s.data()), s.size())); -} - template inline size_t code_point_index(basic_string_view s, size_t n) { size_t size = s.size(); return n < size ? n : size; } -// Calculates the index of the nth code point in a UTF-8 string. -inline size_t code_point_index(basic_string_view s, size_t n) { - const char8_type* data = s.data(); - size_t num_code_points = 0; - for (size_t i = 0, size = s.size(); i != size; ++i) { - if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) { - return i; - } - } - return s.size(); -} - template OutputIt copy(InputIt first, InputIt last, OutputIt d_first) { while (first != last) @@ -543,26 +400,11 @@ OutputIt fill_n(OutputIt first, Size count, const T& value) { return first; } -template -using needs_conversion = bool_constant< - std::is_same::value_type, - char>::value && - std::is_same::value>; - -template ::value)> +template OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { return internal::copy(begin, end, it); } -template ::value)> -OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { - while (begin != end) - *it++ = static_cast(*begin++); - return it; -} - #ifndef FMT_USE_GRISU # define FMT_USE_GRISU 1 #endif @@ -577,7 +419,7 @@ template void buffer::append(const U* begin, const U* end) { std::size_t new_size = size_ + to_unsigned(end - begin); reserve(new_size); - std::uninitialized_copy(begin, end, make_checked(ptr_, capacity_) + size_); + ::memcpy(ptr_ + size_, begin, (end - begin) * sizeof(U)); size_ = new_size; } } // namespace internal @@ -1059,7 +901,6 @@ struct float_specs { sign_t sign : 8; bool upper : 1; bool locale : 1; - bool percent : 1; bool binary32 : 1; bool use_grisu : 1; bool showpoint : 1; @@ -1262,12 +1103,6 @@ FMT_CONSTEXPR float_specs parse_float_type_spec( result.format = float_format::fixed; result.showpoint |= specs.precision != 0; break; -#if FMT_DEPRECATED_PERCENT - case '%': - result.format = float_format::fixed; - result.percent = true; - break; -#endif case 'A': result.upper = true; FMT_FALLTHROUGH; @@ -1583,8 +1418,7 @@ template class basic_writer { ++group; } buffer -= s.size(); - std::uninitialized_copy(s.data(), s.data() + s.size(), - make_checked(buffer, s.size())); + ::memcpy(buffer, s.data(), s.size() * sizeof(char_type)); }); } }; @@ -1757,12 +1591,7 @@ template class basic_writer { } if (const_check(std::is_same())) fspecs.binary32 = true; fspecs.use_grisu = use_grisu(); - if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) value *= 100; int exp = format_float(promote_float(value), precision, fspecs, buffer); - if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) { - buffer.push_back('%'); - --exp; // Adjust decimal place position. - } fspecs.precision = precision; char_type point = fspecs.locale ? decimal_point(locale_) : static_cast('.'); @@ -1861,7 +1690,6 @@ class arg_formatter_base { protected: writer_type& writer() { return writer_; } - FMT_DEPRECATED format_specs* spec() { return specs_; } format_specs* specs() { return specs_; } iterator out() { return writer_.out(); } @@ -3118,17 +2946,6 @@ typename Context::iterator vformat_to( return h.context.out(); } -// Casts ``p`` to ``const void*`` for pointer formatting. -// Example: -// auto s = format("{}", ptr(p)); -template inline const void* ptr(const T* p) { return p; } -template inline const void* ptr(const std::unique_ptr& p) { - return p.get(); -} -template inline const void* ptr(const std::shared_ptr& p) { - return p.get(); -} - class bytes { private: string_view data_; @@ -3230,7 +3047,6 @@ using format_args_t = basic_format_args>; template ::value && !internal::is_contiguous_back_insert_iterator::value)> inline OutputIt vformat_to( OutputIt out, const S& format_str, @@ -3253,7 +3069,6 @@ inline OutputIt vformat_to( */ template ::value && !internal::is_contiguous_back_insert_iterator::value && internal::is_string::value)> inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) { @@ -3263,56 +3078,6 @@ inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) { make_format_args(args...)); } -template struct format_to_n_result { - /** Iterator past the end of the output range. */ - OutputIt out; - /** Total (not truncated) output size. */ - std::size_t size; -}; - -template -using format_to_n_context = - format_context_t, Char>; - -template -using format_to_n_args = basic_format_args>; - -template -inline format_arg_store, Args...> -make_format_to_n_args(const Args&... args) { - return format_arg_store, Args...>( - args...); -} - -template ::value)> -inline format_to_n_result vformat_to_n( - OutputIt out, std::size_t n, basic_string_view format_str, - format_to_n_args, type_identity_t> args) { - auto it = vformat_to(internal::truncating_iterator(out, n), - format_str, args); - return {it.base(), it.count()}; -} - -/** - \rst - Formats arguments, writes up to ``n`` characters of the result to the output - iterator ``out`` and returns the total output size and the iterator past the - end of the output range. - \endrst - */ -template ::value&& - internal::is_output_iterator::value)> -inline format_to_n_result format_to_n(OutputIt out, std::size_t n, - const S& format_str, - const Args&... args) { - internal::check_format_string(format_str); - using context = format_to_n_context>; - return vformat_to_n(out, n, to_string_view(format_str), - make_format_args(args...)); -} - #if FMT_USE_STRING template inline std::basic_string internal::vformat(