rewritten and simplified write(f/ln) on stream objects

This commit is contained in:
q66 2015-07-22 02:06:36 +01:00
parent debbddc8da
commit b9edc0c568
2 changed files with 41 additions and 56 deletions

View file

@ -113,10 +113,6 @@ struct FileStream: Stream {
return fputc(c, p_f) != EOF; return fputc(c, p_f) != EOF;
} }
bool write(const char *s) {
return fputs(s, p_f) != EOF;
}
void swap(FileStream &s) { void swap(FileStream &s) {
ostd::swap(p_f, s.p_f); ostd::swap(p_f, s.p_f);
ostd::swap(p_owned, s.p_owned); ostd::swap(p_owned, s.p_owned);
@ -144,8 +140,8 @@ namespace detail {
template<typename T> template<typename T>
inline void write_impl(const T &v, EnableIf< inline void write_impl(const T &v, EnableIf<
!IsConstructible<ConstCharRange, const T &>::value, detail::IoNat !IsConstructible<ConstCharRange, const T &>::value, IoNat
> = detail::IoNat()) { > = IoNat()) {
write(ostd::to_string(v)); write(ostd::to_string(v));
} }
} }
@ -174,17 +170,6 @@ inline void writeln(const T &v, const A &...args) {
putc('\n', ::stdout); putc('\n', ::stdout);
} }
namespace detail {
struct UnsafeWritefRange: OutputRange<UnsafeWritefRange, char> {
UnsafeWritefRange(char *p): p_ptr(p) {}
bool put(char c) {
*p_ptr++ = c;
return true;
}
char *p_ptr;
};
}
template<typename ...A> template<typename ...A>
inline void writef(ConstCharRange fmt, const A &...args) { inline void writef(ConstCharRange fmt, const A &...args) {
char buf[512]; char buf[512];

View file

@ -48,9 +48,33 @@ namespace detail {
return false; return false;
} }
}; };
struct UnsafeWritefRange: OutputRange<UnsafeWritefRange, char> {
UnsafeWritefRange(char *p): p_ptr(p) {}
bool put(char c) {
*p_ptr++ = c;
return true;
}
char *p_ptr;
};
} }
struct Stream { struct Stream {
private:
struct StNat {};
bool write_impl(ConstCharRange s) {
return write_bytes(s.data(), s.size()) == s.size();
}
template<typename T>
inline void write_impl(const T &v, EnableIf<
!IsConstructible<ConstCharRange, const T &>::value, StNat
> = StNat()) {
write(ostd::to_string(v));
}
public:
using Offset = StreamOffset; using Offset = StreamOffset;
virtual ~Stream() {} virtual ~Stream() {}
@ -87,17 +111,9 @@ struct Stream {
return write_bytes(&wc, 1) == 1; return write_bytes(&wc, 1) == 1;
} }
virtual bool write(const char *s) { template<typename T>
Size len = strlen(s); bool write(const T &v) {
return write_bytes(s, len) == len; write_impl(v);
}
virtual bool write(const String &s) {
return write_bytes(s.data(), s.size()) == s.size();
}
template<typename T> bool write(const T &v) {
return write(to_string(v));
} }
template<typename T, typename ...A> template<typename T, typename ...A>
@ -105,15 +121,8 @@ struct Stream {
return write(v) && write(args...); return write(v) && write(args...);
} }
virtual bool writeln(const String &s) { template<typename T>
return write(s) && putchar('\n'); bool writeln(const T &v) {
}
virtual bool writeln(const char *s) {
return write(s) && putchar('\n');
}
template<typename T> bool writeln(const T &v) {
return write(v) && putchar('\n'); return write(v) && putchar('\n');
} }
@ -123,34 +132,25 @@ struct Stream {
} }
template<typename ...A> template<typename ...A>
bool writef(const char *fmt, const A &...args) { bool writef(ConstCharRange fmt, const A &...args) {
char buf[512]; char buf[512];
Size need = format(detail::FormatOutRange<sizeof(buf)>(buf), Ptrdiff need = format(detail::FormatOutRange<sizeof(buf)>(buf),
fmt, args...); fmt, args...);
if (need < sizeof(buf)) if (need < 0)
return write_bytes(buf, need) == need; return false;
String s; else if (Size(need) < sizeof(buf))
return write_bytes(buf, need) == Size(need);
Vector<char> s;
s.reserve(need); s.reserve(need);
s[need] = '\0'; format(detail::UnsafeWritefRange(s.data()), fmt, args...);
format(s.iter(), fmt, args...); return write_bytes(s.data(), need) == Size(need);
return write_bytes(s.data(), need) == need;
} }
template<typename ...A> template<typename ...A>
bool writef(const String &fmt, const A &...args) { bool writefln(ConstCharRange fmt, const A &...args) {
return writef(fmt.data(), args...);
}
template<typename ...A>
bool writefln(const char *fmt, const A &...args) {
return writef(fmt, args...) && putchar('\n'); return writef(fmt, args...) && putchar('\n');
} }
template<typename ...A>
bool writefln(const String &fmt, const A &...args) {
return writefln(fmt.data(), args...);
}
template<typename T = char> template<typename T = char>
StreamRange<T> iter(); StreamRange<T> iter();