source: icXML/icXML-devel/src/icxmlc/XMLScanIterator.hpp @ 3583

Last change on this file since 3583 was 3583, checked in by nmedfort, 5 years ago

more compile fixes

File size: 27.9 KB
Line 
1/*
2 *  Copyright © 2012 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icXML is a trademark of International Characters.
5 */
6
7/*
8 * @author Nigel Medforth, nigelm -at- interational-characters.com
9 * @version $Id: XMLScanIterator.hpp 384 2013-10-21 22:28:13Z nigelm $
10 *
11 */
12
13#ifndef XMLSCANITERATOR_HPP
14#define XMLSCANITERATOR_HPP
15
16#include <icxmlc/XMLConfig.hpp>
17
18XERCES_CPP_NAMESPACE_BEGIN
19
20typedef scanword_t iterator_t;
21
22/// ---------------------------------------------------------------------------------------------------------------
23
24template <XMLCh Char>
25class XMLChIterator
26{
27public:
28
29        XMLChIterator(const XMLCh* string, const XMLSize_t length)
30        : fIterator(0)
31        , fOffset(0)
32        , fPosition(0)
33        , fNextOffset(0)
34        , fString(string)
35        , fLength(length)
36    , fComplementMask(0)
37        {
38                scan();
39        }
40
41        bool next()
42        {
43                while (!fIterator)
44                {
45                        if (unlikely(!scan()))
46                        {
47                                return 0;
48                        }
49                }
50
51        const size_t pos = scan_forward_zeroes(fIterator);
52
53        fPosition = fOffset + pos;
54
55                fIterator &= (fIterator - 1);
56
57        fComplementMask &= ~mask(pos);
58        fComplementMask &= (fComplementMask - 1);
59
60                return 1;
61        }
62
63    bool nextc()
64    {
65        iterator_t temp = (~fIterator) & fComplementMask;
66        while (!temp)
67        {
68            if (likely(scan()))
69            {               
70                temp = (~fIterator) & fComplementMask;
71                continue;
72            }
73            return 0;
74        }
75
76        const iterator_t pos = scan_forward_zeroes(temp);
77        fPosition = fOffset + pos;
78        fIterator &= ~mask(pos);
79        return 1;
80    }
81
82        iterator_t pos()
83        {
84                return fPosition;
85        }
86
87private:
88
89    IDISA_ALWAYS_INLINE
90    static iterator_t mask(const size_t pos)
91    {
92        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
93    }
94
95    IDISA_ALWAYS_INLINE
96    static iterator_t load(const BytePack * string, size_t index)
97        {
98        BytePack b0 = bitblock::load_unaligned(&string[index]);
99        BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
100
101        const BytePack mask1 = simd<16>::constant<Char>();
102                BytePack t0 = simd<16>::eq(b0, mask1);
103                BytePack t1 = simd<16>::eq(b1, mask1);
104
105        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
106        }
107
108    IDISA_ALWAYS_INLINE
109    bool scan()
110    {
111        if (unlikely(fLength == 0))
112        {
113            return 0;
114        }
115
116        fOffset = fNextOffset;
117
118        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
119
120        #ifdef __ARCH_64
121        if (likely(fLength >= 64))
122        {
123            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
124            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
125            fNextOffset += 64;
126            fLength -= 64;
127        }
128        else
129        {
130            if (fLength >= 48)
131            {
132                fComplementMask = mask(48 | (fLength & 15));
133                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
134            }
135            else if (fLength >= 32)
136            {
137                fComplementMask = mask(32 | (fLength & 15));
138                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
139            }
140            else
141            {
142                fComplementMask = mask(fLength);
143                fIterator = (load(string, 0) | (load(string, 2) << 16));
144            }
145            fIterator &= fComplementMask;
146            fLength = 0;
147        }
148        #else
149        if (likely(fLength >= 32))
150        {
151            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
152            fIterator = (load(string, 0) | (load(string, 2) << 16));
153            fNextOffset += 32;
154            fLength -= 32;
155        }
156        else
157        {
158            if (fLength >= 16)
159            {
160                fComplementMask = mask(16 | (fLength & 15));
161                fIterator = (load(string, 0) | (load(string, 2) << 16));
162            }
163            else
164            {
165                fComplementMask = mask(fLength);
166                fIterator = (load(string, 0) | (load(string, 2) << 16));
167            }
168            fIterator &= fComplementMask;
169            fLength = 0;
170        }
171        #endif
172
173        return 1;
174    }
175
176
177private:
178
179        iterator_t                              fIterator;
180        iterator_t                              fOffset;
181        iterator_t                              fPosition;
182
183        iterator_t                              fNextOffset;
184        const XMLCh *                   fString;
185    size_t                  fLength;
186    iterator_t              fComplementMask;
187};
188
189/// ---------------------------------------------------------------------------------------------------------------
190
191template <XMLCh Char1, XMLCh Char2>
192class XMLChIterator2
193{
194public:
195
196        XMLChIterator2(const XMLCh* string, const XMLSize_t length)
197        : fIterator(0)
198        , fOffset(0)
199        , fPosition(0)
200        , fNextOffset(0)
201        , fString(string)
202        , fLength(length)
203    , fComplementMask(0)
204        {
205                scan();
206        }
207
208
209    bool next()
210    {
211        while (!fIterator)
212        {
213            if (unlikely(!scan()))
214            {
215                return 0;
216            }
217        }
218
219        const size_t pos = scan_forward_zeroes(fIterator);
220
221        fPosition = fOffset + pos;
222
223        fIterator &= (fIterator - 1);
224
225        fComplementMask &= ~mask(pos);
226        fComplementMask &= (fComplementMask - 1);
227
228        return 1;
229    }
230
231    bool nextc()
232    {
233        iterator_t temp = (~fIterator) & fComplementMask;
234        while (!temp)
235        {
236            if (likely(scan()))
237            {
238                temp = (~fIterator) & fComplementMask;
239                continue;
240            }
241            return 0;
242        }
243
244        const iterator_t pos = scan_forward_zeroes(temp);
245        fPosition = fOffset + pos;
246        fIterator &= ~mask(pos);
247        return 1;
248    }
249
250
251        iterator_t pos()
252        {
253                return fPosition;
254        }
255
256private:
257
258    IDISA_ALWAYS_INLINE
259    static iterator_t mask(const size_t pos)
260    {
261        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
262    }
263
264    IDISA_ALWAYS_INLINE
265    iterator_t load(const BytePack * string, size_t index)
266        {
267                const BytePack mask1 = simd<16>::constant<Char1>();
268                const BytePack mask2 = simd<16>::constant<Char2>();
269
270                BytePack b0 = bitblock::load_unaligned(&string[index]);
271                BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
272
273                BytePack t0 = simd<16>::eq(b0, mask1);
274        BytePack t1 = simd<16>::eq(b1, mask1);
275
276                t0 = simd_or(t0, simd<16>::eq(b0, mask2));
277                t1 = simd_or(t1, simd<16>::eq(b1, mask2));
278
279        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
280        }
281
282    IDISA_ALWAYS_INLINE
283    bool scan()
284    {
285        if (unlikely(fLength == 0))
286        {
287            return 0;
288        }
289
290        fOffset = fNextOffset;
291
292        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
293
294        #ifdef __ARCH_64
295        if (likely(fLength >= 64))
296        {
297            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
298            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
299            fNextOffset += 64;
300            fLength -= 64;
301        }
302        else
303        {
304            if (fLength >= 48)
305            {
306                fComplementMask = mask(48 | (fLength & 15));
307                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
308            }
309            else if (fLength >= 32)
310            {
311                fComplementMask = mask(32 | (fLength & 15));
312                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
313            }
314            else
315            {
316                fComplementMask = mask(fLength);
317                fIterator = (load(string, 0) | (load(string, 2) << 16));
318            }
319            fIterator &= fComplementMask;
320            fLength = 0;
321        }
322        #else
323        if (likely(fLength >= 32))
324        {
325            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
326            fIterator = (load(string, 0) | (load(string, 2) << 16));
327            fNextOffset += 32;
328            fLength -= 32;
329        }
330        else
331        {
332            if (fLength >= 16)
333            {
334                fComplementMask = mask(16 | (fLength & 15));
335                fIterator = (load(string, 0) | (load(string, 2) << 16));
336            }
337            else
338            {
339                fComplementMask = mask(fLength);
340                fIterator = (load(string, 0) | (load(string, 2) << 16));
341            }
342            fIterator &= fComplementMask;
343            fLength = 0;
344        }
345        #endif
346
347        return 1;
348    }
349
350private:
351
352        iterator_t                              fIterator;
353        iterator_t                              fOffset;
354        iterator_t                              fPosition;
355
356        iterator_t                              fNextOffset;
357        const XMLCh *                   fString;
358    size_t                  fLength;
359    iterator_t              fComplementMask;
360};
361
362/// ---------------------------------------------------------------------------------------------------------------
363
364template <XMLCh Char1, XMLCh Char2, XMLCh Char3>
365class XMLChIterator3
366{
367public:
368
369        XMLChIterator3(const XMLCh* string, const XMLSize_t length)
370        : fIterator(0)
371        , fOffset(0)
372        , fPosition(0)
373        , fNextOffset(0)
374        , fString(string)
375        , fLength(length)
376    , fComplementMask(0)
377        {
378                scan();
379        }
380
381    bool next()
382    {
383        while (!fIterator)
384        {
385            if (unlikely(!scan()))
386            {
387                return 0;
388            }
389        }
390
391        const size_t pos = scan_forward_zeroes(fIterator);
392
393        fPosition = fOffset + pos;
394
395        fIterator &= (fIterator - 1);
396
397        fComplementMask &= ~mask(pos);
398        fComplementMask &= (fComplementMask - 1);
399
400        return 1;
401    }
402
403    bool nextc()
404    {
405        iterator_t temp = (~fIterator) & fComplementMask;
406        while (!temp)
407        {
408            if (likely(scan()))
409            {
410                temp = (~fIterator) & fComplementMask;
411                continue;
412            }
413            return 0;
414        }
415
416        const iterator_t pos = scan_forward_zeroes(temp);
417        fPosition = fOffset + pos;
418        fIterator &= ~mask(pos);
419        return 1;
420    }
421
422        iterator_t pos()
423        {
424                return fPosition;
425        }
426
427private:
428
429    IDISA_ALWAYS_INLINE
430    iterator_t load(const BytePack * string, size_t index)
431        {
432                const BytePack mask1 = simd<16>::constant<Char1>();
433                const BytePack mask2 = simd<16>::constant<Char2>();
434                const BytePack mask3 = simd<16>::constant<Char3>();
435
436                BytePack b0 = bitblock::load_unaligned(&string[index]);
437                BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
438
439                BytePack t0 = simd<16>::eq(b0, mask1);
440                t0 = simd_or(t0, simd<16>::eq(b0, mask2));
441                t0 = simd_or(t0, simd<16>::eq(b0, mask3));
442
443                BytePack t1 = simd<16>::eq(b1, mask1);
444                t1 = simd_or(t1, simd<16>::eq(b1, mask2));
445                t1 = simd_or(t1, simd<16>::eq(b1, mask3));
446
447        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
448        }
449
450    IDISA_ALWAYS_INLINE
451    static iterator_t mask(const size_t pos)
452    {
453        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
454    }
455
456    IDISA_ALWAYS_INLINE
457    bool scan()
458    {
459        if (unlikely(fLength == 0))
460        {
461            return 0;
462        }
463
464        fOffset = fNextOffset;
465
466        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
467
468        #ifdef __ARCH_64
469        if (likely(fLength >= 64))
470        {
471            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
472            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
473            fNextOffset += 64;
474            fLength -= 64;
475        }
476        else
477        {
478            if (fLength >= 48)
479            {
480                fComplementMask = mask(48 | (fLength & 15));
481                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
482            }
483            else if (fLength >= 32)
484            {
485                fComplementMask = mask(32 | (fLength & 15));
486                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
487            }
488            else
489            {
490                fComplementMask = mask(fLength);
491                fIterator = (load(string, 0) | (load(string, 2) << 16));
492            }
493            fIterator &= fComplementMask;
494            fLength = 0;
495        }
496        #else
497        if (likely(fLength >= 32))
498        {
499            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
500            fIterator = (load(string, 0) | (load(string, 2) << 16));
501            fNextOffset += 32;
502            fLength -= 32;
503        }
504        else
505        {
506            if (fLength >= 16)
507            {
508                fComplementMask = mask(16 | (fLength & 15));
509                fIterator = (load(string, 0) | (load(string, 2) << 16));
510            }
511            else
512            {
513                fComplementMask = mask(fLength);
514                fIterator = (load(string, 0) | (load(string, 2) << 16));
515            }
516            fIterator &= fComplementMask;
517            fLength = 0;
518        }
519        #endif
520
521        return 1;
522    }
523
524private:
525
526        iterator_t                              fIterator;
527        iterator_t                              fOffset;
528        iterator_t                              fPosition;
529
530        iterator_t                              fNextOffset;
531        const XMLCh *                   fString;
532    size_t                  fLength;
533    iterator_t              fComplementMask;
534};
535
536/// ---------------------------------------------------------------------------------------------------------------
537
538template <XMLCh Char1, XMLCh Char2, XMLCh Char3, XMLCh Char4>
539class XMLChIterator4
540{
541public:
542
543    XMLChIterator4(const XMLCh* string, const XMLSize_t length)
544    : fIterator(0)
545    , fOffset(0)
546    , fPosition(0)
547    , fNextOffset(0)
548    , fString(string)
549    , fLength(length)
550    , fComplementMask(0)
551    {
552        scan();
553    }
554
555    bool next()
556    {
557        while (!fIterator)
558        {
559            if (unlikely(!scan()))
560            {
561                return 0;
562            }
563        }
564
565        const size_t pos = scan_forward_zeroes(fIterator);
566
567        fPosition = fOffset + pos;
568
569        fIterator &= (fIterator - 1);
570
571        fComplementMask &= ~mask(pos);
572        fComplementMask &= (fComplementMask - 1);
573
574        return 1;
575    }
576
577    bool nextc()
578    {
579        iterator_t temp = (~fIterator) & fComplementMask;
580        while (!temp)
581        {
582            if (likely(scan()))
583            {
584                temp = (~fIterator) & fComplementMask;
585                continue;
586            }
587            return 0;
588        }
589
590        const iterator_t pos = scan_forward_zeroes(temp);
591        fPosition = fOffset + pos;
592        fIterator &= ~mask(pos);
593        return 1;
594    }
595
596    iterator_t pos()
597    {
598        return fPosition;
599    }
600
601private:
602
603    IDISA_ALWAYS_INLINE
604    iterator_t load(const BytePack * string, size_t index)
605    {
606        const BytePack mask1 = simd<16>::constant<Char1>();
607        const BytePack mask2 = simd<16>::constant<Char2>();
608        const BytePack mask3 = simd<16>::constant<Char3>();
609        const BytePack mask4 = simd<16>::constant<Char4>();
610
611        BytePack b0 = bitblock::load_unaligned(&string[index]);
612        BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
613
614        BytePack t0 = simd<16>::eq(b0, mask1);
615        t0 = simd_or(t0, simd<16>::eq(b0, mask2));
616        t0 = simd_or(t0, simd<16>::eq(b0, mask3));
617        t0 = simd_or(t0, simd<16>::eq(b0, mask4));
618
619        BytePack t1 = simd<16>::eq(b1, mask1);
620        t1 = simd_or(t1, simd<16>::eq(b1, mask2));
621        t1 = simd_or(t1, simd<16>::eq(b1, mask3));
622        t1 = simd_or(t1, simd<16>::eq(b1, mask4));
623
624        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
625    }
626
627    IDISA_ALWAYS_INLINE
628    static iterator_t mask(const size_t pos)
629    {
630        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
631    }
632
633    IDISA_ALWAYS_INLINE
634    bool scan()
635    {
636        if (unlikely(fLength == 0))
637        {
638            return 0;
639        }
640
641        fOffset = fNextOffset;
642
643        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
644
645        #ifdef __ARCH_64
646        if (likely(fLength >= 64))
647        {
648            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
649            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
650            fNextOffset += 64;
651            fLength -= 64;
652        }
653        else
654        {
655            if (fLength >= 48)
656            {
657                fComplementMask = mask(48 | (fLength & 15));
658                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
659            }
660            else if (fLength >= 32)
661            {
662                fComplementMask = mask(32 | (fLength & 15));
663                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
664            }
665            else
666            {
667                fComplementMask = mask(fLength);
668                fIterator = (load(string, 0) | (load(string, 2) << 16));
669            }
670            fIterator &= fComplementMask;
671            fLength = 0;
672        }
673        #else
674        if (likely(fLength >= 32))
675        {
676            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
677            fIterator = (load(string, 0) | (load(string, 2) << 16));
678            fNextOffset += 32;
679            fLength -= 32;
680        }
681        else
682        {
683            if (fLength >= 16)
684            {
685                fComplementMask = mask(16 | (fLength & 15));
686                fIterator = (load(string, 0) | (load(string, 2) << 16));
687            }
688            else
689            {
690                fComplementMask = mask(fLength);
691                fIterator = (load(string, 0) | (load(string, 2) << 16));
692            }
693            fIterator &= fComplementMask;
694            fLength = 0;
695        }
696        #endif
697
698        return 1;
699    }
700
701private:
702
703    iterator_t                          fIterator;
704    iterator_t                          fOffset;
705    iterator_t                          fPosition;
706
707    iterator_t                          fNextOffset;
708    const XMLCh *                       fString;
709    size_t                  fLength;
710    iterator_t              fComplementMask;
711};
712
713
714template <XMLCh CharLo1, XMLCh CharHi1, XMLCh CharLo2, XMLCh CharHi2>
715class XMLChRangeIterator2
716{
717public:
718
719    XMLChRangeIterator2(const XMLCh* string, const XMLSize_t length)
720    : fIterator(0)
721    , fOffset(0)
722    , fPosition(0)
723    , fNextOffset(0)
724    , fString(string)
725    , fLength(length)
726    , fComplementMask(0)
727    {
728        scan();
729    }
730
731    bool next()
732    {
733        while (!fIterator)
734        {
735            if (unlikely(!scan()))
736            {
737                return 0;
738            }
739        }
740
741        const size_t pos = scan_forward_zeroes(fIterator);
742
743        fPosition = fOffset + pos;
744
745        fIterator &= (fIterator - 1);
746
747        fComplementMask &= ~mask(pos);
748        fComplementMask &= (fComplementMask - 1);
749
750        return 1;
751    }
752
753    bool nextc()
754    {
755        iterator_t temp = (~fIterator) & fComplementMask;
756        while (!temp)
757        {
758            if (likely(scan()))
759            {
760                temp = (~fIterator) & fComplementMask;
761                continue;
762            }
763            return 0;
764        }
765
766        const iterator_t pos = scan_forward_zeroes(temp);
767        fPosition = fOffset + pos;
768        fIterator &= ~mask(pos);
769        return 1;
770    }
771
772    iterator_t pos()
773    {
774        return fPosition;
775    }
776
777private:
778
779    template <XMLCh lo, XMLCh hi>
780    IDISA_ALWAYS_INLINE
781    static BytePack within(const BytePack data)
782    {
783        BytePack a;
784        if (lo == 0)
785        {
786            a = simd<16>::eq(data, simd<16>::constant<0>());
787            a = simd_or(a, simd<16>::gt(data, simd<16>::constant<0>()));
788        }
789        else
790        {
791            a = simd<16>::gt(data, simd<16>::constant<lo - 1>());
792        }
793
794        BytePack b;
795        if (hi == 0xFFFF)
796        {
797            b = simd<16>::eq(data, simd<16>::constant<0xFFFF>());
798            b = simd_or(b, simd<16>::lt(data, simd<16>::constant<0xFFFF>()));
799        }
800        else
801        {
802            b = simd<16>::lt(data, simd<16>::constant<hi + 1>());
803        }
804
805        return simd_and(a, b);
806    }
807
808    IDISA_ALWAYS_INLINE
809    iterator_t load(const BytePack * string, size_t index)
810    {
811        BytePack b0 = bitblock::load_unaligned(&string[index]);
812        BytePack t0 = within<CharLo1, CharHi1>(b0);
813        t0 = simd_or(t0, within<CharLo2, CharHi2>(b0));
814
815        BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
816        BytePack t1 = within<CharLo1, CharHi1>(b0);
817        t1 = simd_or(t1, within<CharLo2, CharHi2>(b1));
818
819        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
820    }
821
822    IDISA_ALWAYS_INLINE
823    static iterator_t mask(const size_t pos)
824    {
825        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
826    }
827
828    IDISA_ALWAYS_INLINE
829    bool scan()
830    {
831        if (unlikely(fLength == 0))
832        {
833            return 0;
834        }
835
836        fOffset = fNextOffset;
837
838        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
839
840        #ifdef __ARCH_64
841        if (likely(fLength >= 64))
842        {
843            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
844            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
845            fNextOffset += 64;
846            fLength -= 64;
847        }
848        else
849        {
850            if (fLength >= 48)
851            {
852                fComplementMask = mask(48 | (fLength & 15));
853                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
854            }
855            else if (fLength >= 32)
856            {
857                fComplementMask = mask(32 | (fLength & 15));
858                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
859            }
860            else
861            {
862                fComplementMask = mask(fLength);
863                fIterator = (load(string, 0) | (load(string, 2) << 16));
864            }
865            fIterator &= fComplementMask;
866            fLength = 0;
867        }
868        #else
869        if (likely(fLength >= 32))
870        {
871            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
872            fIterator = (load(string, 0) | (load(string, 2) << 16));
873            fNextOffset += 32;
874            fLength -= 32;
875        }
876        else
877        {
878            if (fLength >= 16)
879            {
880                fComplementMask = mask(16 | (fLength & 15));
881                fIterator = (load(string, 0) | (load(string, 2) << 16));
882            }
883            else
884            {
885                fComplementMask = mask(fLength);
886                fIterator = (load(string, 0) | (load(string, 2) << 16));
887            }
888            fIterator &= fComplementMask;
889            fLength = 0;
890        }
891        #endif
892
893        return 1;
894    }
895
896private:
897
898    iterator_t                          fIterator;
899    iterator_t                          fOffset;
900    iterator_t                          fPosition;
901
902    iterator_t                          fNextOffset;
903    const XMLCh *                       fString;
904    size_t                  fLength;
905    iterator_t              fComplementMask;
906};
907
908template <XMLCh CharLo1, XMLCh CharHi1, XMLCh CharLo2, XMLCh CharHi2, XMLCh CharLo3, XMLCh CharHi3, XMLCh CharLo4, XMLCh CharHi4>
909class XMLChRangeIterator4
910{
911public:
912
913    XMLChRangeIterator4(const XMLCh* string, const XMLSize_t length)
914    : fIterator(0)
915    , fOffset(0)
916    , fPosition(0)
917    , fNextOffset(0)
918    , fString(string)
919    , fLength(length)
920    , fComplementMask(0)
921    {
922        scan();
923    }
924
925    bool next()
926    {
927        while (!fIterator)
928        {
929            if (unlikely(!scan()))
930            {
931                return 0;
932            }
933        }
934
935        const size_t pos = scan_forward_zeroes(fIterator);
936
937        fPosition = fOffset + pos;
938
939        fIterator &= (fIterator - 1);
940
941        fComplementMask &= ~mask(pos);
942        fComplementMask &= (fComplementMask - 1);
943
944        return 1;
945    }
946
947    bool nextc()
948    {
949        iterator_t temp = (~fIterator) & fComplementMask;
950        while (!temp)
951        {
952            if (likely(scan()))
953            {
954                temp = (~fIterator) & fComplementMask;
955                continue;
956            }
957            return 0;
958        }
959
960        const iterator_t pos = scan_forward_zeroes(temp);
961        fPosition = fOffset + pos;
962        fIterator &= ~mask(pos);
963        return 1;
964    }
965
966    iterator_t pos()
967    {
968        return fPosition;
969    }
970
971private:
972
973    template <XMLCh lo, XMLCh hi>
974    IDISA_ALWAYS_INLINE
975    static BytePack within(const BytePack data)
976    {
977        BytePack a;
978        if (lo == 0)
979        {
980            a = simd<16>::eq(data, simd<16>::constant<0>());
981            a = simd_or(a, simd<16>::gt(data, simd<16>::constant<0>()));
982        }
983        else
984        {
985            a = simd<16>::gt(data, simd<16>::constant<lo - 1>());
986        }
987
988        BytePack b;
989        if (hi == 0xFFFF)
990        {
991            b = simd<16>::eq(data, simd<16>::constant<0xFFFF>());
992            b = simd_or(b, simd<16>::lt(data, simd<16>::constant<0xFFFF>()));
993        }
994        else
995        {
996            b = simd<16>::lt(data, simd<16>::constant<hi + 1>());
997        }
998
999        return simd_and(a, b);
1000    }
1001
1002    IDISA_ALWAYS_INLINE
1003    iterator_t load(const BytePack * string, size_t index)
1004    {
1005        BytePack b0 = bitblock::load_unaligned(&string[index]);
1006        BytePack t0 = within<CharLo1, CharHi1>(b0);
1007        t0 = simd_or(t0, within<CharLo2, CharHi2>(b0));
1008        t0 = simd_or(t0, within<CharLo3, CharHi3>(b0));
1009        t0 = simd_or(t0, within<CharLo4, CharHi4>(b0));
1010
1011        BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
1012        BytePack t1 = within<CharLo1, CharHi1>(b0);
1013        t1 = simd_or(t1, within<CharLo2, CharHi2>(b1));
1014        t1 = simd_or(t1, within<CharLo3, CharHi3>(b1));
1015        t1 = simd_or(t1, within<CharLo4, CharHi4>(b1));
1016
1017        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
1018    }
1019
1020    IDISA_ALWAYS_INLINE
1021    static iterator_t mask(const size_t pos)
1022    {
1023        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
1024    }
1025
1026    IDISA_ALWAYS_INLINE
1027    bool scan()
1028    {
1029        if (unlikely(fLength == 0))
1030        {
1031            return 0;
1032        }
1033
1034        fOffset = fNextOffset;
1035
1036        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
1037
1038        #ifdef __ARCH_64
1039        if (likely(fLength >= 64))
1040        {
1041            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
1042            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
1043            fNextOffset += 64;
1044            fLength -= 64;
1045        }
1046        else
1047        {
1048            if (fLength >= 48)
1049            {
1050                fComplementMask = mask(48 | (fLength & 15));
1051                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
1052            }
1053            else if (fLength >= 32)
1054            {
1055                fComplementMask = mask(32 | (fLength & 15));
1056                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
1057            }
1058            else
1059            {
1060                fComplementMask = mask(fLength);
1061                fIterator = (load(string, 0) | (load(string, 2) << 16));
1062            }
1063            fIterator &= fComplementMask;
1064            fLength = 0;
1065        }
1066        #else
1067        if (likely(fLength >= 32))
1068        {
1069            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
1070            fIterator = (load(string, 0) | (load(string, 2) << 16));
1071            fNextOffset += 32;
1072            fLength -= 32;
1073        }
1074        else
1075        {
1076            if (fLength >= 16)
1077            {
1078                fComplementMask = mask(16 | (fLength & 15));
1079                fIterator = (load(string, 0) | (load(string, 2) << 16));
1080            }
1081            else
1082            {
1083                fComplementMask = mask(fLength);
1084                fIterator = (load(string, 0) | (load(string, 2) << 16));
1085            }
1086            fIterator &= fComplementMask;
1087            fLength = 0;
1088        }
1089        #endif
1090
1091        return 1;
1092    }
1093
1094private:
1095
1096    iterator_t                          fIterator;
1097    iterator_t                          fOffset;
1098    iterator_t                          fPosition;
1099
1100    iterator_t                          fNextOffset;
1101    const XMLCh *                       fString;
1102    size_t                  fLength;
1103    iterator_t              fComplementMask;
1104};
1105
1106XERCES_CPP_NAMESPACE_END
1107
1108#endif // XMLSCANITERATOR_HPP
1109
Note: See TracBrowser for help on using the repository browser.