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 | // REQUIRES: std-at-least-c++20 |
10 | // UNSUPPORTED: no-filesystem, no-localization, no-tzdb |
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 | // XFAIL: libcpp-has-no-experimental-tzdb |
17 | // XFAIL: availability-tzdb-missing |
18 | |
19 | // REQUIRES: locale.fr_FR.UTF-8 |
20 | // REQUIRES: locale.ja_JP.UTF-8 |
21 | |
22 | // <chrono> |
23 | |
24 | // class gps_clock; |
25 | |
26 | // template<class charT, class traits, class Duration> |
27 | // basic_ostream<charT, traits>& |
28 | // operator<<(basic_ostream<charT, traits>& os, const gps_time<Duration>& tp); |
29 | |
30 | #include <chrono> |
31 | #include <cassert> |
32 | #include <ratio> |
33 | #include <sstream> |
34 | |
35 | #include "make_string.h" |
36 | #include "platform_support.h" // locale name macros |
37 | #include "test_macros.h" |
38 | |
39 | #define SV(S) MAKE_STRING_VIEW(CharT, S) |
40 | |
41 | template <class CharT, class Duration> |
42 | static std::basic_string<CharT> stream_c_locale(std::chrono::gps_time<Duration> time_point) { |
43 | std::basic_stringstream<CharT> sstr; |
44 | sstr << std::fixed << time_point; |
45 | return sstr.str(); |
46 | } |
47 | |
48 | template <class CharT, class Duration> |
49 | static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::gps_time<Duration> time_point) { |
50 | std::basic_stringstream<CharT> sstr; |
51 | const std::locale locale(LOCALE_fr_FR_UTF_8); |
52 | sstr.imbue(locale); |
53 | sstr << std::fixed << time_point; |
54 | return sstr.str(); |
55 | } |
56 | |
57 | template <class CharT, class Duration> |
58 | static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::gps_time<Duration> time_point) { |
59 | std::basic_stringstream<CharT> sstr; |
60 | const std::locale locale(LOCALE_ja_JP_UTF_8); |
61 | sstr.imbue(locale); |
62 | sstr << std::fixed << time_point; |
63 | return sstr.str(); |
64 | } |
65 | |
66 | template <class CharT> |
67 | static void test_c() { |
68 | using namespace std::literals::chrono_literals; |
69 | namespace cr = std::chrono; |
70 | |
71 | assert(stream_c_locale<CharT>(cr::gps_time<cr::nanoseconds>{946'688'523'123'456'789ns}) == |
72 | SV("2010-01-05 01:01:48.123456789" )); |
73 | assert(stream_c_locale<CharT>(cr::gps_time<cr::microseconds>{946'688'523'123'456us}) == |
74 | SV("2010-01-05 01:01:48.123456" )); |
75 | |
76 | assert(stream_c_locale<CharT>(cr::gps_time<cr::milliseconds>{946'684'822'123ms}) == SV("2010-01-05 00:00:07.123" )); |
77 | assert(stream_c_locale<CharT>(cr::gps_seconds{1'234'567'890s}) == SV("2019-02-18 23:31:12" )); |
78 | assert(stream_c_locale<CharT>(cr::gps_time<cr::minutes>{20'576'131min}) == SV("2019-02-18 23:30:42" )); |
79 | assert(stream_c_locale<CharT>(cr::gps_time<cr::hours>{342'935h}) == SV("2019-02-18 22:59:42" )); |
80 | |
81 | assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<signed char, std::ratio<2, 1>>>{ |
82 | cr::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1980-01-06 00:02:00" )); |
83 | assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<short, std::ratio<1, 2>>>{ |
84 | cr::duration<short, std::ratio<1, 2>>{3600}}) == SV("1980-01-06 00:30:00.0" )); |
85 | assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<int, std::ratio<1, 4>>>{ |
86 | cr::duration<int, std::ratio<1, 4>>{3600}}) == SV("1980-01-06 00:15:00.00" )); |
87 | assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<long, std::ratio<1, 10>>>{ |
88 | cr::duration<long, std::ratio<1, 10>>{36611}}) == SV("1980-01-06 01:01:01.1" )); |
89 | assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<long long, std::ratio<1, 100>>>{ |
90 | cr::duration<long long, std::ratio<1, 100>>{123'456'789'010}}) == SV("2019-02-18 23:31:12.10" )); |
91 | } |
92 | |
93 | template <class CharT> |
94 | static void test_fr_FR() { |
95 | using namespace std::literals::chrono_literals; |
96 | namespace cr = std::chrono; |
97 | |
98 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::nanoseconds>{946'688'523'123'456'789ns}) == |
99 | SV("2010-01-05 01:01:48,123456789" )); |
100 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::microseconds>{946'688'523'123'456us}) == |
101 | SV("2010-01-05 01:01:48,123456" )); |
102 | |
103 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::milliseconds>{946'684'822'123ms}) == |
104 | SV("2010-01-05 00:00:07,123" )); |
105 | assert(stream_fr_FR_locale<CharT>(cr::gps_seconds{1'234'567'890s}) == SV("2019-02-18 23:31:12" )); |
106 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::minutes>{20'576'131min}) == SV("2019-02-18 23:30:42" )); |
107 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::hours>{342'935h}) == SV("2019-02-18 22:59:42" )); |
108 | |
109 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<signed char, std::ratio<2, 1>>>{ |
110 | cr::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1980-01-06 00:02:00" )); |
111 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<short, std::ratio<1, 2>>>{ |
112 | cr::duration<short, std::ratio<1, 2>>{3600}}) == SV("1980-01-06 00:30:00,0" )); |
113 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<int, std::ratio<1, 4>>>{ |
114 | cr::duration<int, std::ratio<1, 4>>{3600}}) == SV("1980-01-06 00:15:00,00" )); |
115 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<long, std::ratio<1, 10>>>{ |
116 | cr::duration<long, std::ratio<1, 10>>{36611}}) == SV("1980-01-06 01:01:01,1" )); |
117 | assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<long long, std::ratio<1, 100>>>{ |
118 | cr::duration<long long, std::ratio<1, 100>>{123'456'789'010}}) == SV("2019-02-18 23:31:12,10" )); |
119 | } |
120 | |
121 | template <class CharT> |
122 | static void test_ja_JP() { |
123 | using namespace std::literals::chrono_literals; |
124 | namespace cr = std::chrono; |
125 | |
126 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::nanoseconds>{946'688'523'123'456'789ns}) == |
127 | SV("2010-01-05 01:01:48.123456789" )); |
128 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::microseconds>{946'688'523'123'456us}) == |
129 | SV("2010-01-05 01:01:48.123456" )); |
130 | |
131 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::milliseconds>{946'684'822'123ms}) == |
132 | SV("2010-01-05 00:00:07.123" )); |
133 | assert(stream_ja_JP_locale<CharT>(cr::gps_seconds{1'234'567'890s}) == SV("2019-02-18 23:31:12" )); |
134 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::minutes>{20'576'131min}) == SV("2019-02-18 23:30:42" )); |
135 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::hours>{342'935h}) == SV("2019-02-18 22:59:42" )); |
136 | |
137 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<signed char, std::ratio<2, 1>>>{ |
138 | cr::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1980-01-06 00:02:00" )); |
139 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<short, std::ratio<1, 2>>>{ |
140 | cr::duration<short, std::ratio<1, 2>>{3600}}) == SV("1980-01-06 00:30:00.0" )); |
141 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<int, std::ratio<1, 4>>>{ |
142 | cr::duration<int, std::ratio<1, 4>>{3600}}) == SV("1980-01-06 00:15:00.00" )); |
143 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<long, std::ratio<1, 10>>>{ |
144 | cr::duration<long, std::ratio<1, 10>>{36611}}) == SV("1980-01-06 01:01:01.1" )); |
145 | assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<long long, std::ratio<1, 100>>>{ |
146 | cr::duration<long long, std::ratio<1, 100>>{123'456'789'010}}) == SV("2019-02-18 23:31:12.10" )); |
147 | } |
148 | |
149 | template <class CharT> |
150 | static void test() { |
151 | test_c<CharT>(); |
152 | test_fr_FR<CharT>(); |
153 | test_ja_JP<CharT>(); |
154 | } |
155 | |
156 | int main(int, char**) { |
157 | test<char>(); |
158 | |
159 | #ifndef TEST_HAS_NO_WIDE_CHARACTERS |
160 | test<wchar_t>(); |
161 | #endif |
162 | |
163 | return 0; |
164 | } |
165 | |