@geofflangdale 's code seems to "define" characters to be one of '\t', '\n', '\r', ' ' from reading of the code.
One issue to contend with is that the definition of "white space" depends on the character encoding, so UTF-8 has other white space characters.
Anyhow, let us look at whether what Geoff does is optimally efficient...
The code to detect white space looks like this...
__m256i v_lo = _mm256_and_si256(
_mm256_shuffle_epi8(low_nibble_mask, input_lo),
_mm256_shuffle_epi8(high_nibble_mask,
_mm256_and_si256(_mm256_srli_epi32(input_lo, 4),
_mm256_set1_epi8(0x7f))));
__m256i tmp_ws_lo = _mm256_cmpeq_epi8(
_mm256_and_si256(v_lo, whitespace_shufti_mask), _mm256_set1_epi8(0));
So AND, SHUF, SHUF, AND, SHIFT, CMP, AND...
And then I guess you have to negate the result...
It sure is complicated!!!
I think you can do it more cheaply... (OR, CMP, SHUF, ADDS) and detect all of the five ASCII white space characters (tab, line feed, line tabulation, form feed, carriage return, space):
__m128i mask_20 = _mm_set1_epi8( 0x20 );// c==32
__m128i mask_70 = _mm_set1_epi8( 0x70 );// adding 0x70 does not check low 4-bits
// but moves any value >= 16 above 128
//for 9 <= c <= 13:
__m128i lut_cntrl = _mm_setr_epi8(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00);
__m128i v = ... // your data
__m128i bytemask = _mm_or_si128(_mm_cmpeq_epi8(mask_20, v),
_mm_shuffle_epi8(lut_cntrl, _mm_adds_epu8(mask_70, v)));
// bytemask has 0xFF on ASCII white space