module; #include module tricks; import std; namespace brc { std::size_t find_delim(std::string_view string, char target) { constexpr auto width = std::simd::vec::size(); const auto needle = std::simd::vec(static_cast(target)); auto i = std::size_t(0); for (; i + width <= string.size(); i += width) { const auto chunk = std::simd::vec( std::span(reinterpret_cast(string.data() + i), width)); const auto mask = chunk == needle; if (const auto bits = mask.to_bitset(); bits.any()) { return i + std::countr_zero(bits.to_ullong()); } } for (; i < string.size(); ++i) { if (string[i] == target) return i; } return string.size(); } std::inplace_vector find_delim_batch(std::string_view string, char target) { constexpr auto BatchSize = 4; auto sizes = std::inplace_vector(); constexpr auto width = std::simd::vec::size(); const auto needle = std::simd::vec(static_cast(target)); std::size_t i = 0; for (; i + width <= string.size() && sizes.size() < BatchSize; i += width) { const auto chunk = std::simd::vec( std::span(reinterpret_cast(string.data() + i), width)); const auto mask = chunk == needle; auto bits = mask.to_bitset().to_ullong(); while (bits != 0 && sizes.size() < BatchSize) { const auto bit_pos = std::countr_zero(bits); sizes.push_back(i + bit_pos); bits &= bits - 1; } } for (; i < string.size() && sizes.size() < BatchSize; ++i) { if (string[i] == target) { sizes.push_back(i); } } return sizes; } } // namespace brc