#pragma once

#include <winsock2.h>

class UniqueSocket
{
public:
	explicit UniqueSocket(SOCKET socket = INVALID_SOCKET) : mSocket(socket) {}
	~UniqueSocket() { reset(); }

	UniqueSocket(const UniqueSocket&) = delete;
	UniqueSocket& operator=(const UniqueSocket&) = delete;

	UniqueSocket(UniqueSocket&& other) noexcept : mSocket(other.release()) {}

	UniqueSocket& operator=(UniqueSocket&& other) noexcept
	{
		if (this != &other)
			reset(other.release());
		return *this;
	}

	SOCKET get() const { return mSocket; }
	bool valid() const { return mSocket != INVALID_SOCKET; }

	SOCKET release()
	{
		SOCKET socket = mSocket;
		mSocket = INVALID_SOCKET;
		return socket;
	}

	void reset(SOCKET socket = INVALID_SOCKET)
	{
		if (valid())
			closesocket(mSocket);
		mSocket = socket;
	}

private:
	SOCKET mSocket;
};
