1+ // ===----------------------------------------------------------------------===//
12//
23// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
34// See https://llvm.org/LICENSE.txt for license information.
1516// diagnoses the issue.
1617
1718#include < format>
19+ #include < variant>
1820
1921struct no_formatter_specialization {};
2022void test_no_formatter_specialization () {
@@ -36,7 +38,9 @@ struct std::formatter<correct_formatter_specialization, CharT> {
3638 }
3739
3840 template <class FormatContext >
39- typename FormatContext::iterator format (correct_formatter_specialization&, FormatContext&) const ;
41+ typename FormatContext::iterator format (correct_formatter_specialization&, FormatContext& ctx) const {
42+ return ctx.out ();
43+ }
4044};
4145void test_correct_formatter_specialization () {
4246 correct_formatter_specialization t;
@@ -52,7 +56,9 @@ struct std::formatter<formatter_not_semiregular, CharT> {
5256 formatter (int );
5357
5458 template <class ParseContext >
55- constexpr typename ParseContext::iterator parse (ParseContext&);
59+ constexpr typename ParseContext::iterator parse (ParseContext& ctx) {
60+ return ctx.begin ();
61+ }
5662
5763 template <class FormatContext >
5864 typename FormatContext::iterator format (formatter_not_semiregular&, FormatContext&) const ;
@@ -87,7 +93,9 @@ struct parse_function_invalid_arguments {};
8793template <class CharT >
8894struct std ::formatter<parse_function_invalid_arguments, CharT> {
8995 template <class ParseContext >
90- constexpr typename ParseContext::iterator parse (ParseContext&, int );
96+ constexpr typename ParseContext::iterator parse (ParseContext& ctx, int ) {
97+ return ctx.begin ();
98+ }
9199
92100 template <class FormatContext >
93101 typename FormatContext::iterator format (parse_function_invalid_arguments&, FormatContext&) const ;
@@ -106,7 +114,9 @@ struct parse_function_invalid_return_type {};
106114template <class CharT >
107115struct std ::formatter<parse_function_invalid_return_type, CharT> {
108116 template <class ParseContext >
109- constexpr int parse (ParseContext&);
117+ constexpr int parse (ParseContext&) {
118+ return 42 ;
119+ }
110120
111121 template <class FormatContext >
112122 typename FormatContext::iterator format (parse_function_invalid_return_type&, FormatContext&) const ;
@@ -125,7 +135,9 @@ struct no_format_function {};
125135template <class CharT >
126136struct std ::formatter<no_format_function, CharT> {
127137 template <class ParseContext >
128- constexpr typename ParseContext::iterator parse (ParseContext&);
138+ constexpr typename ParseContext::iterator parse (ParseContext& ctx) {
139+ return ctx.begin ();
140+ }
129141};
130142void test_no_format_function () {
131143 no_format_function t;
@@ -141,7 +153,9 @@ struct format_function_invalid_arguments {};
141153template <class CharT >
142154struct std ::formatter<format_function_invalid_arguments, CharT> {
143155 template <class ParseContext >
144- constexpr typename ParseContext::iterator parse (ParseContext&);
156+ constexpr typename ParseContext::iterator parse (ParseContext& ctx) {
157+ return ctx.begin ();
158+ }
145159
146160 template <class FormatContext >
147161 typename FormatContext::iterator format (format_function_invalid_arguments&) const ;
@@ -160,7 +174,9 @@ struct format_function_invalid_return_type {};
160174template <class CharT >
161175struct std ::formatter<format_function_invalid_return_type, CharT> {
162176 template <class ParseContext >
163- constexpr typename ParseContext::iterator parse (ParseContext&);
177+ constexpr typename ParseContext::iterator parse (ParseContext& ctx) {
178+ return ctx.begin ();
179+ }
164180
165181 template <class FormatContext >
166182 int format (format_function_invalid_return_type&, FormatContext&) const ;
@@ -179,7 +195,9 @@ struct format_function_not_const_qualified {};
179195template <class CharT >
180196struct std ::formatter<format_function_not_const_qualified, CharT> {
181197 template <class ParseContext >
182- constexpr typename ParseContext::iterator parse (ParseContext&);
198+ constexpr typename ParseContext::iterator parse (ParseContext& ctx) {
199+ return ctx.begin ();
200+ }
183201
184202 template <class FormatContext >
185203 typename FormatContext::iterator format (format_function_not_const_qualified&, FormatContext&);
@@ -193,3 +211,193 @@ void test_format_function_not_const_qualified() {
193211 (void )std::format (L" {}" , t);
194212#endif
195213}
214+
215+ struct auto_deduction_correct_formatter_specialization
216+ : std::variant<auto_deduction_correct_formatter_specialization*> {
217+ auto_deduction_correct_formatter_specialization* p = nullptr ;
218+ constexpr const std::variant<auto_deduction_correct_formatter_specialization*>& decay () const noexcept {
219+ return *this ;
220+ }
221+ };
222+
223+ template <>
224+ struct std ::formatter<auto_deduction_correct_formatter_specialization, char > {
225+ template <class ParseContext >
226+ static constexpr auto parse (ParseContext& ctx) {
227+ return ctx.begin ();
228+ }
229+ static constexpr auto format (const auto_deduction_correct_formatter_specialization& x, auto & ctx) {
230+ if (!x.p )
231+ return ctx.out ();
232+ auto m = [&](const auto_deduction_correct_formatter_specialization* t) {
233+ return std::format_to (ctx.out (), " {}" , *t);
234+ };
235+ return std::visit (m, x.decay ());
236+ }
237+ };
238+
239+ void test_auto_deduction_correct_formatter_specialization () {
240+ auto_deduction_correct_formatter_specialization t;
241+ (void )std::format (" {}" , t);
242+ }
243+
244+ struct auto_deduction_no_parse_function : std::variant<auto_deduction_no_parse_function*> {
245+ auto_deduction_no_parse_function* p = nullptr ;
246+ constexpr const std::variant<auto_deduction_no_parse_function*>& decay () const noexcept { return *this ; }
247+ };
248+
249+ template <>
250+ struct std ::formatter<auto_deduction_no_parse_function, char > {
251+ static constexpr auto format (const auto_deduction_no_parse_function& x, auto & ctx) {
252+ if (!x.p )
253+ return ctx.out ();
254+ auto m = [&](const auto_deduction_no_parse_function* t) { return std::format_to (ctx.out (), " {}" , *t); };
255+ return std::visit (m, x.decay ());
256+ }
257+ };
258+
259+ void test_auto_deduction_no_parse_function () {
260+ auto_deduction_no_parse_function t;
261+ // expected-error@*:* {{static assertion failed: The required formatter specialization does not have a parse function taking the proper arguments.}}
262+ (void )std::format (" {}" , t);
263+ }
264+
265+ struct auto_deduction_parse_function_invalid_arguments
266+ : std::variant<auto_deduction_parse_function_invalid_arguments*> {
267+ auto_deduction_parse_function_invalid_arguments* p = nullptr ;
268+ constexpr const std::variant<auto_deduction_parse_function_invalid_arguments*>& decay () const noexcept {
269+ return *this ;
270+ }
271+ };
272+
273+ template <>
274+ struct std ::formatter<auto_deduction_parse_function_invalid_arguments, char > {
275+ template <class ParseContext >
276+ static constexpr auto parse (ParseContext& ctx, int ) {
277+ return ctx.begin ();
278+ }
279+ static constexpr auto format (const auto_deduction_parse_function_invalid_arguments& x, auto & ctx) {
280+ if (!x.p )
281+ return ctx.out ();
282+ auto m = [&](const auto_deduction_parse_function_invalid_arguments* t) {
283+ return std::format_to (ctx.out (), " {}" , *t);
284+ };
285+ return std::visit (m, x.decay ());
286+ }
287+ };
288+
289+ void test_auto_deduction_parse_function_invalid_arguments () {
290+ auto_deduction_parse_function_invalid_arguments t;
291+ // expected-error@*:* {{static assertion failed: The required formatter specialization does not have a parse function taking the proper arguments.}}
292+ (void )std::format (" {}" , t);
293+ }
294+
295+ struct auto_deduction_parse_function_invalid_return_types
296+ : std::variant<auto_deduction_parse_function_invalid_return_types*> {
297+ auto_deduction_parse_function_invalid_return_types* p = nullptr ;
298+ constexpr const std::variant<auto_deduction_parse_function_invalid_return_types*>& decay () const noexcept {
299+ return *this ;
300+ }
301+ };
302+
303+ template <>
304+ struct std ::formatter<auto_deduction_parse_function_invalid_return_types, char > {
305+ template <class ParseContext >
306+ static constexpr auto parse (ParseContext&) {
307+ return 42 ;
308+ }
309+ static constexpr auto format (const auto_deduction_parse_function_invalid_return_types& x, auto & ctx) {
310+ if (!x.p )
311+ return ctx.out ();
312+ auto m = [&](const auto_deduction_parse_function_invalid_return_types* t) {
313+ return std::format_to (ctx.out (), " {}" , *t);
314+ };
315+ return std::visit (m, x.decay ());
316+ }
317+ };
318+
319+ void test_auto_deduction_parse_function_invalid_return_types () {
320+ // expected-error@*:* {{static assertion failed: The required formatter specialization's parse function does not return the required type.}}
321+ auto_deduction_parse_function_invalid_return_types t;
322+ (void )std::format (" {}" , t);
323+ }
324+
325+ struct auto_deduction_no_format_function : std::variant<auto_deduction_no_format_function*> {
326+ auto_deduction_no_format_function* p = nullptr ;
327+ // expected-error@*:* 2 {{static assertion failed: The required formatter specialization's format function does not return the required type.}}
328+ constexpr const std::variant<auto_deduction_no_format_function*>& decay () const noexcept { return *this ; }
329+ };
330+
331+ template <>
332+ struct std ::formatter<auto_deduction_no_format_function, char > {
333+ template <class ParseContext >
334+ static constexpr auto parse (ParseContext& ctx) {
335+ return ctx.begin ();
336+ }
337+ };
338+
339+ void test_auto_deduction_no_format_function () {
340+ // expected-error@*:* {{static assertion failed: The required formatter specialization does not have a format function taking the proper arguments.}}
341+ auto_deduction_no_format_function t;
342+ (void )std::format (" {}" , t);
343+ }
344+
345+ struct auto_deduction_format_function_invalid_arguments
346+ : std::variant<auto_deduction_format_function_invalid_arguments*> {
347+ auto_deduction_format_function_invalid_arguments* p = nullptr ;
348+ constexpr const std::variant<auto_deduction_format_function_invalid_arguments*>& decay () const noexcept {
349+ return *this ;
350+ }
351+ };
352+
353+ template <>
354+ struct std ::formatter<auto_deduction_format_function_invalid_arguments, char > {
355+ template <class ParseContext >
356+ static constexpr auto parse (ParseContext& ctx) {
357+ return ctx.begin ();
358+ }
359+ static constexpr auto format (const auto_deduction_format_function_invalid_arguments& x, auto & ctx, int ) {
360+ if (!x.p )
361+ return ctx.out ();
362+ auto m = [&](const auto_deduction_format_function_invalid_arguments* t) {
363+ return std::format_to (ctx.out (), " {}" , *t);
364+ };
365+ return std::visit (m, x.decay ());
366+ }
367+ };
368+
369+ void test_auto_deduction_format_function_invalid_arguments () {
370+ // expected-error@*:* {{static assertion failed: The required formatter specialization does not have a format function taking the proper arguments.}}
371+ auto_deduction_format_function_invalid_arguments t;
372+ (void )std::format (" {}" , t);
373+ }
374+
375+ struct auto_deduction_format_function_invalid_return_types
376+ : std::variant<auto_deduction_format_function_invalid_return_types*> {
377+ auto_deduction_format_function_invalid_return_types* p = nullptr ;
378+ constexpr const std::variant<auto_deduction_format_function_invalid_return_types*>& decay () const noexcept {
379+ return *this ;
380+ }
381+ };
382+
383+ template <>
384+ struct std ::formatter<auto_deduction_format_function_invalid_return_types, char > {
385+ template <class ParseContext >
386+ static constexpr auto parse (ParseContext& ctx) {
387+ return ctx.begin ();
388+ }
389+ static constexpr auto format (const auto_deduction_format_function_invalid_return_types& x, auto & ctx) {
390+ if (!x.p )
391+ return 42 ;
392+ auto m = [&](const auto_deduction_format_function_invalid_return_types* t) {
393+ std::format_to (ctx.out (), " {}" , *t);
394+ return 42 ;
395+ };
396+ return std::visit (m, x.decay ());
397+ }
398+ };
399+
400+ void test_auto_deduction_format_function_invalid_return_types () {
401+ auto_deduction_format_function_invalid_return_types t;
402+ (void )std::format (" {}" , t);
403+ }
0 commit comments