Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #10652 from shuffle2/fmt
update fmt and fix warnings that popped up with vs 17.2
  • Loading branch information
Tilka committed May 13, 2022
2 parents 27c6731 + 7b8e6c5 commit fcb3f9e
Show file tree
Hide file tree
Showing 24 changed files with 2,255 additions and 2,128 deletions.
28 changes: 3 additions & 25 deletions Externals/fmt/CMakeLists.txt
Expand Up @@ -125,7 +125,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${CMAKE_CURRENT_SOURCE_DIR}/support/cmake")

include(cxx14)
include(CheckCXXCompilerFlag)
include(JoinPaths)

list(FIND CMAKE_CXX_COMPILE_FEATURES "cxx_variadic_templates" index)
Expand Down Expand Up @@ -209,18 +208,6 @@ if (FMT_MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio")
${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*")
endif ()

set(strtod_l_headers stdlib.h)
if (APPLE)
set(strtod_l_headers ${strtod_l_headers} xlocale.h)
endif ()

include(CheckSymbolExists)
if (WIN32)
check_symbol_exists(_strtod_l "${strtod_l_headers}" HAVE_STRTOD_L)
else ()
check_symbol_exists(strtod_l "${strtod_l_headers}" HAVE_STRTOD_L)
endif ()

function(add_headers VAR)
set(headers ${${VAR}})
foreach (header ${ARGN})
Expand All @@ -244,17 +231,6 @@ endif ()
add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} README.rst ChangeLog.rst)
add_library(fmt::fmt ALIAS fmt)

if (HAVE_STRTOD_L)
target_compile_definitions(fmt PUBLIC FMT_LOCALE)
endif ()

if (MINGW)
check_cxx_compiler_flag("-Wa,-mbig-obj" FMT_HAS_MBIG_OBJ)
if (${FMT_HAS_MBIG_OBJ})
target_compile_options(fmt PUBLIC "-Wa,-mbig-obj")
endif()
endif ()

if (FMT_WERROR)
target_compile_options(fmt PRIVATE ${WERROR_FLAG})
endif ()
Expand All @@ -275,6 +251,7 @@ set(FMT_DEBUG_POSTFIX d CACHE STRING "Debug library postfix.")

set_target_properties(fmt PROPERTIES
VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR}
PUBLIC_HEADER "${FMT_HEADERS}"
DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}")

# Set FMT_LIB_NAME for pkg-config fmt.pc. We cannot use the OUTPUT_NAME target
Expand Down Expand Up @@ -352,6 +329,8 @@ if (FMT_INSTALL)
install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name}
LIBRARY DESTINATION ${FMT_LIB_DIR}
ARCHIVE DESTINATION ${FMT_LIB_DIR}
PUBLIC_HEADER DESTINATION "${FMT_INC_DIR}/fmt"
FRAMEWORK DESTINATION "."
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

# Use a namespace because CMake provides better diagnostics for namespaced
Expand All @@ -368,7 +347,6 @@ if (FMT_INSTALL)

install(FILES $<TARGET_PDB_FILE:${INSTALL_TARGETS}>
DESTINATION ${FMT_LIB_DIR} OPTIONAL)
install(FILES ${FMT_HEADERS} DESTINATION "${FMT_INC_DIR}/fmt")
install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}")
endif ()

Expand Down
2 changes: 1 addition & 1 deletion Externals/fmt/ChangeLog.rst
Expand Up @@ -6,7 +6,7 @@
`#2696 <https://github.com/fmtlib/fmt/pull/2696>`_).
Thanks `@saraedum (Julian Rüth) <https://github.com/saraedum>`_.

* Fixed chorno formatting on big endian systems
* Fixed chrono formatting on big endian systems
(`#2698 <https://github.com/fmtlib/fmt/issues/2698>`_,
`#2699 <https://github.com/fmtlib/fmt/pull/2699>`_).
Thanks `@phprus (Vladislav Shchapov) <https://github.com/phprus>`_ and
Expand Down
13 changes: 7 additions & 6 deletions Externals/fmt/README.rst
@@ -1,5 +1,7 @@
{fmt}
=====
.. image:: https://user-images.githubusercontent.com/
576385/156254208-f5b743a9-88cf-439d-b0c0-923d53e8d551.png
:width: 25%
:alt: {fmt}

.. image:: https://github.com/fmtlib/fmt/workflows/linux/badge.svg
:target: https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux
Expand All @@ -26,9 +28,8 @@
**{fmt}** is an open-source formatting library providing a fast and safe
alternative to C stdio and C++ iostreams.

If you like this project, please consider donating to the BYSOL
Foundation that helps victims of political repressions in Belarus:
https://bysol.org/en/bs/general/.
If you like this project, please consider donating to one of the funds that
help victims of the war in Ukraine: https://www.stopputin.net/.

`Documentation <https://fmt.dev>`__

Expand Down Expand Up @@ -123,7 +124,7 @@ Output::
Default format: 42s 100ms
strftime-like format: 03:15:30

**Print a container** (`run <https://godbolt.org/z/MjsY7c>`_)
**Print a container** (`run <https://godbolt.org/z/MxM1YqjE7>`_)

.. code:: c++

Expand Down
8 changes: 4 additions & 4 deletions Externals/fmt/include/fmt/args.h
Expand Up @@ -95,10 +95,10 @@ class dynamic_format_arg_store
};

template <typename T>
using stored_type = conditional_t<detail::is_string<T>::value &&
!has_formatter<T, Context>::value &&
!detail::is_reference_wrapper<T>::value,
std::basic_string<char_type>, T>;
using stored_type = conditional_t<
std::is_convertible<T, std::basic_string<char_type>>::value &&
!detail::is_reference_wrapper<T>::value,
std::basic_string<char_type>, T>;

// Storage of basic_format_arg must be contiguous.
std::vector<basic_format_arg<Context>> data_;
Expand Down
76 changes: 45 additions & 31 deletions Externals/fmt/include/fmt/chrono.h
Expand Up @@ -10,6 +10,8 @@

#include <algorithm>
#include <chrono>
#include <cmath> // std::isfinite
#include <cstring> // std::memcpy
#include <ctime>
#include <iterator>
#include <locale>
Expand Down Expand Up @@ -321,14 +323,13 @@ constexpr const size_t codecvt_result<CodeUnit>::max_size;
template <typename CodeUnit>
void write_codecvt(codecvt_result<CodeUnit>& out, string_view in_buf,
const std::locale& loc) {
using codecvt = std::codecvt<CodeUnit, char, std::mbstate_t>;
#if FMT_CLANG_VERSION
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated"
auto& f = std::use_facet<codecvt>(loc);
auto& f = std::use_facet<std::codecvt<CodeUnit, char, std::mbstate_t>>(loc);
# pragma clang diagnostic pop
#else
auto& f = std::use_facet<codecvt>(loc);
auto& f = std::use_facet<std::codecvt<CodeUnit, char, std::mbstate_t>>(loc);
#endif
auto mb = std::mbstate_t();
const char* from_next = nullptr;
Expand Down Expand Up @@ -562,10 +563,10 @@ inline void write_digit2_separated(char* buf, unsigned a, unsigned b,
constexpr const size_t len = 8;
if (const_check(is_big_endian())) {
char tmp[len];
memcpy(tmp, &digits, len);
std::memcpy(tmp, &digits, len);
std::reverse_copy(tmp, tmp + len, buf);
} else {
memcpy(buf, &digits, len);
std::memcpy(buf, &digits, len);
}
}

Expand Down Expand Up @@ -1214,7 +1215,7 @@ template <typename OutputIt, typename Char> class tm_writer {
char buf[10];
size_t offset = 0;
if (year >= 0 && year < 10000) {
copy2(buf, digits2(to_unsigned(year / 100)));
copy2(buf, digits2(static_cast<size_t>(year / 100)));
} else {
offset = 4;
write_year_extended(year);
Expand Down Expand Up @@ -1387,15 +1388,6 @@ struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
FMT_CONSTEXPR void on_duration_unit() {}
};

template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline bool isnan(T) {
return false;
}
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
inline bool isnan(T value) {
return std::isnan(value);
}

template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline bool isfinite(T) {
return true;
Expand Down Expand Up @@ -1470,14 +1462,23 @@ inline std::chrono::duration<Rep, std::milli> get_milliseconds(
#endif
}

// Returns the number of fractional digits in the range [0, 18] according to the
// Counts the number of fractional digits in the range [0, 18] according to the
// C++20 spec. If more than 18 fractional digits are required then returns 6 for
// microseconds precision.
constexpr int count_fractional_digits(long long num, long long den, int n = 0) {
return num % den == 0
? n
: (n > 18 ? 6 : count_fractional_digits(num * 10, den, n + 1));
}
template <long long Num, long long Den, int N = 0,
bool Enabled =
(N < 19) && (Num <= std::numeric_limits<long long>::max() / 10)>
struct count_fractional_digits {
static constexpr int value =
Num % Den == 0 ? N : count_fractional_digits<Num * 10, Den, N + 1>::value;
};

// Base case that doesn't instantiate any more templates
// in order to avoid overflow.
template <long long Num, long long Den, int N>
struct count_fractional_digits<Num, Den, N, false> {
static constexpr int value = (Num % Den == 0) ? N : 6;
};

constexpr long long pow10(std::uint32_t n) {
return n == 0 ? 1 : 10 * pow10(n - 1);
Expand Down Expand Up @@ -1663,9 +1664,11 @@ struct chrono_formatter {
out = format_decimal<char_type>(out, n, num_digits).end;
}

template <class Duration> void write_fractional_seconds(Duration d) {
template <typename Duration> void write_fractional_seconds(Duration d) {
FMT_ASSERT(!std::is_floating_point<typename Duration::rep>::value, "");
constexpr auto num_fractional_digits =
count_fractional_digits(Duration::period::num, Duration::period::den);
count_fractional_digits<Duration::period::num,
Duration::period::den>::value;

using subsecond_precision = std::chrono::duration<
typename std::common_type<typename Duration::rep,
Expand All @@ -1674,12 +1677,9 @@ struct chrono_formatter {
if (std::ratio_less<typename subsecond_precision::period,
std::chrono::seconds::period>::value) {
*out++ = '.';
// Don't convert long double to integer seconds to avoid overflow.
using sec = conditional_t<
std::is_same<typename Duration::rep, long double>::value,
std::chrono::duration<long double>, std::chrono::seconds>;
auto fractional = detail::abs(d) - std::chrono::duration_cast<sec>(d);
const auto subseconds =
auto fractional =
detail::abs(d) - std::chrono::duration_cast<std::chrono::seconds>(d);
auto subseconds =
std::chrono::treat_as_floating_point<
typename subsecond_precision::rep>::value
? fractional.count()
Expand Down Expand Up @@ -1770,8 +1770,22 @@ struct chrono_formatter {
if (handle_nan_inf()) return;

if (ns == numeric_system::standard) {
write(second(), 2);
write_fractional_seconds(std::chrono::duration<rep, Period>{val});
if (std::is_floating_point<rep>::value) {
constexpr auto num_fractional_digits =
count_fractional_digits<Period::num, Period::den>::value;
auto buf = memory_buffer();
format_to(std::back_inserter(buf), runtime("{:.{}f}"),
std::fmod(val * static_cast<rep>(Period::num) /
static_cast<rep>(Period::den),
60),
num_fractional_digits);
if (negative) *out++ = '-';
if (buf.size() < 2 || buf[1] == '.') *out++ = '0';
out = std::copy(buf.begin(), buf.end(), out);
} else {
write(second(), 2);
write_fractional_seconds(std::chrono::duration<rep, Period>(val));
}
return;
}
auto time = tm();
Expand Down

0 comments on commit fcb3f9e

Please sign in to comment.