From 99c5b223cef57e57b3dda48e5f1c362423f307ea Mon Sep 17 00:00:00 2001 From: neargye Date: Fri, 22 May 2020 16:48:13 +0500 Subject: [PATCH] add FMT_IF_CONSTEXPR --- include/fmt/chrono.h | 22 +++++++++++----------- include/fmt/core.h | 6 ++++++ include/fmt/printf.h | 4 ++-- include/fmt/ranges.h | 2 +- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 3129f6a5..9fd3eb3a 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -44,7 +44,7 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { static_assert(T::is_integer, "To must be integral"); // A and B are both signed, or both unsigned. - if (F::digits <= T::digits) { + FMT_IF_CONSTEXPR(F::digits <= T::digits) { // From fits in To without any problem. } else { // From does not always fit in To, resort to a dynamic check. @@ -72,7 +72,7 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { static_assert(F::is_integer, "From must be integral"); static_assert(T::is_integer, "To must be integral"); - if (F::is_signed && !T::is_signed) { + FMT_IF_CONSTEXPR(F::is_signed && !T::is_signed) { // From may be negative, not allowed! if (fmt::detail::is_negative(from)) { ec = 1; @@ -80,7 +80,7 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { } // From is positive. Can it always fit in To? - if (F::digits <= T::digits) { + FMT_IF_CONSTEXPR(F::digits <= T::digits) { // yes, From always fits in To. } else { // from may not fit in To, we have to do a dynamic check @@ -91,9 +91,9 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { } } - if (!F::is_signed && T::is_signed) { + FMT_IF_CONSTEXPR(!F::is_signed && T::is_signed) { // can from be held in To? - if (F::digits < T::digits) { + FMT_IF_CONSTEXPR(F::digits < T::digits) { // yes, From always fits in To. } else { // from may not fit in To, we have to do a dynamic check @@ -194,7 +194,7 @@ To safe_duration_cast(std::chrono::duration from, return {}; } // multiply with Factor::num without overflow or underflow - if (Factor::num != 1) { + FMT_IF_CONSTEXPR(Factor::num != 1) { const auto max1 = detail::max_value() / Factor::num; if (count > max1) { ec = 1; @@ -209,7 +209,7 @@ To safe_duration_cast(std::chrono::duration from, } // this can't go wrong, right? den>0 is checked earlier. - if (Factor::den != 1) { + FMT_IF_CONSTEXPR(Factor::den != 1) { count /= Factor::den; } // convert to the to type, safely @@ -268,7 +268,7 @@ To safe_duration_cast(std::chrono::duration from, } // multiply with Factor::num without overflow or underflow - if (Factor::num != 1) { + FMT_IF_CONSTEXPR(Factor::num != 1) { constexpr auto max1 = detail::max_value() / static_cast(Factor::num); if (count > max1) { @@ -285,7 +285,7 @@ To safe_duration_cast(std::chrono::duration from, } // this can't go wrong, right? den>0 is checked earlier. - if (Factor::den != 1) { + FMT_IF_CONSTEXPR(Factor::den != 1) { using common_t = typename std::common_type::type; count /= static_cast(Factor::den); } @@ -785,7 +785,7 @@ OutputIt format_duration_unit(OutputIt out) { if (const char* unit = get_units()) return copy_unit(string_view(unit), out, Char()); const Char num_f[] = {'[', '{', '}', ']', 's', 0}; - if (Period::den == 1) return format_to(out, num_f, Period::num); + FMT_IF_CONSTEXPR(Period::den == 1) return format_to(out, num_f, Period::num); const Char num_def_f[] = {'[', '{', '}', '/', '{', '}', ']', 's', 0}; return format_to(out, num_def_f, Period::num, Period::den); } @@ -1072,7 +1072,7 @@ struct formatter, Char> { begin = detail::parse_width(begin, end, handler); if (begin == end) return {begin, begin}; if (*begin == '.') { - if (std::is_floating_point::value) + FMT_IF_CONSTEXPR(std::is_floating_point::value) begin = detail::parse_precision(begin, end, handler); else handler.on_error("precision not allowed for this argument type"); diff --git a/include/fmt/core.h b/include/fmt/core.h index f1561f8c..6c6cb9fc 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -98,6 +98,12 @@ # define FMT_CONSTEXPR_DECL #endif +#if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L +# define FMT_IF_CONSTEXPR(...) if constexpr (__VA_ARGS__) +#else +# define FMT_IF_CONSTEXPR(...) if (__VA_ARGS__) +#endif + #ifndef FMT_OVERRIDE # if FMT_HAS_FEATURE(cxx_override) || \ (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 diff --git a/include/fmt/printf.h b/include/fmt/printf.h index 71c0e274..f9165cac 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -246,12 +246,12 @@ class printf_arg_formatter : public detail::arg_formatter_base { iterator operator()(T value) { // MSVC2013 fails to compile separate overloads for bool and char_type so // use std::is_same instead. - if (std::is_same::value) { + FMT_IF_CONSTEXPR(std::is_same::value) { format_specs& fmt_specs = *this->specs(); if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0); fmt_specs.type = 0; this->write(value != 0); - } else if (std::is_same::value) { + } else FMT_IF_CONSTEXPR(std::is_same::value) { format_specs& fmt_specs = *this->specs(); if (fmt_specs.type && fmt_specs.type != 'c') return (*this)(static_cast(value)); diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index c48f1727..fce52df6 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -326,7 +326,7 @@ struct formatter, Char> { using base = formatter::type, Char>; auto out = ctx.out(); out = base{}.format(arg, ctx); - if (sizeof...(Args) > 0) { + FMT_IF_CONSTEXPR(sizeof...(Args) > 0) { out = std::copy(value.sep.begin(), value.sep.end(), out); ctx.advance_to(out); return format_args(value, ctx, args...);