[libcxx-commits] [libcxx] a0b50c5 - [libc++] [test] C++03-friendly MAKE_STRING macro.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Wed Dec 1 12:05:23 PST 2021


Author: Arthur O'Dwyer
Date: 2021-12-01T15:02:53-05:00
New Revision: a0b50c56d15273dc8e6475e826cac7f03c39d51f

URL: https://github.com/llvm/llvm-project/commit/a0b50c56d15273dc8e6475e826cac7f03c39d51f
DIFF: https://github.com/llvm/llvm-project/commit/a0b50c56d15273dc8e6475e826cac7f03c39d51f.diff

LOG: [libc++] [test] C++03-friendly MAKE_STRING macro.

Reviewed as part of D114658.

Added: 
    

Modified: 
    libcxx/test/support/make_string.h

Removed: 
    


################################################################################
diff  --git a/libcxx/test/support/make_string.h b/libcxx/test/support/make_string.h
index d417d7e1b4df9..00c2a48e3d004 100644
--- a/libcxx/test/support/make_string.h
+++ b/libcxx/test/support/make_string.h
@@ -11,69 +11,92 @@
 
 #include "test_macros.h"
 
-#if TEST_STD_VER < 11
-#error This header requires C++11 or greater
-#endif
-
 #include <string>
 #include <string_view>
 
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+# define MKSTR_WCHAR_ONLY(...) __VA_ARGS__
+# define MKSTR_AS_WCHAR_LITERAL(x) TEST_CONCAT(L, x), sizeof(TEST_CONCAT(L, x)) / sizeof(wchar_t) - 1
+#else
+# define MKSTR_WCHAR_ONLY(...)
+#endif
+
 #if TEST_STD_VER > 17 && defined(__cpp_char8_t)
-#define CHAR8_ONLY(x) x,
+#define MKSTR_CHAR8_ONLY(...) __VA_ARGS__
+#define MKSTR_AS_U8_LITERAL(x) TEST_CONCAT(u8, x), sizeof(TEST_CONCAT(u8, x)) / sizeof(char8_t) - 1
 #else
-#define CHAR8_ONLY(x)
+#define MKSTR_CHAR8_ONLY(...)
 #endif
 
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-# define IF_WIDE_CHARACTERS(...) __VA_ARGS__
+#if TEST_STD_VER >= 11
+#define MKSTR_CXX11_ONLY(...) __VA_ARGS__
+#define MKSTR_AS_U16_LITERAL(x) TEST_CONCAT(u, x), sizeof(TEST_CONCAT(u, x)) / sizeof(char16_t) - 1
+#define MKSTR_AS_U32_LITERAL(x) TEST_CONCAT(U, x), sizeof(TEST_CONCAT(U, x)) / sizeof(char32_t) - 1
 #else
-# define IF_WIDE_CHARACTERS(...) /* nothing */
+#define MKSTR_CXX11_ONLY(...)
 #endif
 
-#define MKSTR(Str)                                                             \
-  {                                                                            \
-    Str, IF_WIDE_CHARACTERS(TEST_CONCAT(L, Str),)                              \
-        CHAR8_ONLY(TEST_CONCAT(u8, Str)) TEST_CONCAT(u, Str),                  \
-        TEST_CONCAT(U, Str)                                                    \
-  }
+#define MKSTR(Str) MultiStringType(                \
+    MKSTR_WCHAR_ONLY(MKSTR_AS_WCHAR_LITERAL(Str),) \
+    MKSTR_CHAR8_ONLY(MKSTR_AS_U8_LITERAL(Str),)    \
+    MKSTR_CXX11_ONLY(MKSTR_AS_U16_LITERAL(Str),    \
+                     MKSTR_AS_U32_LITERAL(Str),)   \
+    Str, sizeof(Str) - 1                           \
+  )
+
+#define MKSTR_LEN(CharT, Str) MKSTR(Str).length((const CharT*)0)
 
 struct MultiStringType {
-  const char* s;
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-  const wchar_t* w;
-#endif
-#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
-  const char8_t* u8;
-#endif
-  const char16_t* u16;
-  const char32_t* u32;
+  MKSTR_WCHAR_ONLY(const wchar_t* w_; size_t wn_; )
+  MKSTR_CHAR8_ONLY(const char8_t* u8_; size_t u8n_; )
+  MKSTR_CXX11_ONLY(const char16_t* u16_; size_t u16n_; )
+  MKSTR_CXX11_ONLY(const char32_t* u32_; size_t u32n_; )
+  const char* s_; size_t sn_;
 
-  constexpr operator const char*() const { return s; }
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-  constexpr operator const wchar_t*() const { return w; }
-#endif
-#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
-  constexpr operator const char8_t*() const { return u8; }
-#endif
-  constexpr operator const char16_t*() const { return u16; }
-  constexpr operator const char32_t*() const { return u32; }
+  TEST_CONSTEXPR MultiStringType(
+      MKSTR_WCHAR_ONLY(const wchar_t *w, size_t wn,)
+      MKSTR_CHAR8_ONLY(const char8_t *u8, size_t u8n,)
+      MKSTR_CXX11_ONLY(const char16_t *u16, size_t u16n,)
+      MKSTR_CXX11_ONLY(const char32_t *u32, size_t u32n,)
+      const char *s, size_t sn)
+    : MKSTR_WCHAR_ONLY(w_(w), wn_(wn),)
+      MKSTR_CHAR8_ONLY(u8_(u8), u8n_(u8n),)
+      MKSTR_CXX11_ONLY(u16_(u16), u16n_(u16n),)
+      MKSTR_CXX11_ONLY(u32_(u32), u32n_(u32n),)
+      s_(s), sn_(sn) {}
+
+  TEST_CONSTEXPR const char *as_ptr(const char*) const { return s_; }
+  MKSTR_WCHAR_ONLY(TEST_CONSTEXPR const wchar_t *as_ptr(const wchar_t*) const { return w_; })
+  MKSTR_CHAR8_ONLY(constexpr const char8_t *as_ptr(const char8_t*) const { return u8_; })
+  MKSTR_CXX11_ONLY(constexpr const char16_t *as_ptr(const char16_t*) const { return u16_; })
+  MKSTR_CXX11_ONLY(constexpr const char32_t *as_ptr(const char32_t*) const { return u32_; })
+
+  TEST_CONSTEXPR size_t length(const char*) const { return sn_; }
+  MKSTR_WCHAR_ONLY(TEST_CONSTEXPR size_t length(const wchar_t*) const { return wn_; })
+  MKSTR_CHAR8_ONLY(constexpr size_t length(const char8_t*) const { return u8n_; })
+  MKSTR_CXX11_ONLY(constexpr size_t length(const char16_t*) const { return u16n_; })
+  MKSTR_CXX11_ONLY(constexpr size_t length(const char32_t*) const { return u32n_; })
+
+  // These implicit conversions are used by some tests. TODO: maybe eliminate them?
+  TEST_CONSTEXPR operator const char*() const { return s_; }
+  MKSTR_WCHAR_ONLY(TEST_CONSTEXPR operator const wchar_t*() const { return w_; })
+  MKSTR_CHAR8_ONLY(constexpr operator const char8_t*() const { return u8_; })
+  MKSTR_CXX11_ONLY(constexpr operator const char16_t*() const { return u16_; })
+  MKSTR_CXX11_ONLY(constexpr operator const char32_t*() const { return u32_; })
 };
 
-// Helper to convert a const char* string to a basic_string<CharT>.
+// Helper to convert a const char* string to a const 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_CSTRING(CharT, Str)                                               \
+  MKSTR(Str).as_ptr((const CharT*)0)
+
+// Like MAKE_CSTRING but makes a basic_string<CharT>. Embedded nulls are OK.
 #define MAKE_STRING(CharT, Str)                                                \
-  std::basic_string<CharT> {                                                   \
-    static_cast<const CharT*>(MultiStringType MKSTR(Str))                      \
-  }
+  std::basic_string<CharT>(MAKE_CSTRING(CharT, Str), MKSTR_LEN(CharT, Str))
 
+// Like MAKE_CSTRING but makes a basic_string_view<CharT>. Embedded nulls are OK.
 #define MAKE_STRING_VIEW(CharT, Str)                                           \
-  std::basic_string_view<CharT> {                                              \
-    static_cast<const CharT*>(MultiStringType MKSTR(Str))                      \
-  }
-
-// Like MAKE_STRING but converts to a const CharT*.
-#define MAKE_CSTRING(CharT, Str)                                               \
-  static_cast<const CharT*>(MultiStringType MKSTR(Str))
+  std::basic_string_view<CharT>(MAKE_CSTRING(CharT, Str), MKSTR_LEN(CharT, Str))
 
 #endif


        


More information about the libcxx-commits mailing list