@@ -65,33 +65,42 @@ std::string ToBaseString(const T& value) {
65
65
return ToStringHelper::BaseConvert<BASE_BITS>(value);
66
66
}
67
67
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.
73
74
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 ));
75
77
}
76
78
77
79
template <typename Arg, typename ... Args>
78
80
std::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));
83
88
// 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]) {
86
93
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)...);
90
98
}
91
99
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)...);
95
104
}
96
105
case ' d' :
97
106
case ' i' :
@@ -120,17 +129,21 @@ std::string COLD_NOINLINE SPrintFImpl( // NOLINT(runtime/string)
120
129
break ;
121
130
}
122
131
}
123
- return ret + SPrintFImpl (p + 1 , std::forward<Args>(args)...);
132
+ return ret +
133
+ SPrintFImpl (format.substr (offset + 1 ), std::forward<Args>(args)...);
124
134
}
125
135
126
136
template <typename ... Args>
127
137
std::string COLD_NOINLINE SPrintF ( // NOLINT(runtime/string)
128
- const char * format, Args&&... args) {
138
+ std::string_view format,
139
+ Args&&... args) {
129
140
return SPrintFImpl (format, std::forward<Args>(args)...);
130
141
}
131
142
132
143
template <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) {
134
147
FWrite (file, SPrintF (format, std::forward<Args>(args)...));
135
148
}
136
149
0 commit comments