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
5488d0b5
Commit
5488d0b5
authored
Jul 07, 2019
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
spec -> specs
parent
e4f84ee1
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
138 additions
and
150 deletions
+138
-150
include/fmt/chrono.h
include/fmt/chrono.h
+7
-7
include/fmt/format-inl.h
include/fmt/format-inl.h
+7
-7
include/fmt/format.h
include/fmt/format.h
+70
-83
include/fmt/printf.h
include/fmt/printf.h
+50
-49
test/custom-formatter-test.cc
test/custom-formatter-test.cc
+1
-1
test/printf-test.cc
test/printf-test.cc
+3
-3
No files found.
include/fmt/chrono.h
View file @
5488d0b5
...
@@ -715,7 +715,7 @@ struct chrono_formatter {
...
@@ -715,7 +715,7 @@ struct chrono_formatter {
template
<
typename
Rep
,
typename
Period
,
typename
Char
>
template
<
typename
Rep
,
typename
Period
,
typename
Char
>
struct
formatter
<
std
::
chrono
::
duration
<
Rep
,
Period
>
,
Char
>
{
struct
formatter
<
std
::
chrono
::
duration
<
Rep
,
Period
>
,
Char
>
{
private:
private:
basic_format_specs
<
Char
>
spec
;
basic_format_specs
<
Char
>
spec
s
;
int
precision
;
int
precision
;
typedef
internal
::
arg_ref
<
Char
>
arg_ref_type
;
typedef
internal
::
arg_ref
<
Char
>
arg_ref_type
;
arg_ref_type
width_ref
;
arg_ref_type
width_ref
;
...
@@ -744,9 +744,9 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
...
@@ -744,9 +744,9 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
}
}
void
on_error
(
const
char
*
msg
)
{
FMT_THROW
(
format_error
(
msg
));
}
void
on_error
(
const
char
*
msg
)
{
FMT_THROW
(
format_error
(
msg
));
}
void
on_fill
(
Char
fill
)
{
f
.
spec
.
fill
[
0
]
=
fill
;
}
void
on_fill
(
Char
fill
)
{
f
.
spec
s
.
fill
[
0
]
=
fill
;
}
void
on_align
(
align_t
align
)
{
f
.
spec
.
align
=
align
;
}
void
on_align
(
align_t
align
)
{
f
.
spec
s
.
align
=
align
;
}
void
on_width
(
unsigned
width
)
{
f
.
spec
.
width
=
width
;
}
void
on_width
(
unsigned
width
)
{
f
.
spec
s
.
width
=
width
;
}
void
on_precision
(
unsigned
precision
)
{
f
.
precision
=
precision
;
}
void
on_precision
(
unsigned
precision
)
{
f
.
precision
=
precision
;
}
void
end_precision
()
{}
void
end_precision
()
{}
...
@@ -784,7 +784,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
...
@@ -784,7 +784,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
}
}
public:
public:
formatter
()
:
spec
(),
precision
(
-
1
)
{}
formatter
()
:
precision
(
-
1
)
{}
FMT_CONSTEXPR
auto
parse
(
basic_parse_context
<
Char
>&
ctx
)
FMT_CONSTEXPR
auto
parse
(
basic_parse_context
<
Char
>&
ctx
)
->
decltype
(
ctx
.
begin
())
{
->
decltype
(
ctx
.
begin
())
{
...
@@ -804,7 +804,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
...
@@ -804,7 +804,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
using
range
=
internal
::
output_range
<
decltype
(
ctx
.
out
()),
Char
>
;
using
range
=
internal
::
output_range
<
decltype
(
ctx
.
out
()),
Char
>
;
internal
::
basic_writer
<
range
>
w
(
range
(
ctx
.
out
()));
internal
::
basic_writer
<
range
>
w
(
range
(
ctx
.
out
()));
internal
::
handle_dynamic_spec
<
internal
::
width_checker
>
(
internal
::
handle_dynamic_spec
<
internal
::
width_checker
>
(
spec
.
width
,
width_ref
,
ctx
,
format_str
.
begin
());
spec
s
.
width
,
width_ref
,
ctx
,
format_str
.
begin
());
internal
::
handle_dynamic_spec
<
internal
::
precision_checker
>
(
internal
::
handle_dynamic_spec
<
internal
::
precision_checker
>
(
precision
,
precision_ref
,
ctx
,
format_str
.
begin
());
precision
,
precision_ref
,
ctx
,
format_str
.
begin
());
if
(
begin
==
end
||
*
begin
==
'}'
)
{
if
(
begin
==
end
||
*
begin
==
'}'
)
{
...
@@ -816,7 +816,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
...
@@ -816,7 +816,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
f
.
precision
=
precision
;
f
.
precision
=
precision
;
parse_chrono_format
(
begin
,
end
,
f
);
parse_chrono_format
(
begin
,
end
,
f
);
}
}
w
.
write
(
buf
.
data
(),
buf
.
size
(),
spec
);
w
.
write
(
buf
.
data
(),
buf
.
size
(),
spec
s
);
return
w
.
out
();
return
w
.
out
();
}
}
};
};
...
...
include/fmt/format-inl.h
View file @
5488d0b5
...
@@ -754,7 +754,7 @@ FMT_API bool grisu_format(Double value, buffer<char>& buf, int precision,
...
@@ -754,7 +754,7 @@ FMT_API bool grisu_format(Double value, buffer<char>& buf, int precision,
template
<
typename
Double
>
template
<
typename
Double
>
char
*
sprintf_format
(
Double
value
,
internal
::
buffer
<
char
>&
buf
,
char
*
sprintf_format
(
Double
value
,
internal
::
buffer
<
char
>&
buf
,
core_format_specs
spec
)
{
core_format_specs
spec
s
)
{
// Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
// Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
FMT_ASSERT
(
buf
.
capacity
()
!=
0
,
"empty buffer"
);
FMT_ASSERT
(
buf
.
capacity
()
!=
0
,
"empty buffer"
);
...
@@ -763,14 +763,14 @@ char* sprintf_format(Double value, internal::buffer<char>& buf,
...
@@ -763,14 +763,14 @@ char* sprintf_format(Double value, internal::buffer<char>& buf,
char
format
[
max_format_size
];
char
format
[
max_format_size
];
char
*
format_ptr
=
format
;
char
*
format_ptr
=
format
;
*
format_ptr
++
=
'%'
;
*
format_ptr
++
=
'%'
;
if
(
spec
.
alt
||
!
spec
.
type
)
*
format_ptr
++
=
'#'
;
if
(
spec
s
.
alt
||
!
specs
.
type
)
*
format_ptr
++
=
'#'
;
if
(
spec
.
precision
>=
0
)
{
if
(
spec
s
.
precision
>=
0
)
{
*
format_ptr
++
=
'.'
;
*
format_ptr
++
=
'.'
;
*
format_ptr
++
=
'*'
;
*
format_ptr
++
=
'*'
;
}
}
if
(
std
::
is_same
<
Double
,
long
double
>::
value
)
*
format_ptr
++
=
'L'
;
if
(
std
::
is_same
<
Double
,
long
double
>::
value
)
*
format_ptr
++
=
'L'
;
char
type
=
spec
.
type
;
char
type
=
spec
s
.
type
;
if
(
type
==
'%'
)
if
(
type
==
'%'
)
type
=
'f'
;
type
=
'f'
;
...
@@ -792,18 +792,18 @@ char* sprintf_format(Double value, internal::buffer<char>& buf,
...
@@ -792,18 +792,18 @@ char* sprintf_format(Double value, internal::buffer<char>& buf,
std
::
size_t
buffer_size
=
buf
.
capacity
();
std
::
size_t
buffer_size
=
buf
.
capacity
();
start
=
&
buf
[
0
];
start
=
&
buf
[
0
];
int
result
=
int
result
=
format_float
(
start
,
buffer_size
,
format
,
spec
.
precision
,
value
);
format_float
(
start
,
buffer_size
,
format
,
spec
s
.
precision
,
value
);
if
(
result
>=
0
)
{
if
(
result
>=
0
)
{
unsigned
n
=
internal
::
to_unsigned
(
result
);
unsigned
n
=
internal
::
to_unsigned
(
result
);
if
(
n
<
buf
.
capacity
())
{
if
(
n
<
buf
.
capacity
())
{
// Find the decimal point.
// Find the decimal point.
auto
p
=
buf
.
data
(),
end
=
p
+
n
;
auto
p
=
buf
.
data
(),
end
=
p
+
n
;
if
(
*
p
==
'+'
||
*
p
==
'-'
)
++
p
;
if
(
*
p
==
'+'
||
*
p
==
'-'
)
++
p
;
if
(
spec
.
type
!=
'a'
&&
spec
.
type
!=
'A'
)
{
if
(
spec
s
.
type
!=
'a'
&&
specs
.
type
!=
'A'
)
{
while
(
p
<
end
&&
*
p
>=
'0'
&&
*
p
<=
'9'
)
++
p
;
while
(
p
<
end
&&
*
p
>=
'0'
&&
*
p
<=
'9'
)
++
p
;
if
(
p
<
end
&&
*
p
!=
'e'
&&
*
p
!=
'E'
)
{
if
(
p
<
end
&&
*
p
!=
'e'
&&
*
p
!=
'E'
)
{
decimal_point_pos
=
p
;
decimal_point_pos
=
p
;
if
(
!
spec
.
type
)
{
if
(
!
spec
s
.
type
)
{
// Keep only one trailing zero after the decimal point.
// Keep only one trailing zero after the decimal point.
++
p
;
++
p
;
if
(
*
p
==
'0'
)
++
p
;
if
(
*
p
==
'0'
)
++
p
;
...
...
include/fmt/format.h
View file @
5488d0b5
This diff is collapsed.
Click to expand it.
include/fmt/printf.h
View file @
5488d0b5
...
@@ -151,16 +151,16 @@ template <typename Char> class printf_width_handler {
...
@@ -151,16 +151,16 @@ template <typename Char> class printf_width_handler {
private:
private:
typedef
basic_format_specs
<
Char
>
format_specs
;
typedef
basic_format_specs
<
Char
>
format_specs
;
format_specs
&
spec_
;
format_specs
&
spec
s
_
;
public:
public:
explicit
printf_width_handler
(
format_specs
&
spec
)
:
spec_
(
spec
)
{}
explicit
printf_width_handler
(
format_specs
&
spec
s
)
:
specs_
(
specs
)
{}
template
<
typename
T
,
FMT_ENABLE_IF
(
std
::
is_integral
<
T
>
::
value
)
>
template
<
typename
T
,
FMT_ENABLE_IF
(
std
::
is_integral
<
T
>
::
value
)
>
unsigned
operator
()(
T
value
)
{
unsigned
operator
()(
T
value
)
{
auto
width
=
static_cast
<
uint32_or_64_t
<
T
>>
(
value
);
auto
width
=
static_cast
<
uint32_or_64_t
<
T
>>
(
value
);
if
(
internal
::
is_negative
(
value
))
{
if
(
internal
::
is_negative
(
value
))
{
spec_
.
align
=
align
::
left
;
spec
s
_
.
align
=
align
::
left
;
width
=
0
-
width
;
width
=
0
-
width
;
}
}
unsigned
int_max
=
std
::
numeric_limits
<
int
>::
max
();
unsigned
int_max
=
std
::
numeric_limits
<
int
>::
max
();
...
@@ -213,12 +213,12 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
...
@@ -213,12 +213,12 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
context_type
&
context_
;
context_type
&
context_
;
void
write_null_pointer
(
char
)
{
void
write_null_pointer
(
char
)
{
this
->
spec
()
->
type
=
0
;
this
->
spec
s
()
->
type
=
0
;
this
->
write
(
"(nil)"
);
this
->
write
(
"(nil)"
);
}
}
void
write_null_pointer
(
wchar_t
)
{
void
write_null_pointer
(
wchar_t
)
{
this
->
spec
()
->
type
=
0
;
this
->
spec
s
()
->
type
=
0
;
this
->
write
(
L"(nil)"
);
this
->
write
(
L"(nil)"
);
}
}
...
@@ -228,29 +228,29 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
...
@@ -228,29 +228,29 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
/**
/**
\rst
\rst
Constructs an argument formatter object.
Constructs an argument formatter object.
*buffer* is a reference to the output buffer and *spec* contains format
*buffer* is a reference to the output buffer and *spec
s
* contains format
specifier information for standard argument types.
specifier information for standard argument types.
\endrst
\endrst
*/
*/
printf_arg_formatter
(
iterator
iter
,
format_specs
&
spec
,
context_type
&
ctx
)
printf_arg_formatter
(
iterator
iter
,
format_specs
&
spec
s
,
context_type
&
ctx
)
:
base
(
Range
(
iter
),
&
spec
,
internal
::
locale_ref
()),
context_
(
ctx
)
{}
:
base
(
Range
(
iter
),
&
spec
s
,
internal
::
locale_ref
()),
context_
(
ctx
)
{}
template
<
typename
T
,
FMT_ENABLE_IF
(
std
::
is_integral
<
T
>
::
value
)
>
template
<
typename
T
,
FMT_ENABLE_IF
(
std
::
is_integral
<
T
>
::
value
)
>
iterator
operator
()(
T
value
)
{
iterator
operator
()(
T
value
)
{
// MSVC2013 fails to compile separate overloads for bool and char_type so
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
// use std::is_same instead.
if
(
std
::
is_same
<
T
,
bool
>::
value
)
{
if
(
std
::
is_same
<
T
,
bool
>::
value
)
{
format_specs
&
fmt_spec
=
*
this
->
spec
();
format_specs
&
fmt_spec
s
=
*
this
->
specs
();
if
(
fmt_spec
.
type
!=
's'
)
return
base
::
operator
()(
value
?
1
:
0
);
if
(
fmt_spec
s
.
type
!=
's'
)
return
base
::
operator
()(
value
?
1
:
0
);
fmt_spec
.
type
=
0
;
fmt_spec
s
.
type
=
0
;
this
->
write
(
value
!=
0
);
this
->
write
(
value
!=
0
);
}
else
if
(
std
::
is_same
<
T
,
char_type
>::
value
)
{
}
else
if
(
std
::
is_same
<
T
,
char_type
>::
value
)
{
format_specs
&
fmt_spec
=
*
this
->
spec
();
format_specs
&
fmt_spec
s
=
*
this
->
specs
();
if
(
fmt_spec
.
type
&&
fmt_spec
.
type
!=
'c'
)
if
(
fmt_spec
s
.
type
&&
fmt_specs
.
type
!=
'c'
)
return
(
*
this
)(
static_cast
<
int
>
(
value
));
return
(
*
this
)(
static_cast
<
int
>
(
value
));
fmt_spec
.
sign
=
sign
::
none
;
fmt_spec
s
.
sign
=
sign
::
none
;
fmt_spec
.
alt
=
false
;
fmt_spec
s
.
alt
=
false
;
fmt_spec
.
align
=
align
::
right
;
fmt_spec
s
.
align
=
align
::
right
;
return
base
::
operator
()(
value
);
return
base
::
operator
()(
value
);
}
else
{
}
else
{
return
base
::
operator
()(
value
);
return
base
::
operator
()(
value
);
...
@@ -267,7 +267,7 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
...
@@ -267,7 +267,7 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
iterator
operator
()(
const
char
*
value
)
{
iterator
operator
()(
const
char
*
value
)
{
if
(
value
)
if
(
value
)
base
::
operator
()(
value
);
base
::
operator
()(
value
);
else
if
(
this
->
spec
()
->
type
==
'p'
)
else
if
(
this
->
spec
s
()
->
type
==
'p'
)
write_null_pointer
(
char_type
());
write_null_pointer
(
char_type
());
else
else
this
->
write
(
"(null)"
);
this
->
write
(
"(null)"
);
...
@@ -278,7 +278,7 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
...
@@ -278,7 +278,7 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
iterator
operator
()(
const
wchar_t
*
value
)
{
iterator
operator
()(
const
wchar_t
*
value
)
{
if
(
value
)
if
(
value
)
base
::
operator
()(
value
);
base
::
operator
()(
value
);
else
if
(
this
->
spec
()
->
type
==
'p'
)
else
if
(
this
->
spec
s
()
->
type
==
'p'
)
write_null_pointer
(
char_type
());
write_null_pointer
(
char_type
());
else
else
this
->
write
(
L"(null)"
);
this
->
write
(
L"(null)"
);
...
@@ -294,7 +294,7 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
...
@@ -294,7 +294,7 @@ class printf_arg_formatter : public internal::arg_formatter_base<Range> {
/** Formats a pointer. */
/** Formats a pointer. */
iterator
operator
()(
const
void
*
value
)
{
iterator
operator
()(
const
void
*
value
)
{
if
(
value
)
return
base
::
operator
()(
value
);
if
(
value
)
return
base
::
operator
()(
value
);
this
->
spec
()
->
type
=
0
;
this
->
spec
s
()
->
type
=
0
;
write_null_pointer
(
char_type
());
write_null_pointer
(
char_type
());
return
this
->
out
();
return
this
->
out
();
}
}
...
@@ -334,14 +334,15 @@ template <typename OutputIt, typename Char> class basic_printf_context {
...
@@ -334,14 +334,15 @@ template <typename OutputIt, typename Char> class basic_printf_context {
basic_format_args
<
basic_printf_context
>
args_
;
basic_format_args
<
basic_printf_context
>
args_
;
basic_parse_context
<
Char
>
parse_ctx_
;
basic_parse_context
<
Char
>
parse_ctx_
;
static
void
parse_flags
(
format_specs
&
spec
,
const
Char
*&
it
,
const
Char
*
end
);
static
void
parse_flags
(
format_specs
&
specs
,
const
Char
*&
it
,
const
Char
*
end
);
// Returns the argument with specified index or, if arg_index is equal
// Returns the argument with specified index or, if arg_index is equal
// to the maximum unsigned value, the next argument.
// to the maximum unsigned value, the next argument.
format_arg
get_arg
(
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
());
format_arg
get_arg
(
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
());
// Parses argument index, flags and width and returns the argument index.
// Parses argument index, flags and width and returns the argument index.
unsigned
parse_header
(
const
Char
*&
it
,
const
Char
*
end
,
format_specs
&
spec
);
unsigned
parse_header
(
const
Char
*&
it
,
const
Char
*
end
,
format_specs
&
spec
s
);
public:
public:
/**
/**
...
@@ -373,25 +374,25 @@ template <typename OutputIt, typename Char> class basic_printf_context {
...
@@ -373,25 +374,25 @@ template <typename OutputIt, typename Char> class basic_printf_context {
};
};
template
<
typename
OutputIt
,
typename
Char
>
template
<
typename
OutputIt
,
typename
Char
>
void
basic_printf_context
<
OutputIt
,
Char
>::
parse_flags
(
format_specs
&
spec
,
void
basic_printf_context
<
OutputIt
,
Char
>::
parse_flags
(
format_specs
&
spec
s
,
const
Char
*&
it
,
const
Char
*&
it
,
const
Char
*
end
)
{
const
Char
*
end
)
{
for
(;
it
!=
end
;
++
it
)
{
for
(;
it
!=
end
;
++
it
)
{
switch
(
*
it
)
{
switch
(
*
it
)
{
case
'-'
:
case
'-'
:
spec
.
align
=
align
::
left
;
spec
s
.
align
=
align
::
left
;
break
;
break
;
case
'+'
:
case
'+'
:
spec
.
sign
=
sign
::
plus
;
spec
s
.
sign
=
sign
::
plus
;
break
;
break
;
case
'0'
:
case
'0'
:
spec
.
fill
[
0
]
=
'0'
;
spec
s
.
fill
[
0
]
=
'0'
;
break
;
break
;
case
' '
:
case
' '
:
spec
.
sign
=
sign
::
space
;
spec
s
.
sign
=
sign
::
space
;
break
;
break
;
case
'#'
:
case
'#'
:
spec
.
alt
=
true
;
spec
s
.
alt
=
true
;
break
;
break
;
default:
default:
return
;
return
;
...
@@ -411,7 +412,7 @@ basic_printf_context<OutputIt, Char>::get_arg(unsigned arg_index) {
...
@@ -411,7 +412,7 @@ basic_printf_context<OutputIt, Char>::get_arg(unsigned arg_index) {
template
<
typename
OutputIt
,
typename
Char
>
template
<
typename
OutputIt
,
typename
Char
>
unsigned
basic_printf_context
<
OutputIt
,
Char
>::
parse_header
(
unsigned
basic_printf_context
<
OutputIt
,
Char
>::
parse_header
(
const
Char
*&
it
,
const
Char
*
end
,
format_specs
&
spec
)
{
const
Char
*&
it
,
const
Char
*
end
,
format_specs
&
spec
s
)
{
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
();
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
();
char_type
c
=
*
it
;
char_type
c
=
*
it
;
if
(
c
>=
'0'
&&
c
<=
'9'
)
{
if
(
c
>=
'0'
&&
c
<=
'9'
)
{
...
@@ -423,25 +424,25 @@ unsigned basic_printf_context<OutputIt, Char>::parse_header(
...
@@ -423,25 +424,25 @@ unsigned basic_printf_context<OutputIt, Char>::parse_header(
++
it
;
++
it
;
arg_index
=
value
;
arg_index
=
value
;
}
else
{
}
else
{
if
(
c
==
'0'
)
spec
.
fill
[
0
]
=
'0'
;
if
(
c
==
'0'
)
spec
s
.
fill
[
0
]
=
'0'
;
if
(
value
!=
0
)
{
if
(
value
!=
0
)
{
// Nonzero value means that we parsed width and don't need to
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
// parse it or flags again, so return now.
spec
.
width
=
value
;
spec
s
.
width
=
value
;
return
arg_index
;
return
arg_index
;
}
}
}
}
}
}
parse_flags
(
spec
,
it
,
end
);
parse_flags
(
spec
s
,
it
,
end
);
// Parse width.
// Parse width.
if
(
it
!=
end
)
{
if
(
it
!=
end
)
{
if
(
*
it
>=
'0'
&&
*
it
<=
'9'
)
{
if
(
*
it
>=
'0'
&&
*
it
<=
'9'
)
{
internal
::
error_handler
eh
;
internal
::
error_handler
eh
;
spec
.
width
=
parse_nonnegative_int
(
it
,
end
,
eh
);
spec
s
.
width
=
parse_nonnegative_int
(
it
,
end
,
eh
);
}
else
if
(
*
it
==
'*'
)
{
}
else
if
(
*
it
==
'*'
)
{
++
it
;
++
it
;
spec
.
width
=
visit_format_arg
(
spec
s
.
width
=
visit_format_arg
(
internal
::
printf_width_handler
<
char_type
>
(
spec
),
get_arg
());
internal
::
printf_width_handler
<
char_type
>
(
spec
s
),
get_arg
());
}
}
}
}
return
arg_index
;
return
arg_index
;
...
@@ -464,11 +465,11 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
...
@@ -464,11 +465,11 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
}
}
out
=
std
::
copy
(
start
,
it
-
1
,
out
);
out
=
std
::
copy
(
start
,
it
-
1
,
out
);
format_specs
spec
;
format_specs
spec
s
;
spec
.
align
=
align
::
right
;
spec
s
.
align
=
align
::
right
;
// Parse argument index, flags and width.
// Parse argument index, flags and width.
unsigned
arg_index
=
parse_header
(
it
,
end
,
spec
);
unsigned
arg_index
=
parse_header
(
it
,
end
,
spec
s
);
// Parse precision.
// Parse precision.
if
(
it
!=
end
&&
*
it
==
'.'
)
{
if
(
it
!=
end
&&
*
it
==
'.'
)
{
...
@@ -476,24 +477,24 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
...
@@ -476,24 +477,24 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
c
=
it
!=
end
?
*
it
:
0
;
c
=
it
!=
end
?
*
it
:
0
;
if
(
'0'
<=
c
&&
c
<=
'9'
)
{
if
(
'0'
<=
c
&&
c
<=
'9'
)
{
internal
::
error_handler
eh
;
internal
::
error_handler
eh
;
spec
.
precision
=
static_cast
<
int
>
(
parse_nonnegative_int
(
it
,
end
,
eh
));
spec
s
.
precision
=
static_cast
<
int
>
(
parse_nonnegative_int
(
it
,
end
,
eh
));
}
else
if
(
c
==
'*'
)
{
}
else
if
(
c
==
'*'
)
{
++
it
;
++
it
;
spec
.
precision
=
spec
s
.
precision
=
visit_format_arg
(
internal
::
printf_precision_handler
(),
get_arg
());
visit_format_arg
(
internal
::
printf_precision_handler
(),
get_arg
());
}
else
{
}
else
{
spec
.
precision
=
0
;
spec
s
.
precision
=
0
;
}
}
}
}
format_arg
arg
=
get_arg
(
arg_index
);
format_arg
arg
=
get_arg
(
arg_index
);
if
(
spec
.
alt
&&
visit_format_arg
(
internal
::
is_zero_int
(),
arg
))
if
(
spec
s
.
alt
&&
visit_format_arg
(
internal
::
is_zero_int
(),
arg
))
spec
.
alt
=
false
;
spec
s
.
alt
=
false
;
if
(
spec
.
fill
[
0
]
==
'0'
)
{
if
(
spec
s
.
fill
[
0
]
==
'0'
)
{
if
(
arg
.
is_arithmetic
())
if
(
arg
.
is_arithmetic
())
spec
.
align
=
align
::
numeric
;
spec
s
.
align
=
align
::
numeric
;
else
else
spec
.
fill
[
0
]
=
' '
;
// Ignore '0' flag for non-numeric types.
spec
s
.
fill
[
0
]
=
' '
;
// Ignore '0' flag for non-numeric types.
}
}
// Parse length and convert the argument to the required type.
// Parse length and convert the argument to the required type.
...
@@ -539,13 +540,13 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
...
@@ -539,13 +540,13 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
// Parse type.
// Parse type.
if
(
it
==
end
)
FMT_THROW
(
format_error
(
"invalid format string"
));
if
(
it
==
end
)
FMT_THROW
(
format_error
(
"invalid format string"
));
spec
.
type
=
static_cast
<
char
>
(
*
it
++
);
spec
s
.
type
=
static_cast
<
char
>
(
*
it
++
);
if
(
arg
.
is_integral
())
{
if
(
arg
.
is_integral
())
{
// Normalize type.
// Normalize type.
switch
(
spec
.
type
)
{
switch
(
spec
s
.
type
)
{
case
'i'
:
case
'i'
:
case
'u'
:
case
'u'
:
spec
.
type
=
'd'
;
spec
s
.
type
=
'd'
;
break
;
break
;
case
'c'
:
case
'c'
:
visit_format_arg
(
internal
::
char_converter
<
basic_printf_context
>
(
arg
),
visit_format_arg
(
internal
::
char_converter
<
basic_printf_context
>
(
arg
),
...
@@ -557,7 +558,7 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
...
@@ -557,7 +558,7 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
start
=
it
;
start
=
it
;
// Format argument.
// Format argument.
visit_format_arg
(
ArgFormatter
(
out
,
spec
,
*
this
),
arg
);
visit_format_arg
(
ArgFormatter
(
out
,
spec
s
,
*
this
),
arg
);
}
}
return
std
::
copy
(
start
,
it
,
out
);
return
std
::
copy
(
start
,
it
,
out
);
}
}
...
...
test/custom-formatter-test.cc
View file @
5488d0b5
...
@@ -32,7 +32,7 @@ class custom_arg_formatter
...
@@ -32,7 +32,7 @@ class custom_arg_formatter
iterator
operator
()(
double
value
)
{
iterator
operator
()(
double
value
)
{
// Comparing a float to 0.0 is safe.
// Comparing a float to 0.0 is safe.
if
(
round
(
value
*
pow
(
10
,
spec
()
->
precision
))
==
0.0
)
value
=
0
;
if
(
round
(
value
*
pow
(
10
,
spec
s
()
->
precision
))
==
0.0
)
value
=
0
;
return
base
::
operator
()(
value
);
return
base
::
operator
()(
value
);
}
}
};
};
...
...
test/printf-test.cc
View file @
5488d0b5
...
@@ -572,8 +572,8 @@ class custom_printf_arg_formatter : public formatter_t {
...
@@ -572,8 +572,8 @@ class custom_printf_arg_formatter : public formatter_t {
using
formatter_t
::
iterator
;
using
formatter_t
::
iterator
;
custom_printf_arg_formatter
(
formatter_t
::
iterator
iter
,
custom_printf_arg_formatter
(
formatter_t
::
iterator
iter
,
formatter_t
::
format_specs
&
spec
,
context_t
&
ctx
)
formatter_t
::
format_specs
&
spec
s
,
context_t
&
ctx
)
:
formatter_t
(
iter
,
spec
,
ctx
)
{}
:
formatter_t
(
iter
,
spec
s
,
ctx
)
{}
using
formatter_t
::
operator
();
using
formatter_t
::
operator
();
...
@@ -584,7 +584,7 @@ class custom_printf_arg_formatter : public formatter_t {
...
@@ -584,7 +584,7 @@ class custom_printf_arg_formatter : public formatter_t {
iterator
operator
()(
double
value
)
{
iterator
operator
()(
double
value
)
{
#endif
#endif
// Comparing a float to 0.0 is safe.
// Comparing a float to 0.0 is safe.
if
(
round
(
value
*
pow
(
10
,
spec
()
->
precision
))
==
0.0
)
value
=
0
;
if
(
round
(
value
*
pow
(
10
,
spec
s
()
->
precision
))
==
0.0
)
value
=
0
;
return
formatter_t
::
operator
()(
value
);
return
formatter_t
::
operator
()(
value
);
}
}
}
}
...
...
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