blob: 51c0826328d21c1bd70d1d91192b35745364fa4e [file] [log] [blame]
//===----------------------------------------------------------------------===//
// 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, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: libcpp-has-no-incomplete-format
// UTF-32 doesn't work properly
// XFAIL: windows
// <format>
// Tests the Unicode width support of the standard format specifiers.
// It tests [format.string.std]/8 - 11:
// - Properly determining the estimated with of a unicode string.
// - Properly truncating to the wanted maximum width.
// This version runs the test when the platform doesn't have Unicode support.
// REQUIRES: libcpp-has-no-unicode
#include <format>
#include <cassert>
#include "test_macros.h"
#include "make_string.h"
#define CSTR(S) MAKE_CSTRING(CharT, S)
using namespace std::__format_spec;
template <class CharT>
constexpr bool operator==(const __string_alignment<CharT>& lhs,
const __string_alignment<CharT>& rhs) noexcept {
return lhs.__last == rhs.__last && lhs.__size == rhs.__size &&
lhs.__align == rhs.__align;
}
template <class CharT>
constexpr void get_string_alignment(size_t offset, ptrdiff_t size, bool align,
const CharT* str, size_t width,
size_t precision) {
std::basic_string_view<CharT> sv{str};
__string_alignment<CharT> expected{sv.begin() + offset, size, align};
__string_alignment<CharT> traits =
__get_string_alignment(sv.begin(), sv.end(), width, precision);
assert(traits == expected);
}
template <class CharT>
constexpr void get_string_alignment() {
// Truncate the input.
get_string_alignment(2, 2, false, CSTR("abc"), 0, 2);
// The 2-column character gets half accepted.
get_string_alignment(2, 2, false, CSTR("a\u115f"), 0, 2);
// No alignment since the number of characters fits.
get_string_alignment(2, 2, false, CSTR("a\u115f"), 2, 2);
// Same but for a 2-column 4-byte UTF-8 sequence
get_string_alignment(2, 2, false, CSTR("a\U0001f300"), 0, 2);
get_string_alignment(2, 2, false, CSTR("a\U0001f300"), 2, 2);
// No alignment required.
get_string_alignment(3, 3, false, CSTR("abc"), 2, -1);
get_string_alignment(3, 3, false, CSTR("abc"), 3, -1);
get_string_alignment(3 + 2 * (sizeof(CharT) == 1),
3 + 2 * (sizeof(CharT) == 1), false, CSTR("ab\u1111"), 2,
-1);
// Doesn't evaluate 'c' so size -> 0
get_string_alignment(3 + 2 * (sizeof(CharT) == 1),
3 + 2 * (sizeof(CharT) == 1), false,
CSTR("a\u115fc") /* 2-column character */, 3, -1);
// Extend width
get_string_alignment(3, 3, true, CSTR("abc"), 4, -1);
get_string_alignment(3 + 2 * (sizeof(CharT) == 1),
3 + 2 * (sizeof(CharT) == 1), true,
CSTR("a\u1160c") /* 1-column character */, 6, -1);
}
template <class CharT>
constexpr void test() {
get_string_alignment<CharT>();
}
constexpr bool test() {
test<char>();
test<wchar_t>();
#ifndef _LIBCPP_HAS_NO_CHAR8_T
test<char8_t>();
#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<char16_t>();
test<char32_t>();
#endif
return true;
}
int main(int, char**) {
test();
static_assert(test());
return 0;
}