changeset 384:2ce3d1578339

Socket: add SocketAddressAbstract for DRY on operator
author David Demelier <markand@malikania.fr>
date Tue, 23 Jun 2015 14:54:53 +0200
parents 403fa2642e19
children b732c4431f7d
files C++/modules/Socket/SocketAddress.cpp C++/modules/Socket/SocketAddress.h
diffstat 2 files changed, 67 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/C++/modules/Socket/SocketAddress.cpp	Tue Jun 23 14:47:42 2015 +0200
+++ b/C++/modules/Socket/SocketAddress.cpp	Tue Jun 23 14:54:53 2015 +0200
@@ -22,6 +22,28 @@
 #include "Socket.h"
 #include "SocketAddress.h"
 
+bool operator==(const SocketAddressAbstract &address1, const SocketAddressAbstract &address2) noexcept
+{
+	const char *addr1 = reinterpret_cast<const char *>(&address1.address());
+	const char *addr2 = reinterpret_cast<const char *>(&address2.address());
+
+	return std::equal(
+		addr1, addr1 + address1.length(),
+		addr2, addr2 + address2.length()
+	);
+}
+
+bool operator<(const SocketAddressAbstract &address1, const SocketAddressAbstract &address2) noexcept
+{
+	const char *addr1 = reinterpret_cast<const char *>(&address1.address());
+	const char *addr2 = reinterpret_cast<const char *>(&address2.address());
+
+	return std::lexicographical_compare(
+		addr1, addr1 + address1.length(),
+		addr2, addr2 + address2.length()
+	);
+}
+
 namespace address {
 
 /* --------------------------------------------------------
@@ -94,28 +116,6 @@
 	};
 }
 
-bool operator==(const Ip &ip1, const Ip &ip2) noexcept
-{
-	const char *addr1 = reinterpret_cast<const char *>(&ip1.address());
-	const char *addr2 = reinterpret_cast<const char *>(&ip2.address());
-
-	return std::equal(
-		addr1, addr1 + ip1.length(),
-		addr2, addr2 + ip2.length()
-	);
-}
-
-bool operator<(const Ip &ip1, const Ip &ip2) noexcept
-{
-	const char *addr1 = reinterpret_cast<const char *>(&ip1.address());
-	const char *addr2 = reinterpret_cast<const char *>(&ip2.address());
-
-	return std::lexicographical_compare(
-		addr1, addr1 + ip1.length(),
-		addr2, addr2 + ip2.length()
-	);
-}
-
 /* --------------------------------------------------------
  * Unix implementation
  * -------------------------------------------------------- */
@@ -155,28 +155,6 @@
 	};
 }
 
-bool operator==(const Unix &unix1, const Unix &unix2) noexcept
-{
-	const char *addr1 = reinterpret_cast<const char *>(&unix1.address());
-	const char *addr2 = reinterpret_cast<const char *>(&unix2.address());
-
-	return std::equal(
-		addr1, addr1 + unix1.length(),
-		addr2, addr2 + unix2.length()
-	);
-}
-
-bool operator<(const Unix &unix1, const Unix &unix2) noexcept
-{
-	const char *addr1 = reinterpret_cast<const char *>(&unix1.address());
-	const char *addr2 = reinterpret_cast<const char *>(&unix1.address());
-
-	return std::lexicographical_compare(
-		addr1, addr1 + unix1.length(),
-		addr2, addr2 + unix2.length()
-	);
-}
-
 #endif // _WIN32
 
 } // !address
--- a/C++/modules/Socket/SocketAddress.h	Tue Jun 23 14:47:42 2015 +0200
+++ b/C++/modules/Socket/SocketAddress.h	Tue Jun 23 14:54:53 2015 +0200
@@ -96,6 +96,31 @@
 using SocketAddressInfo = std::unordered_map<std::string, std::string>;
 
 /**
+ * @class SocketAddressAbstract
+ * @brief Generic base class for addresses
+ */
+class SocketAddressAbstract {
+public:
+	/**
+	 * Get the address as base type.
+	 *
+	 * @return the base address reference
+	 */
+	virtual const sockaddr &address() const noexcept = 0;
+
+	/**
+	 * Get the address length.
+	 *
+	 * @return the length
+	 */
+	virtual socklen_t length() const noexcept = 0;
+};
+
+bool operator==(const SocketAddressAbstract &addr1, const SocketAddressAbstract &addr2) noexcept;
+
+bool operator<(const SocketAddressAbstract &addr1, const SocketAddressAbstract &addr2) noexcept;
+
+/**
  * @brief Predefined addresses.
  */
 namespace address {
@@ -110,7 +135,7 @@
  * @see Ipv4
  * @see Ipv6
  */
-class Ip {
+class Ip : public SocketAddressAbstract {
 private:
 	union {
 		sockaddr_in m_sin;
@@ -144,17 +169,9 @@
 	Ip(const sockaddr_storage &ss, socklen_t length);
 
 	/**
-	 * @copydoc SocketAddress::length
-	 */
-	socklen_t length() const noexcept
-	{
-		return (m_domain == AF_INET6) ? sizeof (sockaddr_in6) : sizeof (sockaddr_in);
-	}
-
-	/**
 	 * @copydoc SocketAddress::address
 	 */
-	const sockaddr &address() const noexcept
+	const sockaddr &address() const noexcept override
 	{
 		// Can't get a ternary operator to work here.
 		if (m_domain == AF_INET6)
@@ -164,15 +181,19 @@
 	}
 
 	/**
+	 * @copydoc SocketAddress::length
+	 */
+	socklen_t length() const noexcept override
+	{
+		return (m_domain == AF_INET6) ? sizeof (sockaddr_in6) : sizeof (sockaddr_in);
+	}
+
+	/**
 	 * @copydoc SocketAddress::info
 	 */
 	SocketAddressInfo info() const;
 };
 
-bool operator==(const Ip &ip1, const Ip &ip2) noexcept;
-
-bool operator<(const Ip &ip1, const Ip &ip2) noexcept;
-
 /**
  * @class Ipv6
  * @brief Convenient helper for IPv6 protocol
@@ -225,7 +246,7 @@
  *
  * Create an address to a specific path. Only available on Unix.
  */
-class Unix {
+class Unix : public SocketAddressAbstract {
 private:
 	sockaddr_un m_sun;
 	std::string m_path;
@@ -253,9 +274,17 @@
 	Unix(const sockaddr_storage &ss, socklen_t length);
 
 	/**
+	 * @copydoc SocketAddress::address
+	 */
+	inline const sockaddr &address() const noexcept override
+	{
+		return reinterpret_cast<const sockaddr &>(m_sun);
+	}
+
+	/**
 	 * @copydoc SocketAddress::length
 	 */
-	inline socklen_t length() const noexcept
+	inline socklen_t length() const noexcept override
 	{
 #if defined(SOCKET_HAVE_SUN_LEN)
 		return SUN_LEN(&m_sun);
@@ -265,23 +294,11 @@
 	}
 
 	/**
-	 * @copydoc SocketAddress::address
-	 */
-	inline const sockaddr &address() const noexcept
-	{
-		return reinterpret_cast<const sockaddr &>(m_sun);
-	}
-
-	/**
 	 * @copydoc SocketAddress::info
 	 */
 	SocketAddressInfo info() const;
 };
 
-bool operator==(const Unix &unix1, const Unix &unix2) noexcept;
-
-bool operator<(const Unix &unix1, const Unix &unix2) noexcept;
-
 #endif // !_WIN32
 
 } // !address