From 922f19b7769511ba0eb75569f321999c7c6cdddb Mon Sep 17 00:00:00 2001 From: q66 Date: Fri, 10 Feb 2017 17:44:06 +0100 Subject: [PATCH] make write(x) equivalent to write("%s", x) --- ostd/format.hh | 9 +++++++++ ostd/io.hh | 18 ++---------------- ostd/stream.hh | 43 ++++++++++++++++++++++--------------------- 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/ostd/format.hh b/ostd/format.hh index ba5f596..b7d33f3 100644 --- a/ostd/format.hh +++ b/ostd/format.hh @@ -151,6 +151,15 @@ struct FormatSpec { p_nested_escape(escape), p_fmt(fmt) {} + FormatSpec(char spec, int width = -1, int prec = -1, int flags = 0): + p_flags(flags), + p_width((width >= 0) ? width : 0), + p_precision((prec >= 0) ? prec : 0), + p_has_width(width >= 0), + p_has_precision(prec >= 0), + p_spec(spec) + {} + template bool read_until_spec(R &writer, size_t *wret) { size_t written = 0; diff --git a/ostd/io.hh b/ostd/io.hh index 6efd30e..b39b53e 100644 --- a/ostd/io.hh +++ b/ostd/io.hh @@ -151,21 +151,6 @@ static FileStream err(stderr); /* no need to call anything from FileStream, prefer simple calls... */ namespace detail { - struct IoNat {}; - - inline void write_impl(ConstCharRange s) { - fwrite(&s[0], 1, s.size(), stdout); - } - - template - inline void write_impl( - T const &v, std::enable_if_t< - !std::is_constructible_v, IoNat - > = IoNat() - ) { - write_impl(ostd::to_string(v)); - } - /* lightweight output range for direct stdout */ struct StdoutRange: OutputRange { StdoutRange() {} @@ -180,7 +165,8 @@ namespace detail { template inline void write(T const &v) { - detail::write_impl(v); + // TODO: switch to direct FormatSpec later + format(detail::StdoutRange{}, "%s", v); } template diff --git a/ostd/stream.hh b/ostd/stream.hh index e0e4e7b..9a4d815 100644 --- a/ostd/stream.hh +++ b/ostd/stream.hh @@ -34,23 +34,6 @@ template> struct StreamRange; struct Stream { -private: - struct StNat {}; - - bool write_impl(ConstCharRange s) { - return write_bytes(s.data(), s.size()) == s.size(); - } - - template - inline bool write_impl( - T const &v, std::enable_if_t< - !std::is_constructible_v, StNat - > = StNat() - ) { - return write(ostd::to_string(v)); - } - -public: using Offset = StreamOffset; virtual ~Stream() {} @@ -90,9 +73,7 @@ public: } template - bool write(T const &v) { - return write_impl(v); - } + bool write(T const &v); template bool write(T const &v, A const &...args) { @@ -204,9 +185,29 @@ inline StreamRange Stream::iter() { return StreamRange(*this); } +namespace detail { + /* lightweight output range for write/writef on streams */ + struct FmtStreamRange: OutputRange { + FmtStreamRange(Stream &s): p_s(s) {} + bool put(char c) { + return p_s.putchar(c); + } + size_t put_n(char const *p, size_t n) { + return p_s.put(p, n); + } + Stream &p_s; + }; +} + +template +inline bool Stream::write(T const &v) { + // TODO: switch to direct FormatSpec later + return format(detail::FmtStreamRange{*this}, "%s", v) >= 0; +} + template inline bool Stream::writef(ConstCharRange fmt, A const &...args) { - return format(iter(), fmt, args...) >= 0; + return format(detail::FmtStreamRange{*this}, fmt, args...) >= 0; } }