From b7632e9641fc1fefa970552d40c241989e4ab126 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 4 Mar 2018 08:13:08 -0800 Subject: [PATCH] Make format_to return iterator and update docs --- doc/api.rst | 23 +++++++++++------------ include/fmt/core.h | 25 ++++++++++++++----------- include/fmt/format.h | 31 ++++++++++++++++--------------- include/fmt/ostream.h | 2 +- 4 files changed, 42 insertions(+), 39 deletions(-) diff --git a/doc/api.rst b/doc/api.rst index de5604b4..1c9d1bc2 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -4,9 +4,8 @@ API Reference ************* -All functions and classes provided by the fmt library reside in namespace -``fmt`` and macros have prefix ``FMT_``. For brevity the namespace is usually -omitted in examples. +All functions and classes provided by the {fmt} library reside in namespace +``fmt`` and macros have prefix ``FMT_``. Format API ========== @@ -60,28 +59,28 @@ Formatting user-defined types To make a user-defined type formattable, specialize the ``formatter`` struct template and implement ``parse`` and ``format`` methods:: - struct MyStruct { double x, y; }; + struct point { double x, y; }; namespace fmt { template <> - struct formatter { + struct formatter { template auto parse(ParseContext &ctx) { return ctx.begin(); } template - auto format(const MyStruct &s, FormatContext &ctx) { - return format_to(ctx.begin(), "[MyStruct: x={:.1f}, y={:.2f}]", s.x, s.y); + auto format(const point &p, FormatContext &ctx) { + return format_to(ctx.begin(), "({:.1f}, {:.1f})", p.x, p.y); } }; } -Then you can pass objects of type ``MyStruct`` to any formatting function:: +Then you can pass objects of type ``point`` to any formatting function:: - MyStruct m = {1, 2}; - std::string s = fmt::format("m={}", m); - // s == "m=[MyStruct: x=1.0, y=2.00]" + point p = {1, 2}; + std::string s = fmt::format("{}", p); + // s == "(1.0, 2.0)" -In the example above the ``formatter::parse`` function ignores the +In the example above the ``formatter::parse`` function ignores the contents of the format string referred to by ``ctx.begin()`` so the object will always be formatted in the same way. See ``formatter::parse`` in :file:`fmt/time.h` for an advanced example of how to parse the format string and diff --git a/include/fmt/core.h b/include/fmt/core.h index fe214cf0..ebcf7cfe 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1118,7 +1118,7 @@ struct named_arg : named_arg_base { **Example**:: - print("Elapsed time: {s:.2f} seconds", arg("s", 1.23)); + fmt::print("Elapsed time: {s:.2f} seconds", arg("s", 1.23)); \endrst */ template @@ -1144,7 +1144,7 @@ FMT_API void vprint_colored(Color c, string_view format, format_args args); Formats a string and prints it to stdout using ANSI escape sequences to specify color (experimental). Example: - print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23); + fmt::print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23); */ template inline void print_colored(Color c, string_view format_str, @@ -1152,10 +1152,10 @@ inline void print_colored(Color c, string_view format_str, vprint_colored(c, format_str, make_args(args...)); } -void vformat_to(internal::buffer &buf, string_view format_str, - format_args args); -void vformat_to(internal::wbuffer &buf, wstring_view format_str, - wformat_args args); +context::iterator vformat_to(internal::buffer &buf, string_view format_str, + format_args args); +wcontext::iterator vformat_to(internal::wbuffer &buf, wstring_view format_str, + wformat_args args); template struct is_contiguous : std::false_type {}; @@ -1168,11 +1168,14 @@ struct is_contiguous> : std::true_type {}; /** Formats a string and writes the output to ``out``. */ template -typename std::enable_if::value>::type +typename std::enable_if< + is_contiguous::value, std::back_insert_iterator>::type vformat_to(std::back_insert_iterator out, string_view format_str, format_args args) { - internal::container_buffer buf(internal::get_container(out)); + auto& container = internal::get_container(out); + internal::container_buffer buf(container); vformat_to(buf, format_str, args); + return std::back_inserter(container); } std::string vformat(string_view format_str, format_args args); @@ -1184,7 +1187,7 @@ std::wstring vformat(wstring_view format_str, wformat_args args); **Example**:: - std::string message = format("The answer is {}", 42); + std::string message = fmt::format("The answer is {}", 42); \endrst */ template @@ -1204,7 +1207,7 @@ FMT_API void vprint(std::FILE *f, string_view format_str, format_args args); **Example**:: - print(stderr, "Don't {}!", "panic"); + fmt::print(stderr, "Don't {}!", "panic"); \endrst */ template @@ -1220,7 +1223,7 @@ FMT_API void vprint(string_view format_str, format_args args); **Example**:: - print("Elapsed time: {0:.2f} seconds", 1.23); + fmt::print("Elapsed time: {0:.2f} seconds", 1.23); \endrst */ template diff --git a/include/fmt/format.h b/include/fmt/format.h index 5d3edd6f..94b1cfcb 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2146,7 +2146,7 @@ class arg_formatter: using base::operator(); - /** Formats an argument of a custom (user-defined) type. */ + /** Formats an argument of a user-defined type. */ void operator()(typename basic_arg::handle handle) const { handle.format(ctx_); } @@ -3324,28 +3324,28 @@ std::basic_string to_string(const basic_memory_buffer &buffer) { return std::basic_string(buffer.data(), buffer.size()); } -inline void vformat_to(internal::buffer &buf, string_view format_str, - format_args args) { +inline context::iterator vformat_to( + internal::buffer &buf, string_view format_str, format_args args) { typedef back_insert_range range; - vformat_to>(buf, format_str, args); + return vformat_to>(buf, format_str, args); } -inline void vformat_to(internal::wbuffer &buf, wstring_view format_str, - wformat_args args) { +inline wcontext::iterator vformat_to( + internal::wbuffer &buf, wstring_view format_str, wformat_args args) { typedef back_insert_range range; - vformat_to>(buf, format_str, args); + return vformat_to>(buf, format_str, args); } template -inline void format_to(memory_buffer &buf, string_view format_str, - const Args & ... args) { - vformat_to(buf, format_str, make_args(args...)); +inline context::iterator format_to( + memory_buffer &buf, string_view format_str, const Args & ... args) { + return vformat_to(buf, format_str, make_args(args...)); } template -inline void format_to(wmemory_buffer &buf, wstring_view format_str, - const Args & ... args) { - vformat_to(buf, format_str, make_args(args...)); +inline wcontext::iterator format_to( + wmemory_buffer &buf, wstring_view format_str, const Args & ... args) { + return vformat_to(buf, format_str, make_args(args...)); } template @@ -3373,10 +3373,11 @@ inline OutputIt format_to(OutputIt out, string_view format_str, } template -inline typename std::enable_if::value>::type +inline typename std::enable_if< + is_contiguous::value, std::back_insert_iterator>::type format_to(std::back_insert_iterator out, string_view format_str, const Args & ... args) { - vformat_to(out, format_str, make_args(args...)); + return vformat_to(out, format_str, make_args(args...)); } inline std::string vformat(string_view format_str, format_args args) { diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index 3ec8919a..3ac5cd65 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -133,7 +133,7 @@ inline void vprint(std::ostream &os, string_view format_str, format_args args) { **Example**:: - print(cerr, "Don't {}!", "panic"); + fmt::print(cerr, "Don't {}!", "panic"); \endrst */ template