protohackers

My solutions to the protohackers.com challenges.
git clone git://henryandlizzy.uk/protohackers
Log | Files | Refs

fd.hpp (1207B)


      1 #pragma once
      2 #include <unistd.h>
      3 #include <err.h>
      4 
      5 #include <string>
      6 #include <span>
      7 
      8 struct descriptor
      9 {
     10 	descriptor()
     11 	:	fd(-1)
     12 	{}
     13 
     14 	explicit descriptor(int d)
     15 	:	fd(d)
     16 	{}
     17 
     18 	~descriptor()
     19 	{
     20 		close();
     21 	}
     22 
     23 	descriptor(descriptor&& old)
     24 	:	fd(old.fd)
     25 	{
     26 		old.fd = -1;
     27 	}
     28 
     29 	descriptor& operator =(descriptor&& old)
     30 	{
     31 		if (this != &old)
     32 		{
     33 			close();
     34 			fd = old.fd;
     35 			old.fd = -1;
     36 		}
     37 		return *this;
     38 	}
     39 
     40 	descriptor(descriptor const&) = delete;
     41 	descriptor& operator =(descriptor const&) = delete;
     42 
     43 	void close()
     44 	{
     45 		if (*this)
     46 			::close(fd);
     47 		fd = -1;
     48 	}
     49 
     50 	explicit operator bool() const
     51 	{
     52 		return fd != -1;
     53 	}
     54 
     55 	operator int() const
     56 	{
     57 		return fd;
     58 	}
     59 
     60 private:
     61 	int fd;
     62 };
     63 
     64 ssize_t write(int d, std::string_view s)
     65 {
     66 	if (ssize_t n = ::write(d, s.data(), s.size()); n != -1)
     67 		return n;
     68 	::err(1, "write");
     69 }
     70 
     71 std::string read(descriptor& d)
     72 {
     73 	char buf[256];
     74 	ssize_t n = ::read(d, buf, sizeof buf);
     75 	if (n > 0)
     76 		return {buf, (size_t)n};
     77 	else
     78 		return {};
     79 }
     80 
     81 std::string_view read(int d, std::span<char> buf)
     82 {
     83 	ssize_t n = ::read(d, buf.data(), buf.size());
     84 	if ((n < 0) or ((size_t)n > buf.size()))
     85 		err(1, "read");
     86 	else if (n)
     87 		return {buf.data(), (size_t)n};
     88 	else
     89 		return {};
     90 }