forked from fmtlib/fmt
Allocate large enough buffer to make _ecvt_s happy. Swap the order of template parameters in TempFormatter for convenience.
This commit is contained in:
14
format.h
14
format.h
@@ -191,8 +191,8 @@ inline int SignBit(double value) {
|
|||||||
if (value < 0) return 1;
|
if (value < 0) return 1;
|
||||||
if (value == value) return 0;
|
if (value == value) return 0;
|
||||||
int dec = 0, sign = 0;
|
int dec = 0, sign = 0;
|
||||||
char dummy;
|
char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
|
||||||
_ecvt_s(&dummy, 1, value, 0, &dec, &sign);
|
_ecvt_s(&buffer, sizeof(buffer), value, 0, &dec, &sign);
|
||||||
return sign;
|
return sign;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1155,7 +1155,7 @@ class NoAction {
|
|||||||
Objects of this class normally exist only as temporaries returned
|
Objects of this class normally exist only as temporaries returned
|
||||||
by one of the formatting functions which explains the name.
|
by one of the formatting functions which explains the name.
|
||||||
*/
|
*/
|
||||||
template <typename Char, typename Action = NoAction>
|
template <typename Action = NoAction, typename Char = char>
|
||||||
class TempFormatter : public internal::ArgInserter<Char> {
|
class TempFormatter : public internal::ArgInserter<Char> {
|
||||||
private:
|
private:
|
||||||
BasicFormatter<Char> formatter_;
|
BasicFormatter<Char> formatter_;
|
||||||
@@ -1232,8 +1232,8 @@ class TempFormatter : public internal::ArgInserter<Char> {
|
|||||||
See also `Format String Syntax`_.
|
See also `Format String Syntax`_.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
inline TempFormatter<char> Format(StringRef format) {
|
inline TempFormatter<> Format(StringRef format) {
|
||||||
return TempFormatter<char>(format);
|
return TempFormatter<>(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A formatting action that writes formatted output to stdout.
|
// A formatting action that writes formatted output to stdout.
|
||||||
@@ -1246,8 +1246,8 @@ struct Write {
|
|||||||
// Formats a string and prints it to stdout.
|
// Formats a string and prints it to stdout.
|
||||||
// Example:
|
// Example:
|
||||||
// Print("Elapsed time: {0:.2f} seconds") << 1.23;
|
// Print("Elapsed time: {0:.2f} seconds") << 1.23;
|
||||||
inline TempFormatter<char, Write> Print(StringRef format) {
|
inline TempFormatter<Write> Print(StringRef format) {
|
||||||
return TempFormatter<char, Write>(format);
|
return TempFormatter<Write>(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Throws Exception(message) if format contains '}', otherwise throws
|
// Throws Exception(message) if format contains '}', otherwise throws
|
||||||
|
@@ -1086,7 +1086,7 @@ struct CountCalls {
|
|||||||
TEST(TempFormatterTest, Action) {
|
TEST(TempFormatterTest, Action) {
|
||||||
int num_calls = 0;
|
int num_calls = 0;
|
||||||
{
|
{
|
||||||
fmt::TempFormatter<char, CountCalls> af("test", CountCalls(num_calls));
|
fmt::TempFormatter<CountCalls> af("test", CountCalls(num_calls));
|
||||||
EXPECT_EQ(0, num_calls);
|
EXPECT_EQ(0, num_calls);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(1, num_calls);
|
EXPECT_EQ(1, num_calls);
|
||||||
@@ -1095,7 +1095,7 @@ TEST(TempFormatterTest, Action) {
|
|||||||
TEST(TempFormatterTest, ActionNotCalledOnError) {
|
TEST(TempFormatterTest, ActionNotCalledOnError) {
|
||||||
int num_calls = 0;
|
int num_calls = 0;
|
||||||
{
|
{
|
||||||
typedef fmt::TempFormatter<char, CountCalls> TestFormatter;
|
typedef fmt::TempFormatter<CountCalls> TestFormatter;
|
||||||
EXPECT_THROW(TestFormatter af("{0", CountCalls(num_calls)), FormatError);
|
EXPECT_THROW(TestFormatter af("{0", CountCalls(num_calls)), FormatError);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(0, num_calls);
|
EXPECT_EQ(0, num_calls);
|
||||||
@@ -1108,8 +1108,8 @@ TEST(TempFormatterTest, ActionNotCalledOnError) {
|
|||||||
TEST(TempFormatterTest, ArgLifetime) {
|
TEST(TempFormatterTest, ArgLifetime) {
|
||||||
// The following code is for testing purposes only. It is a definite abuse
|
// The following code is for testing purposes only. It is a definite abuse
|
||||||
// of the API and shouldn't be used in real applications.
|
// of the API and shouldn't be used in real applications.
|
||||||
const fmt::TempFormatter<char> &af = fmt::Format("{0}");
|
const fmt::TempFormatter<> &af = fmt::Format("{0}");
|
||||||
const_cast<fmt::TempFormatter<char>&>(af) << std::string("test");
|
const_cast<fmt::TempFormatter<>&>(af) << std::string("test");
|
||||||
// String object passed as an argument to TempFormatter has
|
// String object passed as an argument to TempFormatter has
|
||||||
// been destroyed, but ArgInserter dtor hasn't been called yet.
|
// been destroyed, but ArgInserter dtor hasn't been called yet.
|
||||||
// But that's OK since the Arg's dtor takes care of this and
|
// But that's OK since the Arg's dtor takes care of this and
|
||||||
@@ -1128,8 +1128,8 @@ struct PrintError {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fmt::TempFormatter<char, PrintError> ReportError(const char *format) {
|
fmt::TempFormatter<PrintError> ReportError(const char *format) {
|
||||||
return fmt::TempFormatter<char, PrintError>(format);
|
return fmt::TempFormatter<PrintError>(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TempFormatterTest, Examples) {
|
TEST(TempFormatterTest, Examples) {
|
||||||
|
Reference in New Issue
Block a user