| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System.Collections.Generic; |
| | | 5 | | using System.Diagnostics; |
| | | 6 | | using System.Runtime.CompilerServices; |
| | | 7 | | |
| | | 8 | | namespace System.Buffers |
| | | 9 | | { |
| | | 10 | | internal sealed class BitmapCharSearchValues : SearchValues<char> |
| | | 11 | | { |
| | | 12 | | private readonly uint[] _bitmap; |
| | | 13 | | |
| | 514 | 14 | | public BitmapCharSearchValues(ReadOnlySpan<char> values, int maxInclusive) |
| | | 15 | | { |
| | 514 | 16 | | Debug.Assert(maxInclusive <= char.MaxValue); |
| | | 17 | | |
| | 514 | 18 | | _bitmap = new uint[maxInclusive / 32 + 1]; |
| | | 19 | | |
| | 320612 | 20 | | foreach (char c in values) |
| | | 21 | | { |
| | 159792 | 22 | | _bitmap[c >> 5] |= 1u << c; |
| | | 23 | | } |
| | 514 | 24 | | } |
| | | 25 | | |
| | | 26 | | internal override char[] GetValues() |
| | | 27 | | { |
| | 0 | 28 | | var chars = new List<char>(); |
| | 0 | 29 | | uint[] bitmap = _bitmap; |
| | | 30 | | |
| | 0 | 31 | | for (int i = 0; i < _bitmap.Length * 32; i++) |
| | | 32 | | { |
| | 0 | 33 | | if (Contains(bitmap, i)) |
| | | 34 | | { |
| | 0 | 35 | | chars.Add((char)i); |
| | | 36 | | } |
| | | 37 | | } |
| | | 38 | | |
| | 0 | 39 | | return chars.ToArray(); |
| | | 40 | | } |
| | | 41 | | |
| | | 42 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 43 | | internal override bool ContainsCore(char value) => |
| | 40831 | 44 | | Contains(_bitmap, value); |
| | | 45 | | |
| | | 46 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 47 | | private static bool Contains(uint[] bitmap, int value) |
| | | 48 | | { |
| | 303727 | 49 | | uint offset = (uint)(value >> 5); |
| | 303727 | 50 | | return offset < (uint)bitmap.Length && (bitmap[offset] & (1u << value)) != 0; |
| | | 51 | | } |
| | | 52 | | |
| | | 53 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 54 | | internal override int IndexOfAny(ReadOnlySpan<char> span) => |
| | 2056 | 55 | | IndexOfAny<IndexOfAnyAsciiSearcher.DontNegate>(span); |
| | | 56 | | |
| | | 57 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 58 | | internal override int IndexOfAnyExcept(ReadOnlySpan<char> span) => |
| | 2056 | 59 | | IndexOfAny<IndexOfAnyAsciiSearcher.Negate>(span); |
| | | 60 | | |
| | | 61 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 62 | | internal override int LastIndexOfAny(ReadOnlySpan<char> span) => |
| | 1028 | 63 | | LastIndexOfAny<IndexOfAnyAsciiSearcher.DontNegate>(span); |
| | | 64 | | |
| | | 65 | | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| | | 66 | | internal override int LastIndexOfAnyExcept(ReadOnlySpan<char> span) => |
| | 1028 | 67 | | LastIndexOfAny<IndexOfAnyAsciiSearcher.Negate>(span); |
| | | 68 | | |
| | | 69 | | private int IndexOfAny<TNegator>(ReadOnlySpan<char> span) |
| | | 70 | | where TNegator : struct, IndexOfAnyAsciiSearcher.INegator |
| | | 71 | | { |
| | 4112 | 72 | | uint[] bitmap = _bitmap; |
| | | 73 | | |
| | 448084 | 74 | | for (int i = 0; i < span.Length; i++) |
| | | 75 | | { |
| | 223090 | 76 | | char c = span[i]; |
| | 223090 | 77 | | if (TNegator.NegateIfNeeded(Contains(bitmap, c))) |
| | | 78 | | { |
| | 3160 | 79 | | return i; |
| | | 80 | | } |
| | | 81 | | } |
| | | 82 | | |
| | 952 | 83 | | return -1; |
| | | 84 | | } |
| | | 85 | | |
| | | 86 | | private int LastIndexOfAny<TNegator>(ReadOnlySpan<char> span) |
| | | 87 | | where TNegator : struct, IndexOfAnyAsciiSearcher.INegator |
| | | 88 | | { |
| | 2056 | 89 | | uint[] bitmap = _bitmap; |
| | 2056 | 90 | | int searchSpaceLength = span.Length; |
| | | 91 | | |
| | 40098 | 92 | | while (--searchSpaceLength >= 0) |
| | | 93 | | { |
| | 39806 | 94 | | char c = span[searchSpaceLength]; |
| | 39806 | 95 | | if (TNegator.NegateIfNeeded(Contains(bitmap, c))) |
| | | 96 | | { |
| | | 97 | | break; |
| | | 98 | | } |
| | | 99 | | } |
| | | 100 | | |
| | 2056 | 101 | | return searchSpaceLength; |
| | | 102 | | } |
| | | 103 | | } |
| | | 104 | | } |
| | | 105 | | |