net/addr/ip: Add InAnyAddr compile time strings
Change-Id: Ib4bf557b9991afd3087577190dd4d03eb2abca1f
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 6987255..b2c5350 100644
--- a/include/stdplus/net/addr/ip.hpp
+++ b/include/stdplus/net/addr/ip.hpp
@@ -447,6 +447,40 @@
{}
};
+template <typename CharT, std::size_t N>
+struct CompileInAnyAddr
+{
+ CharT str[N - 1];
+ union
+ {
+ stdplus::In4Addr addr4;
+ stdplus::In6Addr addr6;
+ } u;
+ bool v4 = true;
+ bool valid = true;
+
+ constexpr CompileInAnyAddr(const CharT (&str)[N]) noexcept :
+ u({.addr4 = {}})
+ {
+ std::copy(str, str + N - 1, this->str);
+ std::basic_string_view<CharT> sv{this->str, N - 1};
+ try
+ {
+ if (sv.find(':') == sv.npos)
+ {
+ u = {.addr4 = FromStr<In4Addr>{}(sv)};
+ return;
+ }
+ u = {.addr6 = FromStr<In6Addr>{}(sv)};
+ v4 = false;
+ }
+ catch (...)
+ {
+ valid = false;
+ }
+ }
+};
+
} // namespace detail
inline namespace in_addr_literals
@@ -466,6 +500,13 @@
return Str.addr;
}
+template <detail::CompileInAnyAddr Str>
+constexpr auto operator"" _ip() noexcept
+{
+ static_assert(Str.valid, "stdplus::InAnyAddr");
+ return Str.v4 ? InAnyAddr(Str.u.addr4) : InAnyAddr(Str.u.addr6);
+}
+
} // namespace in_addr_literals
} // namespace stdplus
diff --git a/test/net/addr/ip.cpp b/test/net/addr/ip.cpp
index 4256e42..acb88c1 100644
--- a/test/net/addr/ip.cpp
+++ b/test/net/addr/ip.cpp
@@ -188,6 +188,30 @@
EXPECT_EQ(
(In6Addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 0, 1}),
fs("::ffff:192.168.0.1"sv));
+
+ constexpr bool tv = detail::CompileInAnyAddr("192.0.0.0").valid;
+ EXPECT_TRUE(tv);
+ constexpr bool tv2 = detail::CompileInAnyAddr("::").valid;
+ EXPECT_TRUE(tv2);
+ EXPECT_EQ((In4Addr{}), "0.0.0.0"_ip);
+ EXPECT_EQ((In6Addr{}), "::"_ip);
+ EXPECT_EQ("ff02::"_ip, (In6Addr{0xff, 2}));
+ EXPECT_EQ("1::"_ip, (In6Addr{0, 1}));
+ EXPECT_EQ("100::"_ip, (In6Addr{1}));
+ EXPECT_EQ("2::"_ip, (In6Addr{0, 2}));
+ EXPECT_EQ("ff::"_ip, (In6Addr{0, 0xff}));
+ EXPECT_EQ("::100"_ip,
+ (In6Addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}));
+ EXPECT_EQ("::1"_ip,
+ (In6Addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}));
+ EXPECT_EQ("::2"_ip,
+ (In6Addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}));
+ EXPECT_EQ("::ff"_ip,
+ (In6Addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff}));
+ EXPECT_EQ("1::1"_ip,
+ (In6Addr{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}));
+ EXPECT_EQ("5::b"_ip,
+ (In6Addr{0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xb}));
}
TEST(ToStr, InAnyAddr)