net/addr/ip: Add InAnyAddr ToStr conversion

Change-Id: I664d53c15df5ab9f6bf9b9e0efa653d5b726896b
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/stdplus/net/addr/ip.hpp b/include/stdplus/net/addr/ip.hpp
index afc7d45..ae320d0 100644
--- a/include/stdplus/net/addr/ip.hpp
+++ b/include/stdplus/net/addr/ip.hpp
@@ -282,6 +282,21 @@
     }
 };
 
+template <>
+struct ToStr<InAnyAddr>
+{
+    using type = InAnyAddr;
+    static constexpr std::size_t buf_size = std::max(ToStr<In4Addr>::buf_size,
+                                                     ToStr<In6Addr>::buf_size);
+
+    template <typename CharT>
+    constexpr CharT* operator()(CharT* buf, InAnyAddr v) const noexcept
+    {
+        return std::visit([=](auto v) { return ToStr<decltype(v)>{}(buf, v); },
+                          v);
+    }
+};
+
 } // namespace stdplus
 
 template <>
@@ -320,3 +335,8 @@
 struct fmt::formatter<stdplus::In6Addr, CharT> :
     stdplus::Format<stdplus::ToStr<stdplus::In6Addr>, CharT>
 {};
+
+template <typename CharT>
+struct fmt::formatter<stdplus::InAnyAddr, CharT> :
+    stdplus::Format<stdplus::ToStr<stdplus::InAnyAddr>, CharT>
+{};
diff --git a/src/net/addr/ip.cpp b/src/net/addr/ip.cpp
index 96b78cd..a17e4fd 100644
--- a/src/net/addr/ip.cpp
+++ b/src/net/addr/ip.cpp
@@ -7,4 +7,5 @@
 template In6Addr FromStr<In6Addr>::operator()(std::string_view) const;
 template char* ToStr<In6Addr>::operator()(char*, In6Addr) const noexcept;
 template InAnyAddr FromStr<InAnyAddr>::operator()(std::string_view) const;
+template char* ToStr<InAnyAddr>::operator()(char*, InAnyAddr) const noexcept;
 } // namespace stdplus
diff --git a/test/net/addr/ip.cpp b/test/net/addr/ip.cpp
index 74e72b2..5493b69 100644
--- a/test/net/addr/ip.cpp
+++ b/test/net/addr/ip.cpp
@@ -163,4 +163,13 @@
         fs("::ffff:192.168.0.1"sv));
 }
 
+TEST(ToStr, InAnyAddr)
+{
+    ToStrHandle<ToStr<InAnyAddr>> tsh;
+    EXPECT_EQ("1.15.3.4", tsh(In4Addr{1, 15, 3, 4}));
+    EXPECT_EQ("ff::", tsh(In6Addr{0, 0xff}));
+
+    EXPECT_EQ("a ff00:: b", fmt::format("a {} b", InAnyAddr{In6Addr{0xff}}));
+}
+
 } // namespace stdplus