@@ -24,6 +24,10 @@ struct UserDefinedType
24
24
{
25
25
};
26
26
27
+ struct UserDefinedTypeWithParser
28
+ {
29
+ };
30
+
27
31
enum class UserFormattedEnum
28
32
{
29
33
One = 1 ,
@@ -76,15 +80,40 @@ StringType reserved_codepoint()
76
80
} // namespace
77
81
78
82
template <typename CharType>
79
- struct fly ::Formatter<UserDefinedType, CharType> :
80
- public fly::Formatter<std::basic_string_view<CharType>, CharType>
83
+ struct fly ::Formatter<UserDefinedType, CharType>
81
84
{
82
85
template <typename FormatContext>
83
- void format (const UserDefinedType & , FormatContext &context)
86
+ void format (UserDefinedType, FormatContext &context)
84
87
{
85
- fly::Formatter<std::basic_string_view<CharType>, CharType>::format (
86
- FLY_STR (CharType, " UserDefinedType" ),
87
- context);
88
+ fly::BasicString<CharType>::format_to (
89
+ context.out (),
90
+ FLY_ARR (CharType, " {}" ),
91
+ FLY_STR (CharType, " UserDefinedType" ));
92
+ }
93
+ };
94
+
95
+ template <typename CharType>
96
+ struct fly ::Formatter<UserDefinedTypeWithParser, CharType>
97
+ {
98
+ bool m_option {false };
99
+
100
+ template <typename FormatParseContext>
101
+ constexpr void parse (FormatParseContext &context)
102
+ {
103
+ if (context.lexer ().consume_if (FLY_CHR (CharType, ' o' )))
104
+ {
105
+ m_option = true ;
106
+ }
107
+ if (!context.lexer ().consume_if (FLY_CHR (CharType, ' }' )))
108
+ {
109
+ context.on_error (" UserDefinedTypeWithParser error!" );
110
+ }
111
+ }
112
+
113
+ template <typename FormatContext>
114
+ void format (UserDefinedTypeWithParser, FormatContext &context)
115
+ {
116
+ fly::BasicString<CharType>::format_to (context.out (), FLY_ARR (CharType, " {}" ), m_option);
88
117
}
89
118
};
90
119
@@ -482,14 +511,6 @@ CATCH_TEMPLATE_TEST_CASE("FormatTypes", "[string]", char, wchar_t, char8_t, char
482
511
return !value.empty ();
483
512
};
484
513
485
- CATCH_SECTION (" User-defined types may be formatted without presentation type" )
486
- {
487
- UserDefinedType gt {};
488
- test_format (FMT (" {}" ), FMT (" UserDefinedType" ), gt);
489
- test_format (FMT (" {}" ), FMT (" One" ), UserFormattedEnum::One);
490
- test_format (FMT (" {}" ), FMT (" Two" ), UserFormattedEnum::Two);
491
- }
492
-
493
514
CATCH_SECTION (" Presentation type may be set (character)" )
494
515
{
495
516
test_format (FMT (" {:c}" ), FMT (" a" ), ' a' );
@@ -748,6 +769,61 @@ CATCH_TEMPLATE_TEST_CASE("FormatTypes", "[string]", char, wchar_t, char8_t, char
748
769
}
749
770
}
750
771
772
+ // This test is broken up because otherwise it is too large for Windows and a stack overflow occurs.
773
+ CATCH_TEMPLATE_TEST_CASE (
774
+ " FormatUserDefinedTypes" ,
775
+ " [string]" ,
776
+ char ,
777
+ wchar_t ,
778
+ char8_t ,
779
+ char16_t ,
780
+ char32_t )
781
+ {
782
+ using BasicString = fly::BasicString<TestType>;
783
+
784
+ using char_type = typename BasicString::char_type;
785
+
786
+ UserDefinedType u {};
787
+ UserDefinedTypeWithParser p {};
788
+
789
+ CATCH_SECTION (" User-defined types inherit parent's parse method" )
790
+ {
791
+ test_format (FMT (" {:.1s}" ), FMT (" O" ), UserFormattedEnum::One);
792
+ test_format (FMT (" {:.2s}" ), FMT (" On" ), UserFormattedEnum::One);
793
+ test_format (FMT (" {:.3s}" ), FMT (" One" ), UserFormattedEnum::One);
794
+ }
795
+
796
+ CATCH_SECTION (" User-defined types may define a parse method" )
797
+ {
798
+ test_format (FMT (" {}" ), FMT (" false" ), p);
799
+ test_format (FMT (" {:o}" ), FMT (" true" ), p);
800
+ }
801
+
802
+ CATCH_SECTION (" User-defined types with a parse method may report errors" )
803
+ {
804
+ test_format (FMT (" {:x}" ), FMT (" UserDefinedTypeWithParser error!" ), p);
805
+ }
806
+
807
+ CATCH_SECTION (" User-defined types do not need to define a parse method" )
808
+ {
809
+ test_format (FMT (" {}" ), FMT (" UserDefinedType" ), u);
810
+ test_format (FMT (" {0}" ), FMT (" UserDefinedType" ), u);
811
+ test_format (FMT (" {:}" ), FMT (" UserDefinedType" ), u);
812
+ }
813
+
814
+ CATCH_SECTION (" User-defined formatter without a parse method may not have formatting options" )
815
+ {
816
+ test_format (
817
+ FMT (" {:s}" ),
818
+ FMT (" User-defined formatter without a parse method may not have formatting options" ),
819
+ u);
820
+ test_format (
821
+ FMT (" {:.3}" ),
822
+ FMT (" User-defined formatter without a parse method may not have formatting options" ),
823
+ u);
824
+ }
825
+ }
826
+
751
827
#if defined(FLY_COMPILER_DISABLE_CONSTEVAL)
752
828
753
829
// This test is broken up because otherwise it is too large for Windows and a stack overflow occurs.
0 commit comments