diff --git a/ostd/io.hh b/ostd/io.hh index 1c84ef9..6166373 100644 --- a/ostd/io.hh +++ b/ostd/io.hh @@ -113,10 +113,6 @@ struct FileStream: Stream { return fputc(c, p_f) != EOF; } - bool write(const char *s) { - return fputs(s, p_f) != EOF; - } - void swap(FileStream &s) { ostd::swap(p_f, s.p_f); ostd::swap(p_owned, s.p_owned); @@ -144,8 +140,8 @@ namespace detail { template inline void write_impl(const T &v, EnableIf< - !IsConstructible::value, detail::IoNat - > = detail::IoNat()) { + !IsConstructible::value, IoNat + > = IoNat()) { write(ostd::to_string(v)); } } @@ -174,17 +170,6 @@ inline void writeln(const T &v, const A &...args) { putc('\n', ::stdout); } -namespace detail { - struct UnsafeWritefRange: OutputRange { - UnsafeWritefRange(char *p): p_ptr(p) {} - bool put(char c) { - *p_ptr++ = c; - return true; - } - char *p_ptr; - }; -} - template inline void writef(ConstCharRange fmt, const A &...args) { char buf[512]; diff --git a/ostd/stream.hh b/ostd/stream.hh index b655bad..2816518 100644 --- a/ostd/stream.hh +++ b/ostd/stream.hh @@ -48,9 +48,33 @@ namespace detail { return false; } }; + + struct UnsafeWritefRange: OutputRange { + UnsafeWritefRange(char *p): p_ptr(p) {} + bool put(char c) { + *p_ptr++ = c; + return true; + } + char *p_ptr; + }; } struct Stream { +private: + struct StNat {}; + + bool write_impl(ConstCharRange s) { + return write_bytes(s.data(), s.size()) == s.size(); + } + + template + inline void write_impl(const T &v, EnableIf< + !IsConstructible::value, StNat + > = StNat()) { + write(ostd::to_string(v)); + } + +public: using Offset = StreamOffset; virtual ~Stream() {} @@ -87,17 +111,9 @@ struct Stream { return write_bytes(&wc, 1) == 1; } - virtual bool write(const char *s) { - Size len = strlen(s); - return write_bytes(s, len) == len; - } - - virtual bool write(const String &s) { - return write_bytes(s.data(), s.size()) == s.size(); - } - - template bool write(const T &v) { - return write(to_string(v)); + template + bool write(const T &v) { + write_impl(v); } template @@ -105,15 +121,8 @@ struct Stream { return write(v) && write(args...); } - virtual bool writeln(const String &s) { - return write(s) && putchar('\n'); - } - - virtual bool writeln(const char *s) { - return write(s) && putchar('\n'); - } - - template bool writeln(const T &v) { + template + bool writeln(const T &v) { return write(v) && putchar('\n'); } @@ -123,34 +132,25 @@ struct Stream { } template - bool writef(const char *fmt, const A &...args) { + bool writef(ConstCharRange fmt, const A &...args) { char buf[512]; - Size need = format(detail::FormatOutRange(buf), + Ptrdiff need = format(detail::FormatOutRange(buf), fmt, args...); - if (need < sizeof(buf)) - return write_bytes(buf, need) == need; - String s; + if (need < 0) + return false; + else if (Size(need) < sizeof(buf)) + return write_bytes(buf, need) == Size(need); + Vector s; s.reserve(need); - s[need] = '\0'; - format(s.iter(), fmt, args...); - return write_bytes(s.data(), need) == need; + format(detail::UnsafeWritefRange(s.data()), fmt, args...); + return write_bytes(s.data(), need) == Size(need); } template - bool writef(const String &fmt, const A &...args) { - return writef(fmt.data(), args...); - } - - template - bool writefln(const char *fmt, const A &...args) { + bool writefln(ConstCharRange fmt, const A &...args) { return writef(fmt, args...) && putchar('\n'); } - template - bool writefln(const String &fmt, const A &...args) { - return writefln(fmt.data(), args...); - } - template StreamRange iter();