Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into fuzz
Browse files Browse the repository at this point in the history
# Conflicts:
#	include/fmt/chrono.h
  • Loading branch information
pauldreik committed May 9, 2019
2 parents 7de0fde + e9bab6d commit 9a91093
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 37 deletions.
39 changes: 24 additions & 15 deletions include/fmt/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,13 +376,11 @@ struct chrono_format_checker {
FMT_NORETURN void on_tz_name() { report_no_date(); }
};

template <typename T,
typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline bool isnan(T) {
return false;
}
template <typename T, typename std::enable_if<std::is_floating_point<T>::value,
int>::type = 0>
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
inline bool isnan(T value) {
return std::isnan(value);
}
Expand All @@ -394,17 +392,33 @@ template <typename T> inline int to_int(T value) {
return static_cast<int>(value);
}

template <typename T,
typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
inline T mod(T x, int y) {
return x % y;
}
template <typename T, typename std::enable_if<std::is_floating_point<T>::value,
int>::type = 0>
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
inline T mod(T x, int y) {
return std::fmod(x, y);
}

template <typename Rep, typename Period,
typename std::enable_if<std::is_integral<Rep>::value, int>::type = 0>
inline std::chrono::duration<Rep, std::milli> get_milliseconds(
std::chrono::duration<Rep, Period> d) {
auto s = std::chrono::duration_cast<std::chrono::seconds>(d);
return std::chrono::duration_cast<std::chrono::milliseconds>(d - s);
}

template <
typename Rep, typename Period,
typename std::enable_if<std::is_floating_point<Rep>::value, int>::type = 0>
inline std::chrono::duration<Rep, std::milli> get_milliseconds(
std::chrono::duration<Rep, Period> d) {
auto ms =
std::chrono::duration_cast<std::chrono::duration<Rep, std::milli>>(d);
return std::chrono::duration<Rep, std::milli>(mod(ms.count(), 1000));
}

template <typename Rep, typename OutputIt>
OutputIt static format_chrono_duration_value(OutputIt out, Rep val,
int precision) {
Expand Down Expand Up @@ -450,17 +464,12 @@ struct chrono_formatter {
d = -d;
*out++ = '-';
}

s = std::chrono::duration_cast<seconds>(d);
ms = get_milliseconds(d);
if constexpr (is_floating_point) {
auto tmpseconds = std::chrono::duration_cast<seconds>(d);
s = seconds{std::floor(tmpseconds.count())};
ms = std::chrono::duration_cast<milliseconds>(tmpseconds - s);
if (!std::isfinite(s.count()) || !std::isfinite(ms.count())) {
FMT_THROW(format_error("internal overflow of floating point duration"));
}
} else {
s = std::chrono::duration_cast<seconds>(d);
ms = std::chrono::duration_cast<milliseconds>(d - s);
}
}

Expand Down
3 changes: 2 additions & 1 deletion include/fmt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@

// An enable_if helper to be used in template parameters. enable_if in template
// parameters results in much shorter symbols: https://godbolt.org/z/sWw4vP.
#define FMT_ENABLE_IF(...) typename std::enable_if<__VA_ARGS__, int>::type = 0
#define FMT_ENABLE_IF_T(...) typename std::enable_if<(__VA_ARGS__), int>::type
#define FMT_ENABLE_IF(...) FMT_ENABLE_IF_T(__VA_ARGS__) = 0

FMT_BEGIN_NAMESPACE
namespace internal {
Expand Down
3 changes: 1 addition & 2 deletions include/fmt/format-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,7 @@ template <int GRISU_VERSION> struct grisu_shortest_handler {
}
};

template <typename Double, typename std::enable_if<
sizeof(Double) == sizeof(uint64_t), int>::type>
template <typename Double, FMT_ENABLE_IF_T(sizeof(Double) == sizeof(uint64_t))>
FMT_FUNC bool grisu_format(Double value, buffer<char>& buf, int precision,
unsigned options, int& exp) {
FMT_ASSERT(value >= 0, "value is negative");
Expand Down
2 changes: 1 addition & 1 deletion include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -2244,7 +2244,7 @@ FMT_CONSTEXPR bool do_check_format_string(basic_string_view<Char> s,
}

template <typename... Args, typename S,
typename std::enable_if<is_compile_string<S>::value, int>::type>
FMT_ENABLE_IF_T(is_compile_string<S>::value)>
void check_format_string(S format_str) {
typedef typename S::char_type char_t;
FMT_CONSTEXPR_DECL bool invalid_format =
Expand Down
4 changes: 4 additions & 0 deletions include/fmt/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

#include "chrono.h"

#ifdef _MSC_VER
#pragma message("fmt/time.h is deprecated, use fmt/chrono.h instead")
#else
#warning fmt/time.h is deprecated, use fmt/chrono.h instead
#endif

#endif // FMT_TIME_H_
1 change: 1 addition & 0 deletions support/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ def update_site(env):
b.data = b.data.replace('std::FILE*', 'std::FILE *')
b.data = b.data.replace('unsigned int', 'unsigned')
b.data = b.data.replace('operator""_', 'operator"" _')
b.data = b.data.replace(', size_t', ', std::size_t')
# Fix a broken link in index.rst.
index = os.path.join(target_doc_dir, 'index.rst')
with rewrite(index) as b:
Expand Down
6 changes: 5 additions & 1 deletion test/chrono-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,13 +307,17 @@ TEST(ChronoTest, InvalidColons) {
}

TEST(ChronoTest, SpecialDurations) {
EXPECT_EQ("40", fmt::format("{:%S}", std::chrono::duration<double>(1e20)));
EXPECT_EQ(
"40.",
fmt::format("{:%S}", std::chrono::duration<double>(1e20)).substr(0, 3));
EXPECT_EQ("-00:01",
fmt::format("{:%M:%S}", std::chrono::duration<double>(-1)));
auto nan = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ(
"nan nan nan nan.nan nan:nan nan",
fmt::format("{:%I %H %M %S %R %r}", std::chrono::duration<double>(nan)));
fmt::format("{:%S}",
std::chrono::duration<float, std::atto>(1.79400457e+31f));
}

TEST(ChronoTest, DurationIsFloatNaN) {
Expand Down
4 changes: 4 additions & 0 deletions test/custom-formatter-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
//
// For the license information refer to format.h.

#ifndef _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS
#endif

#include "fmt/format.h"
#include "gtest-extra.h"

Expand Down
16 changes: 16 additions & 0 deletions test/format-impl-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,19 @@ TEST(FormatTest, FormatErrorCode) {
TEST(FormatTest, CountCodePoints) {
EXPECT_EQ(4, fmt::internal::count_code_points(fmt::u8string_view("ёжик")));
}

// Tests fmt::internal::count_digits for integer type Int.
template <typename Int> void test_count_digits() {
for (Int i = 0; i < 10; ++i) EXPECT_EQ(1u, fmt::internal::count_digits(i));
for (Int i = 1, n = 1, end = std::numeric_limits<Int>::max() / 10; n <= end;
++i) {
n *= 10;
EXPECT_EQ(i, fmt::internal::count_digits(n - 1));
EXPECT_EQ(i + 1, fmt::internal::count_digits(n));
}
}

TEST(UtilTest, CountDigits) {
test_count_digits<uint32_t>();
test_count_digits<uint64_t>();
}
16 changes: 0 additions & 16 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -140,22 +140,6 @@ template <typename Char> struct WriteChecker {
EXPECT_PRED_FORMAT1(WriteChecker<wchar_t>(), value)
} // namespace

// Tests fmt::internal::count_digits for integer type Int.
template <typename Int> void test_count_digits() {
for (Int i = 0; i < 10; ++i) EXPECT_EQ(1u, fmt::internal::count_digits(i));
for (Int i = 1, n = 1, end = std::numeric_limits<Int>::max() / 10; n <= end;
++i) {
n *= 10;
EXPECT_EQ(i, fmt::internal::count_digits(n - 1));
EXPECT_EQ(i + 1, fmt::internal::count_digits(n));
}
}

TEST(UtilTest, CountDigits) {
test_count_digits<uint32_t>();
test_count_digits<uint64_t>();
}

struct uint32_pair {
uint32_t u[2];
};
Expand Down
2 changes: 1 addition & 1 deletion test/posix-mock-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// For the license information refer to format.h.

// Disable bogus MSVC warnings.
#ifdef _MSC_VER
#ifndef _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS
#endif

Expand Down

0 comments on commit 9a91093

Please sign in to comment.