Improve separation between code unit types

This commit is contained in:
Victor Zverovich
2021-05-19 08:52:16 -07:00
parent 39c3c4ec22
commit 95c358f721
6 changed files with 29 additions and 28 deletions

View File

@@ -494,12 +494,10 @@ template <typename Char> class basic_string_view {
}; };
using string_view = basic_string_view<char>; using string_view = basic_string_view<char>;
using wstring_view = basic_string_view<wchar_t>;
/** Specifies if ``T`` is a character type. Can be specialized by users. */ /** Specifies if ``T`` is a character type. Can be specialized by users. */
template <typename T> struct is_char : std::false_type {}; template <typename T> struct is_char : std::false_type {};
template <> struct is_char<char> : std::true_type {}; template <> struct is_char<char> : std::true_type {};
template <> struct is_char<wchar_t> : std::true_type {};
/** /**
\rst \rst
@@ -597,16 +595,7 @@ template <typename S> using char_t = typename detail::char_t_impl<S>::type;
\rst \rst
Parsing context consisting of a format string range being parsed and an Parsing context consisting of a format string range being parsed and an
argument counter for automatic indexing. argument counter for automatic indexing.
You can use the ```format_parse_context`` type alias for ``char`` instead.
You can use one of the following type aliases for common character types:
+-----------------------+-------------------------------------+
| Type | Definition |
+=======================+=====================================+
| format_parse_context | basic_format_parse_context<char> |
+-----------------------+-------------------------------------+
| wformat_parse_context | basic_format_parse_context<wchar_t> |
+-----------------------+-------------------------------------+
\endrst \endrst
*/ */
template <typename Char, typename ErrorHandler = detail::error_handler> template <typename Char, typename ErrorHandler = detail::error_handler>
@@ -673,7 +662,6 @@ class basic_format_parse_context : private ErrorHandler {
}; };
using format_parse_context = basic_format_parse_context<char>; using format_parse_context = basic_format_parse_context<char>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
template <typename Context> class basic_format_arg; template <typename Context> class basic_format_arg;
template <typename Context> class basic_format_args; template <typename Context> class basic_format_args;
@@ -1565,7 +1553,6 @@ template <typename Char>
using buffer_context = using buffer_context =
basic_format_context<detail::buffer_appender<Char>, Char>; basic_format_context<detail::buffer_appender<Char>, Char>;
using format_context = buffer_context<char>; using format_context = buffer_context<char>;
using wformat_context = buffer_context<wchar_t>;
// Workaround an alias issue: https://stackoverflow.com/q/62767544/471164. // Workaround an alias issue: https://stackoverflow.com/q/62767544/471164.
#define FMT_BUFFER_CONTEXT(Char) \ #define FMT_BUFFER_CONTEXT(Char) \
@@ -1777,10 +1764,9 @@ template <typename Context> class basic_format_args {
}; };
/** An alias to ``basic_format_args<format_context>``. */ /** An alias to ``basic_format_args<format_context>``. */
// Separate types would result in shorter symbols but break ABI compatibility // A separate type would result in shorter symbols but break ABI compatibility
// between clang and gcc on ARM (#1919). // between clang and gcc on ARM (#1919).
using format_args = basic_format_args<format_context>; using format_args = basic_format_args<format_context>;
using wformat_args = basic_format_args<wformat_context>;
// We cannot use enum classes as bit fields because of a gcc bug // We cannot use enum classes as bit fields because of a gcc bug
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414.

View File

@@ -623,6 +623,9 @@ void iterator_buffer<OutputIt, T, Traits>::flush() {
FMT_MODULE_EXPORT_BEGIN FMT_MODULE_EXPORT_BEGIN
using wstring_view = basic_string_view<wchar_t>;
template <> struct is_char<wchar_t> : std::true_type {};
template <> struct is_char<detail::char8_type> : std::true_type {}; template <> struct is_char<detail::char8_type> : std::true_type {};
template <> struct is_char<char16_t> : std::true_type {}; template <> struct is_char<char16_t> : std::true_type {};
template <> struct is_char<char32_t> : std::true_type {}; template <> struct is_char<char32_t> : std::true_type {};
@@ -2888,4 +2891,8 @@ FMT_END_NAMESPACE
# define FMT_FUNC # define FMT_FUNC
#endif #endif
#ifdef FMT_DEPRECATED_WCHAR
# include "wchar.h"
#endif
#endif // FMT_FORMAT_H_ #endif // FMT_FORMAT_H_

View File

@@ -14,6 +14,10 @@
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
using wformat_parse_context = basic_format_parse_context<wchar_t>;
using wformat_context = buffer_context<wchar_t>;
using wformat_args = basic_format_args<wformat_context>;
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
// Workaround broken conversion on older gcc. // Workaround broken conversion on older gcc.
template <typename... Args> using wformat_string = wstring_view; template <typename... Args> using wformat_string = wstring_view;

View File

@@ -2380,16 +2380,6 @@ TEST(format_test, vformat_to) {
s.clear(); s.clear();
fmt::vformat_to(std::back_inserter(s), FMT_STRING("{}"), args); fmt::vformat_to(std::back_inserter(s), FMT_STRING("{}"), args);
EXPECT_EQ("42", s); EXPECT_EQ("42", s);
using wcontext = fmt::wformat_context;
fmt::basic_format_arg<wcontext> warg = fmt::detail::make_arg<wcontext>(42);
auto wargs = fmt::basic_format_args<wcontext>(&warg, 1);
auto w = std::wstring();
fmt::vformat_to(std::back_inserter(w), L"{}", wargs);
EXPECT_EQ(L"42", w);
w.clear();
fmt::vformat_to(std::back_inserter(w), FMT_STRING(L"{}"), wargs);
EXPECT_EQ(L"42", w);
} }
template <typename T> static std::string fmt_to_string(const T& t) { template <typename T> static std::string fmt_to_string(const T& t) {

View File

@@ -88,8 +88,10 @@ TEST(locale_test, wformat) {
auto loc = std::locale(std::locale(), new numpunct<wchar_t>()); auto loc = std::locale(std::locale(), new numpunct<wchar_t>());
EXPECT_EQ(L"1234567", fmt::format(std::locale(), L"{:L}", 1234567)); EXPECT_EQ(L"1234567", fmt::format(std::locale(), L"{:L}", 1234567));
EXPECT_EQ(L"1~234~567", fmt::format(loc, L"{:L}", 1234567)); EXPECT_EQ(L"1~234~567", fmt::format(loc, L"{:L}", 1234567));
fmt::format_arg_store<fmt::wformat_context, int> as{1234567}; using wcontext = fmt::buffer_context<wchar_t>;
EXPECT_EQ(L"1~234~567", fmt::vformat(loc, L"{:L}", fmt::wformat_args(as))); fmt::format_arg_store<wcontext, int> as{1234567};
EXPECT_EQ(L"1~234~567",
fmt::vformat(loc, L"{:L}", fmt::basic_format_args<wcontext>(as)));
EXPECT_EQ(L"1234567", fmt::format(std::locale("C"), L"{:L}", 1234567)); EXPECT_EQ(L"1234567", fmt::format(std::locale("C"), L"{:L}", 1234567));
auto no_grouping_loc = std::locale(std::locale(), new no_grouping<wchar_t>()); auto no_grouping_loc = std::locale(std::locale(), new no_grouping<wchar_t>());

View File

@@ -9,6 +9,18 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
TEST(format_test, vformat_to) {
using wcontext = fmt::wformat_context;
fmt::basic_format_arg<wcontext> warg = fmt::detail::make_arg<wcontext>(42);
auto wargs = fmt::basic_format_args<wcontext>(&warg, 1);
auto w = std::wstring();
fmt::vformat_to(std::back_inserter(w), L"{}", wargs);
EXPECT_EQ(L"42", w);
w.clear();
fmt::vformat_to(std::back_inserter(w), FMT_STRING(L"{}"), wargs);
EXPECT_EQ(L"42", w);
}
#if FMT_USE_USER_DEFINED_LITERALS #if FMT_USE_USER_DEFINED_LITERALS
TEST(format_test, format_udl) { TEST(format_test, format_udl) {
using namespace fmt::literals; using namespace fmt::literals;