/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import Foundation public struct TSet : SetAlgebra, Hashable, Collection, ExpressibleByArrayLiteral, TSerializable { /// Typealias for Storage type public typealias Storage = Set /// Internal Storage used for TSet (Set\) internal var storage : Storage /// Mark: Collection public typealias Indices = Storage.Indices public typealias Index = Storage.Index public typealias IndexDistance = Int public typealias SubSequence = Storage.SubSequence public var indices: Indices { return storage.indices } // Must implement isEmpty even though both SetAlgebra and Collection provide it due to their conflciting default implementations public var isEmpty: Bool { return storage.isEmpty } public func distance(from start: Index, to end: Index) -> IndexDistance { return storage.distance(from: start, to: end) } public func index(_ i: Index, offsetBy n: IndexDistance) -> Index { return storage.index(i, offsetBy: n) } public func index(_ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index) -> Index? { return storage.index(i, offsetBy: n, limitedBy: limit) } #if swift(>=3.2) public subscript (position: Storage.Index) -> Element { return storage[position] } #else public subscript (position: Storage.Index) -> Element? { return storage[position] } #endif /// Mark: SetAlgebra internal init(storage: Set) { self.storage = storage } public func contains(_ member: Element) -> Bool { return storage.contains(member) } public mutating func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element) { return storage.insert(newMember) } public mutating func remove(_ member: Element) -> Element? { return storage.remove(member) } public func union(_ other: TSet) -> TSet { return TSet(storage: storage.union(other.storage)) } public mutating func formIntersection(_ other: TSet) { return storage.formIntersection(other.storage) } public mutating func formSymmetricDifference(_ other: TSet) { return storage.formSymmetricDifference(other.storage) } public mutating func formUnion(_ other: TSet) { return storage.formUnion(other.storage) } public func intersection(_ other: TSet) -> TSet { return TSet(storage: storage.intersection(other.storage)) } public func symmetricDifference(_ other: TSet) -> TSet { return TSet(storage: storage.symmetricDifference(other.storage)) } public mutating func update(with newMember: Element) -> Element? { return storage.update(with: newMember) } /// Mark: IndexableBase public var startIndex: Index { return storage.startIndex } public var endIndex: Index { return storage.endIndex } public func index(after i: Index) -> Index { return storage.index(after: i) } public func formIndex(after i: inout Storage.Index) { storage.formIndex(after: &i) } public subscript(bounds: Range) -> SubSequence { return storage[bounds] } /// Mark: Hashable public var hashValue : Int { let prime = 31 var result = 1 for element in storage { result = prime &* result &+ element.hashValue } return result } /// Mark: TSerializable public static var thriftType : TType { return .set } public init() { storage = Storage() } public init(arrayLiteral elements: Element...) { self.storage = Storage(elements) } public init(_ sequence: Source) where Source.Iterator.Element == Element { storage = Storage(sequence) } public static func read(from proto: TProtocol) throws -> TSet { let (elementType, size) = try proto.readSetBegin() if elementType != Element.thriftType { throw TProtocolError(error: .invalidData, extendedError: .unexpectedType(type: elementType)) } var set = TSet() for _ in 0..(lhs: TSet, rhs: TSet) -> Bool { return lhs.storage == rhs.storage }