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
6ee9f2ed
Commit
6ee9f2ed
authored
Jul 21, 2016
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make printf argument formatters public (#335, #360)
parent
631ffef4
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
56 additions
and
19 deletions
+56
-19
doc/api.rst
doc/api.rst
+6
-0
fmt/format.h
fmt/format.h
+5
-5
fmt/printf.h
fmt/printf.h
+36
-8
test/custom-formatter-test.cc
test/custom-formatter-test.cc
+9
-6
No files found.
doc/api.rst
View file @
6ee9f2ed
...
@@ -145,6 +145,12 @@ argument type doesn't match its format specification.
...
@@ -145,6 +145,12 @@ argument type doesn't match its format specification.
.. doxygenclass:: fmt::PrintfFormatter
.. doxygenclass:: fmt::PrintfFormatter
:members:
:members:
.. doxygenclass:: fmt::BasicPrintfArgFormatter
:members:
.. doxygenclass:: fmt::PrintfArgFormatter
:members:
Write API
Write API
=========
=========
...
...
fmt/format.h
View file @
6ee9f2ed
...
@@ -381,6 +381,9 @@ typedef BasicWriter<wchar_t> WWriter;
...
@@ -381,6 +381,9 @@ typedef BasicWriter<wchar_t> WWriter;
template
<
typename
Char
>
template
<
typename
Char
>
class
ArgFormatter
;
class
ArgFormatter
;
template
<
typename
Impl
,
typename
Char
>
class
BasicPrintfArgFormatter
;
template
<
typename
CharType
,
template
<
typename
CharType
,
typename
ArgFormatter
=
fmt
::
ArgFormatter
<
CharType
>
>
typename
ArgFormatter
=
fmt
::
ArgFormatter
<
CharType
>
>
class
BasicFormatter
;
class
BasicFormatter
;
...
@@ -1319,9 +1322,6 @@ class RuntimeError : public std::runtime_error {
...
@@ -1319,9 +1322,6 @@ class RuntimeError : public std::runtime_error {
~
RuntimeError
()
throw
();
~
RuntimeError
()
throw
();
};
};
template
<
typename
Impl
,
typename
Char
>
class
BasicPrintfArgFormatter
;
template
<
typename
Char
>
template
<
typename
Char
>
class
ArgMap
;
class
ArgMap
;
}
// namespace internal
}
// namespace internal
...
@@ -1979,7 +1979,7 @@ class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
...
@@ -1979,7 +1979,7 @@ class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
:
internal
::
ArgFormatterBase
<
Impl
,
Char
>
(
formatter
.
writer
(),
spec
),
:
internal
::
ArgFormatterBase
<
Impl
,
Char
>
(
formatter
.
writer
(),
spec
),
formatter_
(
formatter
),
format_
(
fmt
)
{}
formatter_
(
formatter
),
format_
(
fmt
)
{}
/** Formats argument of a custom (user-defined) type. */
/** Formats a
n a
rgument of a custom (user-defined) type. */
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
{
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
{
c
.
format
(
&
formatter_
,
c
.
value
,
&
format_
);
c
.
format
(
&
formatter_
,
c
.
value
,
&
format_
);
}
}
...
@@ -2406,7 +2406,7 @@ class BasicWriter {
...
@@ -2406,7 +2406,7 @@ class BasicWriter {
friend
class
internal
::
ArgFormatterBase
;
friend
class
internal
::
ArgFormatterBase
;
template
<
typename
Impl
,
typename
Char_
>
template
<
typename
Impl
,
typename
Char_
>
friend
class
internal
::
BasicPrintfArgFormatter
;
friend
class
BasicPrintfArgFormatter
;
protected:
protected:
/**
/**
...
...
fmt/printf.h
View file @
6ee9f2ed
...
@@ -170,21 +170,47 @@ class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
...
@@ -170,21 +170,47 @@ class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
return
static_cast
<
unsigned
>
(
width
);
return
static_cast
<
unsigned
>
(
width
);
}
}
};
};
}
// namespace internal
/**
\rst
A ``printf`` argument formatter based on the `curiously recurring template
pattern <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some
or all of the visit methods with the same signatures as the methods in
`~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`.
Pass the subclass as the *Impl* template parameter. When a formatting
function processes an argument, it will dispatch to a visit method
specific to the argument type. For example, if the argument type is
``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
will be called. If the subclass doesn't contain a method with this signature,
then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its
superclass will be called.
\endrst
*/
template
<
typename
Impl
,
typename
Char
>
template
<
typename
Impl
,
typename
Char
>
class
BasicPrintfArgFormatter
:
public
ArgFormatterBase
<
Impl
,
Char
>
{
class
BasicPrintfArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
>
{
private:
private:
void
write_null_pointer
()
{
void
write_null_pointer
()
{
this
->
spec
().
type_
=
0
;
this
->
spec
().
type_
=
0
;
this
->
write
(
"(nil)"
);
this
->
write
(
"(nil)"
);
}
}
typedef
ArgFormatterBase
<
Impl
,
Char
>
Base
;
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
>
Base
;
public:
public:
BasicPrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
/**
:
ArgFormatterBase
<
Impl
,
Char
>
(
w
,
s
)
{}
\rst
Constructs an argument formatter object.
*writer* is a reference to the output writer and *spec* contains format
specifier information for standard argument types.
\endrst
*/
BasicPrintfArgFormatter
(
BasicWriter
<
Char
>
&
writer
,
FormatSpec
&
spec
)
:
internal
::
ArgFormatterBase
<
Impl
,
Char
>
(
writer
,
spec
)
{}
/** Formats an argument of type ``bool``. */
void
visit_bool
(
bool
value
)
{
void
visit_bool
(
bool
value
)
{
FormatSpec
&
fmt_spec
=
this
->
spec
();
FormatSpec
&
fmt_spec
=
this
->
spec
();
if
(
fmt_spec
.
type_
!=
's'
)
if
(
fmt_spec
.
type_
!=
's'
)
...
@@ -193,6 +219,7 @@ class BasicPrintfArgFormatter : public ArgFormatterBase<Impl, Char> {
...
@@ -193,6 +219,7 @@ class BasicPrintfArgFormatter : public ArgFormatterBase<Impl, Char> {
this
->
write
(
value
);
this
->
write
(
value
);
}
}
/** Formats a character. */
void
visit_char
(
int
value
)
{
void
visit_char
(
int
value
)
{
const
FormatSpec
&
fmt_spec
=
this
->
spec
();
const
FormatSpec
&
fmt_spec
=
this
->
spec
();
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
...
@@ -215,6 +242,7 @@ class BasicPrintfArgFormatter : public ArgFormatterBase<Impl, Char> {
...
@@ -215,6 +242,7 @@ class BasicPrintfArgFormatter : public ArgFormatterBase<Impl, Char> {
*
out
=
static_cast
<
Char
>
(
value
);
*
out
=
static_cast
<
Char
>
(
value
);
}
}
/** Formats a null-terminated C string. */
void
visit_cstring
(
const
char
*
value
)
{
void
visit_cstring
(
const
char
*
value
)
{
if
(
value
)
if
(
value
)
Base
::
visit_cstring
(
value
);
Base
::
visit_cstring
(
value
);
...
@@ -224,6 +252,7 @@ class BasicPrintfArgFormatter : public ArgFormatterBase<Impl, Char> {
...
@@ -224,6 +252,7 @@ class BasicPrintfArgFormatter : public ArgFormatterBase<Impl, Char> {
this
->
write
(
"(null)"
);
this
->
write
(
"(null)"
);
}
}
/** Formats a pointer. */
void
visit_pointer
(
const
void
*
value
)
{
void
visit_pointer
(
const
void
*
value
)
{
if
(
value
)
if
(
value
)
return
Base
::
visit_pointer
(
value
);
return
Base
::
visit_pointer
(
value
);
...
@@ -231,7 +260,8 @@ class BasicPrintfArgFormatter : public ArgFormatterBase<Impl, Char> {
...
@@ -231,7 +260,8 @@ class BasicPrintfArgFormatter : public ArgFormatterBase<Impl, Char> {
write_null_pointer
();
write_null_pointer
();
}
}
void
visit_custom
(
Arg
::
CustomValue
c
)
{
/** Formats an argument of a custom (user-defined) type. */
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
{
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
const
Char
format_str
[]
=
{
'}'
,
0
};
const
Char
format_str
[]
=
{
'}'
,
0
};
const
Char
*
format
=
format_str
;
const
Char
*
format
=
format_str
;
...
@@ -248,11 +278,9 @@ class PrintfArgFormatter
...
@@ -248,11 +278,9 @@ class PrintfArgFormatter
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
{}
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
{}
};
};
}
// namespace internal
/** This template formats data and writes the output to a writer. */
/** This template formats data and writes the output to a writer. */
template
<
typename
Char
,
template
<
typename
Char
,
typename
ArgFormatter
=
PrintfArgFormatter
<
Char
>
>
typename
ArgFormatter
=
internal
::
PrintfArgFormatter
<
Char
>
>
class
PrintfFormatter
:
private
internal
::
FormatterBase
{
class
PrintfFormatter
:
private
internal
::
FormatterBase
{
private:
private:
BasicWriter
<
Char
>
&
writer_
;
BasicWriter
<
Char
>
&
writer_
;
...
...
test/custom-formatter-test.cc
View file @
6ee9f2ed
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
#include "fmt/printf.h"
#include "fmt/printf.h"
#include "gtest-extra.h"
#include "gtest-extra.h"
using
fmt
::
internal
::
BasicPrintfArgFormatter
;
using
fmt
::
BasicPrintfArgFormatter
;
// A custom argument formatter that doesn't print `-` for floating-point values
// A custom argument formatter that doesn't print `-` for floating-point values
// rounded to 0.
// rounded to 0.
...
@@ -30,15 +30,18 @@ class CustomArgFormatter
...
@@ -30,15 +30,18 @@ class CustomArgFormatter
// A custom argument formatter that doesn't print `-` for floating-point values
// A custom argument formatter that doesn't print `-` for floating-point values
// rounded to 0.
// rounded to 0.
class
CustomPAF
:
public
BasicPrintfArgFormatter
<
CustomPAF
,
char
>
{
class
CustomPrintfArgFormatter
:
public
BasicPrintfArgFormatter
<
CustomPrintfArgFormatter
,
char
>
{
public:
public:
CustomPAF
(
fmt
::
BasicWriter
<
char
>
&
writer
,
fmt
::
FormatSpec
&
spec
)
typedef
BasicPrintfArgFormatter
<
CustomPrintfArgFormatter
,
char
>
Base
;
:
BasicPrintfArgFormatter
<
CustomPAF
,
char
>
(
writer
,
spec
)
{}
CustomPrintfArgFormatter
(
fmt
::
BasicWriter
<
char
>
&
w
,
fmt
::
FormatSpec
&
spec
)
:
Base
(
w
,
spec
)
{}
void
visit_double
(
double
value
)
{
void
visit_double
(
double
value
)
{
if
(
round
(
value
*
pow
(
10
,
spec
().
precision
()))
==
0
)
if
(
round
(
value
*
pow
(
10
,
spec
().
precision
()))
==
0
)
value
=
0
;
value
=
0
;
Bas
icPrintfArgFormatter
<
CustomPAF
,
char
>
::
visit_double
(
value
);
Bas
e
::
visit_double
(
value
);
}
}
};
};
...
@@ -53,7 +56,7 @@ FMT_VARIADIC(std::string, custom_format, const char *)
...
@@ -53,7 +56,7 @@ FMT_VARIADIC(std::string, custom_format, const char *)
std
::
string
custom_sprintf
(
const
char
*
format_str
,
fmt
::
ArgList
args
){
std
::
string
custom_sprintf
(
const
char
*
format_str
,
fmt
::
ArgList
args
){
fmt
::
MemoryWriter
writer
;
fmt
::
MemoryWriter
writer
;
fmt
::
PrintfFormatter
<
char
,
CustomP
AF
>
formatter
(
args
,
writer
);
fmt
::
PrintfFormatter
<
char
,
CustomP
rintfArgFormatter
>
formatter
(
args
,
writer
);
formatter
.
format
(
format_str
);
formatter
.
format
(
format_str
);
return
writer
.
str
();
return
writer
.
str
();
}
}
...
...
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