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-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10// UNSUPPORTED: no-localization
11// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
12
13// TODO FMT This test should not require std::to_chars(floating-point)
14// XFAIL: availability-fp_to_chars-missing
15
16// REQUIRES: locale.fr_FR.UTF-8
17// REQUIRES: locale.ja_JP.UTF-8
18
19// <chrono>
20// class month_day;
21
22// template<class charT, class traits>
23// basic_ostream<charT, traits>&
24// operator<<(basic_ostream<charT, traits>& os, const month_day& md);
25
26#include <chrono>
27#include <cassert>
28#include <sstream>
29
30#include "make_string.h"
31#include "platform_support.h" // locale name macros
32#include "test_macros.h"
33#include "assert_macros.h"
34#include "concat_macros.h"
35
36#define SV(S) MAKE_STRING_VIEW(CharT, S)
37
38#define TEST_EQUAL(OUT, EXPECTED) \
39 TEST_REQUIRE(OUT == EXPECTED, \
40 TEST_WRITE_CONCATENATED( \
41 "\nExpression ", #OUT, "\nExpected output ", EXPECTED, "\nActual output ", OUT, '\n'));
42
43template <class CharT>
44static std::basic_string<CharT> stream_c_locale(std::chrono::month_day md) {
45 std::basic_stringstream<CharT> sstr;
46 sstr << md;
47 return sstr.str();
48}
49
50template <class CharT>
51static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::month_day md) {
52 std::basic_stringstream<CharT> sstr;
53 const std::locale locale(LOCALE_fr_FR_UTF_8);
54 sstr.imbue(locale);
55 sstr << md;
56 return sstr.str();
57}
58
59template <class CharT>
60static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::month_day md) {
61 std::basic_stringstream<CharT> sstr;
62 const std::locale locale(LOCALE_ja_JP_UTF_8);
63 sstr.imbue(locale);
64 sstr << md;
65 return sstr.str();
66}
67
68template <class CharT>
69static void test() {
70 using namespace std::literals::chrono_literals;
71
72 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 0d}),
73 SV("0 is not a valid month/00 is not a valid day"));
74 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 1d}),
75 SV("0 is not a valid month/01"));
76 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),
77 SV("Jan/255 is not a valid day"));
78 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("Jan/31"));
79 // February is considered valid with 29 days; it lacks the year information
80 // to do a proper validation.
81 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("Feb/29"));
82 // The month_day stream operator has no validation, this means never validate
83 // dates don't get
84 // Jun/31 is not a valid month day
85 // which is inconsistent with other stream operators.
86 // TODO FMT file an issue about this.
87 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("Jun/31"));
88
89 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 0d}),
90 SV("0 is not a valid month/00 is not a valid day"));
91 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 1d}),
92 SV("0 is not a valid month/01"));
93#if defined(__APPLE__)
94 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),
95 SV("jan/255 is not a valid day"));
96 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("jan/31"));
97 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("fév/29"));
98 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("jui/31"));
99#else // defined(__APPLE__)
100 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),
101 SV("janv./255 is not a valid day"));
102 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("janv./31"));
103 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("févr./29"));
104 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("juin/31"));
105#endif // defined(__APPLE__)
106
107 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 0d}),
108 SV("0 is not a valid month/00 is not a valid day"));
109 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{0}, 1d}),
110 SV("0 is not a valid month/01"));
111#if defined(__APPLE__)
112 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),
113 SV(" 1/255 is not a valid day"));
114 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV(" 1/31"));
115 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV(" 2/29"));
116 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV(" 6/31"));
117#elif defined(_WIN32) // defined(__APPLE__)
118 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),
119 SV("1/255 is not a valid day"));
120 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("1/31"));
121 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("2/29"));
122 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("6/31"));
123#elif defined(_AIX) // defined(__APPLE__)
124 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),
125 SV("1月/255 is not a valid day"));
126 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV("1月/31"));
127 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV("2月/29"));
128 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV("6月/31"));
129#else // defined(__APPLE__)
130 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 255d}),
131 SV(" 1月/255 is not a valid day"));
132 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{1}, 31d}), SV(" 1月/31"));
133 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{2}, 29d}), SV(" 2月/29"));
134 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::month_day{std::chrono::month{6}, 31d}), SV(" 6月/31"));
135#endif // defined(__APPLE__)
136}
137
138int main(int, char**) {
139 test<char>();
140#ifndef TEST_HAS_NO_WIDE_CHARACTERS
141 test<wchar_t>();
142#endif
143
144 return 0;
145}
146

source code of libcxx/test/std/time/time.cal/time.cal.md/time.cal.md.nonmembers/ostream.pass.cpp