Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
fmt
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
fmt
Commits
ade5381f
Commit
ade5381f
authored
Dec 17, 2012
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Preliminary support for custom formatting.
parent
059934fd
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
76 additions
and
15 deletions
+76
-15
format.cc
format.cc
+7
-0
format.h
format.h
+37
-14
format_test.cc
format_test.cc
+32
-1
No files found.
format.cc
View file @
ade5381f
...
...
@@ -433,3 +433,10 @@ void Formatter::DoFormat() {
buffer_
.
append
(
start
,
s
+
1
);
buffer_
.
resize
(
buffer_
.
size
()
-
1
);
// Don't count the terminating zero.
}
void
Formatter
::
Write
(
const
std
::
string
&
s
,
unsigned
width
)
{
char
*
out
=
GrowBuffer
(
std
::
max
<
std
::
size_t
>
(
width
,
s
.
size
()));
std
::
copy
(
s
.
begin
(),
s
.
end
(),
out
);
if
(
width
>
s
.
size
())
std
::
fill_n
(
out
+
s
.
size
(),
width
-
s
.
size
(),
' '
);
}
format.h
View file @
ade5381f
...
...
@@ -148,7 +148,7 @@ class Formatter {
CHAR
,
STRING
,
WSTRING
,
POINTER
,
CUSTOM
};
typedef
void
(
Formatter
::*
FormatFunc
)(
const
void
*
arg
,
int
width
);
typedef
void
(
Formatter
::*
FormatFunc
)(
const
void
*
arg
,
unsigned
width
);
// A format argument.
class
Arg
{
...
...
@@ -236,7 +236,7 @@ class Formatter {
// so it will be alive in the Arg's destructor where Format is called.
// Note that the string object will not necessarily be alive when
// the destructor of ArgInserter is called.
formatter
->
Format
();
formatter
->
CompleteFormatting
();
}
};
...
...
@@ -247,6 +247,7 @@ class Formatter {
int
num_open_braces_
;
friend
class
internal
::
ArgInserter
;
friend
class
ArgFormatter
;
void
Add
(
const
Arg
&
arg
)
{
args_
.
push_back
(
&
arg
);
...
...
@@ -265,7 +266,7 @@ class Formatter {
// Formats an argument of a custom type, such as a user-defined class.
template
<
typename
T
>
void
FormatCustomArg
(
const
void
*
arg
,
int
width
);
void
FormatCustomArg
(
const
void
*
arg
,
unsigned
width
);
unsigned
ParseUInt
(
const
char
*&
s
)
const
;
...
...
@@ -274,7 +275,7 @@ class Formatter {
void
DoFormat
();
void
Format
()
{
void
CompleteFormatting
()
{
if
(
!
format_
)
return
;
DoFormat
();
}
...
...
@@ -301,6 +302,10 @@ class Formatter {
const
char
*
c_str
()
const
{
return
&
buffer_
[
0
];
}
std
::
string
str
()
const
{
return
std
::
string
(
&
buffer_
[
0
],
buffer_
.
size
());
}
// Writes a string to the output buffer padding with spaces if
// necessary to achieve the desired width.
void
Write
(
const
std
::
string
&
s
,
unsigned
width
);
}
;
namespace
internal
{
...
...
@@ -336,7 +341,7 @@ class ArgInserter {
Formatter
*
f
=
formatter_
;
if
(
f
)
{
formatter_
=
0
;
f
->
Format
();
f
->
CompleteFormatting
();
}
return
f
;
}
...
...
@@ -352,14 +357,14 @@ class ArgInserter {
};
static
Formatter
*
Format
(
Proxy
p
)
{
p
.
formatter
->
Format
();
p
.
formatter
->
CompleteFormatting
();
return
p
.
formatter
;
}
public:
~
ArgInserter
()
{
if
(
formatter_
)
formatter_
->
Format
();
formatter_
->
CompleteFormatting
();
}
// Feeds an argument to a formatter.
...
...
@@ -387,16 +392,34 @@ class ArgInserter {
};
}
// ArgFormatter provides access to the format buffer within custom
// Format functions. It is not desirable to pass Formatter to these
// functions because Formatter::operator() is not reentrant and
// therefore can't be used for argument formatting.
class
ArgFormatter
{
private:
Formatter
&
formatter_
;
public:
explicit
ArgFormatter
(
Formatter
&
f
)
:
formatter_
(
f
)
{}
void
Write
(
const
std
::
string
&
s
,
unsigned
width
)
{
formatter_
.
Write
(
s
,
width
);
}
};
// The default formatting function.
template
<
typename
T
>
void
Formatter
::
FormatCustomArg
(
const
void
*
arg
,
int
width
)
{
const
T
&
value
=
*
static_cast
<
const
T
*>
(
arg
);
void
Format
(
ArgFormatter
&
af
,
unsigned
width
,
const
T
&
value
)
{
std
::
ostringstream
os
;
os
<<
value
;
std
::
string
str
(
os
.
str
());
char
*
out
=
GrowBuffer
(
std
::
max
<
std
::
size_t
>
(
width
,
str
.
size
()));
std
::
copy
(
str
.
begin
(),
str
.
end
(),
out
);
if
(
static_cast
<
unsigned
>
(
width
)
>
str
.
size
())
std
::
fill_n
(
out
+
str
.
size
(),
width
-
str
.
size
(),
' '
);
af
.
Write
(
os
.
str
(),
width
);
}
template
<
typename
T
>
void
Formatter
::
FormatCustomArg
(
const
void
*
arg
,
unsigned
width
)
{
ArgFormatter
af
(
*
this
);
Format
(
af
,
width
,
*
static_cast
<
const
T
*>
(
arg
));
}
inline
internal
::
ArgInserter
Formatter
::
operator
()(
const
char
*
format
)
{
...
...
format_test.cc
View file @
ade5381f
...
...
@@ -621,6 +621,27 @@ TEST(FormatterTest, FormatString) {
EXPECT_EQ
(
"test"
,
str
(
Format
(
"{0}"
)
<<
std
::
string
(
"test"
)));
}
TEST
(
FormatterTest
,
Write
)
{
Formatter
format
;
format
.
Write
(
"12"
,
2
);
EXPECT_EQ
(
"12"
,
format
.
str
());
format
.
Write
(
"34"
,
4
);
EXPECT_EQ
(
"1234 "
,
format
.
str
());
format
.
Write
(
"56"
,
0
);
EXPECT_EQ
(
"1234 56"
,
format
.
str
());
}
TEST
(
ArgFormatterTest
,
Write
)
{
Formatter
formatter
;
fmt
::
ArgFormatter
format
(
formatter
);
format
.
Write
(
"12"
,
2
);
EXPECT_EQ
(
"12"
,
formatter
.
str
());
format
.
Write
(
"34"
,
4
);
EXPECT_EQ
(
"1234 "
,
formatter
.
str
());
format
.
Write
(
"56"
,
0
);
EXPECT_EQ
(
"1234 56"
,
formatter
.
str
());
}
class
Date
{
int
year_
,
month_
,
day_
;
public:
...
...
@@ -632,7 +653,7 @@ class Date {
}
};
TEST
(
FormatterTest
,
Format
Custom
)
{
TEST
(
FormatterTest
,
Format
UsingIOStreams
)
{
EXPECT_EQ
(
"a string"
,
str
(
Format
(
"{0}"
)
<<
TestString
(
"a string"
)));
std
::
string
s
=
str
(
fmt
::
Format
(
"The date is {0}"
)
<<
Date
(
2012
,
12
,
9
));
EXPECT_EQ
(
"The date is 2012-12-9"
,
s
);
...
...
@@ -640,6 +661,16 @@ TEST(FormatterTest, FormatCustom) {
CheckUnknownTypes
(
date
,
""
,
"object"
);
}
class
Answer
{};
void
Format
(
fmt
::
ArgFormatter
&
af
,
unsigned
width
,
Answer
)
{
af
.
Write
(
"42"
,
width
);
}
TEST
(
FormatterTest
,
CustomFormat
)
{
EXPECT_EQ
(
"42"
,
str
(
Format
(
"{0}"
)
<<
Answer
()));
}
TEST
(
FormatterTest
,
FormatStringFromSpeedTest
)
{
EXPECT_EQ
(
"1.2340000000:0042:+3.13:str:0x3e8:X:%"
,
str
(
Format
(
"{0:0.10f}:{1:04}:{2:+g}:{3}:{4}:{5}:%"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment