Add wchar.h for wide char overloads
This commit is contained in:
parent
ce14eafc24
commit
0dd91e20d5
@ -187,7 +187,8 @@ endfunction()
|
||||
|
||||
# Define the fmt library, its includes and the needed defines.
|
||||
add_headers(FMT_HEADERS args.h chrono.h color.h compile.h core.h format.h
|
||||
format-inl.h locale.h os.h ostream.h printf.h ranges.h)
|
||||
format-inl.h locale.h os.h ostream.h printf.h ranges.h
|
||||
wchar.h)
|
||||
if (FMT_OS)
|
||||
set(FMT_SOURCES src/format.cc src/os.cc)
|
||||
else()
|
||||
|
@ -392,8 +392,8 @@ FMT_CONSTEXPR typename std::make_unsigned<Int>::type to_unsigned(Int value) {
|
||||
|
||||
FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char micro[] = "\u00B5";
|
||||
|
||||
template <typename Char> constexpr bool is_unicode() {
|
||||
return FMT_UNICODE || sizeof(Char) != 1 ||
|
||||
constexpr bool is_utf8() {
|
||||
return FMT_UNICODE ||
|
||||
(sizeof(micro) == 3 && micro[0] == 0xC2 && micro[1] == 0xB5);
|
||||
}
|
||||
FMT_END_DETAIL_NAMESPACE
|
||||
@ -2895,12 +2895,12 @@ FMT_INLINE auto vformat(
|
||||
return detail::vformat(to_string_view(format_str), args);
|
||||
}
|
||||
|
||||
#if FMT_COMPILE_TIME_CHECKS
|
||||
template <typename Char, typename... Args> class basic_format_string {
|
||||
private:
|
||||
basic_string_view<Char> str;
|
||||
|
||||
public:
|
||||
#if FMT_COMPILE_TIME_CHECKS
|
||||
template <size_t N>
|
||||
consteval basic_format_string(const char (&s)[N]) : str(s) {
|
||||
if constexpr (detail::count_named_args<Args...>() == 0) {
|
||||
@ -2909,21 +2909,29 @@ template <typename Char, typename... Args> class basic_format_string {
|
||||
detail::parse_format_string<true>(string_view(s, N), checker(s, {}));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T,
|
||||
FMT_ENABLE_IF(std::is_constructible_v<string_view, const T&>)>
|
||||
basic_format_string(const T& s) : str(s) {}
|
||||
FMT_ENABLE_IF(std::is_constructible<basic_string_view<Char>,
|
||||
const T&>::value)>
|
||||
basic_format_string(const T& s) : str(s) {
|
||||
static_assert(
|
||||
detail::count<
|
||||
(std::is_base_of<detail::view, remove_reference_t<Args>>::value &&
|
||||
std::is_reference<Args>::value)...>() == 0,
|
||||
"passing views as lvalues is disallowed");
|
||||
detail::check_format_string<Args...>(s);
|
||||
}
|
||||
|
||||
operator basic_string_view<Char>() const { return str; }
|
||||
FMT_INLINE operator basic_string_view<Char>() const { return str; }
|
||||
};
|
||||
|
||||
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
|
||||
// Workaround broken conversion on older gcc.
|
||||
template <typename... Args> using format_string = string_view;
|
||||
#else
|
||||
template <typename... Args>
|
||||
using format_string = basic_format_string<char, std::type_identity_t<Args>...>;
|
||||
|
||||
template <typename... T>
|
||||
FMT_INLINE auto format(format_string<T...> str, T&&... args) -> std::string {
|
||||
return detail::vformat(str, make_format_args(args...));
|
||||
}
|
||||
using format_string = basic_format_string<char, type_identity_t<Args>...>;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -2936,15 +2944,9 @@ FMT_INLINE auto format(format_string<T...> str, T&&... args) -> std::string {
|
||||
std::string message = fmt::format("The answer is {}", 42);
|
||||
\endrst
|
||||
*/
|
||||
// Pass char_t as a default template parameter instead of using
|
||||
// std::basic_string<char_t<S>> to reduce the symbol size.
|
||||
template <typename S, typename... Args, typename Char = char_t<S>,
|
||||
FMT_ENABLE_IF(!FMT_COMPILE_TIME_CHECKS ||
|
||||
!std::is_same<Char, char>::value)>
|
||||
FMT_INLINE auto format(const S& format_str, Args&&... args)
|
||||
-> std::basic_string<Char> {
|
||||
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
|
||||
return detail::vformat(to_string_view(format_str), vargs);
|
||||
template <typename... T>
|
||||
FMT_INLINE auto format(format_string<T...> str, T&&... args) -> std::string {
|
||||
return detail::vformat(str, make_format_args(args...));
|
||||
}
|
||||
|
||||
FMT_API void vprint(string_view, format_args);
|
||||
@ -2952,8 +2954,8 @@ FMT_API void vprint(std::FILE*, string_view, format_args);
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats ``args`` according to specifications in ``format_str`` and writes the
|
||||
output to the file ``f``. Strings are assumed to be Unicode-encoded unless the
|
||||
Formats ``args`` according to specifications in ``str`` and writes the
|
||||
output to the file ``f``. Strings are assumed to be in UTF-8 unless the
|
||||
``FMT_UNICODE`` macro is set to 0.
|
||||
|
||||
**Example**::
|
||||
@ -2961,32 +2963,29 @@ FMT_API void vprint(std::FILE*, string_view, format_args);
|
||||
fmt::print(stderr, "Don't {}!", "panic");
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline void print(std::FILE* f, const S& format_str, Args&&... args) {
|
||||
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
|
||||
return detail::is_unicode<Char>()
|
||||
? vprint(f, to_string_view(format_str), vargs)
|
||||
: detail::vprint_mojibake(f, to_string_view(format_str), vargs);
|
||||
template <typename... T>
|
||||
inline void print(std::FILE* f, format_string<T...> str, T&&... args) {
|
||||
const auto& vargs = make_format_args(args...);
|
||||
return detail::is_utf8() ? vprint(f, str, vargs)
|
||||
: detail::vprint_mojibake(f, str, vargs);
|
||||
}
|
||||
|
||||
/**
|
||||
\rst
|
||||
Formats ``args`` according to specifications in ``format_str`` and writes
|
||||
the output to ``stdout``. Strings are assumed to be Unicode-encoded unless
|
||||
the ``FMT_UNICODE`` macro is set to 0.
|
||||
Formats ``args`` according to specifications in ``str`` and writes the output
|
||||
to ``stdout``. Strings are assumed to be in UTF-8 unless the ``FMT_UNICODE``
|
||||
macro is set to 0.
|
||||
|
||||
**Example**::
|
||||
|
||||
fmt::print("Elapsed time: {0:.2f} seconds", 1.23);
|
||||
\endrst
|
||||
*/
|
||||
template <typename S, typename... Args, typename Char = char_t<S>>
|
||||
inline void print(const S& format_str, Args&&... args) {
|
||||
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
|
||||
return detail::is_unicode<Char>()
|
||||
? vprint(to_string_view(format_str), vargs)
|
||||
: detail::vprint_mojibake(stdout, to_string_view(format_str),
|
||||
vargs);
|
||||
template <typename... T>
|
||||
inline void print(format_string<T...> str, T&&... args) {
|
||||
const auto& vargs = make_format_args(args...);
|
||||
return detail::is_utf8() ? vprint(str, vargs)
|
||||
: detail::vprint_mojibake(stdout, str, vargs);
|
||||
}
|
||||
|
||||
FMT_MODULE_EXPORT_END
|
||||
|
@ -2658,6 +2658,16 @@ auto detail::vformat(
|
||||
return to_string(buffer);
|
||||
}
|
||||
|
||||
// Pass char_t as a default template parameter instead of using
|
||||
// std::basic_string<char_t<S>> to reduce the symbol size.
|
||||
template <typename S, typename... Args, typename Char = char_t<S>,
|
||||
FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
|
||||
FMT_INLINE auto format(const S& format_str, Args&&... args)
|
||||
-> std::basic_string<Char> {
|
||||
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
|
||||
return detail::vformat(to_string_view(format_str), vargs);
|
||||
}
|
||||
|
||||
template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
|
||||
void vprint(std::FILE* f, basic_string_view<Char> format_str,
|
||||
wformat_args args) {
|
||||
|
39
include/fmt/wchar.h
Normal file
39
include/fmt/wchar.h
Normal file
@ -0,0 +1,39 @@
|
||||
// Formatting library for C++ - experimental wchar_t support
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifndef FMT_WCHAR_H_
|
||||
#define FMT_WCHAR_H_
|
||||
|
||||
#include "format.h"
|
||||
|
||||
namespace fmt {
|
||||
|
||||
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
|
||||
// Workaround broken conversion on older gcc.
|
||||
template <typename... Args> using wformat_string = wstring_view;
|
||||
#else
|
||||
template <typename... Args>
|
||||
using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;
|
||||
#endif
|
||||
|
||||
template <typename... Args>
|
||||
constexpr format_arg_store<wformat_context, Args...> make_wformat_args(
|
||||
const Args&... args) {
|
||||
return {args...};
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
void print(std::FILE* f, wformat_string<T...> str, T&&... args) {
|
||||
return vprint(f, wstring_view(str), make_wformat_args(args...));
|
||||
}
|
||||
|
||||
template <typename... T> void print(wformat_string<T...> str, T&&... args) {
|
||||
return vprint(wstring_view(str), make_wformat_args(args...));
|
||||
}
|
||||
} // namespace fmt
|
||||
|
||||
#endif // FMT_WCHAR_H_
|
@ -72,6 +72,7 @@ add_fmt_test(compile-test)
|
||||
add_fmt_test(printf-test)
|
||||
add_fmt_test(ranges-test)
|
||||
add_fmt_test(scan-test)
|
||||
add_fmt_test(wchar-test)
|
||||
|
||||
if (NOT MSVC)
|
||||
# FMT_ENFORCE_COMPILE_STRING is not supported under MSVC due to compiler bugs.
|
||||
|
@ -590,11 +590,6 @@ TEST(core_test, to_string_view_foreign_strings) {
|
||||
EXPECT_EQ(type, fmt::detail::type::string_type);
|
||||
}
|
||||
|
||||
TEST(core_test, format_foreign_strings) {
|
||||
using namespace test_ns;
|
||||
EXPECT_EQ(fmt::format(test_string<char>("{}"), 42), "42");
|
||||
}
|
||||
|
||||
struct implicitly_convertible_to_string {
|
||||
operator std::string() const { return "foo"; }
|
||||
};
|
||||
|
@ -1580,8 +1580,6 @@ TEST(format_test, print) {
|
||||
EXPECT_WRITE(stdout, fmt::print("Don't {}!", "panic"), "Don't panic!");
|
||||
EXPECT_WRITE(stderr, fmt::print(stderr, "Don't {}!", "panic"),
|
||||
"Don't panic!");
|
||||
// Check that the wide print overload compiles.
|
||||
if (fmt::detail::const_check(false)) fmt::print(L"test");
|
||||
}
|
||||
|
||||
TEST(format_test, variadic) {
|
||||
|
15
test/wchar-test.cc
Normal file
15
test/wchar-test.cc
Normal file
@ -0,0 +1,15 @@
|
||||
// Formatting library for C++ - formatting library tests
|
||||
//
|
||||
// Copyright (c) 2012 - present, Victor Zverovich
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#include "fmt/wchar.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(wchar_test, print) {
|
||||
// Check that the wide print overload compiles.
|
||||
if (fmt::detail::const_check(false)) fmt::print(L"test");
|
||||
}
|
Loading…
Reference in New Issue
Block a user