remove silly intermediate ranges for writef, print directly to stream

This commit is contained in:
q66 2017-02-01 19:29:42 +01:00
parent 077835e4b6
commit 3e683a2436
2 changed files with 21 additions and 58 deletions

View file

@ -165,6 +165,17 @@ namespace detail {
) {
write_impl(ostd::to_string(v));
}
/* lightweight output range for direct stdout */
struct StdoutRange: OutputRange<StdoutRange, char> {
StdoutRange() {}
bool put(char c) {
return putchar(c) != EOF;
}
size_t put_n(char const *p, size_t n) {
return fwrite(p, 1, n, stdout);
}
};
}
template<typename T>
@ -181,38 +192,25 @@ inline void write(T const &v, A const &...args) {
template<typename T>
inline void writeln(T const &v) {
write(v);
putc('\n', stdout);
putchar('\n');
}
template<typename T, typename ...A>
inline void writeln(T const &v, A const &...args) {
write(v);
write(args...);
putc('\n', stdout);
putchar('\n');
}
template<typename ...A>
inline void writef(ConstCharRange fmt, A const &...args) {
char buf[512];
ptrdiff_t need = format(
detail::FormatOutRange<sizeof(buf)>(buf), fmt, args...
);
if (need < 0) {
return;
} else if (size_t(need) < sizeof(buf)) {
fwrite(buf, 1, need, stdout);
return;
}
std::vector<char> s;
s.reserve(need);
format(detail::UnsafeWritefRange(s.data()), fmt, args...);
fwrite(s.data(), 1, need, stdout);
format(detail::StdoutRange{}, fmt, args...);
}
template<typename ...A>
inline void writefln(ConstCharRange fmt, A const &...args) {
writef(fmt, args...);
putc('\n', stdout);
putchar('\n');
}
} /* namespace ostd */

View file

@ -35,32 +35,6 @@ enum class StreamSeek {
template<typename T = char, bool = IsPod<T>>
struct StreamRange;
namespace detail {
template<size_t N>
struct FormatOutRange: OutputRange<FormatOutRange<N>, char> {
FormatOutRange(char *ibuf): buf(ibuf), idx(0) {}
FormatOutRange(FormatOutRange const &r): buf(r.buf), idx(r.idx) {}
char *buf;
size_t idx;
bool put(char v) {
if (idx < N) {
buf[idx++] = v;
return true;
}
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 {
private:
struct StNat {};
@ -138,21 +112,7 @@ public:
}
template<typename ...A>
bool writef(ConstCharRange fmt, A const &...args) {
char buf[512];
ptrdiff_t need = format(
detail::FormatOutRange<sizeof(buf)>(buf), fmt, args...
);
if (need < 0) {
return false;
} else if (size_t(need) < sizeof(buf)) {
return write_bytes(buf, need) == size_t(need);
}
std::vector<char> s;
s.reserve(need);
format(detail::UnsafeWritefRange(s.data()), fmt, args...);
return write_bytes(s.data(), need) == size_t(need);
}
bool writef(ConstCharRange fmt, A const &...args);
template<typename ...A>
bool writefln(ConstCharRange fmt, A const &...args) {
@ -246,6 +206,11 @@ inline StreamRange<T> Stream::iter() {
return StreamRange<T>(*this);
}
template<typename ...A>
inline bool Stream::writef(ConstCharRange fmt, A const &...args) {
return format(iter(), fmt, args...) >= 0;
}
}
#endif