fd/ops: Support our sock class natively

Change-Id: Ib79331dc34a480594e44731457c69b2f6a73f96a
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include-fd/stdplus/fd/ops.hpp b/include-fd/stdplus/fd/ops.hpp
index 74cba26..c77b6d6 100644
--- a/include-fd/stdplus/fd/ops.hpp
+++ b/include-fd/stdplus/fd/ops.hpp
@@ -1,6 +1,7 @@
 #pragma once
 #include <stdplus/fd/dupable.hpp>
 #include <stdplus/fd/intf.hpp>
+#include <stdplus/net/addr/sock.hpp>
 #include <stdplus/raw.hpp>
 
 #include <span>
@@ -101,14 +102,32 @@
     return fd.truncate(size);
 }
 
-template <typename SockAddr>
-inline void bind(Fd& fd, SockAddr&& sockaddr)
+inline void bind(Fd& fd, const SockAddrBuf& addr)
+{
+    return fd.bind({reinterpret_cast<const std::byte*>(&addr), addr.len});
+}
+
+inline void bind(Fd& fd, const SockAddr auto& addr)
+{
+    return bind(fd, addr.buf());
+}
+
+inline void bind(Fd& fd, const auto& sockaddr)
 {
     return fd.bind(raw::asSpan<std::byte>(sockaddr));
 }
 
-template <typename SockAddr>
-inline void connect(Fd& fd, SockAddr&& sockaddr)
+inline void connect(Fd& fd, const SockAddrBuf& addr)
+{
+    return fd.connect({reinterpret_cast<const std::byte*>(&addr), addr.len});
+}
+
+inline void connect(Fd& fd, const SockAddr auto& addr)
+{
+    return connect(fd, addr.buf());
+}
+
+inline void connect(Fd& fd, const auto& sockaddr)
 {
     return fd.connect(raw::asSpan<std::byte>(sockaddr));
 }
diff --git a/test/fd/ops.cpp b/test/fd/ops.cpp
index 0a7638f..dde1788 100644
--- a/test/fd/ops.cpp
+++ b/test/fd/ops.cpp
@@ -22,6 +22,19 @@
     EXPECT_EQ(0, static_cast<int>(f));
 }
 
+TEST(Connect, Success)
+{
+    testing::StrictMock<FdMock> fd;
+    SockAddrBuf buf;
+    EXPECT_CALL(fd, connect(_)).WillOnce([&](std::span<const std::byte> addr) {
+        std::copy(addr.begin(), addr.end(), reinterpret_cast<std::byte*>(&buf));
+        buf.len = addr.size();
+    });
+    Sock6Addr addr(In6Addr{0xff}, 365, 0);
+    connect(fd, addr);
+    EXPECT_EQ(Sock6Addr::fromBuf(buf), addr);
+}
+
 TEST(ReadExact, Success)
 {
     testing::StrictMock<FdMock> fd;