4 #ifndef LEXY_DETAIL_SWAR_HPP_INCLUDED
5 #define LEXY_DETAIL_SWAR_HPP_INCLUDED
23 template <
typename CharT>
25 static_assert(
sizeof(CharT) <
sizeof(
swar_int) &&
sizeof(
swar_int) %
sizeof(CharT) == 0);
26 return sizeof(
swar_int) /
sizeof(CharT);
29 template <
typename CharT>
32 template <
typename CharT>
35 if constexpr (std::is_same_v<CharT, LEXY_CHAR8_T>)
39 return std::make_unsigned_t<CharT>(c);
41 template <
typename CharT>
45 template <
typename CharT>
51 for (
auto i = 0u; i != swar_length<CharT>; ++i)
53 result <<= char_bit_size<CharT>;
60 template <
typename CharT>
66 for (
auto i = 0u; i != swar_length<CharT>; ++i)
68 result <<= char_bit_size<CharT>;
75 template <
typename H,
typename... T>
78 if (std::size_t(index) == char_bit_size<swar_int>)
84 _swar_pack(result, index +
int(char_bit_size<H>), t...);
87 template <
typename CharT>
96 constexpr
auto mask = (
swar_int(1) << char_bit_size<CharT>)-1;
97 return (
value >> idx * char_bit_size<CharT>)&
mask;
103 template <
int SkipFirstNChars = 0,
typename... CharT>
106 using char_type = std::common_type_t<CharT...>;
109 _swar_pack(result.value, -SkipFirstNChars *
int(char_bit_size<char_type>), cs...);
111 auto count = int(
sizeof...(CharT)) - SkipFirstNChars;
117 else if (
count >=
int(swar_length<char_type>))
120 result.count = swar_length<char_type>;
125 result.count = std::size_t(
count);
132 template <
typename CharT>
136 return swar_length<CharT>;
138 auto mask = lhs ^ rhs;
140 #if defined(__GNUC__)
141 auto bit_idx = __builtin_ctzll(mask);
142 #elif defined(_MSC_VER)
143 unsigned long bit_idx;
144 if (!_BitScanForward64(&bit_idx, mask))
147 # error "unsupported compiler; please file an issue"
150 return std::size_t(bit_idx) / char_bit_size<CharT>;
154 template <
typename CharT, CharT N>
159 constexpr
auto offset =
swar_fill(CharT(N));
160 auto zero_or_msb = v - offset;
162 constexpr
auto msb_mask =
swar_fill(CharT(1 << (char_bit_size<CharT> - 1)));
163 auto not_msb = ~v & msb_mask;
165 return zero_or_msb & not_msb;
169 template <
typename CharT>
172 return swar_has_char_less<CharT, 1>(v);
176 template <
typename CharT, CharT C>
179 if constexpr (C == 0)
181 return swar_has_zero<CharT>(v);
186 return swar_has_zero<CharT>(v ^ mask);
195 template <
typename Reader>
198 template <
typename Derived>
204 auto ptr =
static_cast<const Derived&
>(*this).position();
207 #if LEXY_IS_LITTLE_ENDIAN
208 std::memcpy(&result, ptr,
sizeof(
swar_int));
211 auto dst =
reinterpret_cast<char*
>(&result);
213 for (
auto i = 0u; i != length; ++i)
215 std::memcpy(dst + i, ptr + length - i - 1,
sizeof(
char_type));
223 auto ptr =
static_cast<Derived&
>(*this).position();
224 ptr += swar_length<typename Derived::encoding::char_type>;
225 static_cast<Derived&
>(*this).reset({ptr});
229 auto ptr =
static_cast<Derived&
>(*this).position();
231 static_cast<Derived&
>(*this).reset({ptr});
238 if (
auto remainder = size_in_bytes %
sizeof(
swar_int); remainder > 0)
239 size_in_bytes +=
sizeof(
swar_int) - remainder;
242 return size_in_bytes;
246 #endif // LEXY_DETAIL_SWAR_HPP_INCLUDED