From c21c6b8c4b89b3a3abc88ecec0ffbb76481db325 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 16 Mar 2019 12:58:18 -0700 Subject: [PATCH] Move enable_if to template params --- include/fmt/color.h | 15 ++-- include/fmt/core.h | 140 ++++++++++++++++++------------------ include/fmt/format-inl.h | 7 +- include/fmt/format.h | 151 +++++++++++++++++---------------------- include/fmt/locale.h | 22 +++--- include/fmt/ostream.h | 8 +-- include/fmt/prepare.h | 16 ++--- include/fmt/printf.h | 109 ++++++++++++---------------- include/fmt/ranges.h | 18 ++--- 9 files changed, 220 insertions(+), 266 deletions(-) diff --git a/include/fmt/color.h b/include/fmt/color.h index 3e98ba4a..b29ab082 100644 --- a/include/fmt/color.h +++ b/include/fmt/color.h @@ -587,10 +587,10 @@ void vprint(std::FILE* f, const text_style& ts, const S& format, fmt::print(fmt::emphasis::bold | fg(fmt::color::red), "Elapsed time: {0:.2f} seconds", 1.23); */ -template -typename std::enable_if::value>::type print( - std::FILE* f, const text_style& ts, const String& format_str, - const Args&... args) { +template ::value)> +void print(std::FILE* f, const text_style& ts, const String& format_str, + const Args&... args) { internal::check_format_string(format_str); typedef typename internal::char_t::type char_t; typedef typename buffer_context::type context_t; @@ -605,9 +605,10 @@ typename std::enable_if::value>::type print( fmt::print(fmt::emphasis::bold | fg(fmt::color::red), "Elapsed time: {0:.2f} seconds", 1.23); */ -template -typename std::enable_if::value>::type print( - const text_style& ts, const String& format_str, const Args&... args) { +template ::value)> +void print(const text_style& ts, const String& format_str, + const Args&... args) { return print(stdout, ts, format_str, args...); } diff --git a/include/fmt/core.h b/include/fmt/core.h index 00f9ffb1..76d6ccd1 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -208,7 +208,9 @@ # include #endif -#define FMT_ENABLE_IF_T(...) typename std::enable_if<__VA_ARGS__>::type +// 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 FMT_BEGIN_NAMESPACE namespace internal { @@ -513,8 +515,7 @@ struct compile_string {}; template struct is_compile_string : std::is_base_of {}; -template ::value)> +template ::value)> FMT_CONSTEXPR basic_string_view to_string_view( const S& s) { return s; @@ -791,15 +792,15 @@ FMT_MAKE_VALUE(int_type, signed char, int) FMT_MAKE_VALUE(uint_type, unsigned char, unsigned) // This doesn't use FMT_MAKE_VALUE because of ambiguity in gcc 4.4. -template -FMT_CONSTEXPR FMT_ENABLE_IF_T(std::is_same::value, - init) make_value(Char val) { +template ::value)> +FMT_CONSTEXPR init make_value(Char val) { return val; } -template -FMT_CONSTEXPR FMT_ENABLE_IF_T(!std::is_same::value, - init) make_value(char val) { +template ::value)> +FMT_CONSTEXPR init make_value(char val) { return val; } @@ -835,36 +836,36 @@ FMT_MAKE_VALUE(pointer_type, std::nullptr_t, const void*) // pointer cast it to "void *" or "const void *". In particular, this forbids // formatting of "[const] volatile char *" which is printed as bool by // iostreams. -template -FMT_ENABLE_IF_T(!std::is_same::value) -make_value(const T*) { +template ::value)> +void make_value(const T*) { static_assert(!sizeof(T), "formatting of non-void pointers is disallowed"); } -template -inline FMT_ENABLE_IF_T( - std::is_enum::value&& convert_to_int::value, - init) make_value(const T& val) { +template ::value&& + std::is_enum::value)> +inline init make_value(const T& val) { return static_cast(val); } -template -inline FMT_ENABLE_IF_T(is_constructible, T>::value && - !internal::is_string::value, - init, string_type>) - make_value(const T& val) { +template , T>::value && + !internal::is_string::value)> +inline init, string_type> make_value(const T& val) { return basic_string_view(val); } -template -inline FMT_ENABLE_IF_T( - !convert_to_int::value && !std::is_same::value && - !std::is_convertible>::value && - !is_constructible, T>::value && - !internal::is_string::value, - // Implicit conversion to std::string is not handled here because it's - // unsafe: https://github.com/fmtlib/fmt/issues/729 - init) make_value(const T& val) { +// Implicit conversion to std::string is not handled here because it's +// unsafe: https://github.com/fmtlib/fmt/issues/729 +template < + typename C, typename T, typename Char = typename C::char_type, + FMT_ENABLE_IF(!convert_to_int::value && + !std::is_same::value && + !std::is_convertible>::value && + !is_constructible, T>::value && + !internal::is_string::value)> +inline init make_value(const T& val) { return val; } @@ -876,11 +877,9 @@ init make_value( return static_cast(&val); } -template -FMT_CONSTEXPR11 FMT_ENABLE_IF_T( - internal::is_string::value, - init, string_type>) - make_value(const S& val) { +template ::value)> +FMT_CONSTEXPR11 init, string_type> +make_value(const S& val) { // Handle adapted strings. static_assert(std::is_same::type>::value, @@ -1067,14 +1066,15 @@ FMT_CONSTEXPR basic_format_arg make_arg(const T& value) { return arg; } -template -inline FMT_ENABLE_IF_T(IS_PACKED, value) make_arg(const T& value) { +template +inline value make_arg(const T& value) { return make_value(value); } -template -inline FMT_ENABLE_IF_T(!IS_PACKED, basic_format_arg) - make_arg(const T& value) { +template +inline basic_format_arg make_arg(const T& value) { return make_arg(value); } } // namespace internal @@ -1314,15 +1314,10 @@ struct wformat_args : basic_format_args { #endif #if FMT_USE_ALIAS_TEMPLATES /** String's character type. */ -template -using char_t = FMT_ENABLE_IF_T(internal::is_string::value, - typename internal::char_t::type); +template using char_t = typename internal::char_t::type; # define FMT_CHAR(S) fmt::char_t #else -template -struct char_t : std::enable_if::value, - typename internal::char_t::type> {}; -# define FMT_CHAR(S) typename char_t::type +# define FMT_CHAR(S) typename internal::char_t::type #endif namespace internal { @@ -1356,14 +1351,15 @@ template struct named_arg : named_arg_base { : named_arg_base(name), value(val) {} }; -template -inline FMT_ENABLE_IF_T(!is_compile_string::value) - check_format_string(const S&) {} -template -FMT_ENABLE_IF_T(is_compile_string::value) -check_format_string(S); +template ::value)> +inline void check_format_string(const S&) {} +template ::value)> +void check_format_string(S); -template +template ::value)> inline format_arg_store::type, Args...> make_args_checked(const S& format_str, const Args&... args) { internal::check_format_string(format_str); @@ -1396,7 +1392,7 @@ typename buffer_context::type::iterator vformat_to( fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23)); \endrst */ -template +template ::value)> inline internal::named_arg arg(const S& name, const T& arg) { return {name, arg}; } @@ -1415,8 +1411,8 @@ struct is_contiguous> : std::true_type {}; /** Formats a string and writes the output to ``out``. */ template -FMT_ENABLE_IF_T(is_contiguous::value, - std::back_insert_iterator) +typename std::enable_if::value, + std::back_insert_iterator>::type vformat_to(std::back_insert_iterator out, const S& format_str, basic_format_args::type> args) { internal::container_buffer buf(internal::get_container(out)); @@ -1424,17 +1420,18 @@ vformat_to(std::back_insert_iterator out, const S& format_str, return out; } -template -inline FMT_ENABLE_IF_T( - is_contiguous::value&& internal::is_string::value, - std::back_insert_iterator) - format_to(std::back_insert_iterator out, const S& format_str, - const Args&... args) { +template ::value&& internal::is_string::value)> +inline std::back_insert_iterator format_to( + std::back_insert_iterator out, const S& format_str, + const Args&... args) { return vformat_to(out, to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } -template +template ::value)> inline std::basic_string vformat( const S& format_str, basic_format_args::type> args) { @@ -1451,7 +1448,8 @@ inline std::basic_string vformat( std::string message = fmt::format("The answer is {}", 42); \endrst */ -template +template ::value)> inline std::basic_string format(const S& format_str, const Args&... args) { return internal::vformat(to_string_view(format_str), @@ -1472,9 +1470,9 @@ FMT_API void vprint(std::FILE* f, wstring_view format_str, wformat_args args); fmt::print(stderr, "Don't {}!", "panic"); \endrst */ -template -inline FMT_ENABLE_IF_T(internal::is_string::value, void) - print(std::FILE* f, const S& format_str, const Args&... args) { +template ::value)> +inline void print(std::FILE* f, const S& format_str, const Args&... args) { vprint(f, to_string_view(format_str), internal::make_args_checked(format_str, args...)); } @@ -1491,9 +1489,9 @@ FMT_API void vprint(wstring_view format_str, wformat_args args); fmt::print("Elapsed time: {0:.2f} seconds", 1.23); \endrst */ -template -inline FMT_ENABLE_IF_T(internal::is_string::value, void) - print(const S& format_str, const Args&... args) { +template ::value)> +inline void print(const S& format_str, const Args&... args) { vprint(to_string_view(format_str), internal::make_args_checked(format_str, args...)); } diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 0318298d..0f9af8b6 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -639,9 +639,10 @@ struct shortest_handler { } }; -template -FMT_FUNC typename std::enable_if::type -grisu2_format(Double value, buffer& buf, int precision, bool fixed, int& exp) { +template ::type> +FMT_FUNC bool grisu2_format(Double value, buffer& buf, int precision, + bool fixed, int& exp) { FMT_ASSERT(value >= 0, "value is negative"); if (value <= 0) { // <= instead of == to silence a warning. if (precision < 0) { diff --git a/include/fmt/format.h b/include/fmt/format.h index d4fd9bb4..ed605679 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -603,11 +603,9 @@ extern template int char_traits::format_float( long double value); #endif -template -inline typename std::enable_if< - is_contiguous::value, - typename checked::type>::type -reserve(std::back_insert_iterator& it, std::size_t n) { +template ::value)> +inline typename checked::type reserve( + std::back_insert_iterator& it, std::size_t n) { Container& c = internal::get_container(it); std::size_t size = c.size(); c.resize(size + n); @@ -735,16 +733,12 @@ class truncating_iterator // Returns true if value is negative, false otherwise. // Same as (value < 0) but doesn't produce warnings if T is an unsigned type. -template -FMT_CONSTEXPR - typename std::enable_if::is_signed, bool>::type - is_negative(T value) { +template ::is_signed)> +FMT_CONSTEXPR bool is_negative(T value) { return value < 0; } -template -FMT_CONSTEXPR - typename std::enable_if::is_signed, bool>::type - is_negative(T) { +template ::is_signed)> +FMT_CONSTEXPR bool is_negative(T) { return false; } @@ -820,17 +814,15 @@ struct needs_conversion char>::value && std::is_same::value> {}; -template -typename std::enable_if::value, - OutputIt>::type -copy_str(InputIt begin, InputIt end, OutputIt it) { +template ::value)> +OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { return std::copy(begin, end, it); } -template -typename std::enable_if::value, - OutputIt>::type -copy_str(InputIt begin, InputIt end, OutputIt it) { +template ::value)> +OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { return std::transform(begin, end, it, to_char8_t); } @@ -1137,12 +1129,11 @@ namespace internal { // Formats value using Grisu2 algorithm: // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf -template -FMT_API typename std::enable_if::type -grisu2_format(Double value, buffer& buf, int precision, bool fixed, int& exp); -template -inline typename std::enable_if::type -grisu2_format(Double, buffer&, int, bool, int&) { +template +FMT_API bool grisu2_format(Double value, buffer& buf, int precision, bool fixed, + int& exp); +template +inline bool grisu2_format(Double, buffer&, int, bool, int&) { return false; } @@ -1466,11 +1457,9 @@ template class arg_formatter_base { return out(); } - template - typename std::enable_if::value || - std::is_same::value, - iterator>::type - operator()(T value) { + template ::value || + std::is_same::value)> + 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) { @@ -1485,9 +1474,8 @@ template class arg_formatter_base { return out(); } - template - typename std::enable_if::value, iterator>::type - operator()(T value) { + template ::value)> + iterator operator()(T value) { writer_.write_double(value, specs_ ? *specs_ : format_specs()); return out(); } @@ -1608,18 +1596,14 @@ class width_checker : public function { public: explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {} - template - FMT_CONSTEXPR - typename std::enable_if::value, unsigned long long>::type - operator()(T value) { + template ::value)> + FMT_CONSTEXPR unsigned long long operator()(T value) { if (is_negative(value)) handler_.on_error("negative width"); return static_cast(value); } - template - FMT_CONSTEXPR - typename std::enable_if::value, unsigned long long>::type - operator()(T) { + template ::value)> + FMT_CONSTEXPR unsigned long long operator()(T) { handler_.on_error("width is not integer"); return 0; } @@ -1633,18 +1617,14 @@ class precision_checker : public function { public: explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {} - template - FMT_CONSTEXPR - typename std::enable_if::value, unsigned long long>::type - operator()(T value) { + template ::value)> + FMT_CONSTEXPR unsigned long long operator()(T value) { if (is_negative(value)) handler_.on_error("negative precision"); return static_cast(value); } - template - FMT_CONSTEXPR - typename std::enable_if::value, unsigned long long>::type - operator()(T) { + template ::value)> + FMT_CONSTEXPR unsigned long long operator()(T) { handler_.on_error("precision is not integer"); return 0; } @@ -1828,10 +1808,8 @@ struct string_view_metadata { : offset_(view.data() - primary_string.data()), size_(view.size()) {} FMT_CONSTEXPR string_view_metadata(std::size_t offset, std::size_t size) : offset_(offset), size_(size) {} - template - FMT_CONSTEXPR typename std::enable_if::value, - basic_string_view>::type - to_view(S&& str) const { + template ::value)> + FMT_CONSTEXPR basic_string_view to_view(S&& str) const { const auto view = to_string_view(str); return basic_string_view(view.data() + offset_, size_); } @@ -2266,9 +2244,9 @@ FMT_CONSTEXPR bool do_check_format_string(basic_string_view s, return true; } -template -typename std::enable_if::value>::type check_format_string( - S format_str) { +template ::value, int>::type> +void check_format_string(S format_str) { typedef typename S::char_type char_t; FMT_CONSTEXPR_DECL bool invalid_format = internal::do_check_format_string class basic_writer { Formats *value* and writes it to the buffer. \endrst */ - template - typename std::enable_if::value, void>::type write( - T value, FormatSpec spec, FormatSpecs... specs) { + template ::value)> + void write(T value, FormatSpec spec, FormatSpecs... specs) { format_specs s(spec, specs...); s.align_ = ALIGN_RIGHT; write_int(value, s); @@ -2809,9 +2787,8 @@ template class basic_writer { write(data, size, spec); } - template - typename std::enable_if::value>::type write( - const T* p) { + template ::value)> + void write(const T* p) { format_specs specs; specs.flags = HASH_FLAG; specs.type = 'x'; @@ -2879,8 +2856,8 @@ void basic_writer::write_double(T value, const format_specs& spec) { } } write_inf_or_nan = {*this, spec, sign, handler.as_percentage}; - // Format infinity and NaN ourselves because sprintf's output is not consistent - // across platforms. + // Format infinity and NaN ourselves because sprintf's output is not + // consistent across platforms. if (internal::fputil::isinfinity(value)) return write_inf_or_nan(handler.upper ? "INF" : "inf"); if (internal::fputil::isnotanumber(value)) @@ -3403,7 +3380,8 @@ typename buffer_context::type::iterator internal::vformat_to( args); } -template +template ::value)> inline typename buffer_context::type::iterator vformat_to( internal::basic_buffer& buf, const S& format_str, basic_format_args::type> args) { @@ -3477,11 +3455,11 @@ struct format_args_t { type; }; -template -inline typename std::enable_if::value, - OutputIt>::type -vformat_to(OutputIt out, const String& format_str, - typename format_args_t::type args) { +template ::value)> +inline OutputIt vformat_to( + OutputIt out, const String& format_str, + typename format_args_t::type args) { typedef output_range range; return vformat_to>(range(out), to_string_view(format_str), args); @@ -3499,9 +3477,10 @@ vformat_to(OutputIt out, const String& format_str, \endrst */ template -inline FMT_ENABLE_IF_T(internal::is_string::value&& - internal::is_output_iterator::value, - OutputIt) +inline + typename std::enable_if::value && + internal::is_output_iterator::value, + OutputIt>::type format_to(OutputIt out, const S& format_str, const Args&... args) { internal::check_format_string(format_str); typedef typename format_context_t::type context; @@ -3535,11 +3514,11 @@ make_format_to_n_args(const Args&... args) { Args...>(args...); } -template -inline typename std::enable_if::value, - format_to_n_result>::type -vformat_to_n(OutputIt out, std::size_t n, basic_string_view format_str, - typename format_to_n_args::type args) { +template ::value)> +inline format_to_n_result vformat_to_n( + OutputIt out, std::size_t n, basic_string_view format_str, + typename format_to_n_args::type args) { typedef internal::truncating_iterator It; auto it = vformat_to(It(out, n), format_str, args); return {it.base(), it.count()}; @@ -3552,12 +3531,12 @@ vformat_to_n(OutputIt out, std::size_t n, basic_string_view format_str, end of the output range. \endrst */ -template -inline FMT_ENABLE_IF_T(internal::is_string::value&& - internal::is_output_iterator::value, - format_to_n_result) - format_to_n(OutputIt out, std::size_t n, const S& format_str, - const Args&... args) { +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); typedef FMT_CHAR(S) Char; format_arg_store::type, Args...> diff --git a/include/fmt/locale.h b/include/fmt/locale.h index 39c32eb0..4a33b666 100644 --- a/include/fmt/locale.h +++ b/include/fmt/locale.h @@ -49,23 +49,21 @@ inline std::basic_string format(const std::locale& loc, {internal::make_args_checked(format_str, args...)}); } -template -inline typename std::enable_if::value, - OutputIt>::type -vformat_to(OutputIt out, const std::locale& loc, const String& format_str, - typename format_args_t::type args) { +template ::value)> +inline OutputIt vformat_to( + OutputIt out, const std::locale& loc, const String& format_str, + typename format_args_t::type args) { typedef output_range range; return vformat_to>( range(out), to_string_view(format_str), args, internal::locale_ref(loc)); } -template -inline - typename std::enable_if::value && - internal::is_output_iterator::value, - OutputIt>::type - format_to(OutputIt out, const std::locale& loc, const S& format_str, - const Args&... args) { +template ::value&& + internal::is_output_iterator::value)> +inline OutputIt format_to(OutputIt out, const std::locale& loc, + const S& format_str, const Args&... args) { internal::check_format_string(format_str); typedef typename format_context_t::type context; format_arg_store as{args...}; diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index 798b05c0..5f70fed6 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -134,10 +134,10 @@ inline void vprint( fmt::print(cerr, "Don't {}!", "panic"); \endrst */ -template -inline typename std::enable_if::value>::type print( - std::basic_ostream& os, const S& format_str, - const Args&... args) { +template ::value)> +inline void print(std::basic_ostream& os, const S& format_str, + const Args&... args) { vprint(os, to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } diff --git a/include/fmt/prepare.h b/include/fmt/prepare.h index 08275a54..2e063e1e 100644 --- a/include/fmt/prepare.h +++ b/include/fmt/prepare.h @@ -198,10 +198,10 @@ class prepared_format { return it.count(); } - template - inline typename std::enable_if::value, - format_to_n_result>::type - format_to_n(OutputIt out, unsigned n, const Args&... args) const { + template ::value)> + inline format_to_n_result format_to_n(OutputIt out, unsigned n, + const Args&... args) const { format_arg_store::type, Args...> as(args...); @@ -221,11 +221,9 @@ class prepared_format { return to_string(buffer); } - template - inline typename std::enable_if::value, - std::back_insert_iterator>::type - format_to(std::back_insert_iterator out, - const Args&... args) const { + template ::value)> + inline std::back_insert_iterator format_to( + std::back_insert_iterator out, const Args&... args) const { internal::container_buffer buffer(internal::get_container(out)); typedef back_insert_range> range; this->vformat_to(range(buffer), make_args_checked(format_, args...)); diff --git a/include/fmt/printf.h b/include/fmt/printf.h index 407d23a8..c3d8b556 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -36,17 +36,15 @@ template <> struct int_checker { class printf_precision_handler : public function { public: - template - typename std::enable_if::value, int>::type operator()( - T value) { + template ::value)> + int operator()(T value) { if (!int_checker::is_signed>::fits_in_int(value)) FMT_THROW(format_error("number is too big")); return static_cast(value); } - template - typename std::enable_if::value, int>::type operator()( - T) { + template ::value)> + int operator()(T) { FMT_THROW(format_error("precision is not integer")); return 0; } @@ -55,15 +53,13 @@ class printf_precision_handler : public function { // An argument visitor that returns true iff arg is a zero integer. class is_zero_int : public function { public: - template - typename std::enable_if::value, bool>::type operator()( - T value) { + template ::value)> + bool operator()(T value) { return value == 0; } - template - typename std::enable_if::value, bool>::type operator()( - T) { + template ::value)> + bool operator()(T) { return false; } }; @@ -88,9 +84,8 @@ class arg_converter : public function { if (type_ != 's') operator()(value); } - template - typename std::enable_if::value>::type operator()( - U value) { + template ::value)> + void operator()(U value) { bool is_signed = type_ == 'd' || type_ == 'i'; typedef typename std::conditional::value, U, T>::type TargetType; @@ -117,10 +112,8 @@ class arg_converter : public function { } } - template - typename std::enable_if::value>::type operator()(U) { - // No conversion needed for non-integral types. - } + template ::value)> + void operator()(U) {} // No conversion needed for non-integral types. }; // Converts an integer argument to T for printf, if T is an integral type. @@ -140,17 +133,14 @@ template class char_converter : public function { public: explicit char_converter(basic_format_arg& arg) : arg_(arg) {} - template - typename std::enable_if::value>::type operator()( - T value) { + template ::value)> + void operator()(T value) { typedef typename Context::char_type Char; arg_ = internal::make_arg(static_cast(value)); } - template - typename std::enable_if::value>::type operator()(T) { - // No conversion needed for non-integral types. - } + template ::value)> + void operator()(T) {} // No conversion needed for non-integral types. }; // Checks if an argument is a valid printf width specifier and sets @@ -165,9 +155,8 @@ class printf_width_handler : public function { public: explicit printf_width_handler(format_specs& spec) : spec_(spec) {} - template - typename std::enable_if::value, unsigned>::type - operator()(T value) { + template ::value)> + unsigned operator()(T value) { typedef typename internal::int_traits::main_type UnsignedType; UnsignedType width = static_cast(value); if (internal::is_negative(value)) { @@ -179,9 +168,8 @@ class printf_width_handler : public function { return static_cast(width); } - template - typename std::enable_if::value, unsigned>::type - operator()(T) { + template ::value)> + unsigned operator()(T) { FMT_THROW(format_error("width is not integer")); return 0; } @@ -252,9 +240,8 @@ class printf_arg_formatter printf_arg_formatter(iterator iter, format_specs& spec, context_type& ctx) : base(Range(iter), &spec, internal::locale_ref()), context_(ctx) {} - template - typename std::enable_if::value, iterator>::type - operator()(T value) { + template ::value)> + 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) { @@ -275,9 +262,8 @@ class printf_arg_formatter return this->out(); } - template - typename std::enable_if::value, iterator>::type - operator()(T value) { + template ::value)> + iterator operator()(T value) { return base::operator()(value); } @@ -637,10 +623,9 @@ inline std::basic_string vsprintf( return to_string(buffer); } -template -inline typename std::enable_if::value, - format_to_n_result>::type -vsnprintf( +template ::value)> +inline format_to_n_result vsnprintf( OutputIt out, std::size_t n, const S& format, basic_format_args::type> args) { @@ -658,10 +643,10 @@ vsnprintf( std::string message = fmt::sprintf("The answer is %d", 42); \endrst */ -template -inline FMT_ENABLE_IF_T(internal::is_string::value, - std::basic_string) - sprintf(const S& format, const Args&... args) { +template ::value)> +inline std::basic_string sprintf(const S& format, + const Args&... args) { internal::check_format_string(format); typedef internal::basic_buffer buffer; typedef typename basic_printf_context_t::type context; @@ -683,12 +668,12 @@ inline FMT_ENABLE_IF_T(internal::is_string::value, res Res = fmt::snprintf(std::back_inserter(out), 5, "The answer is %d", 42); \endrst */ -template -inline FMT_ENABLE_IF_T(internal::is_string::value&& - internal::is_output_iterator::value, - format_to_n_result) - snprintf(OutputIt out, std::size_t n, const S& format, - const Args&... args) { +template ::value&& + internal::is_output_iterator::value)> +inline format_to_n_result snprintf(OutputIt out, std::size_t n, + const S& format, + const Args&... args) { internal::check_format_string(format); typedef FMT_CHAR(S) Char; typedef typename basic_printf_n_context_t::type context; @@ -720,9 +705,9 @@ inline int vfprintf( fmt::fprintf(stderr, "Don't %s!", "panic"); \endrst */ -template -inline FMT_ENABLE_IF_T(internal::is_string::value, int) - fprintf(std::FILE* f, const S& format, const Args&... args) { +template ::value)> +inline int fprintf(std::FILE* f, const S& format, const Args&... args) { internal::check_format_string(format); typedef internal::basic_buffer buffer; typedef typename basic_printf_context_t::type context; @@ -748,9 +733,9 @@ inline int vprintf( fmt::printf("Elapsed time: %.2f seconds", 1.23); \endrst */ -template -inline FMT_ENABLE_IF_T(internal::is_string::value, int) - printf(const S& format_str, const Args&... args) { +template ::value)> +inline int printf(const S& format_str, const Args&... args) { internal::check_format_string(format_str); typedef internal::basic_buffer buffer; typedef typename basic_printf_context_t::type context; @@ -779,10 +764,10 @@ inline int vfprintf( fmt::fprintf(cerr, "Don't %s!", "panic"); \endrst */ -template -inline FMT_ENABLE_IF_T(internal::is_string::value, int) - fprintf(std::basic_ostream& os, const S& format_str, - const Args&... args) { +template ::value)> +inline int fprintf(std::basic_ostream& os, const S& format_str, + const Args&... args) { internal::check_format_string(format_str); typedef internal::basic_buffer buffer; typedef typename basic_printf_context_t::type context; diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 9201433e..646d63f9 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -161,21 +161,15 @@ template void for_each(Tuple&& tup, F&& f) { for_each(indexes, std::forward(tup), std::forward(f)); } -template -FMT_CONSTEXPR const char* format_str_quoted( - bool add_space, const Arg&, - typename std::enable_if< - !is_like_std_string::type>::value>::type* = - nullptr) { +template ::type>::value)> +FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) { return add_space ? " {}" : "{}"; } -template -FMT_CONSTEXPR const char* format_str_quoted( - bool add_space, const Arg&, - typename std::enable_if< - is_like_std_string::type>::value>::type* = - nullptr) { +template ::type>::value)> +FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) { return add_space ? " \"{}\"" : "\"{}\""; }