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