make write(x) equivalent to write("%s", x)

master
Daniel Kolesa 2017-02-10 17:44:06 +01:00
parent e1f5cc477f
commit 922f19b776
3 changed files with 33 additions and 37 deletions

View File

@ -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<typename R>
bool read_until_spec(R &writer, size_t *wret) {
size_t written = 0;

View File

@ -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<typename T>
inline void write_impl(
T const &v, std::enable_if_t<
!std::is_constructible_v<ConstCharRange, T const &>, IoNat
> = IoNat()
) {
write_impl(ostd::to_string(v));
}
/* lightweight output range for direct stdout */
struct StdoutRange: OutputRange<StdoutRange, char> {
StdoutRange() {}
@ -180,7 +165,8 @@ namespace detail {
template<typename T>
inline void write(T const &v) {
detail::write_impl(v);
// TODO: switch to direct FormatSpec later
format(detail::StdoutRange{}, "%s", v);
}
template<typename T, typename ...A>

View File

@ -34,23 +34,6 @@ template<typename T = char, bool = std::is_pod_v<T>>
struct StreamRange;
struct Stream {
private:
struct StNat {};
bool write_impl(ConstCharRange s) {
return write_bytes(s.data(), s.size()) == s.size();
}
template<typename T>
inline bool write_impl(
T const &v, std::enable_if_t<
!std::is_constructible_v<ConstCharRange, T const &>, StNat
> = StNat()
) {
return write(ostd::to_string(v));
}
public:
using Offset = StreamOffset;
virtual ~Stream() {}
@ -90,9 +73,7 @@ public:
}
template<typename T>
bool write(T const &v) {
return write_impl(v);
}
bool write(T const &v);
template<typename T, typename ...A>
bool write(T const &v, A const &...args) {
@ -204,9 +185,29 @@ inline StreamRange<T> Stream::iter() {
return StreamRange<T>(*this);
}
namespace detail {
/* lightweight output range for write/writef on streams */
struct FmtStreamRange: OutputRange<FmtStreamRange, char> {
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<typename T>
inline bool Stream::write(T const &v) {
// TODO: switch to direct FormatSpec later
return format(detail::FmtStreamRange{*this}, "%s", v) >= 0;
}
template<typename ...A>
inline bool Stream::writef(ConstCharRange fmt, A const &...args) {
return format(iter(), fmt, args...) >= 0;
return format(detail::FmtStreamRange{*this}, fmt, args...) >= 0;
}
}