@@ -65,33 +65,42 @@ std::string ToBaseString(const T& value) {
6565 return ToStringHelper::BaseConvert<BASE_BITS>(value);
6666}
6767
68- inline std::string SPrintFImpl (const char * format) {
69- const char * p = strchr (format, ' %' );
70- if (p == nullptr ) [[unlikely]]
71- return format;
72- CHECK_EQ (p[1 ], ' %' ); // Only '%%' allowed when there are no arguments.
68+ inline std::string SPrintFImpl (std::string_view format) {
69+ auto offset = format.find (' %' );
70+ if (offset == std::string_view::npos) return std::string (format);
71+ CHECK_LT (offset + 1 , format.size ());
72+ CHECK_EQ (format[offset + 1 ],
73+ ' %' ); // Only '%%' allowed when there are no arguments.
7374
74- return std::string (format, p + 1 ) + SPrintFImpl (p + 2 );
75+ return std::string (format.substr (0 , offset + 1 )) +
76+ SPrintFImpl (format.substr (offset + 2 ));
7577}
7678
7779template <typename Arg, typename ... Args>
7880std::string COLD_NOINLINE SPrintFImpl ( // NOLINT(runtime/string)
79- const char * format, Arg&& arg, Args&&... args) {
80- const char * p = strchr (format, ' %' );
81- CHECK_NOT_NULL (p); // If you hit this, you passed in too many arguments.
82- std::string ret (format, p);
81+ std::string_view format,
82+ Arg&& arg,
83+ Args&&... args) {
84+ auto offset = format.find (' %' );
85+ CHECK_NE (offset, std::string_view::npos); // If you hit this, you passed in
86+ // too many arguments.
87+ std::string ret (format.substr (0 , offset));
8388 // Ignore long / size_t modifiers
84- while (strchr (" lz" , *++p) != nullptr ) {}
85- switch (*p) {
89+ while (++offset < format.size () &&
90+ (format[offset] == ' l' || format[offset] == ' z' )) {
91+ }
92+ switch (offset == format.size () ? ' \0 ' : format[offset]) {
8693 case ' %' : {
87- return ret + ' %' + SPrintFImpl (p + 1 ,
88- std::forward<Arg>(arg),
89- std::forward<Args>(args)...);
94+ return ret + ' %' +
95+ SPrintFImpl (format.substr (offset + 1 ),
96+ std::forward<Arg>(arg),
97+ std::forward<Args>(args)...);
9098 }
9199 default : {
92- return ret + ' %' + SPrintFImpl (p,
93- std::forward<Arg>(arg),
94- std::forward<Args>(args)...);
100+ return ret + ' %' +
101+ SPrintFImpl (format.substr (offset),
102+ std::forward<Arg>(arg),
103+ std::forward<Args>(args)...);
95104 }
96105 case ' d' :
97106 case ' i' :
@@ -120,17 +129,21 @@ std::string COLD_NOINLINE SPrintFImpl( // NOLINT(runtime/string)
120129 break ;
121130 }
122131 }
123- return ret + SPrintFImpl (p + 1 , std::forward<Args>(args)...);
132+ return ret +
133+ SPrintFImpl (format.substr (offset + 1 ), std::forward<Args>(args)...);
124134}
125135
126136template <typename ... Args>
127137std::string COLD_NOINLINE SPrintF ( // NOLINT(runtime/string)
128- const char * format, Args&&... args) {
138+ std::string_view format,
139+ Args&&... args) {
129140 return SPrintFImpl (format, std::forward<Args>(args)...);
130141}
131142
132143template <typename ... Args>
133- void COLD_NOINLINE FPrintF (FILE* file, const char * format, Args&&... args) {
144+ void COLD_NOINLINE FPrintF (FILE* file,
145+ std::string_view format,
146+ Args&&... args) {
134147 FWrite (file, SPrintF (format, std::forward<Args>(args)...));
135148}
136149
0 commit comments