#ifndef _SOCKET_HPP #define _SOCKET_HPP #include "AsyncManager.hpp" #include #include #ifndef PLATFORM_WINDOWS # include # include #else # include #endif class Socket { int fd; protected: void reset() { fd = -1; } void set(int _fd) { fd = _fd; } public: using Port = uint16_t; Socket() : fd(-1) {} Socket(int domain, int type, int protocol) { fd = socket(domain, type, protocol); } Socket(Socket&) = delete; Socket(const Socket&) = delete; Socket(Socket&& o) : fd(o.fd) { o.fd = -1; } auto& operator =(Socket&& o) { close(fd); fd = o.fd; o.fd = -1; return *this; } ~Socket() { close(fd); } operator int() const { return fd; } int get() const { return fd; } }; template class SocketConnection : public SenderT, public ReceiverT, public Socket { public: SocketConnection(AsyncManager& asyncManager, Socket&& socket) // Double-initialization seems to yield better assembly : SenderT(asyncManager, socket), ReceiverT(asyncManager, socket), Socket(std::move(socket)) { SenderT::fd = get(); ReceiverT::fd = get(); } }; #endif