File: BitSet%2BInitializers.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (217 lines) | stat: -rw-r--r-- 6,524 bytes parent folder | download
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Collections open source project
//
// Copyright (c) 2021 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

#if !COLLECTIONS_SINGLE_MODULE
import InternalCollectionsUtilities
#endif

extension BitSet {
  /// Initializes a new, empty bit set.
  ///
  /// This is equivalent to initializing with an empty array literal.
  /// For example:
  ///
  ///     let set1 = BitSet()
  ///     print(set1.isEmpty) // true
  ///
  ///     let set2: BitSet = []
  ///     print(set2.isEmpty) // true
  ///
  /// - Complexity: O(1)
  public init() {
    self.init(_rawStorage: [])
  }

  @usableFromInline
  init(_words: [_Word]) {
    self._storage = _words
    _shrink()
    _checkInvariants()
  }
  
  /// Initialize a new bit set from the raw bits of the supplied sequence of
  /// words. (The term "words" is used here to mean a sequence of `UInt`
  /// values, as in the `words` property of `BinaryInteger`.)
  ///
  /// The resulting bit set will contain precisely those integers that
  /// correspond to `true` bits within `words`. Bits are counted from least
  /// to most significant within each word.
  ///
  ///     let bits = BitSet(words: [5, 2])
  ///     // bits is [0, 2, UInt.bitWidth + 1]
  ///
  /// - Complexity: O(`words.count`)
  @inlinable
  public init(words: some Sequence<UInt>) {
    self.init(_words: words.map { _Word($0) })
  }
  
  /// Initialize a new bit set from the raw bits of the supplied integer value.
  ///
  /// The resulting bit set will contain precisely those integers that
  /// correspond to `true` bits within `x`. Bits are counted from least
  /// to most significant.
  ///
  ///     let bits = BitSet(bitPattern: 42)
  ///     // bits is [1, 3, 5]
  ///
  /// - Complexity: O(`x.bitWidth`)
  @inlinable
  public init(bitPattern x: some BinaryInteger) {
    self.init(words: x.words)
  }

  /// Initialize a new bit set from the storage bits of the given bit array.
  /// The resulting bit set will contain exactly those integers that address
  /// `true` elements in the array.
  ///
  /// Note that this conversion is lossy -- it discards the precise length of
  /// the input array.
  ///
  /// - Complexity: O(`array.count`)
  public init(_ array: BitArray) {
    self.init(_words: array._storage)
  }

  /// Create a new bit set containing the elements of a sequence.
  ///
  /// - Parameters:
  ///   - elements: The sequence of elements to turn into a bit set.
  ///
  /// - Complexity: O(*n*), where *n* is the number of elements in the sequence.
  @inlinable
  public init(
    _ elements: __owned some Sequence<Int>
  ) {
    if let elements = _specialize(elements, for: BitSet.self) {
      self = elements
      return
    }
    if let elements = _specialize(elements, for: BitSet.Counted.self) {
      self = elements._bits
      return
    }
    self.init()
    for value in elements {
      self.insert(value)
    }
  }

  /// Create a new bit set containing all the nonnegative elements of a
  /// sequence of integers.
  ///
  /// Items in `elements` that are negative are silently ignored.
  ///
  /// - Parameters:
  ///   - elements: The sequence of elements to turn into a bit set.
  ///
  /// - Complexity: O(*n*), where *n* is the number of elements in the sequence.
  @inlinable
  internal init(
    _validMembersOf elements: __owned some Sequence<Int>
  ) {
    if let elements = _specialize(elements, for: BitSet.self) {
      self = elements
      return
    }
    if let elements = _specialize(elements, for: BitSet.Counted.self) {
      self = elements._bits
      return
    }
    if let elements = _specialize(elements, for: Range<Int>.self) {
      let r = elements
      self.init(_range: r._clampedToUInt())
      return
    }
    self.init()
    for value in elements {
      guard let value = UInt(exactly: value) else { continue }
      self._insert(value)
    }
  }
}

extension BitSet {
  /// Create a new bit set containing the elements of a range of integers.
  ///
  /// - Parameters:
  ///   - range: The range to turn into a bit set. The range must not contain
  ///      negative values.
  ///
  /// - Complexity: O(`range.upperBound`)
  public init(_ range: Range<Int>) {
    guard let range = range._toUInt() else {
      preconditionFailure("BitSet can only hold nonnegative integers")
    }
    self.init(_range: range)
  }

  @usableFromInline
  internal init(_range range: Range<UInt>) {
    _storage = []
    let lower = _UnsafeHandle.Index(range.lowerBound)
    let upper = _UnsafeHandle.Index(range.upperBound)
    if lower.word > 0 {
      _storage.append(contentsOf: repeatElement(.empty, count: lower.word))
    }
    if lower.word == upper.word {
      _storage.append(_Word(from: lower.bit, to: upper.bit))
    } else {
      _storage.append(_Word(upTo: lower.bit).complement())
      let filledWords = upper.word &- lower.word
      if filledWords > 0 {
        _storage.append(
          contentsOf: repeatElement(.allBits, count: filledWords &- 1))
      }
      _storage.append(_Word(upTo: upper.bit))
    }
    _shrink()
    _checkInvariants()
  }
}

extension BitSet {
  internal init(
    _combining handles: (_UnsafeHandle, _UnsafeHandle),
    includingTail: Bool,
    using function: (_Word, _Word) -> _Word
  ) {
    let w1 = handles.0._words
    let w2 = handles.1._words
    let capacity = (
      includingTail
      ? Swift.max(w1.count, w2.count)
      : Swift.min(w1.count, w2.count))
    _storage = Array(unsafeUninitializedCapacity: capacity) { buffer, count in
      let sharedCount = Swift.min(w1.count, w2.count)
      for w in 0 ..< sharedCount {
        buffer.initializeElement(at: w, to: function(w1[w], w2[w]))
      }
      if includingTail {
        if w1.count < w2.count {
          for w in w1.count ..< w2.count {
            buffer.initializeElement(at: w, to: function(_Word.empty, w2[w]))
          }
        } else {
          for w in w2.count ..< w1.count {
            buffer.initializeElement(at: w, to: function(w1[w], _Word.empty))
          }
        }
      }
      // Adjust the word count based on results.
      count = capacity
      while count > 0, buffer[count - 1].isEmpty {
        count -= 1
      }
    }
    _checkInvariants()
  }
}