liblinux++

A hosted C++ runtime without any libc.
git clone git://henryandlizzy.uk/liblinux++
Log | Files | Refs

writer.cpp (1246B)


      1 #include "vector.hpp"
      2 
      3 struct writer
      4 {
      5 	virtual void write(char const c)
      6 	{
      7 		write({&c, 1});
      8 	}
      9 	virtual void write(span<char const>) = 0;
     10 protected:
     11 	~writer() = default;
     12 };
     13 
     14 struct fd_writer : writer
     15 {
     16 	fd_writer(fd f) : out{f} {}
     17 
     18 	void write(span<char const> data) override
     19 	{
     20 		assert(*::write(out, data) == data.size());
     21 	}
     22 private:
     23 	fd out;
     24 };
     25 
     26 struct buf_writer : writer
     27 {
     28 	buf_writer() noexcept = default;
     29 
     30 	void write(span<char const> data) override
     31 	{
     32 		buffer.push_back(data);
     33 	}
     34 	span<char const> get() const noexcept
     35 	{
     36 		return {buffer.data(), buffer.size()};
     37 	}
     38 private:
     39 	vector<char> buffer;
     40 };
     41 
     42 void decimal(writer& w, uint64_t n)
     43 {
     44 	char buf[20];
     45 	char* const end = buf + sizeof(buf);
     46 	char* p = end;
     47 	do
     48 	{
     49 		assert(--p >= buf);
     50 		*p = n % 10 + '0';
     51 		n /= 10;
     52 	} while (n);
     53 	w.write({p, end});
     54 }
     55 
     56 void test(uint64_t x, span<char const> expect)
     57 {
     58 	buf_writer w;
     59 	decimal(w, x);
     60 	assert(w.get() == expect);
     61 }
     62 
     63 #define tst(x) test(x##LLU, #x ""_sp)
     64 
     65 int main()
     66 {
     67 	tst(0);
     68 	tst(9);
     69 	tst(100);
     70 	tst(100100);
     71 	tst(18446744073709551615);
     72 
     73 	buf_writer x;
     74 	writer* w = &x;
     75 	w->write("Hello, "_sp);
     76 	decimal(*w, 1234567890);
     77 	w->write(" World! Wow what a lovely day!\n"_sp);
     78 	fd_writer cout{stdout};
     79 	w = &cout;
     80 	w->write(x.get());
     81 }