diff options
Diffstat (limited to 'Sources/NorgKit/Helpers/ASCIIByteSet.swift')
| -rw-r--r-- | Sources/NorgKit/Helpers/ASCIIByteSet.swift | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/Sources/NorgKit/Helpers/ASCIIByteSet.swift b/Sources/NorgKit/Helpers/ASCIIByteSet.swift new file mode 100644 index 0000000..59efbe7 --- /dev/null +++ b/Sources/NorgKit/Helpers/ASCIIByteSet.swift @@ -0,0 +1,30 @@ +/// A membership test over the ASCII range (bytes `0`–`127`) +/// We use this for performance, since markers are always ASCII, and this this +/// faster than using Character. +struct ASCIIByteSet { + private let low: UInt64 + private let high: UInt64 + + /// Builds a set from the ASCII values. + init(_ characters: String) { + var lo: UInt64 = 0 + var hi: UInt64 = 0 + for byte in characters.utf8 { + if byte < 64 { + lo |= 1 << UInt64(byte) + } else if byte < 128 { + hi |= 1 << UInt64(byte - 64) + } + } + low = lo + high = hi + } + + /// Whether `byte` is in the set. + @inline(__always) + func contains(_ byte: UInt8) -> Bool { + if byte < 64 { return low & (1 << UInt64(byte)) != 0 } + if byte < 128 { return high & (1 << UInt64(byte &- 64)) != 0 } + return false + } +} |