[libc++] Adds a make_string test helper function.

These function makes it easier to write generic unit tests for the
format header. It solves the issue where it's not possible to use
  `templated_prefix"foo"`
where `templated_prefix` resolves to: nothing, `L`, `u8`, `u`,
or `U`. The templated_prefix would be more faster during execution.

Reviewed By: ldionne, #libc, curdeius

Differential Revision: https://reviews.llvm.org/D93414

GitOrigin-RevId: e275e629830fb2a776d724aef77e7e9e2e5ae931
diff --git a/test/support/filesystem_test_helper.h b/test/support/filesystem_test_helper.h
index eeee3e9..259d676 100644
--- a/test/support/filesystem_test_helper.h
+++ b/test/support/filesystem_test_helper.h
@@ -19,6 +19,7 @@
 #include <chrono>
 #include <vector>
 
+#include "make_string.h"
 #include "test_macros.h"
 #include "rapid-cxx-test.h"
 #include "format_string.h"
@@ -430,32 +431,6 @@
 
 // Misc test types
 
-#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
-#define CHAR8_ONLY(x) x,
-#else
-#define CHAR8_ONLY(x)
-#endif
-
-#define MKSTR(Str) {Str, TEST_CONCAT(L, Str), CHAR8_ONLY(TEST_CONCAT(u8, Str)) TEST_CONCAT(u, Str), TEST_CONCAT(U, Str)}
-
-struct MultiStringType {
-  const char* s;
-  const wchar_t* w;
-#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
-  const char8_t* u8;
-#endif
-  const char16_t* u16;
-  const char32_t* u32;
-
-  operator const char* () const { return s; }
-  operator const wchar_t* () const { return w; }
-#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
-  operator const char8_t* () const { return u8; }
-#endif
-  operator const char16_t* () const { return u16; }
-  operator const char32_t* () const { return u32; }
-};
-
 const MultiStringType PathList[] = {
         MKSTR(""),
         MKSTR(" "),
diff --git a/test/support/make_string.h b/test/support/make_string.h
new file mode 100644
index 0000000..ede81b0
--- /dev/null
+++ b/test/support/make_string.h
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_TEST_MAKE_STRING_H
+#define SUPPORT_TEST_MAKE_STRING_H
+
+#include "test_macros.h"
+
+#if TEST_STD_VER < 11
+#error This header requires C++11 or greater
+#endif
+
+#include <string>
+
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+#define CHAR8_ONLY(x) x,
+#else
+#define CHAR8_ONLY(x)
+#endif
+
+#define MKSTR(Str)                                                             \
+  {                                                                            \
+    Str, TEST_CONCAT(L, Str),                                                  \
+        CHAR8_ONLY(TEST_CONCAT(u8, Str)) TEST_CONCAT(u, Str),                  \
+        TEST_CONCAT(U, Str)                                                    \
+  }
+
+struct MultiStringType {
+  const char* s;
+  const wchar_t* w;
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+  const char8_t* u8;
+#endif
+  const char16_t* u16;
+  const char32_t* u32;
+
+  operator const char*() const { return s; }
+  operator const wchar_t*() const { return w; }
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+  operator const char8_t*() const { return u8; }
+#endif
+  operator const char16_t*() const { return u16; }
+  operator const char32_t*() const { return u32; }
+};
+
+// Helper to convert a const char* string to a basic_string<CharT>.
+// This helper is used in unit tests to make them generic. The input should be
+// valid ASCII which means the input is also valid UTF-8.
+#define MAKE_STRING(CharT, Str)                                                \
+  std::basic_string<CharT> {                                                   \
+    static_cast<const CharT*>(MultiStringType MKSTR(Str))                      \
+  }
+
+#endif
diff --git a/test/support/test.support/make_string_header.pass.cpp b/test/support/test.support/make_string_header.pass.cpp
new file mode 100644
index 0000000..0d16854
--- /dev/null
+++ b/test/support/test.support/make_string_header.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-has-no-localization
+
+// "support/make_string.h"
+
+#include "make_string.h"
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+  // clang-format off
+  assert(MAKE_STRING(char,
+         " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
+    ==   " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
+
+  assert(MAKE_STRING(wchar_t,
+         " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
+    ==  L" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+  assert(MAKE_STRING(char8_t,
+         " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
+    == u8" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
+#endif
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+  assert(MAKE_STRING(char16_t,
+         " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
+    ==  u" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
+
+  assert(MAKE_STRING(char32_t,
+         " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
+    ==  U" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"
+             "OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
+#endif
+
+  // clang-format on
+  return 0;
+}