From 3f983afae5af45fbcff7cd7b966f5724d6523b3d Mon Sep 17 00:00:00 2001 From: q66 Date: Mon, 20 Feb 2017 19:36:38 +0100 Subject: [PATCH] support for printing iterable objects and tuples with %s --- ostd/format.hh | 52 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/ostd/format.hh b/ostd/format.hh index c2001c1..a218fd0 100644 --- a/ostd/format.hh +++ b/ostd/format.hh @@ -679,6 +679,30 @@ private: write_str(writer, escape, val); return; } + /* tuples */ + if constexpr(detail::is_tuple_like) { + if (spec() != 's') { + throw format_error{"ranges need the '%s' spec"}; + } + writer.put('<'); + write_tuple_val<0, std::tuple_size::value>( + writer, !(flags() & FMT_FLAG_DASH), ", ", val + ); + writer.put('>'); + return; + } + /* ranges */ + if constexpr(detail::iterable_test) { + if (spec() != 's') { + throw format_error{"tuples need the '%s' spec"}; + } + writer.put('{'); + write_range_val( + writer, !(flags() & FMT_FLAG_DASH), false, "%s", ", ", val + ); + writer.put('}'); + return; + } /* bools, check if printing as string, otherwise convert to int */ if constexpr(std::is_same_v) { if (spec() == 's') { @@ -745,26 +769,28 @@ private: template inline void write_range_item( - R &writer, bool expandval, string_range fmt, T const &item + R &writer, bool escape, bool expandval, string_range fmt, T const &item ) const { if constexpr(detail::is_tuple_like) { if (expandval) { - std::apply([&writer, esc = p_nested_escape, &fmt]( + std::apply([&writer, escape, &fmt]( auto const &...args ) mutable { - format_spec sp{fmt, esc}; + format_spec sp{fmt, escape}; sp.write_fmt(writer, args...); }, item); return; } } - format_spec sp{fmt, p_nested_escape}; + format_spec sp{fmt, escape}; sp.write_fmt(writer, item); } template void write_range_val( - R &writer, bool expandval, string_range sep, T const &val + R &writer, bool escape, bool expandval, string_range ifmt, + string_range sep, + T const &val ) const { if constexpr(detail::iterable_test) { auto range = ostd::iter(val); @@ -772,7 +798,7 @@ private: return; } for (;;) { - write_range_item(writer, expandval, rest(), range.front()); + write_range_item(writer, escape, expandval, ifmt, range.front()); range.pop_front(); if (range.empty()) { break; @@ -784,6 +810,18 @@ private: } } + template + void write_tuple_val( + R &writer, bool escape, string_range sep, T const &tup + ) const { + format_spec sp{"%s", escape}; + sp.write_fmt(writer, std::get(tup)); + if constexpr(I < (N - 1)) { + range_put_all(writer, sep); + write_tuple_val(writer, escape, sep, tup); + } + } + /* range writer */ template void write_range( @@ -797,7 +835,7 @@ private: write_range(writer, idx - 1, expandval, sep, args...); } } else { - write_range_val(writer, expandval, sep, val); + write_range_val(writer, nested_escape(), expandval, rest(), sep, val); } }