aboutsummaryrefslogtreecommitdiff
path: root/Sources/NorgKit/Helpers/ASCIIByteSet.swift
blob: 59efbe72079b7526cabb847475ee2f96e34162ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
  }
}