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