#ifndef _SOCKET_HPP
#define _SOCKET_HPP
#include <memory>
#include <unistd.h>
#if defined(PLATFORM_WINDOWS)
#   include <ws2tcpip.h>
#elif defined(PLATFORM_WII)
#include <network.h>
#else
#   include <sys/socket.h>
#   include <sys/select.h>
#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 SenderT, class ReceiverT>
class SocketConnection : public SenderT, public ReceiverT, public Socket {
public:
    SocketConnection(Socket&& socket)
        // Double-initialization seems to yield better assembly
        : SenderT(socket), ReceiverT(socket), Socket(std::move(socket)) {
        SenderT::fd = get();
        ReceiverT::fd = get();
    }
};
#endif