Skip to content

Commit 010164e

Browse files
committed
[stdlib] _Bitset: Switch to using ManagedBuffer for storage
1 parent 6f01f5c commit 010164e

File tree

1 file changed

+45
-21
lines changed

1 file changed

+45
-21
lines changed

stdlib/public/core/Bitset.swift

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,8 @@ extension _Bitset: Sequence {
503503
return wordIndex * Word.capacity + v
504504
}
505505
guard let storage = self.storage else { return nil }
506-
while wordIndex < storage._wordCount {
507-
word = storage._words[wordIndex]
506+
while wordIndex < storage.wordCount {
507+
word = storage[word: wordIndex]
508508
// Note that _wordIndex is offset by 1 due to word0;
509509
// this is why the index needs to be incremented at exactly this point.
510510
wordIndex += 1
@@ -520,18 +520,23 @@ extension _Bitset: Sequence {
520520
////////////////////////////////////////////////////////////////////////////////
521521

522522
extension _Bitset {
523-
/// A simple bitmap storage class with room for a specific number of
524-
/// tail-allocated bits.
525523
@_fixed_layout
526524
@usableFromInline
527-
internal final class Storage {
525+
internal struct StorageHeader {
528526
@usableFromInline
529-
internal fileprivate(set) var _wordCount: Int
527+
internal var wordCount: Int
530528

531-
internal init(_doNotCall: ()) {
532-
_internalInvariantFailure("This class cannot be directly initialized")
529+
@inlinable
530+
internal init(wordCount: Int) {
531+
self.wordCount = wordCount
533532
}
534533
}
534+
535+
/// A simple bitmap storage class with room for a specific number of
536+
/// tail-allocated bits.
537+
@_fixed_layout
538+
@usableFromInline
539+
internal final class Storage: ManagedBuffer<StorageHeader, Word> {}
535540
}
536541

537542
extension _Bitset.Storage {
@@ -543,44 +548,63 @@ extension _Bitset.Storage {
543548
internal static func allocateUninitialized(
544549
wordCount: Int
545550
) -> _Bitset.Storage {
546-
let storage = Builtin.allocWithTailElems_1(
547-
_Bitset.Storage.self,
548-
wordCount._builtinWordValue, Word.self)
549-
storage._wordCount = wordCount
550-
return storage
551+
let storage = create(
552+
minimumCapacity: wordCount,
553+
makingHeaderWith: { storage in
554+
_Bitset.StorageHeader(wordCount: wordCount)
555+
})
556+
return unsafeDowncast(storage, to: _Bitset.Storage.self)
557+
}
558+
559+
@inlinable
560+
@inline(__always)
561+
internal var wordCount: Int {
562+
return header.wordCount
551563
}
552564

553565
@inlinable
554566
internal func clear() {
555-
_words.assign(repeating: .empty, count: _wordCount)
567+
firstElementAddress.assign(repeating: .empty, count: wordCount)
556568
}
557569

558570
@inlinable
559571
internal func copy() -> _Bitset.Storage {
560-
let storage = _Bitset.Storage.allocateUninitialized(wordCount: _wordCount)
572+
let storage = _Bitset.Storage.allocateUninitialized(wordCount: wordCount)
561573
storage.copy(contentsOf: self.bitset)
562574
return storage
563575
}
564576

565577
@inlinable
566578
func copy(contentsOf bitset: _UnsafeBitset) {
567-
_internalInvariant(bitset.wordCount == self._wordCount)
568-
self._words.assign(from: bitset.words, count: bitset.wordCount)
579+
_internalInvariant(bitset.wordCount == self.wordCount)
580+
firstElementAddress.assign(from: bitset.words, count: bitset.wordCount)
569581
}
570582

571583
@inlinable
572-
internal var _words: UnsafeMutablePointer<Word> {
584+
internal subscript(word index: Int) -> Word {
573585
@inline(__always)
574586
get {
575-
let addr = Builtin.projectTailElems(self, Word.self)
576-
return UnsafeMutablePointer(addr)
587+
_internalInvariant(index >= 0 && index < wordCount)
588+
return firstElementAddress[index]
589+
}
590+
@inline(__always)
591+
set {
592+
_internalInvariant(index >= 0 && index < wordCount)
593+
firstElementAddress[index] = newValue
594+
}
595+
@inline(__always)
596+
_modify {
597+
_internalInvariant(index >= 0 && index < wordCount)
598+
yield &firstElementAddress[index]
577599
}
578600
}
579601

580602
@inlinable
581603
internal var bitset: _UnsafeBitset {
582604
@inline(__always) get {
583-
return _UnsafeBitset(words: _words, wordCount: _wordCount)
605+
return _UnsafeBitset(
606+
words: firstElementAddress,
607+
wordCount: wordCount)
584608
}
585609
}
586610
}

0 commit comments

Comments
 (0)