File: BitSet%2BSetAlgebra%20isStrictSubset.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, 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 (159 lines) | stat: -rw-r--r-- 5,224 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
//===----------------------------------------------------------------------===//
//
// 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 {
  /// Returns a Boolean value that indicates whether this bit set is a strict
  /// subset of the given set.
  ///
  /// Set *A* is a strict subset of another set *B* if every member of *A* is
  /// also a member of *B* and *B* contains at least one element that is not a
  /// member of *A*.
  ///
  ///     let a: BitSet = [1, 2, 3, 4]
  ///     let b: BitSet = [1, 2, 4]
  ///     let c: BitSet = [0, 1]
  ///     a.isStrictSubset(of: a) // false
  ///     b.isStrictSubset(of: a) // true
  ///     c.isStrictSubset(of: a) // false
  ///
  /// - Parameter other: Another bit set.
  ///
  /// - Returns: `true` if the set is a strict subset of `other`;
  ///     otherwise, `false`.
  ///
  /// - Complexity: O(*max*), where *max* is the largest item in `self`.
  public func isStrictSubset(of other: Self) -> Bool {
    self._read { first in
      other._read { second in
        let w1 = first._words
        let w2 = second._words
        if w1.count > w2.count {
          return false
        }
        var strict = w1.count < w2.count
        for i in 0 ..< w1.count {
          if !w1[i].subtracting(w2[i]).isEmpty {
            return false
          }
          strict = strict || w1[i] != w2[i]
        }
        return strict
      }
    }
  }

  /// Returns a Boolean value that indicates whether this bit set is a strict
  /// subset of the given set.
  ///
  /// Set *A* is a strict subset of another set *B* if every member of *A* is
  /// also a member of *B* and *B* contains at least one element that is not a
  /// member of *A*.
  ///
  /// - Parameter other: A counted bit set.
  ///
  /// - Returns: `true` if the set is a strict subset of `other`;
  ///     otherwise, `false`.
  ///
  /// - Complexity: O(*max*), where *max* is the largest item in `self`.
  public func isStrictSubset(of other: BitSet.Counted) -> Bool {
    isStrictSubset(of: other._bits)
  }

  /// Returns a Boolean value that indicates whether this set is a strict
  /// subset of the given set.
  ///
  /// Set *A* is a strict subset of another set *B* if every member of *A* is
  /// also a member of *B* and *B* contains at least one element that is not a
  /// member of *A*.
  ///
  ///     let b: BitSet = [0, 1, 2]
  ///     let c: BitSet = [2, 3, 4]
  ///     b.isStrictSubset(of: -10 ..< 4) // true
  ///     c.isStrictSubset(of: -10 ..< 4) // false
  ///
  /// - Parameter other: An arbitrary range of integers.
  ///
  /// - Returns: `true` if the set is a strict subset of `other`;
  ///     otherwise, `false`.
  ///
  /// - Complexity: O(*max*), where *max* is the largest item in `self`.
  public func isStrictSubset(of other: Range<Int>) -> Bool {
    isSubset(of: other) && !isSuperset(of: other)
  }

  /// Returns a Boolean value that indicates whether this bit set is a strict
  /// subset of the values in a given sequence of integers.
  ///
  /// Set *A* is a strict subset of another set *B* if every member of *A* is
  /// also a member of *B* and *B* contains at least one element that is not a
  /// member of *A*.
  ///
  ///     let a = [1, 2, 3, 4, -10]
  ///     let b: BitSet = [1, 2, 4]
  ///     let c: BitSet = [0, 1]
  ///     b.isStrictSubset(of: a) // true
  ///     c.isStrictSubset(of: a) // false
  ///
  /// - Parameter other: A sequence of arbitrary integers.
  ///
  /// - Returns: `true` if the set is a strict subset of `other`;
  ///     otherwise, `false`.
  ///
  /// - Complexity: O(*max*) + *k*, where *max* is the largest item in `self`,
  ///    and *k* is the complexity of iterating over all elements in `other`.
  @inlinable
  public func isStrictSubset(of other: some Sequence<Int>) -> Bool {
    if let other = _specialize(other, for: BitSet.self) {
      return isStrictSubset(of: other)
    }
    if let other = _specialize(other, for: BitSet.Counted.self) {
      return isStrictSubset(of: other)
    }
    if let other = _specialize(other, for: Range<Int>.self) {
      return isStrictSubset(of: other)
    }

    if isEmpty {
      var it = other.makeIterator()
      return it.next() != nil
    }

    let selfCount = self.count
    return _UnsafeHandle.withTemporaryBitSet(
      wordCount: _storage.count
    ) { seen in
      var strict = false
      var it = other.makeIterator()
      var c = 0
      while let i = it.next() {
        guard self.contains(i) else {
          strict = true
          continue
        }
        if seen.insert(UInt(i)) {
          c &+= 1
          if c == selfCount {
            while !strict, let i = it.next() {
              strict = !self.contains(i)
            }
            return strict
          }
        }
      }
      assert(c < selfCount)
      return false
    }
  }
}