28inline auto scan_ipv4_avx2(std::string_view text, IPv4Scan& scan)
noexcept
30 const auto full_words = text.size() / 4u;
31 const auto load_mask =
32 _mm_setr_epi32(full_words > 0 ? -1 : 0, full_words > 1 ? -1 : 0,
33 full_words > 2 ? -1 : 0, 0);
35 _mm_maskload_epi32(
reinterpret_cast<const int*
>(text.data()), load_mask);
36 const auto dots = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(
'.'));
38 const auto full_bytes = full_words * 4u;
39 scan.dot_mask =
static_cast<uint32_t
>(_mm_movemask_epi8(dots)) &
40 ((uint32_t{1} << full_bytes) - 1u);
41 for (std::size_t i = full_bytes; i < text.size(); ++i) {
43 scan.dot_mask |= uint32_t{1} << i;
52 for (std::size_t i = 0; i < text.size(); ++i) {
54 scan.dot_mask |= uint32_t{1} << i;
62 return scan_ipv4_avx2(text, scan);
75 -> std::optional<IPv4Address> {
76 if (std::popcount(scan.dot_mask) != 3) {
81 std::size_t begin = 0;
83 uint32_t remaining_dots = scan.dot_mask;
86 const std::size_t end =
87 remaining_dots == 0 ? text.size() : std::countr_zero(remaining_dots);
88 const std::size_t digits = end - begin;
89 if (digits == 0 || digits > 3)
91 if (digits > 1 && text[begin] ==
'0')
95 for (std::size_t i = begin; i < end; ++i) {
96 const char c = text[i];
97 if (c <
'0' || c >
'9')
99 value = value * 10u +
static_cast<uint32_t
>(c -
'0');
104 out.
bytes[part] =
static_cast<uint8_t
>(value);
106 if (remaining_dots == 0)
109 remaining_dots &= remaining_dots - 1u;
129[[nodiscard]]
inline auto parse_ipv4(std::string_view text)
noexcept
130 -> std::optional<IPv4Address> {
131 if (text.empty() || text.size() > 15) {
147template <std::
size_t N>
148[[nodiscard]]
inline auto parse_ipv4(
const char (&text)[N])
noexcept
149 -> std::optional<IPv4Address> {
150 static_assert(N > 0);
151 const std::size_t length = text[N - 1] ==
'\0' ? N - 1 : N;
152 return parse_ipv4(std::string_view{text, length});
Definition classify.hxx:5
auto scan_ipv4_scalar(std::string_view text, IPv4Scan &scan) noexcept -> bool
Scan IPv4 text for dot positions with portable scalar code.
Definition ipv4.hxx:50
auto parse_ipv4_from_scan(std::string_view text, IPv4Scan scan) noexcept -> std::optional< IPv4Address >
Parse IPv4 bytes after dot positions have been collected.
Definition ipv4.hxx:74
auto scan_ipv4(std::string_view text, IPv4Scan &scan) noexcept -> bool
Scan IPv4 text with the best enabled implementation.
Definition ipv4.hxx:60
auto parse_ipv4(std::string_view text) noexcept -> std::optional< IPv4Address >
Parse strict dotted-decimal IPv4 text.
Definition ipv4.hxx:129
SIMD feature detection and include for VIPA.
Parsed IPv4 address in network byte order.
Definition address.hxx:14
std::array< uint8_t, 4 > bytes
Definition address.hxx:17
Character-position masks collected while scanning IPv4 text.
Definition ipv4.hxx:16
uint32_t dot_mask
Definition ipv4.hxx:18