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