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
c01ec54f
Commit
c01ec54f
authored
Nov 17, 2019
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Document and clean basic_format_parse_context
parent
b0c2ab93
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
59 additions
and
26 deletions
+59
-26
doc/api.rst
doc/api.rst
+39
-15
include/fmt/core.h
include/fmt/core.h
+20
-11
No files found.
doc/api.rst
View file @
c01ec54f
...
@@ -110,31 +110,55 @@ template and implement ``parse`` and ``format`` methods::
...
@@ -110,31 +110,55 @@ template and implement ``parse`` and ``format`` methods::
struct point { double x, y; };
struct point { double x, y; };
namespace fmt {
template <>
template <>
struct formatter<point> {
struct fmt::formatter<point> {
constexpr auto parse(format_parse_context &ctx) { return ctx.begin(); }
// Presentation format: 'f' - fixed, 'e' - exponential.
char presentation = 'f';
// Parses format specifications of the form ['f' | 'e'].
constexpr auto parse(format_parse_context &ctx) {
// [ctx.begin(), ctx.end()) is a character range that contains a part of
// the format string starting from the format specifications to be parsed,
// e.g. in
//
// fmt::format("{:f} - point of interest", point{1, 2});
//
// the range will contain "f} - point of interest". The formatter should
// parse specifiers until '}' or the end of the range. In this example,
// the formatter should parse the 'f' specifier and return an iterator
// pointing to '}'.
// Parse presentation format and store the parse result in the formatter:
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == 'f' || *it == 'e')) presentation = *it++;
// Check if reached the end of the range:
if (it != end && *it != '}')
throw format_error("invalid format");
// Return an iterator past the end of the parsed range:
return it;
}
// Formats the point p using parsed format specification (presentation)
// stored in this formatter.
template <typename FormatContext>
template <typename FormatContext>
auto format(const point &p, FormatContext &ctx) {
auto format(const point& p, FormatContext& ctx) {
return format_to(ctx.out(), "({:.1f}, {:.1f})", p.x, p.y);
return format_to(
}
ctx.out(),
};
presentation == 'f' ? "({:.1f}, {:.1f})" : "({:.1e}, {:.1e})",
p.x, p.y);
}
}
};
Then you can pass objects of type ``point`` to any formatting function::
Then you can pass objects of type ``point`` to any formatting function::
point p = {1, 2};
point p = {1, 2};
std::string s = fmt::format("{}", p);
std::string s = fmt::format("{
:f
}", p);
// s == "(1.0, 2.0)"
// s == "(1.0, 2.0)"
In the example above the ``formatter<point>::parse`` function ignores the
You can also reuse existing formatters via inheritance or composition, for
contents of the format string referred to by ``ctx.begin()`` so the object will
example::
always be formatted in the same way. See ``formatter<tm>::parse`` in
:file:`fmt/chrono.h` for an advanced example of how to parse the format string and
customize the formatted output.
You can also reuse existing formatters, for example::
enum class color {red, green, blue};
enum class color {red, green, blue};
...
...
include/fmt/core.h
View file @
c01ec54f
...
@@ -479,34 +479,43 @@ class basic_format_parse_context : private ErrorHandler {
...
@@ -479,34 +479,43 @@ class basic_format_parse_context : private ErrorHandler {
basic_string_view
<
Char
>
format_str
,
ErrorHandler
eh
=
ErrorHandler
())
basic_string_view
<
Char
>
format_str
,
ErrorHandler
eh
=
ErrorHandler
())
:
ErrorHandler
(
eh
),
format_str_
(
format_str
),
next_arg_id_
(
0
)
{}
:
ErrorHandler
(
eh
),
format_str_
(
format_str
),
next_arg_id_
(
0
)
{}
// Returns an iterator to the beginning of the format string range being
/**
// parsed.
Returns an iterator to the beginning of the format string range being
parsed.
*/
FMT_CONSTEXPR
iterator
begin
()
const
FMT_NOEXCEPT
{
FMT_CONSTEXPR
iterator
begin
()
const
FMT_NOEXCEPT
{
return
format_str_
.
begin
();
return
format_str_
.
begin
();
}
}
// Returns an iterator past the end of the format string range being parsed.
/**
Returns an iterator past the end of the format string range being parsed.
*/
FMT_CONSTEXPR
iterator
end
()
const
FMT_NOEXCEPT
{
return
format_str_
.
end
();
}
FMT_CONSTEXPR
iterator
end
()
const
FMT_NOEXCEPT
{
return
format_str_
.
end
();
}
/
/ Advances the begin iterator to ``it``.
/
** Advances the begin iterator to ``it``. */
FMT_CONSTEXPR
void
advance_to
(
iterator
it
)
{
FMT_CONSTEXPR
void
advance_to
(
iterator
it
)
{
format_str_
.
remove_prefix
(
internal
::
to_unsigned
(
it
-
begin
()));
format_str_
.
remove_prefix
(
internal
::
to_unsigned
(
it
-
begin
()));
}
}
// Returns the next argument index.
/**
Reports an error if using the manual argument indexing; otherwise returns
the next argument index and switches to the automatic indexing.
*/
FMT_CONSTEXPR
int
next_arg_id
()
{
FMT_CONSTEXPR
int
next_arg_id
()
{
if
(
next_arg_id_
>=
0
)
return
next_arg_id_
++
;
if
(
next_arg_id_
>=
0
)
return
next_arg_id_
++
;
on_error
(
"cannot switch from manual to automatic argument indexing"
);
on_error
(
"cannot switch from manual to automatic argument indexing"
);
return
0
;
return
0
;
}
}
FMT_CONSTEXPR
bool
check_arg_id
(
int
)
{
/**
if
(
next_arg_id_
>
0
)
{
Reports an error if using the automatic argument indexing; otherwise
switches to the manual indexing.
*/
FMT_CONSTEXPR
void
check_arg_id
(
int
)
{
if
(
next_arg_id_
>
0
)
on_error
(
"cannot switch from automatic to manual argument indexing"
);
on_error
(
"cannot switch from automatic to manual argument indexing"
);
return
false
;
else
}
next_arg_id_
=
-
1
;
next_arg_id_
=
-
1
;
return
true
;
}
}
FMT_CONSTEXPR
void
check_arg_id
(
basic_string_view
<
Char
>
)
{}
FMT_CONSTEXPR
void
check_arg_id
(
basic_string_view
<
Char
>
)
{}
...
...
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