1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef SUPPORT_TEST_MAKE_STRING_H |
10 | #define SUPPORT_TEST_MAKE_STRING_H |
11 | |
12 | #include "test_macros.h" |
13 | |
14 | #include <string> |
15 | #include <string_view> |
16 | |
17 | #ifndef TEST_HAS_NO_WIDE_CHARACTERS |
18 | # define MKSTR_WCHAR_ONLY(...) __VA_ARGS__ |
19 | # define MKSTR_AS_WCHAR_LITERAL(x) TEST_CONCAT(L, x), sizeof(TEST_CONCAT(L, x)) / sizeof(wchar_t) - 1 |
20 | #else |
21 | # define MKSTR_WCHAR_ONLY(...) |
22 | #endif |
23 | |
24 | #if TEST_STD_VER > 17 && defined(__cpp_char8_t) |
25 | #define MKSTR_CHAR8_ONLY(...) __VA_ARGS__ |
26 | #define MKSTR_AS_U8_LITERAL(x) TEST_CONCAT(u8, x), sizeof(TEST_CONCAT(u8, x)) / sizeof(char8_t) - 1 |
27 | #else |
28 | #define MKSTR_CHAR8_ONLY(...) |
29 | #endif |
30 | |
31 | #if TEST_STD_VER >= 11 |
32 | #define MKSTR_CXX11_ONLY(...) __VA_ARGS__ |
33 | #define MKSTR_AS_U16_LITERAL(x) TEST_CONCAT(u, x), sizeof(TEST_CONCAT(u, x)) / sizeof(char16_t) - 1 |
34 | #define MKSTR_AS_U32_LITERAL(x) TEST_CONCAT(U, x), sizeof(TEST_CONCAT(U, x)) / sizeof(char32_t) - 1 |
35 | #else |
36 | #define MKSTR_CXX11_ONLY(...) |
37 | #endif |
38 | |
39 | #define MKSTR(Str) MultiStringType( \ |
40 | MKSTR_WCHAR_ONLY(MKSTR_AS_WCHAR_LITERAL(Str),) \ |
41 | MKSTR_CHAR8_ONLY(MKSTR_AS_U8_LITERAL(Str),) \ |
42 | MKSTR_CXX11_ONLY(MKSTR_AS_U16_LITERAL(Str), \ |
43 | MKSTR_AS_U32_LITERAL(Str),) \ |
44 | Str, sizeof(Str) - 1 \ |
45 | ) |
46 | |
47 | #define MKSTR_LEN(CharT, Str) MKSTR(Str).length((const CharT*)0) |
48 | |
49 | struct MultiStringType { |
50 | MKSTR_WCHAR_ONLY(const wchar_t* w_; std::size_t wn_; ) |
51 | MKSTR_CHAR8_ONLY(const char8_t* u8_; std::size_t u8n_; ) |
52 | MKSTR_CXX11_ONLY(const char16_t* u16_; std::size_t u16n_; ) |
53 | MKSTR_CXX11_ONLY(const char32_t* u32_; std::size_t u32n_; ) |
54 | const char* s_; std::size_t sn_; |
55 | |
56 | TEST_CONSTEXPR MultiStringType( |
57 | MKSTR_WCHAR_ONLY(const wchar_t *w, std::size_t wn,) |
58 | MKSTR_CHAR8_ONLY(const char8_t *u8, std::size_t u8n,) |
59 | MKSTR_CXX11_ONLY(const char16_t *u16, std::size_t u16n,) |
60 | MKSTR_CXX11_ONLY(const char32_t *u32, std::size_t u32n,) |
61 | const char *s, std::size_t sn) |
62 | : MKSTR_WCHAR_ONLY(w_(w), wn_(wn),) |
63 | MKSTR_CHAR8_ONLY(u8_(u8), u8n_(u8n),) |
64 | MKSTR_CXX11_ONLY(u16_(u16), u16n_(u16n),) |
65 | MKSTR_CXX11_ONLY(u32_(u32), u32n_(u32n),) |
66 | s_(s), sn_(sn) {} |
67 | |
68 | TEST_CONSTEXPR const char *as_ptr(const char*) const { return s_; } |
69 | MKSTR_WCHAR_ONLY(TEST_CONSTEXPR const wchar_t *as_ptr(const wchar_t*) const { return w_; }) |
70 | MKSTR_CHAR8_ONLY(constexpr const char8_t *as_ptr(const char8_t*) const { return u8_; }) |
71 | MKSTR_CXX11_ONLY(constexpr const char16_t *as_ptr(const char16_t*) const { return u16_; }) |
72 | MKSTR_CXX11_ONLY(constexpr const char32_t *as_ptr(const char32_t*) const { return u32_; }) |
73 | |
74 | TEST_CONSTEXPR std::size_t length(const char*) const { return sn_; } |
75 | MKSTR_WCHAR_ONLY(TEST_CONSTEXPR std::size_t length(const wchar_t*) const { return wn_; }) |
76 | MKSTR_CHAR8_ONLY(constexpr std::size_t length(const char8_t*) const { return u8n_; }) |
77 | MKSTR_CXX11_ONLY(constexpr std::size_t length(const char16_t*) const { return u16n_; }) |
78 | MKSTR_CXX11_ONLY(constexpr std::size_t length(const char32_t*) const { return u32n_; }) |
79 | |
80 | // These implicit conversions are used by some tests. TODO: maybe eliminate them? |
81 | TEST_CONSTEXPR operator const char*() const { return s_; } |
82 | MKSTR_WCHAR_ONLY(TEST_CONSTEXPR operator const wchar_t*() const { return w_; }) |
83 | MKSTR_CHAR8_ONLY(constexpr operator const char8_t*() const { return u8_; }) |
84 | MKSTR_CXX11_ONLY(constexpr operator const char16_t*() const { return u16_; }) |
85 | MKSTR_CXX11_ONLY(constexpr operator const char32_t*() const { return u32_; }) |
86 | }; |
87 | |
88 | // Helper to convert a const char* string to a const CharT*. |
89 | // This helper is used in unit tests to make them generic. The input should be |
90 | // valid ASCII which means the input is also valid UTF-8. |
91 | #define MAKE_CSTRING(CharT, Str) \ |
92 | MKSTR(Str).as_ptr(static_cast<const CharT*>(nullptr)) |
93 | |
94 | // Like MAKE_CSTRING but makes a basic_string<CharT>. Embedded nulls are OK. |
95 | #define MAKE_STRING(CharT, Str) \ |
96 | std::basic_string<CharT>(MAKE_CSTRING(CharT, Str), MKSTR_LEN(CharT, Str)) |
97 | |
98 | // Like MAKE_CSTRING but makes a basic_string_view<CharT>. Embedded nulls are OK. |
99 | #define MAKE_STRING_VIEW(CharT, Str) \ |
100 | std::basic_string_view<CharT>(MAKE_CSTRING(CharT, Str), MKSTR_LEN(CharT, Str)) |
101 | |
102 | #endif |
103 | |