[Clang] Deprecate __is_referenceable (#123185)
[llvm-project.git] / libcxx / test / std / utilities / format / format.formattable / concept.formattable.compile.pass.cpp
blob52cfa2c81c21aa297b5de076e3a2ba5f3b0404bb
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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
11 // This test uses std::filesystem::path, which is not always available
12 // XFAIL: availability-filesystem-missing
14 // <format>
16 // template<class T, class charT>
17 // concept formattable = ...
19 #include <array>
20 #include <bitset>
21 #include <bitset>
22 #include <chrono>
23 #include <complex>
24 #include <concepts>
25 #include <deque>
26 #include <filesystem>
27 #include <format>
28 #include <forward_list>
29 #include <list>
30 #include <map>
31 #include <memory>
32 #include <optional>
33 #include <queue>
34 #include <set>
35 #include <span>
36 #include <stack>
37 #include <system_error>
38 #include <tuple>
39 #include <type_traits>
40 #include <unordered_map>
41 #include <unordered_set>
42 #include <valarray>
43 #include <variant>
45 #include "test_macros.h"
46 #include "min_allocator.h"
48 #ifndef TEST_HAS_NO_LOCALIZATION
49 # include <regex>
50 #endif
51 #ifndef TEST_HAS_NO_THREADS
52 # include <thread>
53 #endif
55 template <class T, class CharT>
56 void assert_is_not_formattable() {
57 // clang-format off
58 static_assert(!std::formattable< T , CharT>);
59 static_assert(!std::formattable< T& , CharT>);
60 static_assert(!std::formattable< T&& , CharT>);
61 static_assert(!std::formattable<const T , CharT>);
62 static_assert(!std::formattable<const T& , CharT>);
63 static_assert(!std::formattable<const T&& , CharT>);
64 // clang-format on
67 template <class T, class CharT>
68 void assert_is_formattable() {
69 // Only formatters for CharT == char || CharT == wchar_t are enabled for the
70 // standard formatters. When CharT is a different type the formatter should
71 // be disabled.
72 if constexpr (std::same_as<CharT, char>
73 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
74 || std::same_as<CharT, wchar_t>
75 #endif
76 ) {
77 // clang-format off
78 static_assert(std::formattable< T , CharT>);
79 static_assert(std::formattable< T& , CharT>);
80 static_assert(std::formattable< T&& , CharT>);
81 static_assert(std::formattable<const T , CharT>);
82 static_assert(std::formattable<const T& , CharT>);
83 static_assert(std::formattable<const T&& , CharT>);
84 // clang-format on
85 } else
86 assert_is_not_formattable<T, CharT>();
89 // Tests for P0645 Text Formatting
90 template <class CharT>
91 void test_P0645() {
92 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
93 // Tests the special formatter that converts a char to a wchar_t.
94 assert_is_formattable<char, wchar_t>();
95 #endif
96 assert_is_formattable<CharT, CharT>();
98 assert_is_formattable<CharT*, CharT>();
99 assert_is_formattable<const CharT*, CharT>();
100 assert_is_formattable<CharT[42], CharT>();
101 if constexpr (!std::same_as<CharT, int>) { // string and string_view only work with proper character types
102 assert_is_formattable<std::basic_string<CharT>, CharT>();
103 assert_is_formattable<std::basic_string_view<CharT>, CharT>();
106 assert_is_formattable<bool, CharT>();
108 assert_is_formattable<signed char, CharT>();
109 assert_is_formattable<signed short, CharT>();
110 assert_is_formattable<signed int, CharT>();
111 assert_is_formattable<signed long, CharT>();
112 assert_is_formattable<signed long long, CharT>();
113 #ifndef TEST_HAS_NO_INT128
114 assert_is_formattable<__int128_t, CharT>();
115 #endif
117 assert_is_formattable<unsigned char, CharT>();
118 assert_is_formattable<unsigned short, CharT>();
119 assert_is_formattable<unsigned int, CharT>();
120 assert_is_formattable<unsigned long, CharT>();
121 assert_is_formattable<unsigned long long, CharT>();
122 #ifndef TEST_HAS_NO_INT128
123 assert_is_formattable<__uint128_t, CharT>();
124 #endif
126 // floating-point types are tested in concept.formattable.float.compile.pass.cpp
128 assert_is_formattable<std::nullptr_t, CharT>();
129 assert_is_formattable<void*, CharT>();
130 assert_is_formattable<const void*, CharT>();
133 // Tests for P1361 Integration of chrono with text formatting
135 // Some tests are commented out since these types haven't been implemented in
136 // chrono yet. After P1361 has been implemented these formatters should be all
137 // enabled.
138 template <class CharT>
139 void test_P1361() {
140 // The chrono formatters require localization support.
141 // [time.format]/7
142 // If the chrono-specs is omitted, the chrono object is formatted as if by
143 // streaming it to std::ostringstream os with the formatting
144 // locale imbued and copying os.str() through the output iterator of the
145 // context with additional padding and adjustments as specified by the format
146 // specifiers.
147 // In libc++ std:::ostringstream requires localization support.
148 #ifndef TEST_HAS_NO_LOCALIZATION
150 assert_is_formattable<std::chrono::microseconds, CharT>();
152 assert_is_formattable<std::chrono::sys_time<std::chrono::microseconds>, CharT>();
153 //assert_is_formattable<std::chrono::utc_time<std::chrono::microseconds>, CharT>();
154 //assert_is_formattable<std::chrono::tai_time<std::chrono::microseconds>, CharT>();
155 //assert_is_formattable<std::chrono::gps_time<std::chrono::microseconds>, CharT>();
156 assert_is_formattable<std::chrono::file_time<std::chrono::microseconds>, CharT>();
157 assert_is_formattable<std::chrono::local_time<std::chrono::microseconds>, CharT>();
159 assert_is_formattable<std::chrono::day, CharT>();
160 assert_is_formattable<std::chrono::month, CharT>();
161 assert_is_formattable<std::chrono::year, CharT>();
163 assert_is_formattable<std::chrono::weekday, CharT>();
164 assert_is_formattable<std::chrono::weekday_indexed, CharT>();
165 assert_is_formattable<std::chrono::weekday_last, CharT>();
167 assert_is_formattable<std::chrono::month_day, CharT>();
168 assert_is_formattable<std::chrono::month_day_last, CharT>();
169 assert_is_formattable<std::chrono::month_weekday, CharT>();
170 assert_is_formattable<std::chrono::month_weekday_last, CharT>();
172 assert_is_formattable<std::chrono::year_month, CharT>();
173 assert_is_formattable<std::chrono::year_month_day, CharT>();
174 assert_is_formattable<std::chrono::year_month_day_last, CharT>();
175 assert_is_formattable<std::chrono::year_month_weekday, CharT>();
176 assert_is_formattable<std::chrono::year_month_weekday_last, CharT>();
178 assert_is_formattable<std::chrono::hh_mm_ss<std::chrono::microseconds>, CharT>();
180 # if !defined(TEST_HAS_NO_EXPERIMENTAL_TZDB)
181 assert_is_formattable<std::chrono::sys_info, CharT>();
182 assert_is_formattable<std::chrono::local_info, CharT>();
184 //assert_is_formattable<std::chrono::zoned_time, CharT>();
185 # endif // !defined(TEST_HAS_NO_EXPERIMENTAL_TZDB)
187 #endif // TEST_HAS_NO_LOCALIZATION
190 // Tests for P1636 Formatters for library types
192 // The paper hasn't been voted in so currently all formatters are disabled.
193 // Note the paper has been abandoned, the types are kept since other papers may
194 // introduce these formatters.
195 template <class CharT>
196 void test_P1636() {
197 assert_is_not_formattable<std::basic_streambuf<CharT>, CharT>();
198 assert_is_not_formattable<std::bitset<42>, CharT>();
199 assert_is_not_formattable<std::complex<double>, CharT>();
200 assert_is_not_formattable<std::error_code, CharT>();
201 assert_is_not_formattable<std::filesystem::path, CharT>();
202 assert_is_not_formattable<std::shared_ptr<int>, CharT>();
203 #ifndef TEST_HAS_NO_LOCALIZATION
204 if constexpr (!std::same_as<CharT, int>) // sub_match only works with proper character types
205 assert_is_not_formattable<std::sub_match<CharT*>, CharT>();
206 #endif
207 #ifndef TEST_HAS_NO_THREADS
208 assert_is_formattable<std::thread::id, CharT>();
209 #endif
210 assert_is_not_formattable<std::unique_ptr<int>, CharT>();
213 template <class CharT, class Vector>
214 void test_P2286_vector_bool() {
215 assert_is_formattable<Vector, CharT>();
216 assert_is_formattable<typename Vector::reference, CharT>();
218 // The const_reference shall be a bool.
219 // However libc++ uses a __bit_const_reference<vector> when
220 // _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL is defined.
221 assert_is_formattable<const Vector&, CharT>();
222 assert_is_formattable<typename Vector::const_reference, CharT>();
225 // Tests for P2286 Formatting ranges
226 template <class CharT>
227 void test_P2286() {
228 assert_is_formattable<std::array<int, 42>, CharT>();
229 assert_is_formattable<std::vector<int>, CharT>();
230 assert_is_formattable<std::deque<int>, CharT>();
231 assert_is_formattable<std::forward_list<int>, CharT>();
232 assert_is_formattable<std::list<int>, CharT>();
234 assert_is_formattable<std::set<int>, CharT>();
235 assert_is_formattable<std::map<int, int>, CharT>();
236 assert_is_formattable<std::multiset<int>, CharT>();
237 assert_is_formattable<std::multimap<int, int>, CharT>();
239 assert_is_formattable<std::unordered_set<int>, CharT>();
240 assert_is_formattable<std::unordered_map<int, int>, CharT>();
241 assert_is_formattable<std::unordered_multiset<int>, CharT>();
242 assert_is_formattable<std::unordered_multimap<int, int>, CharT>();
244 assert_is_formattable<std::stack<int>, CharT>();
245 assert_is_formattable<std::queue<int>, CharT>();
246 assert_is_formattable<std::priority_queue<int>, CharT>();
248 assert_is_formattable<std::span<int>, CharT>();
250 assert_is_formattable<std::valarray<int>, CharT>();
252 assert_is_formattable<std::pair<int, int>, CharT>();
253 assert_is_formattable<std::tuple<int>, CharT>();
255 test_P2286_vector_bool<CharT, std::vector<bool>>();
256 test_P2286_vector_bool<CharT, std::vector<bool, std::allocator<bool>>>();
257 test_P2286_vector_bool<CharT, std::vector<bool, min_allocator<bool>>>();
260 // Tests volatile qualified objects are no longer formattable.
261 template <class CharT>
262 void test_LWG3631() {
263 assert_is_not_formattable<volatile CharT, CharT>();
265 assert_is_not_formattable<volatile bool, CharT>();
267 assert_is_not_formattable<volatile signed int, CharT>();
268 assert_is_not_formattable<volatile unsigned int, CharT>();
270 assert_is_not_formattable<volatile std::chrono::microseconds, CharT>();
271 assert_is_not_formattable<volatile std::chrono::sys_time<std::chrono::microseconds>, CharT>();
272 assert_is_not_formattable<volatile std::chrono::day, CharT>();
274 assert_is_not_formattable<std::array<volatile int, 42>, CharT>();
276 assert_is_not_formattable<std::pair<volatile int, int>, CharT>();
277 assert_is_not_formattable<std::pair<int, volatile int>, CharT>();
278 assert_is_not_formattable<std::pair<volatile int, volatile int>, CharT>();
281 class c {
282 void f();
283 void fc() const;
284 static void sf();
286 enum e { a };
287 enum class ec { a };
288 template <class CharT>
289 void test_disabled() {
290 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
291 assert_is_not_formattable<const char*, wchar_t>();
292 #endif
293 assert_is_not_formattable<const char*, char8_t>();
294 assert_is_not_formattable<const char*, char16_t>();
295 assert_is_not_formattable<const char*, char32_t>();
297 assert_is_not_formattable<c, CharT>();
298 assert_is_not_formattable<const c, CharT>();
299 assert_is_not_formattable<volatile c, CharT>();
300 assert_is_not_formattable<const volatile c, CharT>();
302 assert_is_not_formattable<e, CharT>();
303 assert_is_not_formattable<const e, CharT>();
304 assert_is_not_formattable<volatile e, CharT>();
305 assert_is_not_formattable<const volatile e, CharT>();
307 assert_is_not_formattable<ec, CharT>();
308 assert_is_not_formattable<const ec, CharT>();
309 assert_is_not_formattable<volatile ec, CharT>();
310 assert_is_not_formattable<const volatile ec, CharT>();
312 assert_is_not_formattable<int*, CharT>();
313 assert_is_not_formattable<const int*, CharT>();
314 assert_is_not_formattable<volatile int*, CharT>();
315 assert_is_not_formattable<const volatile int*, CharT>();
317 assert_is_not_formattable<c*, CharT>();
318 assert_is_not_formattable<const c*, CharT>();
319 assert_is_not_formattable<volatile c*, CharT>();
320 assert_is_not_formattable<const volatile c*, CharT>();
322 assert_is_not_formattable<e*, CharT>();
323 assert_is_not_formattable<const e*, CharT>();
324 assert_is_not_formattable<volatile e*, CharT>();
325 assert_is_not_formattable<const volatile e*, CharT>();
327 assert_is_not_formattable<ec*, CharT>();
328 assert_is_not_formattable<const ec*, CharT>();
329 assert_is_not_formattable<volatile ec*, CharT>();
330 assert_is_not_formattable<const volatile ec*, CharT>();
332 assert_is_not_formattable<void (*)(), CharT>();
333 assert_is_not_formattable<void (c::*)(), CharT>();
334 assert_is_not_formattable<void (c::*)() const, CharT>();
336 assert_is_not_formattable<std::optional<int>, CharT>();
337 assert_is_not_formattable<std::variant<int>, CharT>();
339 assert_is_not_formattable<std::shared_ptr<c>, CharT>();
340 assert_is_not_formattable<std::unique_ptr<c>, CharT>();
342 assert_is_not_formattable<std::array<c, 42>, CharT>();
343 assert_is_not_formattable<std::vector<c>, CharT>();
344 assert_is_not_formattable<std::deque<c>, CharT>();
345 assert_is_not_formattable<std::forward_list<c>, CharT>();
346 assert_is_not_formattable<std::list<c>, CharT>();
348 assert_is_not_formattable<std::set<c>, CharT>();
349 assert_is_not_formattable<std::map<c, int>, CharT>();
350 assert_is_not_formattable<std::multiset<c>, CharT>();
351 assert_is_not_formattable<std::multimap<c, int>, CharT>();
353 assert_is_not_formattable<std::unordered_set<c>, CharT>();
354 assert_is_not_formattable<std::unordered_map<c, int>, CharT>();
355 assert_is_not_formattable<std::unordered_multiset<c>, CharT>();
356 assert_is_not_formattable<std::unordered_multimap<c, int>, CharT>();
358 assert_is_not_formattable<std::stack<c>, CharT>();
359 assert_is_not_formattable<std::queue<c>, CharT>();
360 assert_is_not_formattable<std::priority_queue<c>, CharT>();
362 assert_is_not_formattable<std::span<c>, CharT>();
364 assert_is_not_formattable<std::valarray<c>, CharT>();
366 assert_is_not_formattable<std::pair<c, int>, CharT>();
367 assert_is_not_formattable<std::tuple<c>, CharT>();
369 assert_is_not_formattable<std::optional<c>, CharT>();
370 assert_is_not_formattable<std::variant<c>, CharT>();
373 struct abstract {
374 virtual ~abstract() = 0;
377 template <class CharT>
378 requires std::same_as<CharT, char>
379 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
380 || std::same_as<CharT, wchar_t>
381 #endif
382 struct std::formatter<abstract, CharT> {
383 template <class ParseContext>
384 constexpr typename ParseContext::iterator parse(ParseContext& parse_ctx) {
385 return parse_ctx.begin();
388 template <class FormatContext>
389 typename FormatContext::iterator format(const abstract&, FormatContext& ctx) const {
390 return ctx.out();
394 template <class CharT>
395 void test_abstract_class() {
396 assert_is_formattable<abstract, CharT>();
399 template <class CharT>
400 void test() {
401 test_P0645<CharT>();
402 test_P1361<CharT>();
403 test_P1636<CharT>();
404 test_P2286<CharT>();
405 test_LWG3631<CharT>();
406 test_abstract_class<CharT>();
407 test_disabled<CharT>();
410 void test() {
411 test<char>();
412 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
413 test<wchar_t>();
414 #endif
415 test<char8_t>();
416 test<char16_t>();
417 test<char32_t>();