Improve xchar support for std::bitset formatter and fix ``fill`` copying bug
Fixes #4285

Improve ``xchar`` support for ``std::bitset`` formatter and fix a bug when copying the ``fill`` from ``basic_specs``.

{"label": "fmtlib:master", "ref": "master", "sha": "e3ddede6c4ee818825c4e5a6dfa1d384860c27d9"}
I tried to test the formatting of `std::bitset` using `fmt/std.h`, but with `wchar_t` (and `char16_t`) instead of `char`, using this test:

```c++
TEST(std_test, format_bitset_Wide) {
  auto bs = std::bitset<6>(42);
  EXPECT_EQ(fmt::format(L"{}", bs), L"101010");
  EXPECT_EQ(fmt::format(L"{:0>8}", bs), L"00101010");
  EXPECT_EQ(fmt::format(L"{:-^12}", bs), L"---101010---");
}
```

It didn't compile until I applied the following changes to `std.h`:

```diff
--- a/include/fmt/std.h
+++ b/include/fmt/std.h
@@ -184,7 +184,7 @@ FMT_END_NAMESPACE
 FMT_BEGIN_NAMESPACE
 FMT_EXPORT
 template <std::size_t N, typename Char>
-struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
+struct formatter<std::bitset<N>, Char> : nested_formatter<basic_string_view<Char>, Char> {
  private:
   // Functor because C++11 doesn't support generic lambdas.
   struct writer {
@@ -204,7 +204,7 @@ struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
   template <typename FormatContext>
   auto format(const std::bitset<N>& bs, FormatContext& ctx) const
       -> decltype(ctx.out()) {
-    return write_padded(ctx, writer{bs});
+    return this->write_padded(ctx, writer{bs});
   }
 };
```

Now it runs into a segfault, which appears to be caused by the `set_fill` call in `nested_formatter::write_padded`:
```c++
    specs.set_fill(
        basic_string_view<Char>(specs_.fill<Char>(), specs_.fill_size()));
```
in combination with the implementation of `fill()` for non-`char` types returning a nullpointer:
```c++
  template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
  constexpr auto fill() const -> const Char* {
    return nullptr;
  }
```

How is this supposed to work (or rather, can it be made to work)?
std::bitset formatting (nested_formatter) does not work with wchar_t
diff --git a/include/fmt/format.h b/include/fmt/format.h
index d1b83d18673e..2fb85fef0350 100644
--- a/include/fmt/format.h
+++ b/include/fmt/format.h
@@ -3654,6 +3654,17 @@ void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
   parse_format_string(
       fmt, format_handler<Char>{parse_context<Char>(fmt), {out, args, loc}});
 }
+
+template <typename Char>
+void basic_specs_copy_fill(basic_specs& dst, const basic_specs& src) {
+  if (src.fill_size() == 1 && const_check(!std::is_same<Char, char>::value)) {
+    Char fill = src.fill_unit<Char>();
+    dst.set_fill(basic_string_view<Char>(&fill, 1));
+    return;
+  }
+  dst.set_fill(basic_string_view<char>(src.fill<char>(), src.fill_size()));
+}
+
 }  // namespace detail
 
 FMT_BEGIN_EXPORT
@@ -3960,8 +3971,7 @@ template <typename T, typename Char = char> struct nested_formatter {
     write(basic_appender<Char>(buf));
     auto specs = format_specs();
     specs.width = width_;
-    specs.set_fill(
-        basic_string_view<Char>(specs_.fill<Char>(), specs_.fill_size()));
+    detail::basic_specs_copy_fill<Char>(specs, specs_);
     specs.set_align(specs_.align());
     return detail::write<Char>(
         ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
diff --git a/include/fmt/std.h b/include/fmt/std.h
index b00e402255f5..bc277d646267 100644
--- a/include/fmt/std.h
+++ b/include/fmt/std.h
@@ -184,7 +184,8 @@ FMT_END_NAMESPACE
 FMT_BEGIN_NAMESPACE
 FMT_EXPORT
 template <std::size_t N, typename Char>
-struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
+struct formatter<std::bitset<N>, Char>
+    : nested_formatter<basic_string_view<Char>, Char> {
  private:
   // Functor because C++11 doesn't support generic lambdas.
   struct writer {
@@ -204,7 +205,7 @@ struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> {
   template <typename FormatContext>
   auto format(const std::bitset<N>& bs, FormatContext& ctx) const
       -> decltype(ctx.out()) {
-    return write_padded(ctx, writer{bs});
+    return this->write_padded(ctx, writer{bs});
   }
 };
 
@@ -695,9 +696,7 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
 
     auto outer_specs = format_specs();
     outer_specs.width = specs.width;
-    auto fill = specs.template fill<Char>();
-    if (fill)
-      outer_specs.set_fill(basic_string_view<Char>(fill, specs.fill_size()));
+    detail::basic_specs_copy_fill<Char>(outer_specs, specs);
     outer_specs.set_align(specs.align());
 
     specs.width = 0;

diff --git a/test/std-test.cc b/test/std-test.cc
index ab458ae885db..2c57b3f6e394 100644
--- a/test/std-test.cc
+++ b/test/std-test.cc
@@ -91,6 +91,9 @@ TEST(std_test, complex) {
   EXPECT_EQ(fmt::format("{: }", std::complex<double>(1, 2.2)), "( 1+2.2i)");
   EXPECT_EQ(fmt::format("{: }", std::complex<double>(1, -2.2)), "( 1-2.2i)");
 
+  EXPECT_EQ(fmt::format("{:8}", std::complex<double>(1, 2)), "(1+2i)  ");
+  EXPECT_EQ(fmt::format("{:-<8}", std::complex<double>(1, 2)), "(1+2i)--");
+
   EXPECT_EQ(fmt::format("{:>20.2f}", std::complex<double>(1, 2.2)),
             "        (1.00+2.20i)");
   EXPECT_EQ(fmt::format("{:<20.2f}", std::complex<double>(1, 2.2)),
diff --git a/test/xchar-test.cc b/test/xchar-test.cc
index 0f91aa319e84..fd613e820ad8 100644
--- a/test/xchar-test.cc
+++ b/test/xchar-test.cc
@@ -79,7 +79,7 @@ TEST(xchar_test, format) {
   EXPECT_THROW(fmt::format(fmt::runtime(L"{:*\x343E}"), 42), fmt::format_error);
   EXPECT_EQ(fmt::format(L"{}", true), L"true");
   EXPECT_EQ(fmt::format(L"{0}", L'a'), L"a");
-  EXPECT_EQ(fmt::format(L"Letter {}", L'\x40e'), L"Letter \x40e"); // Ў
+  EXPECT_EQ(fmt::format(L"Letter {}", L'\x40e'), L"Letter \x40e");  // Ў
   if (sizeof(wchar_t) == 4)
     EXPECT_EQ(fmt::format(fmt::runtime(L"{:𓀨>3}"), 42), L"𓀨42");
   EXPECT_EQ(fmt::format(L"{}c{}", L"ab", 1), L"abc1");
@@ -491,12 +491,20 @@ TEST(locale_test, sign) {
   EXPECT_EQ(fmt::format(std::locale(), L"{:L}", -50), L"-50");
 }
 
+TEST(std_test_xchar, format_bitset) {
+  auto bs = std::bitset<6>(42);
+  EXPECT_EQ(fmt::format(L"{}", bs), L"101010");
+  EXPECT_EQ(fmt::format(L"{:0>8}", bs), L"00101010");
+  EXPECT_EQ(fmt::format(L"{:-^12}", bs), L"---101010---");
+}
+
 TEST(std_test_xchar, complex) {
   auto s = fmt::format(L"{}", std::complex<double>(1, 2));
   EXPECT_EQ(s, L"(1+2i)");
   EXPECT_EQ(fmt::format(L"{:.2f}", std::complex<double>(1, 2)),
             L"(1.00+2.00i)");
   EXPECT_EQ(fmt::format(L"{:8}", std::complex<double>(1, 2)), L"(1+2i)  ");
+  EXPECT_EQ(fmt::format(L"{:-<8}", std::complex<double>(1, 2)), L"(1+2i)--");
 }
 
 TEST(std_test_xchar, optional) {

{"compile-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "ostream-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "ranges-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "std-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "scan-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "no-builtin-types-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "color-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "chrono-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "format-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "gtest-extra-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "args-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "compile-fp-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "unicode-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "assert-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "posix-mock-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "base-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "printf-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "enforce-checks-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "format-impl-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "os-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "xchar-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"compile-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "ostream-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "ranges-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "std-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "scan-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "no-builtin-types-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "color-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "chrono-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "format-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "gtest-extra-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "args-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "compile-fp-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "unicode-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "assert-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "posix-mock-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "base-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "printf-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "enforce-checks-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "format-impl-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "os-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "xchar-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"passed_count": 21, "failed_count": 0, "skipped_count": 0, "passed_tests": ["compile-test", "no-builtin-types-test", "chrono-test", "gtest-extra-test", "compile-fp-test", "unicode-test", "assert-test", "base-test", "enforce-checks-test", "format-impl-test", "os-test", "xchar-test", "ostream-test", "ranges-test", "std-test", "scan-test", "color-test", "format-test", "args-test", "posix-mock-test", "printf-test"], "failed_tests": [], "skipped_tests": []}
{"passed_count": 0, "failed_count": 0, "skipped_count": 0, "passed_tests": [], "failed_tests": [], "skipped_tests": []}
{"passed_count": 21, "failed_count": 0, "skipped_count": 0, "passed_tests": ["compile-test", "no-builtin-types-test", "chrono-test", "gtest-extra-test", "compile-fp-test", "unicode-test", "assert-test", "base-test", "enforce-checks-test", "format-impl-test", "os-test", "xchar-test", "ostream-test", "ranges-test", "std-test", "scan-test", "color-test", "format-test", "args-test", "posix-mock-test", "printf-test"], "failed_tests": [], "skipped_tests": []}