mirror of
https://github.com/fmtlib/fmt.git
synced 2025-04-01 10:20:59 +00:00
Merge format overloads using SFINAE
This commit is contained in:
parent
2a4e948864
commit
4f16409730
@ -711,7 +711,7 @@ struct result_of<F(Args...)> {
|
|||||||
typedef typename std::result_of<
|
typedef typename std::result_of<
|
||||||
typename std::remove_reference<F>::type(Args...)>::type type;
|
typename std::remove_reference<F>::type(Args...)>::type type;
|
||||||
};
|
};
|
||||||
}
|
} // namespace internal
|
||||||
|
|
||||||
// A formatting argument. It is a trivially copyable/constructible type to
|
// A formatting argument. It is a trivially copyable/constructible type to
|
||||||
// allow storage in basic_memory_buffer.
|
// allow storage in basic_memory_buffer.
|
||||||
@ -1292,6 +1292,44 @@ typename std::enable_if<
|
|||||||
std::string vformat(string_view format_str, format_args args);
|
std::string vformat(string_view format_str, format_args args);
|
||||||
std::wstring vformat(wstring_view format_str, wformat_args args);
|
std::wstring vformat(wstring_view format_str, wformat_args args);
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
// If S is a format string type, format_string_traints<S>::char_type gives its
|
||||||
|
// character type.
|
||||||
|
template <typename S>
|
||||||
|
struct format_string_traits {
|
||||||
|
private:
|
||||||
|
// Use construtbility as a way to detect if format_string_traits is
|
||||||
|
// specialized because other methods are broken on MSVC2013.
|
||||||
|
format_string_traits();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
struct format_string_traits_base { typedef Char char_type; };
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
struct format_string_traits<const Char *>: format_string_traits_base<Char> {};
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
struct format_string_traits<Char *>: format_string_traits_base<Char> {};
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
struct format_string_traits<std::basic_string<Char>>:
|
||||||
|
format_string_traits_base<Char> {};
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
struct format_string_traits<basic_string_view<Char>>:
|
||||||
|
format_string_traits_base<Char> {};
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
struct is_format_string:
|
||||||
|
std::integral_constant<
|
||||||
|
bool, std::is_constructible<format_string_traits<S>>::value> {};
|
||||||
|
|
||||||
|
template <typename... Args, typename S>
|
||||||
|
typename std::enable_if<is_format_string<S>::value>::type
|
||||||
|
check_format_string(S) {}
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
Formats arguments and returns the result as a string.
|
Formats arguments and returns the result as a string.
|
||||||
@ -1302,17 +1340,17 @@ std::wstring vformat(wstring_view format_str, wformat_args args);
|
|||||||
std::string message = fmt::format("The answer is {}", 42);
|
std::string message = fmt::format("The answer is {}", 42);
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
template <typename... Args>
|
template <typename String, typename... Args>
|
||||||
inline std::string format(string_view format_str, const Args & ... args) {
|
inline std::basic_string<
|
||||||
|
typename internal::format_string_traits<String>::char_type>
|
||||||
|
format(String format_str, const Args & ... args) {
|
||||||
|
typedef typename internal::format_string_traits<String>::char_type char_type;
|
||||||
|
internal::check_format_string<Args...>(format_str);
|
||||||
// This should be just
|
// This should be just
|
||||||
// return vformat(format_str, make_format_args(args...));
|
// return vformat(format_str, make_format_args(args...));
|
||||||
// but gcc has trouble optimizing the latter, so break it down.
|
// but gcc has trouble optimizing the latter, so break it down.
|
||||||
format_arg_store<format_context, Args...> as{args...};
|
typedef typename buffer_context<char_type>::type context_type;
|
||||||
return vformat(format_str, as);
|
format_arg_store<context_type, Args...> as{args...};
|
||||||
}
|
|
||||||
template <typename... Args>
|
|
||||||
inline std::wstring format(wstring_view format_str, const Args & ... args) {
|
|
||||||
format_arg_store<wformat_context, Args...> as{args...};
|
|
||||||
return vformat(format_str, as);
|
return vformat(format_str, as);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1352,7 +1352,7 @@ FMT_CONSTEXPR unsigned basic_parse_context<Char, ErrorHandler>::next_arg_id() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct format_string {};
|
struct compile_string {};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@ -1646,8 +1646,8 @@ class arg_formatter_base {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
struct is_format_string:
|
struct is_compile_string:
|
||||||
std::integral_constant<bool, std::is_base_of<format_string, S>::value> {};
|
std::integral_constant<bool, std::is_base_of<compile_string, S>::value> {};
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR bool is_name_start(Char c) {
|
FMT_CONSTEXPR bool is_name_start(Char c) {
|
||||||
@ -2317,7 +2317,8 @@ FMT_CONSTEXPR bool check_format_string(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args, typename String>
|
template <typename... Args, typename String>
|
||||||
void check_format_string(String format_str) {
|
typename std::enable_if<is_compile_string<String>::value>::type
|
||||||
|
check_format_string(String format_str) {
|
||||||
FMT_CONSTEXPR_DECL bool invalid_format =
|
FMT_CONSTEXPR_DECL bool invalid_format =
|
||||||
internal::check_format_string<char, internal::error_handler, Args...>(
|
internal::check_format_string<char, internal::error_handler, Args...>(
|
||||||
string_view(format_str.data(), format_str.size()));
|
string_view(format_str.data(), format_str.size()));
|
||||||
@ -3678,14 +3679,14 @@ inline std::wstring vformat(wstring_view format_str, wformat_args args) {
|
|||||||
|
|
||||||
template <typename String, typename... Args>
|
template <typename String, typename... Args>
|
||||||
inline typename std::enable_if<
|
inline typename std::enable_if<
|
||||||
internal::is_format_string<String>::value, std::string>::type
|
internal::is_compile_string<String>::value, std::string>::type
|
||||||
format(String format_str, const Args & ... args) {
|
format(String format_str, const Args & ... args) {
|
||||||
internal::check_format_string<Args...>(format_str);
|
internal::check_format_string<Args...>(format_str);
|
||||||
return vformat(format_str.data(), make_format_args(args...));
|
return vformat(format_str.data(), make_format_args(args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename String, typename... Args>
|
template <typename String, typename... Args>
|
||||||
inline typename std::enable_if<internal::is_format_string<String>::value>::type
|
inline typename std::enable_if<internal::is_compile_string<String>::value>::type
|
||||||
print(String format_str, const Args & ... args) {
|
print(String format_str, const Args & ... args) {
|
||||||
internal::check_format_string<Args...>(format_str);
|
internal::check_format_string<Args...>(format_str);
|
||||||
return vprint(format_str.data(), make_format_args(args...));
|
return vprint(format_str.data(), make_format_args(args...));
|
||||||
@ -3979,7 +3980,7 @@ FMT_END_NAMESPACE
|
|||||||
|
|
||||||
#define FMT_STRING(s) [] { \
|
#define FMT_STRING(s) [] { \
|
||||||
typedef typename std::decay<decltype(s)>::type pointer; \
|
typedef typename std::decay<decltype(s)>::type pointer; \
|
||||||
struct S : fmt::format_string { \
|
struct S : fmt::compile_string { \
|
||||||
static FMT_CONSTEXPR pointer data() { return s; } \
|
static FMT_CONSTEXPR pointer data() { return s; } \
|
||||||
static FMT_CONSTEXPR size_t size() { return sizeof(s); } \
|
static FMT_CONSTEXPR size_t size() { return sizeof(s); } \
|
||||||
}; \
|
}; \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user