brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · 76f756a Raw
151 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME11 12// This version runs the test when the platform has Unicode support.13// UNSUPPORTED: libcpp-has-no-unicode14 15// XFAIL: availability-fp_to_chars-missing16 17// <format>18 19// The paper20//   P2572R1 std::format fill character allowances21// adds support for Unicode Scalar Values as fill character.22 23#include <format>24 25#include "assert_macros.h"26#include "concat_macros.h"27#include "format.functions.common.h"28#include "make_string.h"29#include "string_literal.h"30#include "test_format_string.h"31#include "test_macros.h"32 33#define SV(S) MAKE_STRING_VIEW(CharT, S)34 35auto check = []<class CharT, class... Args>(36                 std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {37  std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);38  TEST_REQUIRE(out == expected,39               TEST_WRITE_CONCATENATED(40                   "\nFormat string   ", fmt.get(), "\nExpected output ", expected, "\nActual output   ", out, '\n'));41};42 43auto check_exception =44    []<class CharT, class... Args>(45        [[maybe_unused]] std::string_view what,46        [[maybe_unused]] std::basic_string_view<CharT> fmt,47        [[maybe_unused]] Args&&... args) {48      TEST_VALIDATE_EXCEPTION(49          std::format_error,50          [&]([[maybe_unused]] const std::format_error& e) {51            TEST_LIBCPP_REQUIRE(52                e.what() == what,53                TEST_WRITE_CONCATENATED(54                    "\nFormat string   ", fmt, "\nExpected exception ", what, "\nActual exception   ", e.what(), '\n'));55          },56          TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<context_t<CharT>>(args...)));57    };58 59template <class CharT>60void test() {61  // 1, 2, 3, 4 code unit UTF-8 transitions62  check(SV("\u000042\u0000"), SV("{:\u0000^4}"), 42);63  check(SV("\u007f42\u007f"), SV("{:\u007f^4}"), 42);64  check(SV("\u008042\u0080"), SV("{:\u0080^4}"), 42);65  check(SV("\u07ff42\u07ff"), SV("{:\u07ff^4}"), 42);66  check(SV("\u080042\u0800"), SV("{:\u0800^4}"), 42);67  check(SV("\uffff42\uffff"), SV("{:\uffff^4}"), 42);68  check(SV("\U0010000042\U00100000"), SV("{:\U00100000^4}"), 42);69  check(SV("\U0010ffff42\U0010ffff"), SV("{:\U0010ffff^4}"), 42);70 71  // Examples of P2572R172  check(SV("🤡🤡x🤡🤡🤡"), SV("{:🤡^6}"), SV("x"));73  check(SV("🤡🤡🤡"), SV("{:*^6}"), SV("🤡🤡🤡"));74  check(SV("12345678"), SV("{:*>6}"), SV("12345678"));75 76  // Invalid Unicode Scalar Values77  if constexpr (std::same_as<CharT, char>) {78    check_exception("The format specifier contains malformed Unicode characters",79                    std::string_view{"{:\xed\xa0\x80^}"},80                    42); // U+D80081    check_exception("The format specifier contains malformed Unicode characters",82                    std::string_view{"{:\xed\xa0\xbf^}"},83                    42); // U+DBFF84    check_exception("The format specifier contains malformed Unicode characters",85                    std::string_view{"{:\xed\xbf\x80^}"},86                    42); // U+DC0087    check_exception("The format specifier contains malformed Unicode characters",88                    std::string_view{"{:\xed\xbf\xbf^}"},89                    42); // U+DFFF90 91    check_exception("The format specifier contains malformed Unicode characters",92                    std::string_view{"{:\xf4\x90\x80\x80^}"},93                    42); // U+11000094    check_exception("The format specifier contains malformed Unicode characters",95                    std::string_view{"{:\xf4\x90\xbf\xbf^}"},96                    42); // U+11FFFF97 98    check_exception("The format specifier contains malformed Unicode characters",99                    std::string_view{"{:\x80^}"},100                    42); // Trailing code unit with no leading one.101    check_exception("The format specifier contains malformed Unicode characters",102                    std::string_view{"{:\xc0^}"},103                    42); // Missing trailing code unit.104    check_exception("The format specifier contains malformed Unicode characters",105                    std::string_view{"{:\xe0\x80^}"},106                    42); // Missing trailing code unit.107    check_exception("The format specifier contains malformed Unicode characters",108                    std::string_view{"{:\xf0\x80^}"},109                    42); // Missing two trailing code units.110    check_exception("The format specifier contains malformed Unicode characters",111                    std::string_view{"{:\xf0\x80\x80^}"},112                    42); // Missing trailing code unit.113 114#ifndef TEST_HAS_NO_WIDE_CHARACTERS115  } else {116#  ifdef TEST_SHORT_WCHAR117    check_exception("The format specifier contains malformed Unicode characters", std::wstring_view{L"{:\xd800^}"}, 42);118    check_exception("The format specifier contains malformed Unicode characters", std::wstring_view{L"{:\xdbff^}"}, 42);119    check_exception("The format specifier contains malformed Unicode characters", std::wstring_view{L"{:\xdc00^}"}, 42);120    check_exception("The format specifier contains malformed Unicode characters", std::wstring_view{L"{:\xddff^}"}, 42);121 122    check_exception("The format specifier contains malformed Unicode characters",123                    std::wstring_view{L"{:\xdc00\xd800^}"},124                    42); // Reverted surrogates.125 126#  else  // TEST_SHORT_WCHAR127    check_exception("The fill option contains an invalid value", std::wstring_view{L"{:\xd800^}"}, 42);128    check_exception("The fill option contains an invalid value", std::wstring_view{L"{:\xdbff^}"}, 42);129    check_exception("The fill option contains an invalid value", std::wstring_view{L"{:\xdc00^}"}, 42);130    check_exception("The fill option contains an invalid value", std::wstring_view{L"{:\xddff^}"}, 42);131 132    check_exception(133        "The format specifier should consume the input or end with a '}'", std::wstring_view{L"{:\xdc00\xd800^}"}, 42);134 135    check_exception("The fill option contains an invalid value", std::wstring_view{L"{:\x00110000^}"}, 42);136    check_exception("The fill option contains an invalid value", std::wstring_view{L"{:\x0011ffff^}"}, 42);137#  endif // TEST_SHORT_WCHAR138#endif   // TEST_HAS_NO_WIDE_CHARACTERS139  }140}141 142int main(int, char**) {143  test<char>();144 145#ifndef TEST_HAS_NO_WIDE_CHARACTERS146  test<wchar_t>();147#endif148 149  return 0;150}151