forked from OctaForge/libostd
make write(x) equivalent to write("%s", x)
This commit is contained in:
parent
e1f5cc477f
commit
922f19b776
|
@ -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;
|
||||
|
|
18
ostd/io.hh
18
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<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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue