net/addr/ip: Refactor string literal compilation
This makes it possible to re-use the function for subnets too.
Change-Id: I452446a42db5227956bd825aecf9d51cabf884cb
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 601c217..c35fb44 100644
--- a/include/stdplus/net/addr/ip.hpp
+++ b/include/stdplus/net/addr/ip.hpp
@@ -421,20 +421,25 @@
}
};
+template <typename Addr>
+concept InAddr = std::same_as<Addr, In4Addr> || std::same_as<Addr, In6Addr> ||
+ std::same_as<Addr, InAnyAddr>;
+
namespace detail
{
-template <typename Addr, typename CharT, std::size_t N>
-struct CompileInAddr
+template <typename Addr>
+struct CompileInAddrInt;
+
+template <InAddr Addr>
+struct CompileInAddrInt<Addr>
{
- CharT str[N - 1];
Addr addr = {};
bool valid = true;
- constexpr CompileInAddr(const CharT (&str)[N]) noexcept
+ template <typename CharT>
+ constexpr void compile(std::basic_string_view<CharT> sv) noexcept
{
- std::copy(str, str + N - 1, this->str);
- std::basic_string_view<CharT> sv{this->str, N - 1};
try
{
addr = fromStr<Addr>(sv);
@@ -446,6 +451,49 @@
}
};
+template <>
+struct CompileInAddrInt<InAnyAddr>
+{
+ union
+ {
+ stdplus::In4Addr addr4;
+ stdplus::In6Addr addr6;
+ } u = {.addr4 = {}};
+ bool v4 = true;
+ bool valid = true;
+
+ template <typename CharT>
+ constexpr void compile(std::basic_string_view<CharT> sv) noexcept
+ {
+ try
+ {
+ if (sv.find(':') == sv.npos)
+ {
+ u = {.addr4 = FromStr<In4Addr>{}(sv)};
+ return;
+ }
+ u = {.addr6 = FromStr<In6Addr>{}(sv)};
+ v4 = false;
+ }
+ catch (...)
+ {
+ valid = false;
+ }
+ }
+};
+
+template <typename Addr, typename CharT, std::size_t N>
+struct CompileInAddr : CompileInAddrInt<Addr>
+{
+ CharT str[N - 1];
+
+ constexpr CompileInAddr(const CharT (&str)[N]) noexcept
+ {
+ std::copy(str, str + N - 1, this->str);
+ this->compile(std::basic_string_view{this->str, N - 1});
+ }
+};
+
template <typename CharT, std::size_t N>
struct CompileIn4Addr : CompileInAddr<In4Addr, CharT, N>
{
@@ -463,37 +511,11 @@
};
template <typename CharT, std::size_t N>
-struct CompileInAnyAddr
+struct CompileInAnyAddr : CompileInAddr<InAnyAddr, CharT, N>
{
- 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;
- }
- }
+ CompileInAddr<InAnyAddr, CharT, N>(str)
+ {}
};
} // namespace detail
@@ -568,17 +590,7 @@
}
};
-template <typename CharT>
-struct fmt::formatter<stdplus::In4Addr, CharT> :
- stdplus::Format<stdplus::ToStr<stdplus::In4Addr>, CharT>
-{};
-
-template <typename CharT>
-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>
+template <stdplus::InAddr Addr, typename CharT>
+struct fmt::formatter<Addr, CharT> :
+ stdplus::Format<stdplus::ToStr<Addr>, CharT>
{};