mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 02:36:07 +00:00

Also standardize the license comment in several files where it was different from what we normally do.
290 lines
8.8 KiB
C++
290 lines
8.8 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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: no-localization
|
|
// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
|
|
|
|
// TODO FMT This test should not require std::to_chars(floating-point)
|
|
// XFAIL: availability-fp_to_chars-missing
|
|
|
|
// REQUIRES: locale.fr_FR.UTF-8
|
|
// REQUIRES: locale.ja_JP.UTF-8
|
|
|
|
// <chrono>
|
|
|
|
// template<class charT> struct formatter<chrono::year_month, charT>;
|
|
|
|
#include <chrono>
|
|
#include <format>
|
|
|
|
#include <cassert>
|
|
#include <concepts>
|
|
#include <locale>
|
|
#include <iostream>
|
|
#include <type_traits>
|
|
|
|
#include "formatter_tests.h"
|
|
#include "make_string.h"
|
|
#include "platform_support.h" // locale name macros
|
|
#include "string_literal.h"
|
|
#include "test_macros.h"
|
|
|
|
template <class CharT>
|
|
static void test_no_chrono_specs() {
|
|
// Valid month
|
|
check(SV("1970/Jan"), SV("{}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
|
|
check(SV("*1970/Jan*"), SV("{:*^10}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
|
|
check(SV("*1970/Jan"), SV("{:*>9}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
|
|
|
|
// Invalid month_day
|
|
check(SV("1970/0 is not a valid month"),
|
|
SV("{}"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
|
|
check(SV("*1970/0 is not a valid month*"),
|
|
SV("{:*^29}"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
|
|
}
|
|
|
|
template <class CharT>
|
|
static void test_invalid_values() {
|
|
// Test that %b and %B throw an exception.
|
|
check_exception("Formatting a month name from an invalid month number",
|
|
SV("{:%b}"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
|
|
|
|
check_exception("Formatting a month name from an invalid month number",
|
|
SV("{:%B}"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
|
|
}
|
|
|
|
template <class CharT>
|
|
static void test_valid_values() {
|
|
constexpr std::basic_string_view<CharT> fmt = SV(
|
|
"{:"
|
|
"%%b='%b'%t"
|
|
"%%B='%B'%t"
|
|
"%%C='%C'%t"
|
|
"%%h='%h'%t"
|
|
"%%y='%y'%t"
|
|
"%%Y='%Y'%t"
|
|
"%%EC='%EC'%t"
|
|
"%%Ey='%Ey'%t"
|
|
"%%EY='%EY'%t"
|
|
"%%Oy='%Oy'%t"
|
|
"%n}");
|
|
|
|
constexpr std::basic_string_view<CharT> lfmt = SV(
|
|
"{:L"
|
|
"%%b='%b'%t"
|
|
"%%B='%B'%t"
|
|
"%%C='%C'%t"
|
|
"%%h='%h'%t"
|
|
"%%y='%y'%t"
|
|
"%%Y='%Y'%t"
|
|
"%%EC='%EC'%t"
|
|
"%%Ey='%Ey'%t"
|
|
"%%EY='%EY'%t"
|
|
"%%Oy='%Oy'%t"
|
|
"%n}");
|
|
|
|
const std::locale loc(LOCALE_ja_JP_UTF_8);
|
|
std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
|
|
|
|
// Non localized output using C-locale
|
|
check(SV("%b='Jan'\t"
|
|
"%B='January'\t"
|
|
"%C='19'\t"
|
|
"%h='Jan'\t"
|
|
"%y='70'\t"
|
|
"%Y='1970'\t"
|
|
"%EC='19'\t"
|
|
"%Ey='70'\t"
|
|
"%EY='1970'\t"
|
|
"%Oy='70'\t"
|
|
"\n"),
|
|
fmt,
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
|
|
check(SV("%b='May'\t"
|
|
"%B='May'\t"
|
|
"%C='20'\t"
|
|
"%h='May'\t"
|
|
"%y='04'\t"
|
|
"%Y='2004'\t"
|
|
"%EC='20'\t"
|
|
"%Ey='04'\t"
|
|
"%EY='2004'\t"
|
|
"%Oy='04'\t"
|
|
"\n"),
|
|
fmt,
|
|
std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
|
|
|
|
// Use the global locale (fr_FR)
|
|
check(SV(
|
|
#if defined(__APPLE__)
|
|
"%b='jan'\t"
|
|
#else
|
|
"%b='janv.'\t"
|
|
#endif
|
|
"%B='janvier'\t"
|
|
"%C='19'\t"
|
|
#if defined(__APPLE__)
|
|
"%h='jan'\t"
|
|
#else
|
|
"%h='janv.'\t"
|
|
#endif
|
|
"%y='70'\t"
|
|
"%Y='1970'\t"
|
|
"%EC='19'\t"
|
|
"%Ey='70'\t"
|
|
"%EY='1970'\t"
|
|
"%Oy='70'\t"
|
|
"\n"),
|
|
lfmt,
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
|
|
check(SV("%b='mai'\t"
|
|
"%B='mai'\t"
|
|
"%C='20'\t"
|
|
"%h='mai'\t"
|
|
"%y='04'\t"
|
|
"%Y='2004'\t"
|
|
"%EC='20'\t"
|
|
"%Ey='04'\t"
|
|
"%EY='2004'\t"
|
|
"%Oy='04'\t"
|
|
"\n"),
|
|
lfmt,
|
|
std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
|
|
|
|
// Use supplied locale (ja_JP)
|
|
check(loc,
|
|
SV(
|
|
#if defined(_WIN32)
|
|
"%b='1'\t"
|
|
#elif defined(_AIX) // defined(_WIN32)
|
|
"%b='1月'\t"
|
|
#elif defined(__APPLE__) // defined(_WIN32)
|
|
"%b=' 1'\t"
|
|
#else // defined(_WIN32)
|
|
"%b=' 1月'\t"
|
|
#endif // defined(_WIN32)
|
|
"%B='1月'\t"
|
|
"%C='19'\t"
|
|
#if defined(_WIN32)
|
|
"%h='1'\t"
|
|
#elif defined(_AIX) // defined(_WIN32)
|
|
"%h='1月'\t"
|
|
#elif defined(__APPLE__) // defined(_WIN32)
|
|
"%h=' 1'\t"
|
|
#else // defined(_WIN32)
|
|
"%h=' 1月'\t"
|
|
#endif // defined(_WIN32)
|
|
"%y='70'\t"
|
|
"%Y='1970'\t"
|
|
#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
|
|
"%EC='19'\t"
|
|
"%Ey='70'\t"
|
|
"%EY='1970'\t"
|
|
"%Oy='70'\t"
|
|
#else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
|
|
"%EC='昭和'\t"
|
|
"%Ey='45'\t"
|
|
"%EY='昭和45年'\t"
|
|
"%Oy='七十'\t"
|
|
#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
|
|
"\n"),
|
|
lfmt,
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
|
|
check(loc,
|
|
SV(
|
|
|
|
#if defined(_WIN32)
|
|
"%b='5'\t"
|
|
#elif defined(_AIX) // defined(_WIN32)
|
|
"%b='5月'\t"
|
|
#elif defined(__APPLE__) // defined(_WIN32)
|
|
"%b=' 5'\t"
|
|
#else // defined(_WIN32)
|
|
"%b=' 5月'\t"
|
|
#endif // defined(_WIN32)
|
|
"%B='5月'\t"
|
|
"%C='20'\t"
|
|
#if defined(_WIN32)
|
|
"%h='5'\t"
|
|
#elif defined(_AIX) // defined(_WIN32)
|
|
"%h='5月'\t"
|
|
#elif defined(__APPLE__) // defined(_WIN32)
|
|
"%h=' 5'\t"
|
|
#else // defined(_WIN32)
|
|
"%h=' 5月'\t"
|
|
#endif // defined(_WIN32)
|
|
"%y='04'\t"
|
|
"%Y='2004'\t"
|
|
#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
|
|
"%EC='20'\t"
|
|
"%Ey='04'\t"
|
|
"%EY='2004'\t"
|
|
"%Oy='04'\t"
|
|
#else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
|
|
"%EC='平成'\t"
|
|
"%Ey='16'\t"
|
|
"%EY='平成16年'\t"
|
|
"%Oy='四'\t"
|
|
#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
|
|
"\n"),
|
|
lfmt,
|
|
std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
|
|
|
|
std::locale::global(std::locale::classic());
|
|
}
|
|
|
|
template <class CharT>
|
|
static void test() {
|
|
test_no_chrono_specs<CharT>();
|
|
test_invalid_values<CharT>();
|
|
test_valid_values<CharT>();
|
|
|
|
check_invalid_types<CharT>(
|
|
{SV("b"), SV("B"), SV("C"), SV("EC"), SV("Ey"), SV("EY"), SV("h"), SV("m"), SV("Om"), SV("Oy"), SV("y"), SV("Y")},
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
|
|
check_exception("The format specifier expects a '%' or a '}'",
|
|
SV("{:A"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
check_exception("The chrono specifiers contain a '{'",
|
|
SV("{:%%{"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
check_exception("End of input while parsing a conversion specifier",
|
|
SV("{:%"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
check_exception("End of input while parsing the modifier E",
|
|
SV("{:%E"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
check_exception("End of input while parsing the modifier O",
|
|
SV("{:%O"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
|
|
// Precision not allowed
|
|
check_exception("The format specifier expects a '%' or a '}'",
|
|
SV("{:.3}"),
|
|
std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
|
|
}
|
|
|
|
int main(int, char**) {
|
|
test<char>();
|
|
|
|
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
|
|
test<wchar_t>();
|
|
#endif
|
|
|
|
return 0;
|
|
}
|