Skip to content

Instantly share code, notes, and snippets.

@bqqbarbhg
Last active October 14, 2023 18:57
Show Gist options
  • Save bqqbarbhg/78b57412e1ba00bd61fcf92f4676d605 to your computer and use it in GitHub Desktop.
Save bqqbarbhg/78b57412e1ba00bd61fcf92f4676d605 to your computer and use it in GitHub Desktop.
static const uint32_t ufbxi_number_start_mask =
(((1u << 10) - 1) << ((uint32_t)'0' - 32u)) |
(1u << ((uint32_t)'-' - 32u)) |
(1u << ((uint32_t)'+' - 32u)) |
(1u << ((uint32_t)'.' - 32u)) ;
ufbx_static_assert(ufbxi_number_start_codepoint,
((uint32_t)'9' - (uint32_t)'0') == 9 &&
(uint32_t)'0' >= 32u && (uint32_t)'0' < 64u &&
(uint32_t)'-' >= 32u && (uint32_t)'-' < 64u &&
(uint32_t)'+' >= 32u && (uint32_t)'+' < 64u &&
(uint32_t)'.' >= 32u && (uint32_t)'.' < 64u);
static ufbxi_forceinline bool ufbxi_is_number_start(char c)
{
uint32_t v = (uint32_t)(uint8_t)c - 32u;
return v < 32 && ((ufbxi_number_start_mask >> v) & 0x1) != 0;
}
// We can safely skip over anything of the pattern:
// (\s*[0-9\-+\.][0-9\-+\.eE]*\s*,)*
#if 0
uint32_t num_deferred = 0;
{
__m128i c_digit_lo = _mm_set1_epi8('0' - 1);
__m128i c_digit_hi = _mm_set1_epi8('9' + 1);
__m128i c_minus = _mm_set1_epi8('-');
__m128i c_plus = _mm_set1_epi8('+');
__m128i c_dot = _mm_set1_epi8('.');
__m128i c_e = _mm_set1_epi8('e');
__m128i c_lowercase = _mm_set1_epi8(0x20);
const char *src_next = src;
const char *src_defer = src;
for (;;) {
while (src_defer != end && ufbxi_is_space(*src_defer)) src_defer++;
if (src_defer == end || *src_defer != ',') break;
src_defer++;
while (src_defer != end && ufbxi_is_space(*src_defer)) src_defer++;
src_next = src_defer;
num_deferred += 1;
char c = *src_defer;
if (!ufbxi_is_number_start(c)) break;
uint32_t count = 0;
for (;;) {
if (ufbxi_to_size(end - src_defer) <= 16) break;
__m128i a = _mm_loadu_si128((const __m128i*)src_defer);
__m128i eq;
eq = _mm_and_si128(_mm_cmpgt_epi8(a, c_digit_lo), _mm_cmplt_epi8(a, c_digit_hi));
eq = _mm_or_si128(eq, _mm_cmpeq_epi8(_mm_or_si128(a, c_lowercase), c_e));
eq = _mm_or_si128(eq, _mm_cmpeq_epi8(a, c_minus));
eq = _mm_or_si128(eq, _mm_cmpeq_epi8(a, c_plus));
eq = _mm_or_si128(eq, _mm_cmpeq_epi8(a, c_dot));
uint32_t mask = _mm_movemask_epi8(eq);
count = ufbxi_tzcnt32(~mask);
if (count < 16) break;
src_defer += 16;
}
src_defer += count;
}
if (num_deferred > 1) {
if (type == 'd') {
double *v = ufbxi_push(&uc->tmp_stack, double, num_deferred);
ufbxi_check(v);
*v = (double)val;
} else if (type == 'f') {
float *v = ufbxi_push(&uc->tmp_stack, float, num_deferred);
ufbxi_check(v);
*v = (float)val;
}
size_t length = src_next - src;
ufbxi_float_span *span = ufbxi_push(&uc->tmp_ascii_spans, ufbxi_float_span, 1);
ufbxi_check(span);
span->count = num_deferred - 1;
span->source_length = length;
if (ua->src_is_retained || !uc->read_fn) {
span->source = src;
} else {
span->source = ufbxi_push_copy(tmp_buf, char, length, src);
}
span->offset = num_values + 1;
ufbxi_check(span->source);
ua->retain_buf = tmp_buf;
ua->src = src_next;
ufbxi_check(ufbxi_ascii_next_token(uc, &ua->token));
ua->retain_buf = NULL;
*p_num_read = num_deferred;
return 1;
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment