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
7110b460
Commit
7110b460
authored
Sep 12, 2018
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Optimize default formatting
parent
c8a8464f
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
58 additions
and
44 deletions
+58
-44
include/fmt/format.h
include/fmt/format.h
+45
-32
include/fmt/printf.h
include/fmt/printf.h
+8
-8
test/custom-formatter-test.cc
test/custom-formatter-test.cc
+3
-2
test/format-test.cc
test/format-test.cc
+1
-1
test/ostream-test.cc
test/ostream-test.cc
+1
-1
No files found.
include/fmt/format.h
View file @
7110b460
...
...
@@ -1338,12 +1338,10 @@ FMT_CONSTEXPR void handle_float_type_spec(Char spec, Handler &&handler) {
template
<
typename
Char
,
typename
Handler
>
FMT_CONSTEXPR
void
handle_char_specs
(
const
basic_format_specs
<
Char
>
&
specs
,
Handler
&&
handler
)
{
if
(
specs
.
type
()
&&
specs
.
type
()
!=
'c'
)
{
handler
.
on_int
();
return
;
}
if
(
specs
.
align
()
==
ALIGN_NUMERIC
||
specs
.
flag
(
~
0u
)
!=
0
)
const
basic_format_specs
<
Char
>
*
specs
,
Handler
&&
handler
)
{
if
(
!
specs
)
return
handler
.
on_char
();
if
(
specs
->
type
()
&&
specs
->
type
()
!=
'c'
)
return
handler
.
on_int
();
if
(
specs
->
align
()
==
ALIGN_NUMERIC
||
specs
->
flag
(
~
0u
)
!=
0
)
handler
.
on_error
(
"invalid format specifier for char"
);
handler
.
on_char
();
}
...
...
@@ -1470,7 +1468,7 @@ class arg_formatter_base {
private:
typedef
basic_writer
<
Range
>
writer_type
;
writer_type
writer_
;
format_specs
&
specs_
;
format_specs
*
specs_
;
struct
char_writer
{
char_type
value
;
...
...
@@ -1479,11 +1477,14 @@ class arg_formatter_base {
};
void
write_char
(
char_type
value
)
{
writer_
.
write_padded
(
1
,
specs_
,
char_writer
{
value
});
if
(
specs_
)
writer_
.
write_padded
(
1
,
*
specs_
,
char_writer
{
value
});
else
writer_
.
write
(
value
);
}
void
write_pointer
(
const
void
*
p
)
{
format_specs
specs
=
specs_
;
format_specs
specs
=
specs_
?
*
specs_
:
format_specs
()
;
specs
.
flags_
=
HASH_FLAG
;
specs
.
type_
=
'x'
;
writer_
.
write_int
(
reinterpret_cast
<
uintptr_t
>
(
p
),
specs
);
...
...
@@ -1491,22 +1492,24 @@ class arg_formatter_base {
protected:
writer_type
&
writer
()
{
return
writer_
;
}
format_specs
&
spec
()
{
return
specs_
;
}
format_specs
*
spec
()
{
return
specs_
;
}
iterator
out
()
{
return
writer_
.
out
();
}
void
write
(
bool
value
)
{
writer_
.
write_str
(
string_view
(
value
?
"true"
:
"false"
),
specs_
);
string_view
sv
(
value
?
"true"
:
"false"
);
specs_
?
writer_
.
write_str
(
sv
,
*
specs_
)
:
writer_
.
write
(
sv
);
}
void
write
(
const
char_type
*
value
)
{
if
(
!
value
)
FMT_THROW
(
format_error
(
"string pointer is null"
));
auto
length
=
std
::
char_traits
<
char_type
>::
length
(
value
);
writer_
.
write_str
(
basic_string_view
<
char_type
>
(
value
,
length
),
specs_
);
basic_string_view
<
char_type
>
sv
(
value
,
length
);
specs_
?
writer_
.
write_str
(
sv
,
*
specs_
)
:
writer_
.
write
(
sv
);
}
public:
arg_formatter_base
(
Range
r
,
format_specs
&
s
)
:
writer_
(
r
),
specs_
(
s
)
{}
arg_formatter_base
(
Range
r
,
format_specs
*
s
)
:
writer_
(
r
),
specs_
(
s
)
{}
iterator
operator
()(
monostate
)
{
FMT_ASSERT
(
false
,
"invalid argument type"
);
...
...
@@ -1519,14 +1522,14 @@ class arg_formatter_base {
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
if
(
std
::
is_same
<
T
,
bool
>::
value
)
{
if
(
specs_
.
type_
)
if
(
specs_
&&
specs_
->
type_
)
return
(
*
this
)(
value
?
1
:
0
);
write
(
value
!=
0
);
}
else
if
(
std
::
is_same
<
T
,
char_type
>::
value
)
{
internal
::
handle_char_specs
(
specs_
,
char_spec_handler
(
*
this
,
static_cast
<
char_type
>
(
value
)));
}
else
{
writer_
.
write_int
(
value
,
specs_
);
specs_
?
writer_
.
write_int
(
value
,
*
specs_
)
:
writer_
.
write
(
value
);
}
return
out
();
}
...
...
@@ -1534,7 +1537,7 @@ class arg_formatter_base {
template
<
typename
T
>
typename
std
::
enable_if
<
std
::
is_floating_point
<
T
>::
value
,
iterator
>::
type
operator
()(
T
value
)
{
writer_
.
write_double
(
value
,
specs_
);
writer_
.
write_double
(
value
,
specs_
?
*
specs_
:
format_specs
()
);
return
out
();
}
...
...
@@ -1545,7 +1548,12 @@ class arg_formatter_base {
char_spec_handler
(
arg_formatter_base
&
f
,
char_type
val
)
:
formatter
(
f
),
value
(
val
)
{}
void
on_int
()
{
formatter
.
writer_
.
write_int
(
value
,
formatter
.
specs_
);
}
void
on_int
()
{
if
(
formatter
.
specs_
)
formatter
.
writer_
.
write_int
(
value
,
*
formatter
.
specs_
);
else
formatter
.
writer_
.
write
(
value
);
}
void
on_char
()
{
formatter
.
write_char
(
value
);
}
};
...
...
@@ -1561,19 +1569,26 @@ class arg_formatter_base {
};
iterator
operator
()(
const
char_type
*
value
)
{
if
(
!
specs_
)
return
write
(
value
),
out
();
internal
::
handle_cstring_type_spec
(
specs_
.
type_
,
cstring_spec_handler
(
*
this
,
value
));
specs_
->
type_
,
cstring_spec_handler
(
*
this
,
value
));
return
out
();
}
iterator
operator
()(
basic_string_view
<
char_type
>
value
)
{
internal
::
check_string_type_spec
(
specs_
.
type_
,
internal
::
error_handler
());
writer_
.
write_str
(
value
,
specs_
);
if
(
specs_
)
{
internal
::
check_string_type_spec
(
specs_
->
type_
,
internal
::
error_handler
());
writer_
.
write_str
(
value
,
*
specs_
);
}
else
{
writer_
.
write
(
value
);
}
return
out
();
}
iterator
operator
()(
const
void
*
value
)
{
check_pointer_type_spec
(
specs_
.
type_
,
internal
::
error_handler
());
if
(
specs_
)
check_pointer_type_spec
(
specs_
->
type_
,
internal
::
error_handler
());
write_pointer
(
value
);
return
out
();
}
...
...
@@ -2346,7 +2361,7 @@ class arg_formatter:
*spec* contains format specifier information for standard argument types.
\endrst
*/
arg_formatter
(
context_type
&
ctx
,
format_specs
&
spec
)
explicit
arg_formatter
(
context_type
&
ctx
,
format_specs
*
spec
=
{}
)
:
base
(
Range
(
ctx
.
out
()),
spec
),
ctx_
(
ctx
)
{}
using
base
::
operator
();
...
...
@@ -2500,7 +2515,7 @@ class basic_writer {
auto
&&
it
=
reserve
((
is_negative
?
1
:
0
)
+
num_digits
);
if
(
is_negative
)
*
it
++
=
'-'
;
internal
::
format_decimal
(
it
,
abs_value
,
num_digits
);
i
t
=
i
nternal
::
format_decimal
(
it
,
abs_value
,
num_digits
);
}
// The handle_int_type_spec handler that writes an integer.
...
...
@@ -2775,7 +2790,7 @@ class basic_writer {
void
write
(
wstring_view
value
)
{
internal
::
require_wchar
<
char_type
>
();
auto
&&
it
=
reserve
(
value
.
size
());
it
=
std
::
uninitialized_
copy
(
value
.
begin
(),
value
.
end
(),
it
);
it
=
std
::
copy
(
value
.
begin
(),
value
.
end
(),
it
);
}
template
<
typename
...
FormatSpecs
>
...
...
@@ -3176,7 +3191,7 @@ struct formatter<
break
;
case
internal
:
:
char_type
:
handle_char_specs
(
specs_
,
&
specs_
,
internal
::
char_specs_checker
<
decltype
(
eh
),
decltype
(
type_spec
)
>
(
type_spec
,
eh
));
break
;
...
...
@@ -3211,7 +3226,7 @@ struct formatter<
specs_
.
precision_
,
specs_
.
precision_ref
,
ctx
);
typedef
output_range
<
typename
FormatContext
::
iterator
,
typename
FormatContext
::
char_type
>
range_type
;
return
visit
(
arg_formatter
<
range_type
>
(
ctx
,
specs_
),
return
visit
(
arg_formatter
<
range_type
>
(
ctx
,
&
specs_
),
internal
::
make_arg
<
FormatContext
>
(
val
));
}
...
...
@@ -3272,7 +3287,7 @@ class dynamic_formatter {
checker
.
end_precision
();
typedef
output_range
<
typename
FormatContext
::
iterator
,
typename
FormatContext
::
char_type
>
range
;
visit
(
arg_formatter
<
range
>
(
ctx
,
specs_
),
visit
(
arg_formatter
<
range
>
(
ctx
,
&
specs_
),
internal
::
make_arg
<
FormatContext
>
(
val
));
return
ctx
.
out
();
}
...
...
@@ -3328,10 +3343,8 @@ struct format_handler : internal::error_handler {
void
on_replacement_field
(
const
Char
*
p
)
{
context
.
parse_context
().
advance_to
(
p
);
if
(
visit
(
internal
::
custom_formatter
<
Char
,
Context
>
(
context
),
arg
))
return
;
basic_format_specs
<
Char
>
specs
;
context
.
advance_to
(
visit
(
ArgFormatter
(
context
,
specs
),
arg
));
if
(
!
visit
(
internal
::
custom_formatter
<
Char
,
Context
>
(
context
),
arg
))
context
.
advance_to
(
visit
(
ArgFormatter
(
context
),
arg
));
}
iterator
on_format_specs
(
iterator
it
)
{
...
...
@@ -3347,7 +3360,7 @@ struct format_handler : internal::error_handler {
if
(
*
it
!=
'}'
)
on_error
(
"missing '}' in format string"
);
parse_ctx
.
advance_to
(
pointer_from
(
it
));
context
.
advance_to
(
visit
(
ArgFormatter
(
context
,
specs
),
arg
));
context
.
advance_to
(
visit
(
ArgFormatter
(
context
,
&
specs
),
arg
));
return
it
;
}
...
...
include/fmt/printf.h
View file @
7110b460
...
...
@@ -222,12 +222,12 @@ class printf_arg_formatter:
context_type
&
context_
;
void
write_null_pointer
(
char
)
{
this
->
spec
()
.
type_
=
0
;
this
->
spec
()
->
type_
=
0
;
this
->
write
(
"(nil)"
);
}
void
write_null_pointer
(
wchar_t
)
{
this
->
spec
()
.
type_
=
0
;
this
->
spec
()
->
type_
=
0
;
this
->
write
(
L"(nil)"
);
}
...
...
@@ -243,7 +243,7 @@ class printf_arg_formatter:
*/
printf_arg_formatter
(
internal
::
basic_buffer
<
char_type
>
&
buffer
,
format_specs
&
spec
,
context_type
&
ctx
)
:
base
(
back_insert_range
<
internal
::
basic_buffer
<
char_type
>>
(
buffer
),
spec
),
:
base
(
back_insert_range
<
internal
::
basic_buffer
<
char_type
>>
(
buffer
),
&
spec
),
context_
(
ctx
)
{}
template
<
typename
T
>
...
...
@@ -252,13 +252,13 @@ class printf_arg_formatter:
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
if
(
std
::
is_same
<
T
,
bool
>::
value
)
{
format_specs
&
fmt_spec
=
this
->
spec
();
format_specs
&
fmt_spec
=
*
this
->
spec
();
if
(
fmt_spec
.
type_
!=
's'
)
return
base
::
operator
()(
value
?
1
:
0
);
fmt_spec
.
type_
=
0
;
this
->
write
(
value
!=
0
);
}
else
if
(
std
::
is_same
<
T
,
char_type
>::
value
)
{
format_specs
&
fmt_spec
=
this
->
spec
();
format_specs
&
fmt_spec
=
*
this
->
spec
();
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
return
(
*
this
)(
static_cast
<
int
>
(
value
));
fmt_spec
.
flags_
=
0
;
...
...
@@ -280,7 +280,7 @@ class printf_arg_formatter:
iterator
operator
()(
const
char
*
value
)
{
if
(
value
)
base
::
operator
()(
value
);
else
if
(
this
->
spec
()
.
type_
==
'p'
)
else
if
(
this
->
spec
()
->
type_
==
'p'
)
write_null_pointer
(
char_type
());
else
this
->
write
(
"(null)"
);
...
...
@@ -291,7 +291,7 @@ class printf_arg_formatter:
iterator
operator
()(
const
wchar_t
*
value
)
{
if
(
value
)
base
::
operator
()(
value
);
else
if
(
this
->
spec
()
.
type_
==
'p'
)
else
if
(
this
->
spec
()
->
type_
==
'p'
)
write_null_pointer
(
char_type
());
else
this
->
write
(
L"(null)"
);
...
...
@@ -310,7 +310,7 @@ class printf_arg_formatter:
iterator
operator
()(
const
void
*
value
)
{
if
(
value
)
return
base
::
operator
()(
value
);
this
->
spec
()
.
type_
=
0
;
this
->
spec
()
->
type_
=
0
;
write_null_pointer
(
char_type
());
return
this
->
out
();
}
...
...
test/custom-formatter-test.cc
View file @
7110b460
...
...
@@ -19,14 +19,15 @@ class custom_arg_formatter :
typedef
fmt
::
back_insert_range
<
fmt
::
internal
::
buffer
>
range
;
typedef
fmt
::
arg_formatter
<
range
>
base
;
custom_arg_formatter
(
fmt
::
format_context
&
ctx
,
fmt
::
format_specs
&
s
)
custom_arg_formatter
(
fmt
::
format_context
&
ctx
,
fmt
::
format_specs
*
s
=
FMT_NULL
)
:
base
(
ctx
,
s
)
{}
using
base
::
operator
();
iterator
operator
()(
double
value
)
{
// Comparing a float to 0.0 is safe
if
(
round
(
value
*
pow
(
10
,
spec
()
.
precision
()))
==
0.0
)
if
(
round
(
value
*
pow
(
10
,
spec
()
->
precision
()))
==
0.0
)
value
=
0
;
return
base
::
operator
()(
value
);
}
...
...
test/format-test.cc
View file @
7110b460
...
...
@@ -1471,7 +1471,7 @@ class mock_arg_formatter:
typedef
fmt
::
internal
::
arg_formatter_base
<
buffer_range
>
base
;
typedef
buffer_range
range
;
mock_arg_formatter
(
fmt
::
format_context
&
ctx
,
fmt
::
format_specs
&
s
)
mock_arg_formatter
(
fmt
::
format_context
&
ctx
,
fmt
::
format_specs
*
s
=
FMT_NULL
)
:
base
(
fmt
::
internal
::
get_container
(
ctx
.
out
()),
s
)
{
EXPECT_CALL
(
*
this
,
call
(
42
));
}
...
...
test/ostream-test.cc
View file @
7110b460
...
...
@@ -50,7 +50,7 @@ typedef fmt::back_insert_range<fmt::internal::buffer> range;
struct
test_arg_formatter
:
fmt
::
arg_formatter
<
range
>
{
test_arg_formatter
(
fmt
::
format_context
&
ctx
,
fmt
::
format_specs
&
s
)
:
fmt
::
arg_formatter
<
range
>
(
ctx
,
s
)
{}
:
fmt
::
arg_formatter
<
range
>
(
ctx
,
&
s
)
{}
};
TEST
(
OStreamTest
,
CustomArg
)
{
...
...
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