//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import SwiftShims

// General Mutable, Value-Type Collections
// =================================================
//
// Implementation notes
// ====================
//
// `Dictionary` uses two storage schemes: native storage and Cocoa storage.
//
// Native storage is a hash table with open addressing and linear probing. The
// bucket array forms a logical ring (e.g., a chain can wrap around the end of
// buckets array to the beginning of it).
//
// The logical bucket array is implemented as three arrays: Key, Value, and a
// bitmap that marks valid entries. An invalid entry marks the end of a chain.
// There is always at least one invalid entry among the buckets. `Dictionary`
// does not use tombstones.
//
// In addition to the native storage, `Dictionary` can also wrap an
// `NSDictionary` in order to allow bridging `NSDictionary` to `Dictionary` in
// `O(1)`.
//
// Currently native storage uses a data structure like this::
//
//   Dictionary<K,V> (a struct)
//   +------------------------------------------------+
//   |  _VariantDictionaryBuffer<K,V> (an enum)      |
//   | +--------------------------------------------+ |
//   | | [_NativeDictionaryBuffer<K,V> (a struct)] | |
//   | +---|----------------------------------------+ |
//   +----/-------------------------------------------+
//       /
//      |
//      V  _RawNativeDictionaryStorage (a class)  
//   +-----------------------------------------------------------+
//   | capacity                                                  |
//   | count                                                     |
//   | ptrToBits                                                 |
//   | ptrToKeys                                                 |
//   | ptrToValues                                               |
//   | [inline array of bits indicating whether bucket is set ]  |
//   | [inline array of keys                                  ]  |
//   | [inline array of values                                ]  |
//   +-----------------------------------------------------------+
//
//
// Cocoa storage uses a data structure like this::
//
//   Dictionary<K,V> (a struct)
//   +----------------------------------------------+
//   | _VariantDictionaryBuffer<K,V> (an enum)     |
//   | +----------------------------------------+   |
//   | | [ _CocoaDictionaryBuffer (a struct) ] |   |
//   | +---|------------------------------------+   |
//   +-----|----------------------------------------+
//         |
//     +---+
//     |
//     V  NSDictionary (a class)
//   +--------------+
//   | [refcount#1] |
//   +--------------+
//     ^
//     +-+
//       |     Dictionary<K,V>.Index (an enum)
//   +---|-----------------------------------+
//   |   |  _CocoaDictionaryIndex (a struct) |
//   | +-|-----------------------------+     |
//   | | * [ all keys ] [ next index ] |     |
//   | +-------------------------------+     |
//   +---------------------------------------+
//
//
// The Native Kinds of Storage
// ---------------------------
//
// There are three different classes that can provide a native backing storage: 
// * `_RawNativeDictionaryStorage`
// * `_TypedNativeDictionaryStorage<K, V>`                   (extends Raw)
// * `_HashableTypedNativeDictionaryStorage<K: Hashable, V>` (extends Typed)
//
// (Hereafter RawStorage, TypedStorage, and HashableStorage, respectively)
//
// In a less optimized implementation, the parent classes could
// be eliminated, as they exist only to provide special-case behaviors.
// HashableStorage has everything a full implementation of a Dictionary
// requires, and is subsequently able to provide a full NSDictionary 
// implementation. Note that HashableStorage must have the `K: Hashable` 
// constraint because the NSDictionary implementation can't be provided in a 
// constrained extension.
//
// In normal usage, you can expect the backing storage of a Dictionary to be a 
// NativeStorage.
//
// TypedStorage is distinguished from HashableStorage to allow us to create a
// `_NativeDictionaryBuffer<AnyObject, AnyObject>`. Without the Hashable 
// requirement, such a Buffer is restricted to operations which can be performed
// with only the structure of the Storage: indexing and iteration. This is used
// in _SwiftDeferredNSDictionary to construct twin "native" and "bridged"
// storage. Key-based lookups are performed on the native storage, with the
// resultant index then used on the bridged storage.
//
// The only thing that TypedStorage adds over RawStorage is an implementation of
// deinit, to clean up the AnyObjects it stores. Although it nominally 
// inherits an NSDictionary implementation from RawStorage, this implementation 
// isn't useful and is never used. 
//
// RawStorage exists to allow a type-punned empty singleton Storage to be 
// created. Any time an empty Dictionary is created, this Storage is used. If 
// this type didn't exist, then NativeBuffer would have to store a Storage that 
// declared its actual type parameters. Similarly, the empty singleton would 
// have to declare its actual type parameters. If the singleton was, for 
// instance, a `HashableStorage<(), ()>`, then it would be a violation of 
// Swift's strict aliasing rules to pass it where a `HashableStorage<Int, Int>`
// was expected.
//
// It's therefore necessary for several types to store a RawStorage, rather than
// a TypedStorage, to allow for the possibility of the empty singleton. 
// RawStorage also provides an implementation of an always-empty NSDictionary.
//
//
// Index Invalidation
// ------------------
//
// FIXME: decide if this guarantee is worth making, as it restricts
// collision resolution to first-come-first-serve. The most obvious alternative
// would be robin hood hashing. The Rust code base is the best
// resource on a *practical* implementation of robin hood hashing I know of: 
// https://github.com/rust-lang/rust/blob/ac919fcd9d4a958baf99b2f2ed5c3d38a2ebf9d0/src/libstd/collections/hash/map.rs#L70-L178
//
// Indexing a container, `c[i]`, uses the integral offset stored in the index
// to access the elements referenced by the container. Generally, an index into
// one container has no meaning for another. However copy-on-write currently
// preserves indices under insertion, as long as reallocation doesn't occur:
//
//   var (i, found) = d.find(k) // i is associated with d's storage
//   if found {
//      var e = d            // now d is sharing its data with e
//      e[newKey] = newValue // e now has a unique copy of the data
//      return e[i]          // use i to access e
//   }
//
// The result should be a set of iterator invalidation rules familiar to anyone
// familiar with the C++ standard library.  Note that because all accesses to a
// dictionary storage are bounds-checked, this scheme never compromises memory
// safety.
//
//
// Bridging
// ========
//
// Bridging `NSDictionary` to `Dictionary`
// ---------------------------------------
//
// FIXME(eager-bridging): rewrite this based on modern constraints.
//
// `NSDictionary` bridges to `Dictionary<NSObject, AnyObject>` in `O(1)`,
// without memory allocation.
//
// Bridging `Dictionary` to `NSDictionary`
// ---------------------------------------
//
// `Dictionary<K, V>` bridges to `NSDictionary` in O(1)
// but may incur an allocation depending on the following conditions:
//
// * If the Dictionary is freshly allocated without any elements, then it
//   contains the empty singleton Storage which is returned as a toll-free
//   implementation of `NSDictionary`.
//
// * If both `K` and `V` are bridged verbatim, then `Dictionary<K, V>` is 
//   still toll-free bridged to `NSDictionary` by returning its Storage.
//
// * If the Dictionary is actually a lazily bridged NSDictionary, then that
//   NSDictionary is returned. 
//
// * Otherwise, bridging the `Dictionary` is done by wrapping its buffer in a 
//   `_SwiftDeferredNSDictionary<K, V>`. This incurs an O(1)-sized allocation.
//
//   Complete bridging of the native Storage's elements to another Storage 
//   is performed on first access. This is O(n) work, but is hopefully amortized
//   by future accesses.
//
//   This design ensures that:
//   - Every time keys or values are accessed on the bridged `NSDictionary`,
//     new objects are not created.
//   - Accessing the same element (key or value) multiple times will return
//     the same pointer.
//
// Bridging `NSSet` to `Set` and vice versa
// ----------------------------------------
//
// Bridging guarantees for `Set<Element>` are the same as for
// `Dictionary<Element, ()>`.
//

/// This protocol is only used for compile-time checks that
/// every buffer type implements all required operations.
internal protocol _HashBuffer {
  associatedtype Key
  associatedtype Value
  associatedtype Index
  associatedtype SequenceElement
  associatedtype SequenceElementWithoutLabels
  var startIndex: Index { get }
  var endIndex: Index { get }

  func index(after i: Index) -> Index

  func formIndex(after i: inout Index)

  func index(forKey key: Key) -> Index?

  func assertingGet(_ i: Index) -> SequenceElement

  func assertingGet(_ key: Key) -> Value

  func maybeGet(_ key: Key) -> Value?

  @discardableResult
  mutating func updateValue(_ value: Value, forKey key: Key) -> Value?

  @discardableResult
  mutating func insert(
    _ value: Value, forKey key: Key
  ) -> (inserted: Bool, memberAfterInsert: Value)

  @discardableResult
  mutating func remove(at index: Index) -> SequenceElement

  @discardableResult
  mutating func removeValue(forKey key: Key) -> Value?

  mutating func removeAll(keepingCapacity keepCapacity: Bool)

  var count: Int { get }

  static func fromArray(_ elements: [SequenceElementWithoutLabels]) -> Self
}

/// The inverse of the default hash table load factor.  Factored out so that it
/// can be used in multiple places in the implementation and stay consistent.
/// Should not be used outside `Dictionary` implementation.
@_transparent
internal var _hashContainerDefaultMaxLoadFactorInverse: Double {
  return 1.0 / 0.75
}

#if _runtime(_ObjC)
/// Call `[lhs isEqual: rhs]`.
///
/// This function is part of the runtime because `Bool` type is bridged to
/// `ObjCBool`, which is in Foundation overlay.
@_silgen_name("swift_stdlib_NSObject_isEqual")
internal func _stdlib_NSObject_isEqual(_ lhs: AnyObject, _ rhs: AnyObject) -> Bool
#endif


/// A temporary view of an array of AnyObject as an array of Unmanaged<AnyObject>
/// for fast iteration and transformation of the elements.
///
/// Accesses the underlying raw memory as Unmanaged<AnyObject> using untyped
/// memory accesses. The memory remains bound to managed AnyObjects.
internal struct _UnmanagedAnyObjectArray {
  /// Underlying pointer.
  internal var value: UnsafeMutableRawPointer

  internal init(_ up: UnsafeMutablePointer<AnyObject>) {
    self.value = UnsafeMutableRawPointer(up)
  }

  internal init?(_ up: UnsafeMutablePointer<AnyObject>?) {
    guard let unwrapped = up else { return nil }
    self.init(unwrapped)
  }

  internal subscript(i: Int) -> AnyObject {
    get {
      let unmanaged = value.load(
        fromByteOffset: i * MemoryLayout<AnyObject>.stride,
        as: Unmanaged<AnyObject>.self)
      return unmanaged.takeUnretainedValue()
    }
    nonmutating set(newValue) {
      let unmanaged = Unmanaged.passUnretained(newValue)
      value.storeBytes(of: unmanaged,
        toByteOffset: i * MemoryLayout<AnyObject>.stride,
        as: Unmanaged<AnyObject>.self)
    }
  }
}

//===--- APIs unique to Set<Element> --------------------------------------===//

/// An unordered collection of unique elements.
///
/// You use a set instead of an array when you need to test efficiently for
/// membership and you aren't concerned with the order of the elements in the
/// collection, or when you need to ensure that each element appears only once
/// in a collection.
///
/// You can create a set with any element type that conforms to the `Hashable`
/// protocol. By default, most types in the standard library are hashable,
/// including strings, numeric and Boolean types, enumeration cases without
/// associated values, and even sets themselves.
///
/// Swift makes it as easy to create a new set as to create a new array. Simply
/// assign an array literal to a variable or constant with the `Set` type
/// specified.
///
///     let ingredients: Set = ["cocoa beans", "sugar", "cocoa butter", "salt"]
///     if ingredients.contains("sugar") {
///         print("No thanks, too sweet.")
///     }
///     // Prints "No thanks, too sweet."
///
/// Set Operations
/// ==============
///
/// Sets provide a suite of mathematical set operations. For example, you can
/// efficiently test a set for membership of an element or check its
/// intersection with another set:
///
/// - Use the `contains(_:)` method to test whether a set contains a specific
///   element.
/// - Use the "equal to" operator (`==`) to test whether two sets contain the
///   same elements.
/// - Use the `isSubset(of:)` method to test whether a set contains all the
///   elements of another set or sequence.
/// - Use the `isSuperset(of:)` method to test whether all elements of a set
///   are contained in another set or sequence.
/// - Use the `isStrictSubset(of:)` and `isStrictSuperset(of:)` methods to test
///   whether a set is a subset or superset of, but not equal to, another set.
/// - Use the `isDisjoint(with:)` method to test whether a set has any elements
///   in common with another set.
///
/// You can also combine, exclude, or subtract the elements of two sets:
///
/// - Use the `union(_:)` method to create a new set with the elements of a set
///   and another set or sequence.
/// - Use the `intersection(_:)` method to create a new set with only the
///   elements common to a set and another set or sequence.
/// - Use the `symmetricDifference(_:)` method to create a new set with the
///   elements that are in either a set or another set or sequence, but not in
///   both.
/// - Use the `subtracting(_:)` method to create a new set with the elements of
///   a set that are not also in another set or sequence.
///
/// You can modify a set in place by using these methods' mutating
/// counterparts: `formUnion(_:)`, `formIntersection(_:)`,
/// `formSymmetricDifference(_:)`, and `subtract(_:)`.
///
/// Set operations are not limited to use with other sets. Instead, you can
/// perform set operations with another set, an array, or any other sequence
/// type.
///
///     var primes: Set = [2, 3, 5, 7]
///
///     // Tests whether primes is a subset of a Range<Int>
///     print(primes.isSubset(of: 0..<10))
///     // Prints "true"
///
///     // Performs an intersection with an Array<Int>
///     let favoriteNumbers = [5, 7, 15, 21]
///     print(primes.intersection(favoriteNumbers))
///     // Prints "[5, 7]"
///
/// Sequence and Collection Operations
/// ==================================
///
/// In addition to the `Set` type's set operations, you can use any nonmutating
/// sequence or collection methods with a set.
///
///     if primes.isEmpty {
///         print("No primes!")
///     } else {
///         print("We have \(primes.count) primes.")
///     }
///     // Prints "We have 4 primes."
///
///     let primesSum = primes.reduce(0, +)
///     // 'primesSum' == 17
///
///     let primeStrings = primes.sorted().map(String.init)
///     // 'primeStrings' == ["2", "3", "5", "7"]
///
/// You can iterate through a set's unordered elements with a `for`-`in` loop.
///
///     for number in primes {
///         print(number)
///     }
///     // Prints "5"
///     // Prints "7"
///     // Prints "2"
///     // Prints "3"
///
/// Many sequence and collection operations return an array or a type-erasing
/// collection wrapper instead of a set. To restore efficient set operations,
/// create a new set from the result.
///
///     let morePrimes = primes.union([11, 13, 17, 19])
///
///     let laterPrimes = morePrimes.filter { $0 > 10 }
///     // 'laterPrimes' is of type Array<Int>
///
///     let laterPrimesSet = Set(morePrimes.filter { $0 > 10 })
///     // 'laterPrimesSet' is of type Set<Int>
///
/// Bridging Between Set and NSSet
/// ==============================
///
/// You can bridge between `Set` and `NSSet` using the `as` operator. For
/// bridging to be possible, the `Element` type of a set must be a class, an
/// `@objc` protocol (a protocol imported from Objective-C or marked with the
/// `@objc` attribute), or a type that bridges to a Foundation type.
///
/// Bridging from `Set` to `NSSet` always takes O(1) time and space. When the
/// set's `Element` type is neither a class nor an `@objc` protocol, any
/// required bridging of elements occurs at the first access of each element,
/// so the first operation that uses the contents of the set (for example, a
/// membership test) can take O(*n*).
///
/// Bridging from `NSSet` to `Set` first calls the `copy(with:)` method
/// (`- copyWithZone:` in Objective-C) on the set to get an immutable copy and
/// then performs additional Swift bookkeeping work that takes O(1) time. For
/// instances of `NSSet` that are already immutable, `copy(with:)` returns the
/// same set in constant time; otherwise, the copying performance is
/// unspecified. The instances of `NSSet` and `Set` share buffer using the
/// same copy-on-write optimization that is used when two instances of `Set`
/// share buffer.
///
/// - SeeAlso: `Hashable`
@_fixed_layout
public struct Set<Element : Hashable> :
  SetAlgebra, Hashable, Collection, ExpressibleByArrayLiteral {

  internal typealias _Self = Set<Element>
  internal typealias _VariantBuffer = _VariantSetBuffer<Element>
  internal typealias _NativeBuffer = _NativeSetBuffer<Element>

  @_versioned
  internal var _variantBuffer: _VariantBuffer

  /// Creates a new, empty set with at least the specified number of elements'
  /// worth of buffer.
  ///
  /// Use this initializer to avoid repeated reallocations of a set's buffer
  /// if you know you'll be adding elements to the set after creation. The
  /// actual capacity of the created set will be the smallest power of 2 that
  /// is greater than or equal to `minimumCapacity`.
  ///
  /// - Parameter minimumCapacity: The minimum number of elements that the
  ///   newly created set should be able to store without reallocating its
  ///   buffer.
  public init(minimumCapacity: Int) {
    _variantBuffer =
      _VariantBuffer.native(
        _NativeBuffer(minimumCapacity: minimumCapacity))
  }

  /// Private initializer.
  internal init(_nativeBuffer: _NativeSetBuffer<Element>) {
    _variantBuffer = _VariantBuffer.native(_nativeBuffer)
  }

  //
  // All APIs below should dispatch to `_variantBuffer`, without doing any
  // additional processing.
  //

#if _runtime(_ObjC)
  /// Private initializer used for bridging.
  ///
  /// Only use this initializer when both conditions are true:
  ///
  /// * it is statically known that the given `NSSet` is immutable;
  /// * `Element` is bridged verbatim to Objective-C (i.e.,
  ///   is a reference type).
  public init(_immutableCocoaSet: _NSSet) {
    _sanityCheck(_isBridgedVerbatimToObjectiveC(Element.self),
      "Set can be backed by NSSet _variantBuffer only when the member type can be bridged verbatim to Objective-C")
    _variantBuffer = _VariantSetBuffer.cocoa(
      _CocoaSetBuffer(cocoaSet: _immutableCocoaSet))
  }
#endif

  /// The starting position for iterating members of the set.
  ///
  /// If the set is empty, `startIndex` is equal to `endIndex`.
  public var startIndex: Index {
    return _variantBuffer.startIndex
  }

  /// The "past the end" position for the set---that is, the position one
  /// greater than the last valid subscript argument.
  ///
  /// If the set is empty, `endIndex` is equal to `startIndex`.
  public var endIndex: Index {
    return _variantBuffer.endIndex
  }

  public func index(after i: Index) -> Index {
    return _variantBuffer.index(after: i)
  }

  // APINAMING: complexity docs are broadly missing in this file.

  /// Returns a Boolean value that indicates whether the given element exists
  /// in the set.
  ///
  /// This example uses the `contains(_:)` method to test whether an integer is
  /// a member of a set of prime numbers.
  ///
  ///     let primes: Set = [2, 3, 5, 7]
  ///     let x = 5
  ///     if primes.contains(x) {
  ///         print("\(x) is prime!")
  ///     } else {
  ///         print("\(x). Not prime.")
  ///     }
  ///     // Prints "5 is prime!"
  ///
  /// - Parameter member: An element to look for in the set.
  /// - Returns: `true` if `member` exists in the set; otherwise, `false`.
  public func contains(_ member: Element) -> Bool {
    return _variantBuffer.maybeGet(member) != nil
  }

  /// Returns the index of the given element in the set, or `nil` if the
  /// element is not a member of the set.
  ///
  /// - Parameter member: An element to search for in the set.
  /// - Returns: The index of `member` if it exists in the set; otherwise,
  ///   `nil`.
  public func index(of member: Element) -> Index? {
    return _variantBuffer.index(forKey: member)
  }

  /// Inserts the given element in the set if it is not already present.
  ///
  /// If an element equal to `newMember` is already contained in the set, this
  /// method has no effect. In the following example, a new element is
  /// inserted into `classDays`, a set of days of the week. When an existing
  /// element is inserted, the `classDays` set does not change.
  ///
  ///     enum DayOfTheWeek: Int {
  ///         case sunday, monday, tuesday, wednesday, thursday,
  ///             friday, saturday
  ///     }
  ///
  ///     var classDays: Set<DayOfTheWeek> = [.wednesday, .friday]
  ///     print(classDays.insert(.monday))
  ///     // Prints "(true, .monday)"
  ///     print(classDays)
  ///     // Prints "[.friday, .wednesday, .monday]"
  ///
  ///     print(classDays.insert(.friday))
  ///     // Prints "(false, .friday)"
  ///     print(classDays)
  ///     // Prints "[.friday, .wednesday, .monday]"
  ///
  /// - Parameter newMember: An element to insert into the set.
  /// - Returns: `(true, newMember)` if `newMember` was not contained in the
  ///   set. If an element equal to `newMember` was already contained in the
  ///   set, the method returns `(false, oldMember)`, where `oldMember` is the
  ///   element that was equal to `newMember`. In some cases, `oldMember` may
  ///   be distinguishable from `newMember` by identity comparison or some
  ///   other means.
  @discardableResult
  public mutating func insert(
    _ newMember: Element
  ) -> (inserted: Bool, memberAfterInsert: Element) {
    return _variantBuffer.insert(newMember, forKey: newMember)
  }

  /// Inserts the given element into the set unconditionally.
  ///
  /// If an element equal to `newMember` is already contained in the set,
  /// `newMember` replaces the existing element. In this example, an existing
  /// element is inserted into `classDays`, a set of days of the week.
  ///
  ///     enum DayOfTheWeek: Int {
  ///         case sunday, monday, tuesday, wednesday, thursday,
  ///             friday, saturday
  ///     }
  ///
  ///     var classDays: Set<DayOfTheWeek> = [.monday, .wednesday, .friday]
  ///     print(classDays.update(with: .monday))
  ///     // Prints "Optional(.monday)"
  ///
  /// - Parameter newMember: An element to insert into the set.
  /// - Returns: An element equal to `newMember` if the set already contained
  ///   such a member; otherwise, `nil`. In some cases, the returned element
  ///   may be distinguishable from `newMember` by identity comparison or some
  ///   other means.
  @discardableResult
  public mutating func update(with newMember: Element) -> Element? {
    return _variantBuffer.updateValue(newMember, forKey: newMember)
  }

  /// Removes the specified element from the set.
  ///
  /// This example removes the element `"sugar"` from a set of ingredients.
  ///
  ///     var ingredients: Set = ["cocoa beans", "sugar", "cocoa butter", "salt"]
  ///     let toRemove = "sugar"
  ///     if let removed = ingredients.remove(toRemove) {
  ///         print("The recipe is now \(removed)-free.")
  ///     }
  ///     // Prints "The recipe is now sugar-free."
  ///
  /// - Parameter member: The element to remove from the set.
  /// - Returns: The value of the `member` parameter if it was a member of the
  ///   set; otherwise, `nil`.
  @discardableResult
  public mutating func remove(_ member: Element) -> Element? {
    return _variantBuffer.removeValue(forKey: member)
  }

  /// Removes the element at the given index of the set.
  ///
  /// - Parameter position: The index of the member to remove. `position` must
  ///   be a valid index of the set, and must not be equal to the set's end
  ///   index.
  /// - Returns: The element that was removed from the set.
  @discardableResult
  public mutating func remove(at position: Index) -> Element {
    return _variantBuffer.remove(at: position)
  }

  /// Removes all members from the set.
  ///
  /// - Parameter keepingCapacity: If `true`, the set's buffer capacity is
  ///   preserved; if `false`, the underlying buffer is released. The
  ///   default is `false`.
  public mutating func removeAll(keepingCapacity keepCapacity: Bool = false) {
    _variantBuffer.removeAll(keepingCapacity: keepCapacity)
  }

  /// Removes the first element of the set.
  ///
  /// Because a set is not an ordered collection, the "first" element may not
  /// be the first element that was added to the set. The set must not be
  /// empty.
  ///
  /// - Complexity: Amortized O(1) if the set does not wrap a bridged `NSSet`.
  ///   If the set wraps a bridged `NSSet`, the performance is unspecified.
  ///
  /// - Returns: A member of the set.
  @discardableResult
  public mutating func removeFirst() -> Element {
    _precondition(!isEmpty, "can't removeFirst from an empty Set")
    return remove(at: startIndex)
  }

  /// The number of elements in the set.
  ///
  /// - Complexity: O(1).
  public var count: Int {
    return _variantBuffer.count
  }

  //
  // `Sequence` conformance
  //

  /// Accesses the member at the given position.
  public subscript(position: Index) -> Element {
    return _variantBuffer.assertingGet(position)
  }

  /// Returns an iterator over the members of the set.
  @inline(__always)
  public func makeIterator() -> SetIterator<Element> {
    return _variantBuffer.makeIterator()
  }

  //
  // `ExpressibleByArrayLiteral` conformance
  //
  /// Creates a set containing the elements of the given array literal.
  ///
  /// Do not call this initializer directly. It is used by the compiler when
  /// you use an array literal. Instead, create a new set using an array
  /// literal as its value by enclosing a comma-separated list of values in
  /// square brackets. You can use an array literal anywhere a set is expected
  /// by the type context.
  ///
  /// Here, a set of strings is created from an array literal holding only
  /// strings.
  ///
  ///     let ingredients: Set = ["cocoa beans", "sugar", "cocoa butter", "salt"]
  ///     if ingredients.isSuperset(of: ["sugar", "salt"]) {
  ///         print("Whatever it is, it's bound to be delicious!")
  ///     }
  ///     // Prints "Whatever it is, it's bound to be delicious!"
  ///
  /// - Parameter elements: A variadic list of elements of the new set.
  public init(arrayLiteral elements: Element...) {
    self.init(_nativeBuffer: _NativeSetBuffer.fromArray(elements))
  }

  //
  // APIs below this comment should be implemented strictly in terms of
  // *public* APIs above.  `_variantBuffer` should not be accessed directly.
  //
  // This separates concerns for testing.  Tests for the following APIs need
  // not to concern themselves with testing correctness of behavior of
  // underlying buffer (and different variants of it), only correctness of the
  // API itself.
  //

  /// Creates an empty set.
  ///
  /// This is equivalent to initializing with an empty array literal. For
  /// example:
  ///
  ///     var emptySet = Set<Int>()
  ///     print(emptySet.isEmpty)
  ///     // Prints "true"
  ///
  ///     emptySet = []
  ///     print(emptySet.isEmpty)
  ///     // Prints "true"
  public init() {
    self = Set<Element>(_nativeBuffer: _NativeBuffer())
  }

  /// Creates a new set from a finite sequence of items.
  ///
  /// Use this initializer to create a new set from an existing sequence, for
  /// example, an array or a range.
  ///
  ///     let validIndices = Set(0..<7).subtracting([2, 4, 5])
  ///     print(validIndices)
  ///     // Prints "[6, 0, 1, 3]"
  ///
  /// This initializer can also be used to restore set methods after performing
  /// sequence operations such as `filter(_:)` or `map(_:)` on a set. For
  /// example, after filtering a set of prime numbers to remove any below 10,
  /// you can create a new set by using this initializer.
  ///
  ///     let primes: Set = [2, 3, 5, 7, 11, 13, 17, 19, 23]
  ///     let laterPrimes = Set(primes.lazy.filter { $0 > 10 })
  ///     print(laterPrimes)
  ///     // Prints "[17, 19, 23, 11, 13]"
  ///
  /// - Parameter sequence: The elements to use as members of the new set.
  public init<Source : Sequence>(_ sequence: Source)
    where Source.Iterator.Element == Element {
    self.init(minimumCapacity: sequence.underestimatedCount)
    if let s = sequence as? Set<Element> {
      // If this sequence is actually a native `Set`, then we can quickly
      // adopt its native buffer and let COW handle uniquing only
      // if necessary.
      switch s._variantBuffer {
        case .native(let buffer):
          _variantBuffer = .native(buffer)
        case .cocoa(let owner):
          _variantBuffer = .cocoa(owner)
      }
    } else {
      for item in sequence {
        insert(item)
      }
    }
  }

  /// Returns a Boolean value that indicates whether the set is a subset of the
  /// given sequence.
  ///
  /// Set *A* is a subset of another set *B* if every member of *A* is also a
  /// member of *B*.
  ///
  ///     let employees = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let attendees: Set = ["Alicia", "Bethany", "Diana"]
  ///     print(attendees.isSubset(of: employees))
  ///     // Prints "true"
  ///
  /// - Parameter possibleSuperset: A sequence of elements. `possibleSuperset`
  ///   must be finite.
  /// - Returns: `true` if the set is a subset of `possibleSuperset`;
  ///   otherwise, `false`.
  @_inlineable
  public func isSubset<S : Sequence>(of possibleSuperset: S) -> Bool
    where S.Iterator.Element == Element {
    // FIXME(performance): isEmpty fast path, here and elsewhere.
    let other = Set(possibleSuperset)
    return isSubset(of: other)
  }

  /// Returns a Boolean value that indicates whether the set is a strict subset
  /// of the given sequence.
  ///
  /// 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 employees = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let attendees: Set = ["Alicia", "Bethany", "Diana"]
  ///     print(attendees.isStrictSubset(of: employees))
  ///     // Prints "true"
  ///
  ///     // A set is never a strict subset of itself:
  ///     print(attendees.isStrictSubset(of: attendees))
  ///     // Prints "false"
  ///
  /// - Parameter possibleStrictSuperset: A sequence of elements.
  ///   `possibleStrictSuperset` must be finite.
  /// - Returns: `true` is the set is strict subset of
  ///   `possibleStrictSuperset`; otherwise, `false`.
  @_inlineable
  public func isStrictSubset<S : Sequence>(of possibleStrictSuperset: S) -> Bool
    where S.Iterator.Element == Element {
    // FIXME: code duplication.
    let other = Set(possibleStrictSuperset)
    return isStrictSubset(of: other)
  }

  /// Returns a Boolean value that indicates whether the set is a superset of
  /// the given sequence.
  ///
  /// Set *A* is a superset of another set *B* if every member of *B* is also a
  /// member of *A*.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let attendees = ["Alicia", "Bethany", "Diana"]
  ///     print(employees.isSuperset(of: attendees))
  ///     // Prints "true"
  ///
  /// - Parameter possibleSubset: A sequence of elements. `possibleSubset` must
  ///   be finite.
  /// - Returns: `true` if the set is a superset of `possibleSubset`;
  ///   otherwise, `false`.
  @_inlineable
  public func isSuperset<S : Sequence>(of possibleSubset: S) -> Bool
    where S.Iterator.Element == Element {
    // FIXME(performance): Don't build a set; just ask if every element is in
    // `self`.
    let other = Set(possibleSubset)
    return other.isSubset(of: self)
  }

  /// Returns a Boolean value that indicates whether the set is a strict
  /// superset of the given sequence.
  ///
  /// Set *A* is a strict superset of another set *B* if every member of *B* is
  /// also a member of *A* and *A* contains at least one element that is *not*
  /// a member of *B*.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let attendees = ["Alicia", "Bethany", "Diana"]
  ///     print(employees.isStrictSuperset(of: attendees))
  ///     // Prints "true"
  ///     print(employees.isStrictSuperset(of: employees))
  ///     // Prints "false"
  ///
  /// - Parameter possibleStrictSubset: A sequence of elements.
  ///   `possibleStrictSubset` must be finite.
  /// - Returns: `true` if the set is a strict superset of
  ///   `possibleStrictSubset`; otherwise, `false`.
  public func isStrictSuperset<S : Sequence>(of possibleStrictSubset: S) -> Bool
    where S.Iterator.Element == Element {
    let other = Set(possibleStrictSubset)
    return other.isStrictSubset(of: self)
  }

  /// Returns a Boolean value that indicates whether the set has no members in
  /// common with the given sequence.
  ///
  /// In the following example, the `employees` set is disjoint with the
  /// elements of the `visitors` array because no name appears in both.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let visitors = ["Marcia", "Nathaniel", "Olivia"]
  ///     print(employees.isDisjoint(with: visitors))
  ///     // Prints "true"
  ///
  /// - Parameter other: A sequence of elements. `other` must be finite.
  /// - Returns: `true` if the set has no elements in common with `other`;
  ///   otherwise, `false`.
  public func isDisjoint<S : Sequence>(with other: S) -> Bool
    where S.Iterator.Element == Element {
    // FIXME(performance): Don't need to build a set.
    let otherSet = Set(other)
    return isDisjoint(with: otherSet)
  }

  /// Returns a new set with the elements of both this set and the given
  /// sequence.
  ///
  /// In the following example, the `attendeesAndVisitors` set is made up
  /// of the elements of the `attendees` set and the `visitors` array:
  ///
  ///     let attendees: Set = ["Alicia", "Bethany", "Diana"]
  ///     let visitors = ["Marcia", "Nathaniel"]
  ///     let attendeesAndVisitors = attendees.union(visitors)
  ///     print(attendeesAndVisitors)
  ///     // Prints "["Diana", "Nathaniel", "Bethany", "Alicia", "Marcia"]"
  ///
  /// If the set already contains one or more elements that are also in
  /// `other`, the existing members are kept. If `other` contains multiple
  /// instances of equivalent elements, only the first instance is kept.
  ///
  ///     let initialIndices = Set(0..<5)
  ///     let expandedIndices = initialIndices.union([2, 3, 6, 6, 7, 7])
  ///     print(expandedIndices)
  ///     // Prints "[2, 4, 6, 7, 0, 1, 3]"
  ///
  /// - Parameter other: A sequence of elements. `other` must be finite.
  /// - Returns: A new set with the unique elements of this set and `other`.
  @_inlineable
  public func union<S : Sequence>(_ other: S) -> Set<Element>
    where S.Iterator.Element == Element {
    var newSet = self
    newSet.formUnion(other)
    return newSet
  }

  /// Inserts the elements of the given sequence into the set.
  ///
  /// If the set already contains one or more elements that are also in
  /// `other`, the existing members are kept. If `other` contains multiple
  /// instances of equivalent elements, only the first instance is kept.
  ///
  ///     var attendees: Set = ["Alicia", "Bethany", "Diana"]
  ///     let visitors = ["Diana", ""Marcia", "Nathaniel"]
  ///     attendees.formUnion(visitors)
  ///     print(attendees)
  ///     // Prints "["Diana", "Nathaniel", "Bethany", "Alicia", "Marcia"]"
  ///
  /// - Parameter other: A sequence of elements. `other` must be finite.
  @_inlineable
  public mutating func formUnion<S : Sequence>(_ other: S)
    where S.Iterator.Element == Element {
    for item in other {
      insert(item)
    }
  }

  /// Returns a new set containing the elements of this set that do not occur
  /// in the given sequence.
  ///
  /// In the following example, the `nonNeighbors` set is made up of the
  /// elements of the `employees` set that are not elements of `neighbors`:
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let neighbors = ["Bethany", "Eric", "Forlani", "Greta"]
  ///     let nonNeighbors = employees.subtracting(neighbors)
  ///     print(nonNeighbors)
  ///     // Prints "["Chris", "Diana", "Alicia"]"
  ///
  /// - Parameter other: A sequence of elements. `other` must be finite.
  /// - Returns: A new set.
  @_inlineable
  public func subtracting<S : Sequence>(_ other: S) -> Set<Element>
    where S.Iterator.Element == Element {
    return self._subtracting(other)
  }

  @_versioned
  internal func _subtracting<S : Sequence>(_ other: S) -> Set<Element>
    where S.Iterator.Element == Element {
    var newSet = self
    newSet.subtract(other)
    return newSet
  }

  /// Removes the elements of the given sequence from the set.
  ///
  /// In the following example, the elements of the `employees` set that are
  /// also elements of the `neighbors` array are removed. In particular, the
  /// names `"Bethany"` and `"Eric"` are removed from `employees`.
  ///
  ///     var employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let neighbors = ["Bethany", "Eric", "Forlani", "Greta"]
  ///     employees.subtract(neighbors)
  ///     print(employees)
  ///     // Prints "["Chris", "Diana", "Alicia"]"
  ///
  /// - Parameter other: A sequence of elements. `other` must be finite.
  public mutating func subtract<S : Sequence>(_ other: S)
    where S.Iterator.Element == Element {
    _subtract(other)
  }

  internal mutating func _subtract<S : Sequence>(_ other: S)
    where S.Iterator.Element == Element {
    for item in other {
      remove(item)
    }
  }

  /// Returns a new set with the elements that are common to both this set and
  /// the given sequence.
  ///
  /// In the following example, the `bothNeighborsAndEmployees` set is made up
  /// of the elements that are in *both* the `employees` and `neighbors` sets.
  /// Elements that are in only one or the other are left out of the result of
  /// the intersection.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let neighbors = ["Bethany", "Eric", "Forlani", "Greta"]
  ///     let bothNeighborsAndEmployees = employees.intersection(neighbors)
  ///     print(bothNeighborsAndEmployees)
  ///     // Prints "["Bethany", "Eric"]"
  ///
  /// - Parameter other: A sequence of elements. `other` must be finite.
  /// - Returns: A new set.
  @_inlineable
  public func intersection<S : Sequence>(_ other: S) -> Set<Element>
    where S.Iterator.Element == Element {
    let otherSet = Set(other)
    return intersection(otherSet)
  }

  /// Removes the elements of the set that aren't also in the given sequence.
  ///
  /// In the following example, the elements of the `employees` set that are
  /// not also members of the `neighbors` set are removed. In particular, the
  /// names `"Alicia"`, `"Chris"`, and `"Diana"` are removed.
  ///
  ///     var employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let neighbors = ["Bethany", "Eric", "Forlani", "Greta"]
  ///     employees.formIntersection(neighbors)
  ///     print(employees)
  ///     // Prints "["Bethany", "Eric"]"
  ///
  /// - Parameter other: A sequence of elements. `other` must be finite.
  @_inlineable
  public mutating func formIntersection<S : Sequence>(_ other: S)
    where S.Iterator.Element == Element {
    // Because `intersect` needs to both modify and iterate over
    // the left-hand side, the index may become invalidated during
    // traversal so an intermediate set must be created.
    //
    // FIXME(performance): perform this operation at a lower level
    // to avoid invalidating the index and avoiding a copy.
    let result = self.intersection(other)

    // The result can only have fewer or the same number of elements.
    // If no elements were removed, don't perform a reassignment
    // as this may cause an unnecessary uniquing COW.
    if result.count != count {
      self = result
    }
  }

  /// Returns a new set with the elements that are either in this set or in the
  /// given sequence, but not in both.
  ///
  /// In the following example, the `eitherNeighborsOrEmployees` set is made up
  /// of the elements of the `employees` and `neighbors` sets that are not in
  /// both `employees` *and* `neighbors`. In particular, the names `"Bethany"`
  /// and `"Eric"` do not appear in `eitherNeighborsOrEmployees`.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Diana", "Eric"]
  ///     let neighbors = ["Bethany", "Eric", "Forlani"]
  ///     let eitherNeighborsOrEmployees = employees.symmetricDifference(neighbors)
  ///     print(eitherNeighborsOrEmployees)
  ///     // Prints "["Diana", "Forlani", "Alicia"]"
  ///
  /// - Parameter other: A sequence of elements. `other` must be finite.
  /// - Returns: A new set.
  @_inlineable
  public func symmetricDifference<S : Sequence>(_ other: S) -> Set<Element>
    where S.Iterator.Element == Element {
    var newSet = self
    newSet.formSymmetricDifference(other)
    return newSet
  }

  /// Replace this set with the elements contained in this set or the given
  /// set, but not both.
  ///
  /// In the following example, the elements of the `employees` set that are
  /// also members of `neighbors` are removed from `employees`, while the
  /// elements of `neighbors` that are not members of `employees` are added to
  /// `employees`. In particular, the names `"Alicia"`, `"Chris"`, and
  /// `"Diana"` are removed from `employees` while the name `"Forlani"` is
  /// added.
  ///
  ///     var employees: Set = ["Alicia", "Bethany", "Diana", "Eric"]
  ///     let neighbors = ["Bethany", "Eric", "Forlani"]
  ///     employees.formSymmetricDifference(neighbors)
  ///     print(employees)
  ///     // Prints "["Diana", "Forlani", "Alicia"]"
  ///
  /// - Parameter other: A sequence of elements. `other` must be finite.
  @_inlineable
  public mutating func formSymmetricDifference<S : Sequence>(_ other: S)
    where S.Iterator.Element == Element {
    let otherSet = Set(other)
    formSymmetricDifference(otherSet)
  }

  /// The hash value for the set.
  ///
  /// Two sets that are equal will always have equal hash values.
  ///
  /// Hash values are not guaranteed to be equal across different executions of
  /// your program. Do not save hash values to use during a future execution.
  public var hashValue: Int {
    // FIXME(ABI)#177: <rdar://problem/18915294> Cache Set<T> hashValue
    var result: Int = _mixInt(0)
    for member in self {
       result ^= _mixInt(member.hashValue)
    }
    return result
  }

  //
  // `Sequence` conformance
  //

  public func _customContainsEquatableElement(_ member: Element) -> Bool? {
    return contains(member)
  }

  public func _customIndexOfEquatableElement(
     _ member: Element
    ) -> Index?? {
    return Optional(index(of: member))
  }

  //
  // Collection conformance
  //

  /// A Boolean value that indicates whether the set is empty.
  public var isEmpty: Bool {
    return count == 0
  }

  /// The first element of the set.
  ///
  /// The first element of the set is not necessarily the first element added
  /// to the set. Don't expect any particular ordering of set elements.
  ///
  /// If the set is empty, the value of this property is `nil`.
  public var first: Element? {
    return count > 0 ? self[startIndex] : nil
  }
}

/// Check for both subset and equality relationship between
/// a set and some sequence (which may itself be a `Set`).
///
/// (isSubset: lhs ⊂ rhs, isEqual: lhs ⊂ rhs and |lhs| = |rhs|)
@_inlineable
@_versioned
internal func _compareSets<Element>(_ lhs: Set<Element>, _ rhs: Set<Element>)
  -> (isSubset: Bool, isEqual: Bool) {
  // FIXME(performance): performance could be better if we start by comparing
  // counts.
  for member in lhs {
    if !rhs.contains(member) {
      return (false, false)
    }
  }
  return (true, lhs.count == rhs.count)
}

// FIXME: rdar://problem/23549059 (Optimize == for Set)
// Look into initially trying to compare the two sets by directly comparing the
// contents of both buffers in order. If they happen to have the exact same
// ordering we can get the `true` response without ever hashing. If the two
// buffers' contents differ at all then we have to fall back to hashing the
// rest of the elements (but we don't need to hash any prefix that did match).
extension Set {
  /// Returns a Boolean value indicating whether two sets have equal elements.
  ///
  /// - Parameters:
  ///   - lhs: A set.
  ///   - rhs: Another set.
  /// - Returns: `true` if the `lhs` and `rhs` have the same elements; otherwise,
  ///   `false`.
  public static func == (lhs: Set<Element>, rhs: Set<Element>) -> Bool {
    switch (lhs._variantBuffer, rhs._variantBuffer) {
    case (.native(let lhsNative), .native(let rhsNative)):

      if lhsNative._storage === rhsNative._storage {
        return true
      }

      if lhsNative.count != rhsNative.count {
        return false
      }

      for member in lhs {
        let (_, found) =
          rhsNative._find(member, startBucket: rhsNative._bucket(member))
        if !found {
          return false
        }
      }
      return true

    case (_VariantSetBuffer.cocoa(let lhsCocoa),
        _VariantSetBuffer.cocoa(let rhsCocoa)):
  #if _runtime(_ObjC)
      return _stdlib_NSObject_isEqual(lhsCocoa.cocoaSet, rhsCocoa.cocoaSet)
  #else
        _sanityCheckFailure("internal error: unexpected cocoa set")
  #endif

    case (_VariantSetBuffer.native(let lhsNative),
      _VariantSetBuffer.cocoa(let rhsCocoa)):
  #if _runtime(_ObjC)

      if lhsNative.count != rhsCocoa.count {
        return false
      }

      let endIndex = lhsNative.endIndex
      var i = lhsNative.startIndex
      while i != endIndex {
        let key = lhsNative.assertingGet(i)
        let bridgedKey: AnyObject = _bridgeAnythingToObjectiveC(key)
        let optRhsValue: AnyObject? = rhsCocoa.maybeGet(bridgedKey)
        if let rhsValue = optRhsValue {
          if key == _forceBridgeFromObjectiveC(rhsValue, Element.self) {
            i = lhsNative.index(after: i)
            continue
          }
        }
        i = lhsNative.index(after: i)
        return false
      }
      return true
  #else
        _sanityCheckFailure("internal error: unexpected cocoa set")
  #endif

    case (_VariantSetBuffer.cocoa, _VariantSetBuffer.native):
  #if _runtime(_ObjC)
      return rhs == lhs
  #else
        _sanityCheckFailure("internal error: unexpected cocoa set")
  #endif
    }
  }
}

extension Set : CustomStringConvertible, CustomDebugStringConvertible {
  internal func makeDescription(isDebug: Bool) -> String {
    var result = isDebug ? "Set([" : "["
    var first = true
    for member in self {
      if first {
        first = false
      } else {
        result += ", "
      }
      debugPrint(member, terminator: "", to: &result)
    }
    result += isDebug ? "])" : "]"
    return result
  }

  /// A string that represents the contents of the set.
  public var description: String {
    return makeDescription(isDebug: false)
  }

  /// A string that represents the contents of the set, suitable for debugging.
  public var debugDescription: String {
    return makeDescription(isDebug: true)
  }
}

#if _runtime(_ObjC)
@_silgen_name("swift_stdlib_CFSetGetValues")
func _stdlib_CFSetGetValues(_ nss: _NSSet, _: UnsafeMutablePointer<AnyObject>)

/// Equivalent to `NSSet.allObjects`, but does not leave objects on the
/// autorelease pool.
internal func _stdlib_NSSet_allObjects(_ nss: _NSSet) ->
  _HeapBuffer<Int, AnyObject> {
  let count = nss.count
  let storage = _HeapBuffer<Int, AnyObject>(
    _HeapBufferStorage<Int, AnyObject>.self, count, count)
  _stdlib_CFSetGetValues(nss, storage.baseAddress)
  return storage
}
#endif

//===--- Compiler conversion/casting entry points for Set<Element> --------===//

/// Perform a non-bridged upcast that always succeeds.
///
/// - Precondition: `BaseValue` is a base class or base `@objc`
///   protocol (such as `AnyObject`) of `DerivedValue`.
public func _setUpCast<DerivedValue, BaseValue>(_ source: Set<DerivedValue>)
  -> Set<BaseValue> {
  var builder = _SetBuilder<BaseValue>(count: source.count)
  for x in source {
    builder.add(member: x as! BaseValue)
  }
  return builder.take()
}

#if _runtime(_ObjC)

/// Implements an unconditional upcast that involves bridging.
///
/// The cast can fail if bridging fails.
///
/// - Precondition: `SwiftValue` is bridged to Objective-C
///   and requires non-trivial bridging.
public func _setBridgeToObjectiveC<SwiftValue, ObjCValue>(
  _ source: Set<SwiftValue>
) -> Set<ObjCValue> {
  _sanityCheck(_isClassOrObjCExistential(ObjCValue.self))
  _sanityCheck(!_isBridgedVerbatimToObjectiveC(SwiftValue.self))

  var result = Set<ObjCValue>(minimumCapacity: source.count)
  let valueBridgesDirectly =
    _isBridgedVerbatimToObjectiveC(SwiftValue.self) ==
    _isBridgedVerbatimToObjectiveC(ObjCValue.self)

  for member in source {
    var bridgedMember: ObjCValue
    if valueBridgesDirectly {
      bridgedMember = unsafeBitCast(member, to: ObjCValue.self)
    } else {
      let bridged: AnyObject = _bridgeAnythingToObjectiveC(member)
      bridgedMember = unsafeBitCast(bridged, to: ObjCValue.self)
    }
    result.insert(bridgedMember)
  }
  return result
}

#endif

@_silgen_name("_swift_setDownCastIndirect")
public func _setDownCastIndirect<SourceValue, TargetValue>(
  _ source: UnsafePointer<Set<SourceValue>>,
  _ target: UnsafeMutablePointer<Set<TargetValue>>) {
  target.initialize(to: _setDownCast(source.pointee))
}

/// Implements a forced downcast.  This operation should have O(1) complexity.
///
/// The cast can fail if bridging fails.  The actual checks and bridging can be
/// deferred.
///
/// - Precondition: `DerivedValue` is a subtype of `BaseValue` and both
///   are reference types.
public func _setDownCast<BaseValue, DerivedValue>(_ source: Set<BaseValue>)
  -> Set<DerivedValue> {

#if _runtime(_ObjC)
  if _isClassOrObjCExistential(BaseValue.self)
  && _isClassOrObjCExistential(DerivedValue.self) {
    switch source._variantBuffer {
    case _VariantSetBuffer.native(let buffer):
      return Set(_immutableCocoaSet: buffer.bridged())
    case _VariantSetBuffer.cocoa(let cocoaBuffer):
      return Set(_immutableCocoaSet: cocoaBuffer.cocoaSet)
    }
  }
#endif
  return _setDownCastConditional(source)!
}

@_silgen_name("_swift_setDownCastConditionalIndirect")
public func _setDownCastConditionalIndirect<SourceValue, TargetValue>(
  _ source: UnsafePointer<Set<SourceValue>>,
  _ target: UnsafeMutablePointer<Set<TargetValue>>
) -> Bool {
  if let result: Set<TargetValue> = _setDownCastConditional(source.pointee) {
    target.initialize(to: result)
    return true
  }
  return false
}

/// Implements a conditional downcast.
///
/// If the cast fails, the function returns `nil`.  All checks should be
/// performed eagerly.
///
/// - Precondition: `DerivedValue` is a subtype of `BaseValue` and both
///   are reference types.
public func _setDownCastConditional<BaseValue, DerivedValue>(
  _ source: Set<BaseValue>
) -> Set<DerivedValue>? {
  var result = Set<DerivedValue>(minimumCapacity: source.count)
  for member in source {
    if let derivedMember = member as? DerivedValue {
      result.insert(derivedMember)
      continue
    }
    return nil
  }
  return result
}

#if _runtime(_ObjC)

/// Implements an unconditional downcast that involves bridging.
///
/// - Precondition: At least one of `SwiftValue` is a bridged value
///   type, and the corresponding `ObjCValue` is a reference type.
public func _setBridgeFromObjectiveC<ObjCValue, SwiftValue>(
  _ source: Set<ObjCValue>
) -> Set<SwiftValue> {
  let result: Set<SwiftValue>? = _setBridgeFromObjectiveCConditional(source)
  _precondition(result != nil, "This set cannot be bridged from Objective-C")
  return result!
}

/// Implements a conditional downcast that involves bridging.
///
/// If the cast fails, the function returns `nil`.  All checks should be
/// performed eagerly.
///
/// - Precondition: At least one of `SwiftValue` is a bridged value
///   type, and the corresponding `ObjCValue` is a reference type.
public func _setBridgeFromObjectiveCConditional<
  ObjCValue, SwiftValue
>(
  _ source: Set<ObjCValue>
) -> Set<SwiftValue>? {
  _sanityCheck(_isClassOrObjCExistential(ObjCValue.self))
  _sanityCheck(!_isBridgedVerbatimToObjectiveC(SwiftValue.self))

  let valueBridgesDirectly =
    _isBridgedVerbatimToObjectiveC(SwiftValue.self) ==
      _isBridgedVerbatimToObjectiveC(ObjCValue.self)

  var result = Set<SwiftValue>(minimumCapacity: source.count)
  for value in source {
    // Downcast the value.
    var resultValue: SwiftValue
    if valueBridgesDirectly {
      if let bridgedValue = value as? SwiftValue {
        resultValue = bridgedValue
      } else {
        return nil
      }
    } else {
      if let bridgedValue = _conditionallyBridgeFromObjectiveC(
          _reinterpretCastToAnyObject(value), SwiftValue.self) {
        resultValue = bridgedValue
      } else {
        return nil
      }
    }
    result.insert(resultValue)
  }
  return result
}

#endif

//===--- APIs unique to Dictionary<Key, Value> ----------------------------===//

/// A collection whose elements are key-value pairs.
///
/// A dictionary is a type of hash table, providing fast access to the entries
/// it contains. Each entry in the table is identified using its key, which is
/// a hashable type such as a string or number. You use that key to retrieve
/// the corresponding value, which can be any object. In other languages,
/// similar data types are known as hashes or associated arrays.
///
/// Create a new dictionary by using a dictionary literal. A dictionary literal
/// is a comma-separated list of key-value pairs, in which a colon separates
/// each key from its associated value, surrounded by square brackets. You can
/// assign a dictionary literal to a variable or constant or pass it to a
/// function that expects a dictionary.
///
/// Here's how you would create a dictionary of HTTP response codes and their
/// related messages:
///
///     var responseMessages = [200: "OK",
///                             403: "Access forbidden",
///                             404: "File not found",
///                             500: "Internal server error"]
///
/// The `responseMessages` variable is inferred to have type `[Int: String]`.
/// The `Key` type of the dictionary is `Int`, and the `Value` type of the
/// dictionary is `String`.
///
/// To create a dictionary with no key-value pairs, use an empty dictionary
/// literal (`[:]`).
///
///     var emptyDict: [String: String] = [:]
///
/// Any type that conforms to the `Hashable` protocol can be used as a
/// dictionary's `Key` type, including all of Swift's basic types. You can use
/// your own custom types as dictionary keys by making them conform to the
/// `Hashable` protocol.
///
/// Getting and Setting Dictionary Values
/// =====================================
///
/// The most common way to access values in a dictionary is to use a key as a
/// subscript. Subscripting with a key takes the following form:
///
///     print(responseMessages[200])
///     // Prints "Optional("OK")"
///
/// Subscripting a dictionary with a key returns an optional value, because a
/// dictionary might not hold a value for the key that you use in the
/// subscript.
///
/// The next example uses key-based subscripting of the `responseMessages`
/// dictionary with two keys that exist in the dictionary and one that does
/// not.
///
///     let httpResponseCodes = [200, 403, 301]
///     for code in httpResponseCodes {
///         if let message = responseMessages[code] {
///             print("Response \(code): \(message)")
///         } else {
///             print("Unknown response \(code)")
///         }
///     }
///     // Prints "Response 200: OK"
///     // Prints "Response 403: Access Forbidden"
///     // Prints "Unknown response 301"
///
/// You can also update, modify, or remove keys and values from a dictionary
/// using the key-based subscript. To add a new key-value pair, assign a value
/// to a key that isn't yet a part of the dictionary.
///
///     responseMessages[301] = "Moved permanently"
///     print(responseMessages[301])
///     // Prints "Optional("Moved permanently")"
///
/// Update an existing value by assigning a new value to a key that already
/// exists in the dictionary. If you assign `nil` to an existing key, the key
/// and its associated value are removed. The following example updates the
/// value for the `404` code to be simply "Not found" and removes the
/// key-value pair for the `500` code entirely.
///
///     responseMessages[404] = "Not found"
///     responseMessages[500] = nil
///     print(responseMessages)
///     // Prints "[301: "Moved permanently", 200: "OK", 403: "Access forbidden", 404: "Not found"]"
///
/// In a mutable `Dictionary` instance, you can modify in place a value that
/// you've accessed through a keyed subscript. The code sample below declares a
/// dictionary called `interestingNumbers` with string keys and values that
/// are integer arrays, then sorts each array in-place in descending order.
///
///     var interestingNumbers = ["primes": [2, 3, 5, 7, 11, 13, 15],
///                               "triangular": [1, 3, 6, 10, 15, 21, 28],
///                               "hexagonal": [1, 6, 15, 28, 45, 66, 91]]
///     for key in interestingNumbers.keys {
///         interestingNumbers[key]?.sort(by: >)
///     }
///
///     print(interestingNumbers["primes"]!)
///     // Prints "[15, 13, 11, 7, 5, 3, 2]"
///
/// Iterating Over the Contents of a Dictionary
/// ===========================================
///
/// Every dictionary is an unordered collection of key-value pairs. You can
/// iterate over a dictionary using a `for`-`in` loop, decomposing each
/// key-value pair into the elements of a tuple.
///
///     let imagePaths = ["star": "/glyphs/star.png",
///                       "portrait": "/images/content/portrait.jpg",
///                       "spacer": "/images/shared/spacer.gif"]
///
///     for (name, path) in imagePaths {
///         print("The path to '\(name)' is '\(path)'.")
///     }
///     // Prints "The path to 'star' is '/glyphs/star.png'."
///     // Prints "The path to 'portrait' is '/images/content/portrait.jpg'."
///     // Prints "The path to 'spacer' is '/images/shared/spacer.gif'."
///
/// The order of key-value pairs in a dictionary is stable between mutations
/// but is otherwise unpredictable. If you need an ordered collection of
/// key-value pairs and don't need the fast key lookup that `Dictionary`
/// provides, see the `DictionaryLiteral` type for an alternative.
///
/// You can search a dictionary's contents for a particular value using the
/// `contains(where:)` or `index(where:)` methods supplied by default
/// implementation. The following example checks to see if `imagePaths` contains
/// any paths in the `"/glyphs"` directory:
///
///     let glyphIndex = imagePaths.index { $0.value.hasPrefix("/glyphs") }
///     if let index = glyphIndex {
///         print("The '\(imagesPaths[index].key)' image is a glyph.")
///     } else {
///         print("No glyphs found!")
///     }
///     // Prints "The 'star' image is a glyph.")
///
/// Note that in this example, `imagePaths` is subscripted using a dictionary
/// index. Unlike the key-based subscript, the index-based subscript returns
/// the corresponding key-value pair as a non-optional tuple.
///
///     print(imagePaths[glyphIndex!])
///     // Prints "("star", "/glyphs/star.png")"
///
/// A dictionary's indices stay valid across additions to the dictionary as
/// long as the dictionary has enough capacity to store the added values
/// without allocating more buffer. When a dictionary outgrows its buffer,
/// existing indices may be invalidated without any notification.
///
/// When you know how many new values you're adding to a dictionary, use the
/// `init(minimumCapacity:)` initializer to allocate the correct amount of
/// buffer.
///
/// Bridging Between Dictionary and NSDictionary
/// ============================================
///
/// You can bridge between `Dictionary` and `NSDictionary` using the `as`
/// operator. For bridging to be possible, the `Key` and `Value` types of a
/// dictionary must be classes, `@objc` protocols, or types that bridge to
/// Foundation types.
///
/// Bridging from `Dictionary` to `NSDictionary` always takes O(1) time and
/// space. When the dictionary's `Key` and `Value` types are neither classes
/// nor `@objc` protocols, any required bridging of elements occurs at the
/// first access of each element. For this reason, the first operation that
/// uses the contents of the dictionary may take O(*n*).
///
/// Bridging from `NSDictionary` to `Dictionary` first calls the `copy(with:)`
/// method (`- copyWithZone:` in Objective-C) on the dictionary to get an
/// immutable copy and then performs additional Swift bookkeeping work that
/// takes O(1) time. For instances of `NSDictionary` that are already
/// immutable, `copy(with:)` usually returns the same dictionary in O(1) time;
/// otherwise, the copying performance is unspecified. The instances of
/// `NSDictionary` and `Dictionary` share buffer using the same copy-on-write
/// optimization that is used when two instances of `Dictionary` share
/// buffer.
///
/// - SeeAlso: `Hashable`
@_fixed_layout
public struct Dictionary<Key : Hashable, Value> :
  Collection, ExpressibleByDictionaryLiteral {

  internal typealias _Self = Dictionary<Key, Value>
  internal typealias _VariantBuffer = _VariantDictionaryBuffer<Key, Value>
  internal typealias _NativeBuffer = _NativeDictionaryBuffer<Key, Value>

  /// The element type of a dictionary: a tuple containing an individual
  /// key-value pair.
  public typealias Element = (key: Key, value: Value)

  @_versioned
  internal var _variantBuffer: _VariantBuffer

  /// Creates an empty dictionary.
  public init() {
    self = Dictionary<Key, Value>(_nativeBuffer: _NativeBuffer())
  }

  /// Creates a dictionary with at least the given number of elements worth of
  /// buffer.
  ///
  /// Use this initializer to avoid intermediate reallocations when you know
  /// how many key-value pairs you are adding to a dictionary. The actual
  /// capacity of the created dictionary is the smallest power of 2 that
  /// is greater than or equal to `minimumCapacity`.
  ///
  /// - Parameter minimumCapacity: The minimum number of key-value pairs to
  ///   allocate buffer for in the new dictionary.
  public init(minimumCapacity: Int) {
    _variantBuffer =
      .native(_NativeBuffer(minimumCapacity: minimumCapacity))
  }

  internal init(_nativeBuffer: _NativeDictionaryBuffer<Key, Value>) {
    _variantBuffer =
      .native(_nativeBuffer)
  }

#if _runtime(_ObjC)
  /// Private initializer used for bridging.
  ///
  /// Only use this initializer when both conditions are true:
  ///
  /// * it is statically known that the given `NSDictionary` is immutable;
  /// * `Key` and `Value` are bridged verbatim to Objective-C (i.e.,
  ///   are reference types).
  public init(_immutableCocoaDictionary: _NSDictionary) {
    _sanityCheck(
      _isBridgedVerbatimToObjectiveC(Key.self) &&
      _isBridgedVerbatimToObjectiveC(Value.self),
      "Dictionary can be backed by NSDictionary buffer only when both key and value are bridged verbatim to Objective-C")
    _variantBuffer = .cocoa(
      _CocoaDictionaryBuffer(cocoaDictionary: _immutableCocoaDictionary))
  }
#endif

  //
  // All APIs below should dispatch to `_variantBuffer`, without doing any
  // additional processing.
  //

  /// The position of the first element in a nonempty dictionary.
  ///
  /// If the collection is empty, `startIndex` is equal to `endIndex`.
  ///
  /// - Complexity: Amortized O(1) if the dictionary does not wrap a bridged
  ///   `NSDictionary`. If the dictionary wraps a bridged `NSDictionary`, the
  ///   performance is unspecified.
  public var startIndex: Index {
    return _variantBuffer.startIndex
  }

  /// The dictionary's "past the end" position---that is, the position one
  /// greater than the last valid subscript argument.
  ///
  /// If the collection is empty, `endIndex` is equal to `startIndex`.
  ///
  /// - Complexity: Amortized O(1) if the dictionary does not wrap a bridged
  ///   `NSDictionary`; otherwise, the performance is unspecified.
  public var endIndex: Index {
    return _variantBuffer.endIndex
  }

  public func index(after i: Index) -> Index {
    return _variantBuffer.index(after: i)
  }

  /// Returns the index for the given key.
  ///
  /// If the given key is found in the dictionary, this method returns an index
  /// into the dictionary that corresponds with the key-value pair.
  ///
  ///     let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
  ///     let index = countryCodes.index(forKey: "JP")
  ///
  ///     print("Country code for \(countryCodes[index!].value): '\(countryCodes[index!].key)'.")
  ///     // Prints "Country code for Japan: 'JP'."
  ///
  /// - Parameter key: The key to find in the dictionary.
  /// - Returns: The index for `key` and its associated value if `key` is in
  ///   the dictionary; otherwise, `nil`.
  @inline(__always)
  public func index(forKey key: Key) -> Index? {
    // Complexity: amortized O(1) for native buffer, O(*n*) when wrapping an
    // NSDictionary.
    return _variantBuffer.index(forKey: key)
  }

  /// Accesses the key-value pair at the specified position.
  ///
  /// This subscript takes an index into the dictionary, instead of a key, and
  /// returns the corresponding key-value pair as a tuple. When performing
  /// collection-based operations that return an index into a dictionary, use
  /// this subscript with the resulting value.
  ///
  /// For example, to find the key for a particular value in a dictionary, use
  /// the `index(where:)` method.
  ///
  ///     let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
  ///     if let index = countryCodes.index(where: { $0.value == "Japan" }) {
  ///         print(countryCodes[index])
  ///         print("Japan's country code is '\(countryCodes[index].key)'.")
  ///     } else {
  ///         print("Didn't find 'Japan' as a value in the dictionary.")
  ///     }
  ///     // Prints "("JP", "Japan")"
  ///     // Prints "Japan's country code is 'JP'."
  ///
  /// - Parameter position: The position of the key-value pair to access.
  ///   `position` must be a valid index of the dictionary and not equal to
  ///   `endIndex`.
  /// - Returns: A two-element tuple with the key and value corresponding to
  ///   `position`.
  public subscript(position: Index) -> Element {
    return _variantBuffer.assertingGet(position)
  }

  /// Accesses the value associated with the given key for reading and writing.
  ///
  /// This *key-based* subscript returns the value for the given key if the key
  /// is found in the dictionary, or `nil` if the key is not found.
  ///
  /// The following example creates a new dictionary and prints the value of a
  /// key found in the dictionary (`"Coral"`) and a key not found in the
  /// dictionary (`"Cerise"`).
  ///
  ///     var hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156]
  ///     print(hues["Coral"])
  ///     // Prints "Optional(16)"
  ///     print(hues["Cerise"])
  ///     // Prints "nil"
  ///
  /// When you assign a value for a key and that key already exists, the
  /// dictionary overwrites the existing value. If the dictionary doesn't
  /// contain the key, the key and value are added as a new key-value pair.
  ///
  /// Here, the value for the key `"Coral"` is updated from `16` to `18` and a
  /// new key-value pair is added for the key `"Cerise"`.
  ///
  ///     hues["Coral"] = 18
  ///     print(hues["Coral"])
  ///     // Prints "Optional(18)"
  ///
  ///     hues["Cerise"] = 330
  ///     print(hues["Cerise"])
  ///     // Prints "Optional(330)"
  ///
  /// If you assign `nil` as the value for the given key, the dictionary
  /// removes that key and its associated value.
  ///
  /// In the following example, the key-value pair for the key `"Aquamarine"`
  /// is removed from the dictionary by assigning `nil` to the key-based
  /// subscript.
  ///
  ///     hues["Aquamarine"] = nil
  ///     print(hues)
  ///     // Prints "["Coral": 18, "Heliotrope": 296, "Cerise": 330]"
  ///
  /// - Parameter key: The key to find in the dictionary.
  /// - Returns: The value associated with `key` if `key` is in the dictionary;
  ///   otherwise, `nil`.
  public subscript(key: Key) -> Value? {
    @inline(__always)
    get {
      return _variantBuffer.maybeGet(key)
    }
    set(newValue) {
      if let x = newValue {
        // FIXME(performance): this loads and discards the old value.
        _variantBuffer.updateValue(x, forKey: key)
      }
      else {
        // FIXME(performance): this loads and discards the old value.
        removeValue(forKey: key)
      }
    }
  }

  /// Updates the value stored in the dictionary for the given key, or adds a
  /// new key-value pair if the key does not exist.
  ///
  /// Use this method instead of key-based subscripting when you need to know
  /// whether the new value supplants the value of an existing key. If the
  /// value of an existing key is updated, `updateValue(_:forKey:)` returns
  /// the original value.
  ///
  ///     var hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156]
  ///
  ///     if let oldValue = hues.updateValue(18, forKey: "Coral") {
  ///         print("The old value of \(oldValue) was replaced with a new one.")
  ///     }
  ///     // Prints "The old value of 16 was replaced with a new one."
  ///
  /// If the given key is not present in the dictionary, this method adds the
  /// key-value pair and returns `nil`.
  ///
  ///     if let oldValue = hues.updateValue(330, forKey: "Cerise") {
  ///         print("The old value of \(oldValue) was replaced with a new one.")
  ///     } else {
  ///         print("No value was found in the dictionary for that key.")
  ///     }
  ///     // Prints "No value was found in the dictionary for that key."
  ///
  /// - Parameters:
  ///   - value: The new value to add to the dictionary.
  ///   - key: The key to associate with `value`. If `key` already exists in
  ///     the dictionary, `value` replaces the existing associated value. If
  ///     `key` isn't already a key of the dictionary, the `(key, value)` pair
  ///     is added.
  /// - Returns: The value that was replaced, or `nil` if a new key-value pair
  ///   was added.
  @discardableResult
  public mutating func updateValue(
    _ value: Value, forKey key: Key
  ) -> Value? {
    return _variantBuffer.updateValue(value, forKey: key)
  }

  /// Removes and returns the key-value pair at the specified index.
  ///
  /// Calling this method invalidates any existing indices for use with this
  /// dictionary.
  ///
  /// - Parameter index: The position of the key-value pair to remove. `index`
  ///   must be a valid index of the dictionary, and must not equal the
  ///   dictionary's end index.
  /// - Returns: The key-value pair that correspond to `index`.
  ///
  /// - Complexity: O(*n*), where *n* is the number of key-value pairs in the
  ///   dictionary.
  @discardableResult
  public mutating func remove(at index: Index) -> Element {
    return _variantBuffer.remove(at: index)
  }

  /// Removes the given key and its associated value from the dictionary.
  ///
  /// If the key is found in the dictionary, this method returns the key's
  /// associated value. On removal, this method invalidates all indices with
  /// respect to the dictionary.
  ///
  ///     var hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156]
  ///     if let value = hues.removeValue(forKey: "Coral") {
  ///         print("The value \(value) was removed.")
  ///     }
  ///     // Prints "The value 16 was removed."
  ///
  /// If the key isn't found in the dictionary, `removeValue(forKey:)` returns
  /// `nil`.
  ///
  ///     if let value = hues.removeValueForKey("Cerise") {
  ///         print("The value \(value) was removed.")
  ///     } else {
  ///         print("No value found for that key.")
  ///     }
  ///     // Prints "No value found for that key.""
  ///
  /// - Parameter key: The key to remove along with its associated value.
  /// - Returns: The value that was removed, or `nil` if the key was not
  ///   present in the dictionary.
  ///
  /// - Complexity: O(*n*), where *n* is the number of key-value pairs in the
  ///   dictionary.
  @discardableResult
  public mutating func removeValue(forKey key: Key) -> Value? {
    return _variantBuffer.removeValue(forKey: key)
  }

  /// Removes all key-value pairs from the dictionary.
  ///
  /// Calling this method invalidates all indices with respect to the
  /// dictionary.
  ///
  /// - Parameter keepCapacity: Whether the dictionary should keep its
  ///   underlying buffer. If you pass `true`, the operation preserves the
  ///   buffer capacity that the collection has, otherwise the underlying
  ///   buffer is released.  The default is `false`.
  ///
  /// - Complexity: O(*n*), where *n* is the number of key-value pairs in the
  ///   dictionary.
  public mutating func removeAll(keepingCapacity keepCapacity: Bool = false) {
    // The 'will not decrease' part in the documentation comment is worded very
    // carefully.  The capacity can increase if we replace Cocoa buffer with
    // native buffer.
    _variantBuffer.removeAll(keepingCapacity: keepCapacity)
  }

  /// The number of key-value pairs in the dictionary.
  ///
  /// - Complexity: O(1).
  public var count: Int {
    return _variantBuffer.count
  }

  //
  // `Sequence` conformance
  //

  /// Returns an iterator over the dictionary's key-value pairs.
  ///
  /// Iterating over a dictionary yields the key-value pairs as two-element
  /// tuples. You can decompose the tuple in a `for`-`in` loop, which calls
  /// `makeIterator()` behind the scenes, or when calling the iterator's
  /// `next()` method directly.
  ///
  ///     let hues = ["Heliotrope": 296, "Coral": 16, "Aquamarine": 156]
  ///     for (name, hueValue) in hues {
  ///         print("The hue of \(name) is \(hueValue).")
  ///     }
  ///     // Prints "The hue of Heliotrope is 296."
  ///     // Prints "The hue of Coral is 16."
  ///     // Prints "The hue of Aquamarine is 156."
  ///
  /// - Returns: An iterator over the dictionary with elements of type
  ///   `(key: Key, value: Value)`.
  @inline(__always)
  public func makeIterator() -> DictionaryIterator<Key, Value> {
    return _variantBuffer.makeIterator()
  }

  //
  // ExpressibleByDictionaryLiteral conformance
  //

  /// Creates a dictionary initialized with a dictionary literal.
  ///
  /// Do not call this initializer directly. It is called by the compiler to
  /// handle dictionary literals. To use a dictionary literal as the initial
  /// value of a dictionary, enclose a comma-separated list of key-value pairs
  /// in square brackets.
  ///
  /// For example, the code sample below creates a dictionary with string keys
  /// and values.
  ///
  ///     let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
  ///     print(countryCodes)
  ///     // Prints "["BR": "Brazil", "JP": "Japan", "GH": "Ghana"]"
  ///
  /// - Parameter elements: The key-value pairs that will make up the new
  ///   dictionary. Each key in `elements` must be unique.
  ///
  /// - SeeAlso: `ExpressibleByDictionaryLiteral`
  @effects(readonly)
  public init(dictionaryLiteral elements: (Key, Value)...) {
    self.init(_nativeBuffer: _NativeDictionaryBuffer.fromArray(elements))
  }

  //
  // APIs below this comment should be implemented strictly in terms of
  // *public* APIs above.  `_variantBuffer` should not be accessed directly.
  //
  // This separates concerns for testing.  Tests for the following APIs need
  // not to concern themselves with testing correctness of behavior of
  // underlying buffer (and different variants of it), only correctness of the
  // API itself.
  //

  /// A collection containing just the keys of the dictionary.
  ///
  /// When iterated over, keys appear in this collection in the same order as they
  /// occur in the dictionary's key-value pairs. Each key in the keys
  /// collection has a unique value.
  ///
  ///     let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
  ///     for k in countryCodes.keys {
  ///         print(k)
  ///     }
  ///     // Prints "BR"
  ///     // Prints "JP"
  ///     // Prints "GH"
  public var keys: LazyMapCollection<Dictionary, Key> {
    return self.lazy.map { $0.key }
  }

  /// A collection containing just the values of the dictionary.
  ///
  /// When iterated over, values appear in this collection in the same order as they
  /// occur in the dictionary's key-value pairs.
  ///
  ///     let countryCodes = ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
  ///     print(countryCodes)
  ///     // Prints "["BR": "Brazil", "JP": "Japan", "GH": "Ghana"]"
  ///     for v in countryCodes.values {
  ///         print(v)
  ///     }
  ///     // Prints "Brazil"
  ///     // Prints "Japan"
  ///     // Prints "Ghana"
  public var values: LazyMapCollection<Dictionary, Value> {
    return self.lazy.map { $0.value }
  }

  //
  // Collection conformance
  //

  /// A Boolean value that indicates whether the dictionary is empty.
  ///
  /// Dictionaries are empty when created with an initializer or an empty
  /// dictionary literal.
  ///
  ///     var frequencies: [String: Int] = [:]
  ///     print(frequencies.isEmpty)
  ///     // Prints "true"
  public var isEmpty: Bool {
    return count == 0
  }

}

extension Dictionary where Value : Equatable {
  public static func == (lhs: [Key : Value], rhs: [Key : Value]) -> Bool {
    switch (lhs._variantBuffer, rhs._variantBuffer) {
    case (.native(let lhsNative), .native(let rhsNative)):

      if lhsNative._storage === rhsNative._storage {
        return true
      }

      if lhsNative.count != rhsNative.count {
        return false
      }

      for (k, v) in lhs {
        let (pos, found) = rhsNative._find(k, startBucket: rhsNative._bucket(k))
        // FIXME: Can't write the simple code pending
        // <rdar://problem/15484639> Refcounting bug
        /*
        if !found || rhs[pos].value != lhsElement.value {
          return false
        }
        */
        if !found {
          return false
        }
        if rhsNative.value(at: pos.offset) != v {
          return false
        }
      }
      return true

    case (.cocoa(let lhsCocoa), .cocoa(let rhsCocoa)):
  #if _runtime(_ObjC)
      return _stdlib_NSObject_isEqual(
        lhsCocoa.cocoaDictionary, rhsCocoa.cocoaDictionary)
  #else
      _sanityCheckFailure("internal error: unexpected cocoa dictionary")
  #endif

    case (.native(let lhsNative), .cocoa(let rhsCocoa)):
  #if _runtime(_ObjC)

      if lhsNative.count != rhsCocoa.count {
        return false
      }

      let endIndex = lhsNative.endIndex
      var index = lhsNative.startIndex
      while index != endIndex {
        let (key, value) = lhsNative.assertingGet(index)
        let optRhsValue: AnyObject? =
          rhsCocoa.maybeGet(_bridgeAnythingToObjectiveC(key))

        guard let rhsValue = optRhsValue,
          value == _forceBridgeFromObjectiveC(rhsValue, Value.self)
        else {
          return false
        }

        lhsNative.formIndex(after: &index)
        continue
      }
      return true
  #else
      _sanityCheckFailure("internal error: unexpected cocoa dictionary")
  #endif

    case (.cocoa, .native):
  #if _runtime(_ObjC)
      return rhs == lhs
  #else
      _sanityCheckFailure("internal error: unexpected cocoa dictionary")
  #endif
    }
  }

  public static func != (lhs: [Key : Value], rhs: [Key : Value]) -> Bool {
    return !(lhs == rhs)
  }
}

extension Dictionary : CustomStringConvertible, CustomDebugStringConvertible {
  internal func _makeDescription() -> String {
    if count == 0 {
      return "[:]"
    }

    var result = "["
    var first = true
    for (k, v) in self {
      if first {
        first = false
      } else {
        result += ", "
      }
      debugPrint(k, terminator: "", to: &result)
      result += ": "
      debugPrint(v, terminator: "", to: &result)
    }
    result += "]"
    return result
  }

  /// A string that represents the contents of the dictionary.
  public var description: String {
    return _makeDescription()
  }

  /// A string that represents the contents of the dictionary, suitable for
  /// debugging.
  public var debugDescription: String {
    return _makeDescription()
  }
}

#if _runtime(_ObjC)
/// Equivalent to `NSDictionary.allKeys`, but does not leave objects on the
/// autorelease pool.
internal func _stdlib_NSDictionary_allKeys(_ nsd: _NSDictionary)
    -> _HeapBuffer<Int, AnyObject> {
  let count = nsd.count
  let storage = _HeapBuffer<Int, AnyObject>(
    _HeapBufferStorage<Int, AnyObject>.self, count, count)

  nsd.getObjects(nil, andKeys: storage.baseAddress)
  return storage
}
#endif

//===--- Compiler conversion/casting entry points for Dictionary<K, V> ----===//

/// Perform a non-bridged upcast that always succeeds.
///
/// - Precondition: `BaseKey` and `BaseValue` are base classes or base `@objc`
///   protocols (such as `AnyObject`) of `DerivedKey` and `DerivedValue`,
///   respectively.
public func _dictionaryUpCast<DerivedKey, DerivedValue, BaseKey, BaseValue>(
    _ source: Dictionary<DerivedKey, DerivedValue>
) -> Dictionary<BaseKey, BaseValue> {
  var result = Dictionary<BaseKey, BaseValue>(minimumCapacity: source.count)

  for (k, v) in source {
    result[k as! BaseKey] = (v as! BaseValue)
  }
  return result
}

#if _runtime(_ObjC)

/// Implements an unconditional upcast that involves bridging.
///
/// The cast can fail if bridging fails.
///
/// - Precondition: `SwiftKey` and `SwiftValue` are bridged to Objective-C,
///   and at least one of them requires non-trivial bridging.
@inline(never)
@_semantics("stdlib_binary_only")
public func _dictionaryBridgeToObjectiveC<
  SwiftKey, SwiftValue, ObjCKey, ObjCValue
>(
  _ source: Dictionary<SwiftKey, SwiftValue>
) -> Dictionary<ObjCKey, ObjCValue> {

  // Note: We force this function to stay in the swift dylib because
  // it is not performance sensitive and keeping it in the dylib saves
  // a new kilobytes for each specialization for all users of dictionary.

  _sanityCheck(
    !_isBridgedVerbatimToObjectiveC(SwiftKey.self) ||
    !_isBridgedVerbatimToObjectiveC(SwiftValue.self))
  _sanityCheck(
    _isClassOrObjCExistential(ObjCKey.self) ||
    _isClassOrObjCExistential(ObjCValue.self))

  var result = Dictionary<ObjCKey, ObjCValue>(minimumCapacity: source.count)
  let keyBridgesDirectly =
    _isBridgedVerbatimToObjectiveC(SwiftKey.self) ==
      _isBridgedVerbatimToObjectiveC(ObjCKey.self)
  let valueBridgesDirectly =
    _isBridgedVerbatimToObjectiveC(SwiftValue.self) ==
      _isBridgedVerbatimToObjectiveC(ObjCValue.self)
  for (key, value) in source {
    // Bridge the key
    var bridgedKey: ObjCKey
    if keyBridgesDirectly {
      bridgedKey = unsafeBitCast(key, to: ObjCKey.self)
    } else {
      let bridged: AnyObject = _bridgeAnythingToObjectiveC(key)
      bridgedKey = unsafeBitCast(bridged, to: ObjCKey.self)
    }

    // Bridge the value
    var bridgedValue: ObjCValue
    if valueBridgesDirectly {
      bridgedValue = unsafeBitCast(value, to: ObjCValue.self)
    } else {
      let bridged: AnyObject? = _bridgeAnythingToObjectiveC(value)
      bridgedValue = unsafeBitCast(bridged, to: ObjCValue.self)
    }

    result[bridgedKey] = bridgedValue
  }

  return result
}
#endif

@_silgen_name("_swift_dictionaryDownCastIndirect")
public func _dictionaryDownCastIndirect<SourceKey, SourceValue,
                                        TargetKey, TargetValue>(
  _ source: UnsafePointer<Dictionary<SourceKey, SourceValue>>,
  _ target: UnsafeMutablePointer<Dictionary<TargetKey, TargetValue>>) {
  target.initialize(to: _dictionaryDownCast(source.pointee))
}

/// Implements a forced downcast.  This operation should have O(1) complexity.
///
/// The cast can fail if bridging fails.  The actual checks and bridging can be
/// deferred.
///
/// - Precondition: `DerivedKey` is a subtype of `BaseKey`, `DerivedValue` is
///   a subtype of `BaseValue`, and all of these types are reference types.
public func _dictionaryDownCast<BaseKey, BaseValue, DerivedKey, DerivedValue>(
  _ source: Dictionary<BaseKey, BaseValue>
) -> Dictionary<DerivedKey, DerivedValue> {

#if _runtime(_ObjC)
  if _isClassOrObjCExistential(BaseKey.self)
  && _isClassOrObjCExistential(BaseValue.self)
  && _isClassOrObjCExistential(DerivedKey.self)
  && _isClassOrObjCExistential(DerivedValue.self) {

    switch source._variantBuffer {
    case .native(let buffer):
      // Note: it is safe to treat the buffer as immutable here because
      // Dictionary will not mutate buffer with reference count greater than 1.
      return Dictionary(_immutableCocoaDictionary: buffer.bridged())
    case .cocoa(let cocoaBuffer):
      return Dictionary(_immutableCocoaDictionary: cocoaBuffer.cocoaDictionary)
    }
  }
#endif
  return _dictionaryDownCastConditional(source)!
}

@_silgen_name("_swift_dictionaryDownCastConditionalIndirect")
public func _dictionaryDownCastConditionalIndirect<SourceKey, SourceValue,
                                                   TargetKey, TargetValue>(
  _ source: UnsafePointer<Dictionary<SourceKey, SourceValue>>,
  _ target: UnsafeMutablePointer<Dictionary<TargetKey, TargetValue>>
) -> Bool {
  if let result: Dictionary<TargetKey, TargetValue>
       = _dictionaryDownCastConditional(source.pointee) {
    target.initialize(to: result)
    return true
  }
  return false
}

/// Implements a conditional downcast.
///
/// If the cast fails, the function returns `nil`.  All checks should be
/// performed eagerly.
///
/// - Precondition: `DerivedKey` is a subtype of `BaseKey`, `DerivedValue` is
///   a subtype of `BaseValue`, and all of these types are reference types.
public func _dictionaryDownCastConditional<
  BaseKey, BaseValue, DerivedKey, DerivedValue
>(
  _ source: Dictionary<BaseKey, BaseValue>
) -> Dictionary<DerivedKey, DerivedValue>? {

  var result = Dictionary<DerivedKey, DerivedValue>()
  for (k, v) in source {
    guard let k1 = k as? DerivedKey, let v1 = v as? DerivedValue
    else { return nil }
    result[k1] = v1
  }
  return result
}

#if _runtime(_ObjC)
/// Implements an unconditional downcast that involves bridging.
///
/// - Precondition: At least one of `SwiftKey` or `SwiftValue` is a bridged value
///   type, and the corresponding `ObjCKey` or `ObjCValue` is a reference type.
public func _dictionaryBridgeFromObjectiveC<
  ObjCKey, ObjCValue, SwiftKey, SwiftValue
>(
  _ source: Dictionary<ObjCKey, ObjCValue>
) -> Dictionary<SwiftKey, SwiftValue> {
  let result: Dictionary<SwiftKey, SwiftValue>? =
    _dictionaryBridgeFromObjectiveCConditional(source)
  _precondition(result != nil, "dictionary cannot be bridged from Objective-C")
  return result!
}

/// Implements a conditional downcast that involves bridging.
///
/// If the cast fails, the function returns `nil`.  All checks should be
/// performed eagerly.
///
/// - Precondition: At least one of `SwiftKey` or `SwiftValue` is a bridged value
///   type, and the corresponding `ObjCKey` or `ObjCValue` is a reference type.
public func _dictionaryBridgeFromObjectiveCConditional<
  ObjCKey, ObjCValue, SwiftKey, SwiftValue
>(
  _ source: Dictionary<ObjCKey, ObjCValue>
) -> Dictionary<SwiftKey, SwiftValue>? {
  _sanityCheck(
    _isClassOrObjCExistential(ObjCKey.self) ||
    _isClassOrObjCExistential(ObjCValue.self))
  _sanityCheck(
    !_isBridgedVerbatimToObjectiveC(SwiftKey.self) ||
    !_isBridgedVerbatimToObjectiveC(SwiftValue.self))

  let keyBridgesDirectly =
    _isBridgedVerbatimToObjectiveC(SwiftKey.self) ==
      _isBridgedVerbatimToObjectiveC(ObjCKey.self)
  let valueBridgesDirectly =
    _isBridgedVerbatimToObjectiveC(SwiftValue.self) ==
      _isBridgedVerbatimToObjectiveC(ObjCValue.self)

  var result = Dictionary<SwiftKey, SwiftValue>(minimumCapacity: source.count)
  for (key, value) in source {
    // Downcast the key.
    var resultKey: SwiftKey
    if keyBridgesDirectly {
      if let bridgedKey = key as? SwiftKey {
        resultKey = bridgedKey
      } else {
        return nil
      }
    } else {
      if let bridgedKey = _conditionallyBridgeFromObjectiveC(
        _reinterpretCastToAnyObject(key), SwiftKey.self) {
          resultKey = bridgedKey
      } else {
        return nil
      }
    }

    // Downcast the value.
    var resultValue: SwiftValue
    if valueBridgesDirectly {
      if let bridgedValue = value as? SwiftValue {
        resultValue = bridgedValue
      } else {
        return nil
      }
    } else {
      if let bridgedValue = _conditionallyBridgeFromObjectiveC(
        _reinterpretCastToAnyObject(value), SwiftValue.self) {
          resultValue = bridgedValue
      } else {
        return nil
      }
    }

    result[resultKey] = resultValue
  }
  return result
}
#endif
//===--- APIs templated for Dictionary and Set ----------------------------===//

%{
# Tuple items:
# Self: Class name
#
# a_self: Type name when using a generic noun
#
# TypeParametersDecl: Generic parameters appearing in top-level declarations
#
# TypeParameters: Generic parameters appearing in typealiases, etc.
#
# AnyTypeParameters: Generic parameters where all variables are AnyObject
#
# Sequence: The type of things appearing in the collection as a sequence
#                 e.g. dictionaries are a sequence of (Key, Value) pairs.
# AnySequenceType: The same as Sequence but everything is an AnyObject.
collections = [
  ('Set',
   'set',
   'Element : Hashable',
   'Element',
   'AnyObject',
   'Element',
   'AnyObject'),

  ('Dictionary',
   'dictionary',
   'Key : Hashable, Value',
   'Key, Value',
   'AnyObject, AnyObject',
   '(key: Key, value: Value)',
   '(AnyObject, AnyObject)'),
]
}%

% for (Self, a_self, TypeParametersDecl, TypeParameters, AnyTypeParameters, Sequence, AnySequenceType) in collections:

/// An instance of this class has all `${Self}` data tail-allocated.
/// Enough bytes are allocated to hold the bitmap for marking valid entries,
/// keys, and values. The data layout starts with the bitmap, followed by the
/// keys, followed by the values.
//
// See the docs at the top of the file for more details on this type
//
// NOTE: The precise layout of this type is relied on in the runtime
// to provide a statically allocated empty singleton. 
// See stdlib/public/stubs/GlobalObjects.cpp for details.
@objc_non_lazy_realization
internal class _RawNative${Self}Storage:
  _SwiftNativeNS${Self}, _NS${Self}Core
{
  internal typealias RawStorage = _RawNative${Self}Storage
  
  internal final var capacity: Int
  internal final var count: Int

  internal final var initializedEntries: _UnsafeBitMap
  internal final var keys: UnsafeMutableRawPointer
% if Self == 'Dictionary':
  internal final var values: UnsafeMutableRawPointer
% end

  // This API is unsafe and needs a `_fixLifetime` in the caller.
  internal final
  var _initializedHashtableEntriesBitMapBuffer: UnsafeMutablePointer<UInt> {
    return UnsafeMutablePointer(Builtin.projectTailElems(self, UInt.self))
  }

  /// The empty singleton that is used for every single Dictionary that is
  /// created without any elements. The contents of the storage should never
  /// be mutated.
  internal static var empty: RawStorage {
    return Builtin.bridgeFromRawPointer(
      Builtin.addressof(&_swiftEmpty${Self}Storage))
  }

  // This type is made with allocWithTailElems, so no init is ever called.
  // But we still need to have an init to satisfy the compiler.
  internal init(_doNotCallMe: ()) {
    _sanityCheckFailure("Only create this by using the `empty` singleton")
  }

#if _runtime(_ObjC)
  //
  // NS${Self} implementation, assuming Self is the empty singleton
  //

  /// Get the NSEnumerator implementation for self.
  /// _HashableTypedNative${Self}Storage overloads this to give 
  /// _NativeSelfNSEnumerator proper type parameters.
  func enumerator() -> _NSEnumerator {
    return _Native${Self}NSEnumerator<${AnyTypeParameters}>(
        _Native${Self}Buffer(_storage: self))
  }

  @objc(copyWithZone:)
  func copy(with zone: _SwiftNSZone?) -> AnyObject {
    return self
  }

  @objc(countByEnumeratingWithState:objects:count:)
  func countByEnumerating(
    with state: UnsafeMutablePointer<_SwiftNSFastEnumerationState>,
    objects: UnsafeMutablePointer<AnyObject>?, count: Int
  ) -> Int {
    // Even though we never do anything in here, we need to update the
    // state so that callers know we actually ran.
    
    var theState = state.pointee
    if theState.state == 0 {
      theState.state = 1 // Arbitrary non-zero value.
      theState.itemsPtr = AutoreleasingUnsafeMutablePointer(objects)
      theState.mutationsPtr = _fastEnumerationStorageMutationsPtr
    }
    state.pointee = theState
    
    return 0
  }

%if Self == 'Set':

  @objc
  internal required init(objects: UnsafePointer<AnyObject?>, count: Int) {
    _sanityCheckFailure("don't call this designated initializer")
  }

  @objc
  internal func member(_ object: AnyObject) -> AnyObject? {
    return nil
  }

  @objc
  internal func objectEnumerator() -> _NSEnumerator {
    return enumerator()
  }
  
%elif Self == 'Dictionary':

  @objc
  internal required init(
    objects: UnsafePointer<AnyObject?>,
    forKeys: UnsafeRawPointer,
    count: Int
  ) {
    _sanityCheckFailure("don't call this designated initializer")
  }

  @objc(objectForKey:)
  func objectFor(_ aKey: AnyObject) -> AnyObject? {
    return nil
  }

  func keyEnumerator() -> _NSEnumerator {
    return enumerator()
  }

  func getObjects(_ objects: UnsafeMutablePointer<AnyObject>?,
    andKeys keys: UnsafeMutablePointer<AnyObject>?) {
    // Do nothing, we're empty
  }

%end
#endif
}

// See the docs at the top of this file for a description of this type
@_versioned
internal class _TypedNative${Self}Storage<${TypeParameters}> :
  _RawNative${Self}Storage {

%if Self == 'Set': # Set needs these to keep signatures simple.
  internal typealias Key = ${TypeParameters}
  internal typealias Value = ${TypeParameters}
%end

  deinit {
    let keys = self.keys.assumingMemoryBound(to: Key.self)
%if Self == 'Dictionary':
    let values = self.values.assumingMemoryBound(to: Value.self)
%end

    if !_isPOD(Key.self) {
      for i in 0 ..< capacity {
        if initializedEntries[i] {
          (keys+i).deinitialize()
        }
      }
    }

%if Self == 'Dictionary':
    if !_isPOD(Value.self) {
      for i in 0 ..< capacity {
        if initializedEntries[i] {
          (values+i).deinitialize()
        }
      }
    }
%end
    _fixLifetime(self)
  }

  // This type is made with allocWithTailElems, so no init is ever called.
  // But we still need to have an init to satisfy the compiler.
  override internal init(_doNotCallMe: ()) {
    _sanityCheckFailure("Only create this by calling Buffer's inits")
  }

#if _runtime(_ObjC)
%if Self == 'Set':
  @objc
  internal required init(objects: UnsafePointer<AnyObject?>, count: Int) {
    _sanityCheckFailure("don't call this designated initializer")
  }
%elif Self == 'Dictionary':
  @objc
  internal required init(
    objects: UnsafePointer<AnyObject?>,
    forKeys: UnsafeRawPointer,
    count: Int
  ) {
    _sanityCheckFailure("don't call this designated initializer")
  }
%end
#endif
}


// See the docs at the top of this file for a description of this type
@_versioned
final internal class _HashableTypedNative${Self}Storage<${TypeParametersDecl}> :
  _TypedNative${Self}Storage<${TypeParameters}> {

  internal typealias FullContainer = ${Self}<${TypeParameters}>
  internal typealias Buffer = _Native${Self}Buffer<${TypeParameters}>

  // This type is made with allocWithTailElems, so no init is ever called.
  // But we still need to have an init to satisfy the compiler.
  override internal init(_doNotCallMe: ()) {
    _sanityCheckFailure("Only create this by calling Buffer's inits'")
  }

  
#if _runtime(_ObjC)
  // NS${Self} bridging:

  // All actual functionality comes from buffer/full, which are
  // just wrappers around a RawNative${Self}Storage.
  
  var buffer: Buffer {
    return Buffer(_storage: self)
  }

  var full: FullContainer {
    return FullContainer(_nativeBuffer: buffer)
  }

  override func enumerator() -> _NSEnumerator {
    return _Native${Self}NSEnumerator<${TypeParameters}>(
        Buffer(_storage: self))
  }

  @objc(countByEnumeratingWithState:objects:count:)
  override func countByEnumerating(
    with state: UnsafeMutablePointer<_SwiftNSFastEnumerationState>,
    objects: UnsafeMutablePointer<AnyObject>?, count: Int
  ) -> Int {
    var theState = state.pointee
    if theState.state == 0 {
      theState.state = 1 // Arbitrary non-zero value.
      theState.itemsPtr = AutoreleasingUnsafeMutablePointer(objects)
      theState.mutationsPtr = _fastEnumerationStorageMutationsPtr
      theState.extra.0 = CUnsignedLong(full.startIndex._nativeIndex.offset)
    }

    // Test 'objects' rather than 'count' because (a) this is very rare anyway,
    // and (b) the optimizer should then be able to optimize away the
    // unwrapping check below.
    if _slowPath(objects == nil) {
      return 0
    }

    let unmanagedObjects = _UnmanagedAnyObjectArray(objects!)
    var currIndex = _Native${Self}Index<${TypeParameters}>(
        offset: Int(theState.extra.0))
    let endIndex = buffer.endIndex
    var stored = 0
    for i in 0..<count {
      if (currIndex == endIndex) {
        break
      }

      unmanagedObjects[i] = buffer.bridgedKey(at: currIndex)
      
      stored += 1
      buffer.formIndex(after: &currIndex)
    }
    theState.extra.0 = CUnsignedLong(currIndex.offset)
    state.pointee = theState
    return stored
  }

  internal func getObjectFor(_ aKey: AnyObject) -> AnyObject? {
    guard let nativeKey = _conditionallyBridgeFromObjectiveC(aKey, Key.self)
    else { return nil }

    let (i, found) = buffer._find(nativeKey, 
        startBucket: buffer._bucket(nativeKey))

    if found {
      return buffer.bridgedValue(at: i)
    }
    return nil
  }

%if Self == 'Set':

  @objc
  internal required init(objects: UnsafePointer<AnyObject?>, count: Int) {
    _sanityCheckFailure("don't call this designated initializer")
  }

  @objc
  override internal func member(_ object: AnyObject) -> AnyObject? {
    return getObjectFor(object)
  }

%elif Self == 'Dictionary':
  
  @objc
  internal required init(
    objects: UnsafePointer<AnyObject?>,
    forKeys: UnsafeRawPointer,
    count: Int
  ) {
    _sanityCheckFailure("don't call this designated initializer")
  }

  @objc(objectForKey:)
  override func objectFor(_ aKey: AnyObject) -> AnyObject? {
    return getObjectFor(aKey)
  }

  // We also override the following methods for efficiency.
  @objc
  override func getObjects(_ objects: UnsafeMutablePointer<AnyObject>?,
    andKeys keys: UnsafeMutablePointer<AnyObject>?) {
    // The user is expected to provide a storage of the correct size
    if let unmanagedKeys = _UnmanagedAnyObjectArray(keys) {
      if let unmanagedObjects = _UnmanagedAnyObjectArray(objects) {
        // keys nonnull, objects nonnull
        for (offset: i, element: (key: key, value: val)) in full.enumerated() {
          unmanagedObjects[i] = _bridgeAnythingToObjectiveC(val)
          unmanagedKeys[i] = _bridgeAnythingToObjectiveC(key)
        }
      } else {
        // keys nonnull, objects null
        for (offset: i, element: (key: key, value: _)) in full.enumerated() {
          unmanagedKeys[i] = _bridgeAnythingToObjectiveC(key)
        }
      }
    } else {
      if let unmanagedObjects = _UnmanagedAnyObjectArray(objects) {
        // keys null, objects nonnull
        for (offset: i, element: (key: _, value: val)) in full.enumerated() {
          unmanagedObjects[i] = _bridgeAnythingToObjectiveC(val)
        }
      } else {
        // do nothing, both are null
      }
    }
  }
%end
#endif
}


/// A wrapper around _RawNative${Self}Storage that provides most of the 
/// implementation of ${Self}.
///
/// This type and most of its functionality doesn't require Hashable at all.
/// The reason for this is to support storing AnyObject for bridging
/// with _SwiftDeferredNS${Self}. What functionality actually relies on
/// Hashable can be found in an extension.
@_versioned
@_fixed_layout
internal struct _Native${Self}Buffer<${TypeParameters}> {

  internal typealias RawStorage = _RawNative${Self}Storage
  internal typealias TypedStorage = _TypedNative${Self}Storage<${TypeParameters}>
  internal typealias Buffer = _Native${Self}Buffer<${TypeParameters}>
  internal typealias Index = _Native${Self}Index<${TypeParameters}>

%if Self == 'Set': # Set needs these to keep signatures simple.
  internal typealias Key = ${TypeParameters}
  internal typealias Value = ${TypeParameters}
  internal typealias SequenceElementWithoutLabels = Element
%else:
  internal typealias SequenceElementWithoutLabels = (Key, Value)
%end

  /// See this comments on _RawNative${Self}Storage and its subclasses to
  /// understand why we store an untyped storage here.
  internal var _storage: RawStorage

  /// Creates a Buffer with a storage that is typed, but doesn't understand
  /// Hashing. Mostly for bridging; prefer `init(capacity:)`.
  internal init(capacity: Int, unhashable: ()) {
    let numWordsForBitmap = _UnsafeBitMap.sizeInWords(forSizeInBits: capacity)
%if Self == 'Dictionary':
    let storage = Builtin.allocWithTailElems_3(TypedStorage.self,
        numWordsForBitmap._builtinWordValue, UInt.self,
        capacity._builtinWordValue, Key.self,
        capacity._builtinWordValue, Value.self)
%else:
    let storage = Builtin.allocWithTailElems_2(TypedStorage.self,
        numWordsForBitmap._builtinWordValue, UInt.self,
        capacity._builtinWordValue, Key.self)
%end
    self.init(capacity: capacity, storage: storage)
  }

  /// Given a capacity and uninitialized RawStorage, completes the 
  /// initialization and returns a Buffer.  
  internal init(capacity: Int, storage: RawStorage) {
    storage.capacity = capacity
    storage.count = 0
    
    self.init(_storage: storage)

    let initializedEntries = _UnsafeBitMap(
        storage: _initializedHashtableEntriesBitMapBuffer,
        bitCount: capacity)
    initializedEntries.initializeToZero()

    // Compute all the array offsets now, so we don't have to later
    let bitmapAddr = Builtin.projectTailElems(_storage, UInt.self)
    let numWordsForBitmap = _UnsafeBitMap.sizeInWords(forSizeInBits: capacity)
    let keysAddr = Builtin.getTailAddr_Word(bitmapAddr,
           numWordsForBitmap._builtinWordValue, UInt.self, Key.self)

    // Initialize header
    _storage.initializedEntries = initializedEntries
    _storage.keys = UnsafeMutableRawPointer(keysAddr)
%if Self == 'Dictionary':
    let valuesAddr = Builtin.getTailAddr_Word(keysAddr,
        capacity._builtinWordValue, Key.self, Value.self)
    _storage.values = UnsafeMutableRawPointer(valuesAddr)
%end
  }

  // Forwarding the individual fields of the storage in various forms

  @_versioned
  internal var capacity: Int {
    return _assumeNonNegative(_storage.capacity)
  }

  @_versioned
  internal var count: Int {
    set {
      _storage.count = newValue
    }
    get {
      return _assumeNonNegative(_storage.count)
    }
  }

  internal
  var _initializedHashtableEntriesBitMapBuffer: UnsafeMutablePointer<UInt> {
    return _storage._initializedHashtableEntriesBitMapBuffer
  }

  // This API is unsafe and needs a `_fixLifetime` in the caller.
  @_versioned
  internal var keys: UnsafeMutablePointer<Key> {
    return _storage.keys.assumingMemoryBound(to: Key.self)
  }

%if Self == 'Dictionary':
  // This API is unsafe and needs a `_fixLifetime` in the caller.
  @_versioned
  internal var values: UnsafeMutablePointer<Value> {
    return _storage.values.assumingMemoryBound(to: Value.self)
  }
%end

  /// Constructs a buffer adopting the given storage.
  init(_storage: RawStorage) {
    self._storage = _storage
  }

  /// Constructs an instance from the empty singleton.
  init() {
    self._storage = RawStorage.empty
  }



  // Most of the implementation of the _HashBuffer protocol,
  // but only the parts that don't actually rely on hashing.

  @_versioned
  @inline(__always)
  internal func key(at i: Int) -> Key {
    _sanityCheck(i >= 0 && i < capacity)
    _sanityCheck(isInitializedEntry(at: i))
    defer { _fixLifetime(self) }

    let res = (keys + i).pointee
    return res
  }

#if _runtime(_ObjC)
  /// Returns the key at the given Index, bridged.
  ///
  /// Intended for use with verbatim bridgeable keys.
  internal func bridgedKey(at index: Index) -> AnyObject {
    let k = key(at: index.offset)
    return _bridgeAnythingToObjectiveC(k)
  }

  /// Returns the value at the given Index, bridged.
  ///
  /// Intended for use with verbatim bridgeable keys.
  internal func bridgedValue(at index: Index) -> AnyObject {
    let v = value(at: index.offset)
    return _bridgeAnythingToObjectiveC(v)
  }
#endif

  @_versioned
  internal func isInitializedEntry(at i: Int) -> Bool {
    _sanityCheck(i >= 0 && i < capacity)
    defer { _fixLifetime(self) }

    return _storage.initializedEntries[i]
  }

  @_transparent
  internal func destroyEntry(at i: Int) {
    _sanityCheck(isInitializedEntry(at: i))
    defer { _fixLifetime(self) }

    (keys + i).deinitialize()
%if Self == 'Dictionary':
    (values + i).deinitialize()
%end
    _storage.initializedEntries[i] = false
  }

%if Self == 'Set':
  @_transparent
  internal func initializeKey(_ k: Key, at i: Int) {
    _sanityCheck(!isInitializedEntry(at: i))
    defer { _fixLifetime(self) }

    (keys + i).initialize(to: k)
    _storage.initializedEntries[i] = true
  }

  @_transparent
  internal func moveInitializeEntry(from: Buffer, at: Int, toEntryAt: Int) {
    _sanityCheck(!isInitializedEntry(at: toEntryAt))

    defer { _fixLifetime(self) }

    (keys + toEntryAt).initialize(to: (from.keys + at).move())
    from._storage.initializedEntries[at] = false
    _storage.initializedEntries[toEntryAt] = true
  }

  /// Alias for key(at:) in Sets for better code reuse
  @_versioned
  @_transparent
  internal func value(at i: Int) -> Value {
    return key(at: i)
  }

  internal func setKey(_ key: Key, at i: Int) {
    _sanityCheck(i >= 0 && i < capacity)
    _sanityCheck(isInitializedEntry(at: i))
    defer { _fixLifetime(self) }

    (keys + i).pointee = key
  }

%elif Self == 'Dictionary':
  @_transparent
  internal func initializeKey(_ k: Key, value v: Value, at i: Int) {
    _sanityCheck(!isInitializedEntry(at: i))
    defer { _fixLifetime(self) }

    (keys + i).initialize(to: k)
    (values + i).initialize(to: v)
    _storage.initializedEntries[i] = true
  }

  @_transparent
  internal func moveInitializeEntry(from: Buffer, at: Int, toEntryAt: Int) {
    _sanityCheck(!isInitializedEntry(at: toEntryAt))
    defer { _fixLifetime(self) }

    (keys + toEntryAt).initialize(to: (from.keys + at).move())
    (values + toEntryAt).initialize(to: (from.values + at).move())
    from._storage.initializedEntries[at] = false
    _storage.initializedEntries[toEntryAt] = true
  }

  @_versioned
  @_transparent
  internal func value(at i: Int) -> Value {
    _sanityCheck(isInitializedEntry(at: i))
    defer { _fixLifetime(self) }

    return (values + i).pointee
  }

  @_transparent
  internal func setKey(_ key: Key, value: Value, at i: Int) {
    _sanityCheck(isInitializedEntry(at: i))
    defer { _fixLifetime(self) }

    (keys + i).pointee = key
    (values + i).pointee = value
  }

%end

  @_versioned
  internal var startIndex: Index {
    // We start at "index after -1" instead of "0" because we need to find the
    // first occupied slot.
    return index(after: Index(offset: -1))
  }

  @_versioned
  internal var endIndex: Index {
    return Index(offset: capacity)
  }

  @_versioned
  internal func index(after i: Index) -> Index {
    _precondition(i != endIndex)
    var idx = i.offset + 1
    while idx < capacity && !isInitializedEntry(at: idx) {
      idx += 1
    }

    return Index(offset: idx)
  }

  @_versioned
  internal func formIndex(after i: inout Index) {
    i = index(after: i)
  }

  
  internal func assertingGet(_ i: Index) -> SequenceElement {
    _precondition(i.offset >= 0 && i.offset < capacity)
    _precondition(
      isInitializedEntry(at: i.offset),
      "attempting to access ${Self} elements using an invalid Index")
    let key = self.key(at: i.offset)
%if Self == 'Set':
    return key
%elif Self == 'Dictionary':
    return (key, self.value(at: i.offset))
%end

  }
}

extension _Native${Self}Buffer 
  where ${'Key' if Self == 'Dictionary' else 'Element'} : Hashable
{
  internal typealias HashTypedStorage = 
    _HashableTypedNative${Self}Storage<${TypeParameters}>
  internal typealias SequenceElement = ${Sequence}

  @inline(__always)
  internal init(minimumCapacity: Int) {
    // Make sure there's a representable power of 2 >= minimumCapacity
    _sanityCheck(minimumCapacity <= (Int.max >> 1) + 1)
    var capacity = 2
    while capacity < minimumCapacity {
      capacity <<= 1
    }
    self.init(capacity: capacity)
  }

  /// Create a buffer instance with room for at least 'capacity'
  /// entries and all entries marked invalid.
  internal init(capacity: Int) {
    let numWordsForBitmap = _UnsafeBitMap.sizeInWords(forSizeInBits: capacity)
%if Self == 'Dictionary':
    let storage = Builtin.allocWithTailElems_3(HashTypedStorage.self,
        numWordsForBitmap._builtinWordValue, UInt.self,
        capacity._builtinWordValue, Key.self,
        capacity._builtinWordValue, Value.self)
%else:
    let storage = Builtin.allocWithTailElems_2(HashTypedStorage.self,
        numWordsForBitmap._builtinWordValue, UInt.self,
        capacity._builtinWordValue, Key.self)
%end
    self.init(capacity: capacity, storage: storage)
  }

#if _runtime(_ObjC)
  func bridged() -> _NS${Self} {
    // We can zero-cost bridge if our keys are verbatim
    // or if we're the empty singleton.

    // Temporary var for SOME type safety before a cast.
    let nsSet: _NS${Self}Core

    if (_isBridgedVerbatimToObjectiveC(Key.self) &&
        _isBridgedVerbatimToObjectiveC(Value.self)) ||
        self._storage === RawStorage.empty {
      nsSet = self._storage
    } else {
      nsSet = _SwiftDeferredNS${Self}(nativeBuffer: self)
    }

    // Cast from "minimal NS${Self}" to "NS${Self}"
    // Note that if you actually ask Swift for this cast, it will fail.
    // Never trust a shadow protocol!
    return unsafeBitCast(nsSet, to: _NS${Self}.self)
  }
#endif

  /// A textual representation of `self`.
  var description: String {
    var result = ""
#if INTERNAL_CHECKS_ENABLED
    for i in 0..<capacity {
      if isInitializedEntry(at: i) {
        let key = self.key(at: i)
        result += "bucket \(i), ideal bucket = \(_bucket(key)), key = \(key)\n"
      } else {
        result += "bucket \(i), empty\n"
      }
    }
#endif
    return result
  }

  internal var _bucketMask: Int {
    // The capacity is not negative, therefore subtracting 1 will not overflow.
    return capacity &- 1
  }

  @_versioned
  @inline(__always) // For performance reasons.
  internal func _bucket(_ k: Key) -> Int {
    return _squeezeHashValue(k.hashValue, capacity)
  }

  @_versioned
  internal func _index(after bucket: Int) -> Int {
    // Bucket is within 0 and capacity. Therefore adding 1 does not overflow.
    return (bucket &+ 1) & _bucketMask
  }

  internal func _prev(_ bucket: Int) -> Int {
    // Bucket is not negative. Therefore subtracting 1 does not overflow.
    return (bucket &- 1) & _bucketMask
  }

  /// Search for a given key starting from the specified bucket.
  ///
  /// If the key is not present, returns the position where it could be
  /// inserted.
  @_versioned
  @inline(__always)
  internal func _find(_ key: Key, startBucket: Int)
    -> (pos: Index, found: Bool) {

    var bucket = startBucket

    // The invariant guarantees there's always a hole, so we just loop
    // until we find one
    while true {
      let isHole = !isInitializedEntry(at: bucket)
      if isHole {
        return (Index(offset: bucket), false)
      }
      if self.key(at: bucket) == key {
        return (Index(offset: bucket), true)
      }
      bucket = _index(after: bucket)
    }
  }

  @_transparent
  internal static func minimumCapacity(
    minimumCount: Int,
    maxLoadFactorInverse: Double
  ) -> Int {
    // `minimumCount + 1` below ensures that we don't fill in the last hole
    return max(Int(Double(minimumCount) * maxLoadFactorInverse),
               minimumCount + 1)
  }

  /// Buffer should be uniquely referenced.
  /// The `key` should not be present in the ${Self}.
  /// This function does *not* update `count`.

%if Self == 'Set':

  internal func unsafeAddNew(key newKey: Element) {
    let (i, found) = _find(newKey, startBucket: _bucket(newKey))
    _sanityCheck(
      !found, "unsafeAddNew was called, but the key is already present")
    initializeKey(newKey, at: i.offset)
  }

%elif Self == 'Dictionary':

  internal func unsafeAddNew(key newKey: Key, value: Value) {
    let (i, found) = _find(newKey, startBucket: _bucket(newKey))
    _sanityCheck(
      !found, "unsafeAddNew was called, but the key is already present")
    initializeKey(newKey, value: value, at: i.offset)
  }

%end

  //
  // _HashBuffer conformance
  //

  @_versioned
  @inline(__always)
  internal func index(forKey key: Key) -> Index? {
    if count == 0 {
      // Fast path that avoids computing the hash of the key.
      return nil
    }
    let (i, found) = _find(key, startBucket: _bucket(key))
    return found ? i : nil
  }


  internal func assertingGet(_ key: Key) -> Value {
    let (i, found) = _find(key, startBucket: _bucket(key))
    _precondition(found, "key not found")
%if Self == 'Set':
    return self.key(at: i.offset)
%elif Self == 'Dictionary':
    return self.value(at: i.offset)
%end
  }

  @_versioned
  @inline(__always)
  internal func maybeGet(_ key: Key) -> Value? {
    if count == 0 {
      // Fast path that avoids computing the hash of the key.
      return nil
    }

    let (i, found) = _find(key, startBucket: _bucket(key))
    if found {
%if Self == 'Set':
      return self.key(at: i.offset)
%elif Self == 'Dictionary':
      return self.value(at: i.offset)
%end
    }
    return nil
  }

  @discardableResult
  internal func updateValue(_ value: Value, forKey key: Key) -> Value? {
    _sanityCheckFailure(
      "don't call mutating methods on _Native${Self}Buffer")
  }

  @discardableResult
  internal func insert(
    _ value: Value, forKey key: Key
  ) -> (inserted: Bool, memberAfterInsert: Value) {
    _sanityCheckFailure(
      "don't call mutating methods on _Native${Self}Buffer")
  }

  @discardableResult
  internal func remove(at index: Index) -> SequenceElement {
    _sanityCheckFailure(
      "don't call mutating methods on _Native${Self}Buffer")
  }

  @discardableResult
  internal func removeValue(forKey key: Key) -> Value? {
    _sanityCheckFailure(
      "don't call mutating methods on _Native${Self}Buffer")
  }

  internal func removeAll(keepingCapacity keepCapacity: Bool) {
    _sanityCheckFailure(
      "don't call mutating methods on _Native${Self}Buffer")
  }

  @_versioned
  internal static func fromArray(_ elements: [SequenceElementWithoutLabels])
    -> Buffer 
  {
    if elements.isEmpty {
      return Buffer()
    }

    let requiredCapacity =
      Buffer.minimumCapacity(
        minimumCount: elements.count,
        maxLoadFactorInverse: _hashContainerDefaultMaxLoadFactorInverse)
    var nativeBuffer = Buffer(minimumCapacity: requiredCapacity)

%if Self == 'Set':

    var count = 0
    for key in elements {
      let (i, found) =
        nativeBuffer._find(key, startBucket: nativeBuffer._bucket(key))
      if found {
        continue
      }
      nativeBuffer.initializeKey(key, at: i.offset)
      count += 1
    }
    nativeBuffer.count = count

%elif Self == 'Dictionary':

    for (key, value) in elements {
      let (i, found) =
        nativeBuffer._find(key, startBucket: nativeBuffer._bucket(key))
      _precondition(!found, "${Self} literal contains duplicate keys")
      nativeBuffer.initializeKey(key, value: value, at: i.offset)
    }
    nativeBuffer.count = elements.count

%end

    return nativeBuffer
  }
}

#if _runtime(_ObjC)
/// An NSEnumerator that works with any Native${Self}Buffer of
/// verbatim bridgeable elements. Used by the various NS${Self} impls.
final internal class _Native${Self}NSEnumerator<${TypeParameters}>
  : _SwiftNativeNSEnumerator, _NSEnumerator {

  internal typealias Buffer = _Native${Self}Buffer<${TypeParameters}>
  internal typealias Index = _Native${Self}Index<${TypeParameters}>

  internal override required init() {
    _sanityCheckFailure("don't call this designated initializer")
  }

  internal init(_ buffer: Buffer) {
    self.buffer = buffer
    nextIndex = buffer.startIndex
    endIndex = buffer.endIndex
  }

  internal var buffer: Buffer
  internal var nextIndex: Index
  internal var endIndex: Index

  //
  // NSEnumerator implementation.
  //
  // Do not call any of these methods from the standard library!
  //

  @objc
  internal func nextObject() -> AnyObject? {
    if nextIndex == endIndex {
      return nil
    }
    let key = buffer.bridgedKey(at: nextIndex)
    buffer.formIndex(after: &nextIndex)
    return key
  }

  @objc(countByEnumeratingWithState:objects:count:)
  internal func countByEnumerating(
    with state: UnsafeMutablePointer<_SwiftNSFastEnumerationState>,
    objects: UnsafeMutablePointer<AnyObject>,
    count: Int
  ) -> Int {
    var theState = state.pointee
    if theState.state == 0 {
      theState.state = 1 // Arbitrary non-zero value.
      theState.itemsPtr = AutoreleasingUnsafeMutablePointer(objects)
      theState.mutationsPtr = _fastEnumerationStorageMutationsPtr
    }

    if nextIndex == endIndex {
      state.pointee = theState
      return 0
    }

    // Return only a single element so that code can start iterating via fast
    // enumeration, terminate it, and continue via NSEnumerator.
    let key = buffer.bridgedKey(at: nextIndex)
    buffer.formIndex(after: &nextIndex)

    let unmanagedObjects = _UnmanagedAnyObjectArray(objects)
    unmanagedObjects[0] = key
    state.pointee = theState
    return 1
  }
}
#endif

#if _runtime(_ObjC)
/// This class exists for Objective-C bridging. It holds a reference to a
/// Native${Self}Buffer, and can be upcast to NSSelf when bridging is necessary.
/// This is the fallback implementation for situations where toll-free bridging
/// isn't possible. On first access, a Native${Self}Buffer of AnyObject will be
/// constructed containing all the bridged elements.
final internal class _SwiftDeferredNS${Self}<${TypeParametersDecl}>
  : _SwiftNativeNS${Self}, _NS${Self}Core {

  internal typealias NativeBuffer = _Native${Self}Buffer<${TypeParameters}>
  internal typealias BridgedBuffer = _Native${Self}Buffer<${AnyTypeParameters}>
  internal typealias NativeIndex = _Native${Self}Index<${TypeParameters}>
  internal typealias BridgedIndex = _Native${Self}Index<${AnyTypeParameters}>

%if Self == 'Set':
  internal typealias Key = Element
  internal typealias Value = Element
%end

  internal init(minimumCapacity: Int = 2) {
    nativeBuffer = NativeBuffer(minimumCapacity: minimumCapacity)
    super.init()
  }

  internal init(nativeBuffer: NativeBuffer) {
    self.nativeBuffer = nativeBuffer
    super.init()
  }

  // This stored property should be stored at offset zero.  We perform atomic
  // operations on it.
  //
  // Do not access this property directly.
  internal var _heapStorageBridged_DoNotUse: AnyObject?

  /// The unbridged elements.
  internal var nativeBuffer: NativeBuffer

  @objc(copyWithZone:)
  internal func copy(with zone: _SwiftNSZone?) -> AnyObject {
    // Instances of this class should be visible outside of standard library as
    // having `NS${Self}` type, which is immutable.
    return self
  }

%if Self == 'Set':

  //
  // NSSet implementation.
  //
  // Do not call any of these methods from the standard library!  Use only
  // `nativeBuffer`.
  //

  @objc
  internal required init(objects: UnsafePointer<AnyObject?>, count: Int) {
    _sanityCheckFailure("don't call this designated initializer")
  }

  @objc
  internal func member(_ object: AnyObject) -> AnyObject? {
    return bridgingObjectForKey(object)
  }

  @objc
  internal func objectEnumerator() -> _NSEnumerator {
    return enumerator()
  }

%elif Self == 'Dictionary':
  //
  // NSDictionary implementation.
  //
  // Do not call any of these methods from the standard library!  Use only
  // `nativeBuffer`.
  //

  @objc
  internal required init(
    objects: UnsafePointer<AnyObject?>,
    forKeys: UnsafeRawPointer,
    count: Int
  ) {
    _sanityCheckFailure("don't call this designated initializer")
  }

  @objc(objectForKey:)
  internal func objectFor(_ aKey: AnyObject) -> AnyObject? {
    return bridgingObjectForKey(aKey)
  }

  @objc
  internal func keyEnumerator() -> _NSEnumerator {
    return enumerator()
  }

  @objc
  internal func getObjects(
    _ objects: UnsafeMutablePointer<AnyObject>?,
    andKeys keys: UnsafeMutablePointer<AnyObject>?
  ) {
    bridgedAllKeysAndValues(objects, keys)
  }

  @objc(enumerateKeysAndObjectsWithOptions:usingBlock:)
  internal func enumerateKeysAndObjects(options: Int, 
    using block: @convention(block) (Unmanaged<AnyObject>, Unmanaged<AnyObject>,
     UnsafeMutablePointer<UInt8>) -> Void) {
    bridgeEverything()
    let capacity = nativeBuffer.capacity
    var stop: UInt8 = 0
    for position in 0..<capacity {
      if bridgedBuffer.isInitializedEntry(at: position) {
        block(Unmanaged.passUnretained(bridgedBuffer.key(at: position)), 
          Unmanaged.passUnretained(bridgedBuffer.value(at: position)), 
          &stop)
      }
      if stop != 0 { return }
    }
  }
%end

  /// Returns the pointer to the stored property, which contains bridged
  /// ${Self} elements.
  internal var _heapStorageBridgedPtr: UnsafeMutablePointer<AnyObject?> {
    return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
      to: Optional<AnyObject>.self)
  }

  /// The buffer for bridged ${Self} elements, if present.
  internal var _bridgedStorage:
    BridgedBuffer.RawStorage? {
    get {
      if let ref = _stdlib_atomicLoadARCRef(object: _heapStorageBridgedPtr) {
        return unsafeDowncast(ref, to: BridgedBuffer.RawStorage.self)
      }
      return nil
    }
  }

  /// Attach a buffer for bridged ${Self} elements.
  internal func _initializeHeapStorageBridged(_ newStorage: AnyObject) {
    _stdlib_atomicInitializeARCRef(
      object: _heapStorageBridgedPtr, desired: newStorage)
  }

  /// Returns the bridged ${Self} values.
  internal var bridgedBuffer: BridgedBuffer {
    return BridgedBuffer(_storage: _bridgedStorage!)
  }

  internal func bridgeEverything() {
    if _fastPath(_bridgedStorage != nil) {
      return
    }

    // FIXME: rdar://problem/19486139 (split bridged buffers for keys and values)
    // We bridge keys and values unconditionally here, even if one of them
    // actually is verbatim bridgeable (e.g. Dictionary<Int, AnyObject>).
    // Investigate only allocating the buffer for a Set in this case.

    // Create buffer for bridged data.
    let bridged = BridgedBuffer(capacity: nativeBuffer.capacity, unhashable: ())

    // Bridge everything.
    for i in 0..<nativeBuffer.capacity {
      if nativeBuffer.isInitializedEntry(at: i) {
        let key = _bridgeAnythingToObjectiveC(nativeBuffer.key(at: i))
%if Self == 'Set':
        bridged.initializeKey(key, at: i)
%elif Self == 'Dictionary':
        let val = _bridgeAnythingToObjectiveC(nativeBuffer.value(at: i))
        bridged.initializeKey(key, value: val, at: i)
%end
      }
    }

    // Atomically put the bridged elements in place.
    _initializeHeapStorageBridged(bridged._storage)
  }

%if Self == 'Dictionary':

  internal func bridgedAllKeysAndValues(
    _ objects: UnsafeMutablePointer<AnyObject>?,
    _ keys: UnsafeMutablePointer<AnyObject>?
  ) {
    bridgeEverything()
    // The user is expected to provide a storage of the correct size
    var i = 0 // Position in the input storage
    let capacity = nativeBuffer.capacity

    if let unmanagedKeys = _UnmanagedAnyObjectArray(keys) {
      if let unmanagedObjects = _UnmanagedAnyObjectArray(objects) {
        // keys nonnull, objects nonnull
        for position in 0..<capacity {
          if bridgedBuffer.isInitializedEntry(at: position) {
            unmanagedObjects[i] = bridgedBuffer.value(at: position)
            unmanagedKeys[i] = bridgedBuffer.key(at: position)
            i += 1
          }
        }
      } else {
        // keys nonnull, objects null
        for position in 0..<capacity {
          if bridgedBuffer.isInitializedEntry(at: position) {
            unmanagedKeys[i] = bridgedBuffer.key(at: position)
            i += 1
          }
        }
      }
    } else {
      if let unmanagedObjects = _UnmanagedAnyObjectArray(objects) {
        // keys null, objects nonnull
        for position in 0..<capacity {
          if bridgedBuffer.isInitializedEntry(at: position) {
            unmanagedObjects[i] = bridgedBuffer.value(at: position)
            i += 1
          }
        }
      } else {
        // do nothing, both are null
      }
    }
  }

%end

  @objc
  internal var count: Int {
    return nativeBuffer.count
  }

  internal func bridgingObjectForKey(_ aKey: AnyObject)
    -> AnyObject? {
    guard let nativeKey = _conditionallyBridgeFromObjectiveC(aKey, Key.self)
    else { return nil }

    let (i, found) = nativeBuffer._find(
      nativeKey, startBucket: nativeBuffer._bucket(nativeKey))
    if found {
      bridgeEverything()
      return bridgedBuffer.value(at: i.offset)
    }
    return nil
  }

  internal func enumerator() -> _NSEnumerator {
    bridgeEverything()
    return _Native${Self}NSEnumerator<${AnyTypeParameters}>(bridgedBuffer)
  }

  @objc(countByEnumeratingWithState:objects:count:)
  internal func countByEnumerating(
    with state: UnsafeMutablePointer<_SwiftNSFastEnumerationState>,
    objects: UnsafeMutablePointer<AnyObject>?,
    count: Int
  ) -> Int {
    var theState = state.pointee
    if theState.state == 0 {
      theState.state = 1 // Arbitrary non-zero value.
      theState.itemsPtr = AutoreleasingUnsafeMutablePointer(objects)
      theState.mutationsPtr = _fastEnumerationStorageMutationsPtr
      theState.extra.0 = CUnsignedLong(nativeBuffer.startIndex.offset)
    }

    // Test 'objects' rather than 'count' because (a) this is very rare anyway,
    // and (b) the optimizer should then be able to optimize away the
    // unwrapping check below.
    if _slowPath(objects == nil) {
      return 0
    }

    let unmanagedObjects = _UnmanagedAnyObjectArray(objects!)
    var currIndex = _Native${Self}Index<${TypeParameters}>(
        offset: Int(theState.extra.0))
    let endIndex = nativeBuffer.endIndex
    var stored = 0

    // Only need to bridge once, so we can hoist it out of the loop.
    if (currIndex != endIndex) {
      bridgeEverything()
    }
    
    for i in 0..<count {
      if (currIndex == endIndex) {
        break
      }

      let bridgedKey = bridgedBuffer.key(at: currIndex.offset)
      unmanagedObjects[i] = bridgedKey
      stored += 1
      nativeBuffer.formIndex(after: &currIndex)
    }
    theState.extra.0 = CUnsignedLong(currIndex.offset)
    state.pointee = theState
    return stored
  }
}
#else
final internal class _SwiftDeferredNS${Self}<${TypeParametersDecl}> { }
#endif

#if _runtime(_ObjC)
@_versioned
@_fixed_layout
internal struct _Cocoa${Self}Buffer : _HashBuffer {
  @_versioned
  internal var cocoa${Self}: _NS${Self}

  internal typealias Index = _Cocoa${Self}Index
  internal typealias SequenceElement = ${AnySequenceType}
  internal typealias SequenceElementWithoutLabels = ${AnySequenceType}

  internal typealias Key = AnyObject
  internal typealias Value = AnyObject

  internal var startIndex: Index {
    return Index(cocoa${Self}, startIndex: ())
  }

  internal var endIndex: Index {
    return Index(cocoa${Self}, endIndex: ())
  }

  @_versioned
  internal func index(after i: Index) -> Index {
    return i.successor()
  }

  internal func formIndex(after i: inout Index) {
    // FIXME: swift-3-indexing-model: optimize if possible.
    i = i.successor()
  }

  @_versioned
  internal func index(forKey key: Key) -> Index? {
    // Fast path that does not involve creating an array of all keys.  In case
    // the key is present, this lookup is a penalty for the slow path, but the
    // potential savings are significant: we could skip a memory allocation and
    // a linear search.
    if maybeGet(key) == nil {
      return nil
    }

%if Self == 'Set':
    let allKeys = _stdlib_NSSet_allObjects(cocoaSet)
%elif Self == 'Dictionary':
    let allKeys = _stdlib_NSDictionary_allKeys(cocoaDictionary)
%end
    var keyIndex = -1
    for i in 0..<allKeys.value {
      if _stdlib_NSObject_isEqual(key, allKeys[i]) {
        keyIndex = i
        break
      }
    }
    _sanityCheck(keyIndex >= 0,
        "key was found in fast path, but not found later?")
    return Index(cocoa${Self}, allKeys, keyIndex)
  }

  internal func assertingGet(_ i: Index) -> SequenceElement {
%if Self == 'Set':
    let value: Value? = i.allKeys[i.currentKeyIndex]
    _sanityCheck(value != nil, "item not found in underlying NS${Self}")
    return value!
%elif Self == 'Dictionary':
    let key: Key = i.allKeys[i.currentKeyIndex]
    let value: Value = i.cocoaDictionary.objectFor(key)!
    return (key, value)
%end

  }

  internal func assertingGet(_ key: Key) -> Value {
%if Self == 'Set':
    let value: Value? = cocoa${Self}.member(key)
    _precondition(value != nil, "member not found in underlying NS${Self}")
    return value!
%elif Self == 'Dictionary':
    let value: Value? = cocoa${Self}.objectFor(key)
    _precondition(value != nil, "key not found in underlying NS${Self}")
    return value!
%end
  }

  @inline(__always)
  internal func maybeGet(_ key: Key) -> Value? {

%if Self == 'Set':
  return cocoaSet.member(key)
%elif Self == 'Dictionary':
  return cocoaDictionary.objectFor(key)
%end

  }

  @discardableResult
  internal mutating func updateValue(_ value: Value, forKey key: Key) -> Value? {
    _sanityCheckFailure("cannot mutate NS${Self}")
  }

  @discardableResult
  internal mutating func insert(
    _ value: Value, forKey key: Key
  ) -> (inserted: Bool, memberAfterInsert: Value) {
    _sanityCheckFailure("cannot mutate NS${Self}")
  }

  @discardableResult
  internal mutating func remove(at index: Index) -> SequenceElement {
    _sanityCheckFailure("cannot mutate NS${Self}")
  }

  @discardableResult
  internal mutating func removeValue(forKey key: Key) -> Value? {
    _sanityCheckFailure("cannot mutate NS${Self}")
  }

  internal mutating func removeAll(keepingCapacity keepCapacity: Bool) {
    _sanityCheckFailure("cannot mutate NS${Self}")
  }

  internal var count: Int {
    return cocoa${Self}.count
  }

  internal static func fromArray(_ elements: [SequenceElementWithoutLabels])
    -> _Cocoa${Self}Buffer {

    _sanityCheckFailure("this function should never be called")
  }
}
#else
@_versioned
@_fixed_layout
internal struct _Cocoa${Self}Buffer {}
#endif

@_versioned
@_fixed_layout
internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {

  internal typealias NativeBuffer = _Native${Self}Buffer<${TypeParameters}>
  internal typealias NativeIndex = _Native${Self}Index<${TypeParameters}>
  internal typealias CocoaBuffer = _Cocoa${Self}Buffer
  internal typealias SequenceElement = ${Sequence}
  internal typealias SequenceElementWithoutLabels = ${Sequence}
  internal typealias SelfType = _Variant${Self}Buffer

%if Self == 'Set':
  internal typealias Key = ${TypeParameters}
  internal typealias Value = ${TypeParameters}
%end

  case native(NativeBuffer)
  case cocoa(CocoaBuffer)

  @_versioned
  @_transparent
  internal var guaranteedNative: Bool {
    return _canBeClass(Key.self) == 0 || _canBeClass(Value.self) == 0
  }

  internal mutating func isUniquelyReferenced() -> Bool {
    // Note that &self drills down through .native(NativeBuffer) to the first
    // property in NativeBuffer, which is the reference to the storage.
    if _fastPath(guaranteedNative) {
      return _isUnique_native(&self)
    }

    switch self {
    case .native:
      return _isUnique_native(&self)
    case .cocoa:
      // Don't consider Cocoa buffer mutable, even if it is mutable and is
      // uniquely referenced.
      return false
    }
  }

  @_versioned
  internal var asNative: NativeBuffer {
    get {
      switch self {
      case .native(let buffer):
        return buffer
      case .cocoa:
        _sanityCheckFailure("internal error: not backed by native buffer")
      }
    }
    set {
      self = .native(newValue)
    }
  }

#if _runtime(_ObjC)
  internal var asCocoa: CocoaBuffer {
    switch self {
    case .native:
      _sanityCheckFailure("internal error: not backed by NS${Self}")
    case .cocoa(let cocoaBuffer):
      return cocoaBuffer
    }
  }
#endif

  /// Ensure this we hold a unique reference to a native buffer
  /// having at least `minimumCapacity` elements.
  internal mutating func ensureUniqueNativeBuffer(_ minimumCapacity: Int)
    -> (reallocated: Bool, capacityChanged: Bool) {
    switch self {
    case .native:
      let oldCapacity = asNative.capacity
      if isUniquelyReferenced() && oldCapacity >= minimumCapacity {
        return (reallocated: false, capacityChanged: false)
      }

      let oldNativeBuffer = asNative
      var newNativeBuffer = NativeBuffer(minimumCapacity: minimumCapacity)
      let newCapacity = newNativeBuffer.capacity
      for i in 0..<oldCapacity {
        if oldNativeBuffer.isInitializedEntry(at: i) {
          if oldCapacity == newCapacity {
            let key = oldNativeBuffer.key(at: i)
%if Self == 'Set':
            newNativeBuffer.initializeKey(key, at: i)
%elif Self == 'Dictionary':
            let value = oldNativeBuffer.value(at: i)
            newNativeBuffer.initializeKey(key, value: value , at: i)
%end
          } else {
            let key = oldNativeBuffer.key(at: i)
%if Self == 'Set':
            newNativeBuffer.unsafeAddNew(key: key)
%elif Self == 'Dictionary':
            newNativeBuffer.unsafeAddNew(
              key: key,
              value: oldNativeBuffer.value(at: i))
%end
          }
        }
      }
      newNativeBuffer.count = oldNativeBuffer.count

      self = .native(newNativeBuffer)
      return (reallocated: true,
              capacityChanged: oldCapacity != newNativeBuffer.capacity)

    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      let cocoa${Self} = cocoaBuffer.cocoa${Self}
      var newNativeBuffer = NativeBuffer(minimumCapacity: minimumCapacity)
      let oldCocoaIterator = _Cocoa${Self}Iterator(cocoa${Self})
%if Self == 'Set':
      while let key = oldCocoaIterator.next() {
        newNativeBuffer.unsafeAddNew(
            key: _forceBridgeFromObjectiveC(key, Value.self))
      }

%elif Self == 'Dictionary':

      while let (key, value) = oldCocoaIterator.next() {
        newNativeBuffer.unsafeAddNew(
          key: _forceBridgeFromObjectiveC(key, Key.self),
          value: _forceBridgeFromObjectiveC(value, Value.self))
      }

%end
      newNativeBuffer.count = cocoa${Self}.count

      self = .native(newNativeBuffer)
      return (reallocated: true, capacityChanged: true)
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

#if _runtime(_ObjC)
  @inline(never)
  internal mutating func migrateDataToNativeBuffer(
    _ cocoaBuffer: _Cocoa${Self}Buffer
  ) {
    let minCapacity = NativeBuffer.minimumCapacity(
      minimumCount: cocoaBuffer.count,
      maxLoadFactorInverse: _hashContainerDefaultMaxLoadFactorInverse)
    let allocated = ensureUniqueNativeBuffer(minCapacity).reallocated
    _sanityCheck(allocated, "failed to allocate native ${Self} buffer")
  }
#endif

  //
  // _HashBuffer conformance
  //

  internal typealias Index = ${Self}Index<${TypeParameters}>

  internal var startIndex: Index {
    if _fastPath(guaranteedNative) {
      return ._native(asNative.startIndex)
    }

    switch self {
    case .native:
      return ._native(asNative.startIndex)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      return ._cocoa(cocoaBuffer.startIndex)
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  internal var endIndex: Index {
    if _fastPath(guaranteedNative) {
      return ._native(asNative.endIndex)
    }

    switch self {
    case .native:
      return ._native(asNative.endIndex)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      return ._cocoa(cocoaBuffer.endIndex)
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  @_versioned
  func index(after i: Index) -> Index {
    if _fastPath(guaranteedNative) {
      return ._native(asNative.index(after: i._nativeIndex))
    }

    switch self {
    case .native:
      return ._native(asNative.index(after: i._nativeIndex))
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      return ._cocoa(cocoaBuffer.index(after: i._cocoaIndex))
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  internal func formIndex(after i: inout Index) {
    // FIXME: swift-3-indexing-model: optimize if possible.
    i = index(after: i)
  }

  @_versioned
  @inline(__always)
  internal func index(forKey key: Key) -> Index? {
    if _fastPath(guaranteedNative) {
      if let nativeIndex = asNative.index(forKey: key) {
        return ._native(nativeIndex)
      }
      return nil
    }

    switch self {
    case .native:
      if let nativeIndex = asNative.index(forKey: key) {
        return ._native(nativeIndex)
      }
      return nil
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      let anyObjectKey: AnyObject = _bridgeAnythingToObjectiveC(key)
      if let cocoaIndex = cocoaBuffer.index(forKey: anyObjectKey) {
        return ._cocoa(cocoaIndex)
      }
      return nil
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  internal func assertingGet(_ i: Index) -> SequenceElement {
    if _fastPath(guaranteedNative) {
      return asNative.assertingGet(i._nativeIndex)
    }

    switch self {
    case .native:
      return asNative.assertingGet(i._nativeIndex)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
%if Self == 'Set':
      let anyObjectValue: AnyObject = cocoaBuffer.assertingGet(i._cocoaIndex)
      let nativeValue = _forceBridgeFromObjectiveC(anyObjectValue, Value.self)
      return nativeValue
%elif Self == 'Dictionary':
      let (anyObjectKey, anyObjectValue) =
          cocoaBuffer.assertingGet(i._cocoaIndex)
      let nativeKey = _forceBridgeFromObjectiveC(anyObjectKey, Key.self)
      let nativeValue = _forceBridgeFromObjectiveC(anyObjectValue, Value.self)
      return (nativeKey, nativeValue)
%end
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  internal func assertingGet(_ key: Key) -> Value {
    if _fastPath(guaranteedNative) {
      return asNative.assertingGet(key)
    }

    switch self {
    case .native:
      return asNative.assertingGet(key)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      // FIXME: This assumes that Key and Value are bridged verbatim.
      let anyObjectKey: AnyObject = _bridgeAnythingToObjectiveC(key)
      let anyObjectValue: AnyObject = cocoaBuffer.assertingGet(anyObjectKey)
      return _forceBridgeFromObjectiveC(anyObjectValue, Value.self)
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

#if _runtime(_ObjC)
  @_versioned
  @inline(never)
  internal static func maybeGetFromCocoaBuffer(
    _ cocoaBuffer : CocoaBuffer, forKey key: Key
  ) -> Value? {
    let anyObjectKey: AnyObject = _bridgeAnythingToObjectiveC(key)
    if let anyObjectValue = cocoaBuffer.maybeGet(anyObjectKey) {
      return _forceBridgeFromObjectiveC(anyObjectValue, Value.self)
    }
    return nil
  }
#endif

  @_versioned
  @inline(__always)
  internal func maybeGet(_ key: Key) -> Value? {
    if _fastPath(guaranteedNative) {
      return asNative.maybeGet(key)
    }

    switch self {
    case .native:
      return asNative.maybeGet(key)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      return SelfType.maybeGetFromCocoaBuffer(cocoaBuffer, forKey: key)
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  internal mutating func nativeUpdateValue(
    _ value: Value, forKey key: Key
  ) -> Value? {
    var (i, found) = asNative._find(key, startBucket: asNative._bucket(key))

    let minCapacity = found
      ? asNative.capacity
      : NativeBuffer.minimumCapacity(
          minimumCount: asNative.count + 1,
          maxLoadFactorInverse: _hashContainerDefaultMaxLoadFactorInverse)

    let (_, capacityChanged) = ensureUniqueNativeBuffer(minCapacity)
    if capacityChanged {
      i = asNative._find(key, startBucket: asNative._bucket(key)).pos
    }

%if Self == 'Set':
    let oldValue: Value? = found ? asNative.key(at: i.offset) : nil
    if found {
      asNative.setKey(key, at: i.offset)
    } else {
      asNative.initializeKey(key, at: i.offset)
      asNative.count += 1
    }
%elif Self == 'Dictionary':
    let oldValue: Value? = found ? asNative.value(at: i.offset) : nil
    if found {
      asNative.setKey(key, value: value, at: i.offset)
    } else {
      asNative.initializeKey(key, value: value, at: i.offset)
      asNative.count += 1
    }
%end

    return oldValue
  }

  @discardableResult
  internal mutating func updateValue(
    _ value: Value, forKey key: Key
  ) -> Value? {

    if _fastPath(guaranteedNative) {
      return nativeUpdateValue(value, forKey: key)
    }

    switch self {
    case .native:
      return nativeUpdateValue(value, forKey: key)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      migrateDataToNativeBuffer(cocoaBuffer)
      return nativeUpdateValue(value, forKey: key)
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  internal mutating func nativeInsert(
    _ value: Value, forKey key: Key
  ) -> (inserted: Bool, memberAfterInsert: Value) {

    var (i, found) = asNative._find(key, startBucket: asNative._bucket(key))
    if found {
%if Self == 'Set':
      return (inserted: false, memberAfterInsert: asNative.key(at: i.offset))
%elif Self == 'Dictionary':
      return (inserted: false, memberAfterInsert: asNative.value(at: i.offset))
%end
    }

    let minCapacity = NativeBuffer.minimumCapacity(
      minimumCount: asNative.count + 1,
      maxLoadFactorInverse: _hashContainerDefaultMaxLoadFactorInverse)

    let (_, capacityChanged) = ensureUniqueNativeBuffer(minCapacity)

    if capacityChanged {
      i = asNative._find(key, startBucket: asNative._bucket(key)).pos
    }

%if Self == 'Set':
    asNative.initializeKey(key, at: i.offset)
    asNative.count += 1
%elif Self == 'Dictionary':
    asNative.initializeKey(key, value: value, at: i.offset)
    asNative.count += 1
%end

    return (inserted: true, memberAfterInsert: value)
  }

  @discardableResult
  internal mutating func insert(
    _ value: Value, forKey key: Key
  ) -> (inserted: Bool, memberAfterInsert: Value) {

    if _fastPath(guaranteedNative) {
      return nativeInsert(value, forKey: key)
    }

    switch self {
    case .native:
      return nativeInsert(value, forKey: key)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      migrateDataToNativeBuffer(cocoaBuffer)
      return nativeInsert(value, forKey: key)
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  /// - parameter idealBucket: The ideal bucket for the element being deleted.
  /// - parameter offset: The offset of the element that will be deleted.
  /// Precondition: there should be an initialized entry at offset.
  internal mutating func nativeDelete(
    _ nativeBuffer: NativeBuffer, idealBucket: Int, offset: Int
  ) {
    _sanityCheck(
        nativeBuffer.isInitializedEntry(at: offset), "expected initialized entry")

    var nativeBuffer = nativeBuffer

    // remove the element
    nativeBuffer.destroyEntry(at: offset)
    nativeBuffer.count -= 1

    // If we've put a hole in a chain of contiguous elements, some
    // element after the hole may belong where the new hole is.
    var hole = offset

    // Find the first bucket in the contiguous chain
    var start = idealBucket
    while nativeBuffer.isInitializedEntry(at: nativeBuffer._prev(start)) {
      start = nativeBuffer._prev(start)
    }

    // Find the last bucket in the contiguous chain
    var lastInChain = hole
    var b = nativeBuffer._index(after: lastInChain)
    while nativeBuffer.isInitializedEntry(at: b) {
      lastInChain = b
      b = nativeBuffer._index(after: b)
    }

    // Relocate out-of-place elements in the chain, repeating until
    // none are found.
    while hole != lastInChain {
      // Walk backwards from the end of the chain looking for
      // something out-of-place.
      var b = lastInChain
      while b != hole {
        let idealBucket = nativeBuffer._bucket(nativeBuffer.key(at: b))

        // Does this element belong between start and hole?  We need
        // two separate tests depending on whether [start, hole] wraps
        // around the end of the storage
        let c0 = idealBucket >= start
        let c1 = idealBucket <= hole
        if start <= hole ? (c0 && c1) : (c0 || c1) {
          break // Found it
        }
        b = nativeBuffer._prev(b)
      }

      if b == hole { // No out-of-place elements found; we're done adjusting
        break
      }

      // Move the found element into the hole
      nativeBuffer.moveInitializeEntry(
        from: nativeBuffer,
        at: b,
        toEntryAt: hole)
      hole = b
    }
  }

  internal mutating func nativeRemoveObject(forKey key: Key) -> Value? {
    var idealBucket = asNative._bucket(key)
    var (index, found) = asNative._find(key, startBucket: idealBucket)

    // Fast path: if the key is not present, we will not mutate the set,
    // so don't force unique buffer.
    if !found {
      return nil
    }

    let (_, capacityChanged) =
      ensureUniqueNativeBuffer(asNative.capacity)
    let nativeBuffer = asNative
    if capacityChanged {
      idealBucket = nativeBuffer._bucket(key)
      (index, found) = nativeBuffer._find(key, startBucket: idealBucket)
      _sanityCheck(found, "key was lost during buffer migration")
    }
%if Self == 'Set':
    let oldValue = nativeBuffer.key(at: index.offset)
%elif Self == 'Dictionary':
    let oldValue = nativeBuffer.value(at: index.offset)
%end
    nativeDelete(nativeBuffer, idealBucket: idealBucket,
      offset: index.offset)
    return oldValue
  }

  internal mutating func nativeRemove(
    at nativeIndex: NativeIndex
  ) -> SequenceElement {

    // The provided index should be valid, so we will always mutating the
    // set buffer.  Request unique buffer.
    _ = ensureUniqueNativeBuffer(asNative.capacity)
    let nativeBuffer = asNative

    let result = nativeBuffer.assertingGet(nativeIndex)
%if Self == 'Set':
    let key = result
%elif Self == 'Dictionary':
    let key = result.0
%end

    nativeDelete(nativeBuffer, idealBucket: nativeBuffer._bucket(key),
        offset: nativeIndex.offset)
    return result
  }

  @discardableResult
  internal mutating func remove(at index: Index) -> SequenceElement {
    if _fastPath(guaranteedNative) {
      return nativeRemove(at: index._nativeIndex)
    }

    switch self {
    case .native:
      return nativeRemove(at: index._nativeIndex)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      // We have to migrate the data first.  But after we do so, the Cocoa
      // index becomes useless, so get the key first.
      //
      // FIXME(performance): fuse data migration and element deletion into one
      // operation.
      let index = index._cocoaIndex
      let anyObjectKey: AnyObject = index.allKeys[index.currentKeyIndex]
      migrateDataToNativeBuffer(cocoaBuffer)
      let key = _forceBridgeFromObjectiveC(anyObjectKey, Key.self)
      let value = nativeRemoveObject(forKey: key)

%if Self == 'Set':
      _sanityCheck(key == value, "bridging did not preserve equality")
      return key
%elif Self == 'Dictionary':
      return (key, value._unsafelyUnwrappedUnchecked)
%end
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  @discardableResult
  internal mutating func removeValue(forKey key: Key) -> Value? {
    if _fastPath(guaranteedNative) {
      return nativeRemoveObject(forKey: key)
    }

    switch self {
    case .native:
      return nativeRemoveObject(forKey: key)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      let anyObjectKey: AnyObject = _bridgeAnythingToObjectiveC(key)
      if cocoaBuffer.maybeGet(anyObjectKey) == nil {
        return nil
      }
      migrateDataToNativeBuffer(cocoaBuffer)
      return nativeRemoveObject(forKey: key)
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  internal mutating func nativeRemoveAll() {
    if !isUniquelyReferenced() {
        asNative = NativeBuffer(minimumCapacity: asNative.capacity)
        return
    }

    // We have already checked for the empty dictionary case and unique
    // reference, so we will always mutate the dictionary buffer.
    var nativeBuffer = asNative

    for b in 0..<nativeBuffer.capacity {
      if nativeBuffer.isInitializedEntry(at: b) {
        nativeBuffer.destroyEntry(at: b)
      }
    }
    nativeBuffer.count = 0
  }

  internal mutating func removeAll(keepingCapacity keepCapacity: Bool) {
    if count == 0 {
      return
    }

    if !keepCapacity {
      self = .native(NativeBuffer(minimumCapacity: 2))
      return
    }

    if _fastPath(guaranteedNative) {
      nativeRemoveAll()
      return
    }

    switch self {
    case .native:
      nativeRemoveAll()
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      self = .native(NativeBuffer(minimumCapacity: cocoaBuffer.count))
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  internal var count: Int {
    if _fastPath(guaranteedNative) {
      return asNative.count
    }

    switch self {
    case .native:
      return asNative.count
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      return cocoaBuffer.count
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  /// Returns an iterator over the `(Key, Value)` pairs.
  ///
  /// - Complexity: O(1).
  @_versioned
  @inline(__always)
  internal func makeIterator() -> ${Self}Iterator<${TypeParameters}> {
    switch self {
    case .native(let buffer):
      return ._native(
        start: asNative.startIndex, end: asNative.endIndex, buffer: buffer)
    case .cocoa(let cocoaBuffer):
#if _runtime(_ObjC)
      return ._cocoa(_Cocoa${Self}Iterator(cocoaBuffer.cocoa${Self}))
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }

  internal static func fromArray(_ elements: [SequenceElement])
    -> _Variant${Self}Buffer<${TypeParameters}> {

    _sanityCheckFailure("this function should never be called")
  }
}

%{
  compareOperators = ["<", "<=", ">", ">=", "=="]
}%

@_versioned
internal struct _Native${Self}Index<${TypeParameters}> : Comparable {
  @_versioned
  internal var offset: Int

  @_versioned
  internal init(offset: Int) {
    self.offset = offset
  }
}

extension _Native${Self}Index {

% for op in compareOperators:
  internal static func ${op} (
    lhs: _Native${Self}Index<${TypeParameters}>,
    rhs: _Native${Self}Index<${TypeParameters}>
  ) -> Bool {
    return lhs.offset ${op} rhs.offset
  }
% end

}


#if _runtime(_ObjC)
@_versioned
internal struct _Cocoa${Self}Index : Comparable {
  // Assumption: we rely on NSDictionary.getObjects when being
  // repeatedly called on the same NSDictionary, returning items in the same
  // order every time.
  // Similarly, the same assumption holds for NSSet.allObjects.

  /// A reference to the NS${Self}, which owns members in `allObjects`,
  /// or `allKeys`, for NSSet and NSDictionary respectively.
  internal let cocoa${Self}: _NS${Self}
  // FIXME: swift-3-indexing-model: try to remove the cocoa reference, but make
  // sure that we have a safety check for accessing `allKeys`.  Maybe move both
  // into the dictionary/set itself.

  /// An unowned array of keys.
  internal var allKeys: _HeapBuffer<Int, AnyObject>

  /// Index into `allKeys`
  internal var currentKeyIndex: Int

  internal init(_ cocoa${Self}: _NS${Self}, startIndex: ()) {
    self.cocoa${Self} = cocoa${Self}
%if Self == 'Set':
    self.allKeys = _stdlib_NSSet_allObjects(cocoaSet)
%elif Self == 'Dictionary':
    self.allKeys = _stdlib_NSDictionary_allKeys(cocoaDictionary)
%end
    self.currentKeyIndex = 0
  }

  internal init(_ cocoa${Self}: _NS${Self}, endIndex: ()) {
    self.cocoa${Self} = cocoa${Self}
%if Self == 'Set':
    self.allKeys = _stdlib_NS${Self}_allObjects(cocoa${Self})
%elif Self == 'Dictionary':
    self.allKeys = _stdlib_NS${Self}_allKeys(cocoa${Self})
%end
    self.currentKeyIndex = allKeys.value
  }

  internal init(_ cocoa${Self}: _NS${Self},
    _ allKeys: _HeapBuffer<Int, AnyObject>,
    _ currentKeyIndex: Int
  ) {
    self.cocoa${Self} = cocoa${Self}
    self.allKeys = allKeys
    self.currentKeyIndex = currentKeyIndex
  }

  /// Returns the next consecutive value after `self`.
  ///
  /// - Precondition: The next value is representable.
  internal func successor() -> _Cocoa${Self}Index {
    // FIXME: swift-3-indexing-model: remove this method.
    _precondition(
      currentKeyIndex < allKeys.value, "cannot increment endIndex")
    return _Cocoa${Self}Index(cocoa${Self}, allKeys, currentKeyIndex + 1)
  }
}

extension _Cocoa${Self}Index {

% for op in compareOperators:
  internal static func ${op} (
    lhs: _Cocoa${Self}Index,
    rhs: _Cocoa${Self}Index
  ) -> Bool {
    return lhs.currentKeyIndex ${op} rhs.currentKeyIndex
  }
% end

}
#else
internal struct _Cocoa${Self}Index {}
#endif

internal enum ${Self}IndexRepresentation<${TypeParametersDecl}> {
  typealias _Index = ${Self}Index<${TypeParameters}>
  typealias _NativeIndex = _Index._NativeIndex
  typealias _CocoaIndex = _Index._CocoaIndex

  case _native(_NativeIndex)
  case _cocoa(_CocoaIndex)
}

extension ${Self} {
%{
if Self == 'Set':
  SubscriptingWithIndexDoc = """\
/// Used to access the members in an instance of `Set<Element>`."""
elif Self == 'Dictionary':
  SubscriptingWithIndexDoc = """\
/// Used to access the key-value pairs in an instance of
/// `Dictionary<Key, Value>`.
///
/// Dictionary has two subscripting interfaces:
///
/// 1. Subscripting with a key, yielding an optional value:
///
///        v = d[k]!
///
/// 2. Subscripting with an index, yielding a key-value pair:
///
///        (k, v) = d[i]"""
}%

${SubscriptingWithIndexDoc}
public struct Index : Comparable {
  // Index for native buffer is efficient.  Index for bridged NS${Self} is
  // not, because neither NSEnumerator nor fast enumeration support moving
  // backwards.  Even if they did, there is another issue: NSEnumerator does
  // not support NSCopying, and fast enumeration does not document that it is
  // safe to copy the state.  So, we cannot implement Index that is a value
  // type for bridged NS${Self} in terms of Cocoa enumeration facilities.

  internal typealias _NativeIndex = _Native${Self}Index<${TypeParameters}>
  internal typealias _CocoaIndex = _Cocoa${Self}Index

%if Self == 'Set':
  internal typealias Key = ${TypeParameters}
  internal typealias Value = ${TypeParameters}
%end

  internal var _value: ${Self}IndexRepresentation<${TypeParameters}>

  @_versioned
  internal static func _native(_ index: _NativeIndex) -> Index {
    return ${Self}Index(_value: ._native(index))
  }
#if _runtime(_ObjC)
  @_versioned
  internal static func _cocoa(_ index: _CocoaIndex) -> Index {
    return ${Self}Index(_value: ._cocoa(index))
  }
#endif

  @_versioned
  @_transparent
  internal var _guaranteedNative: Bool {
    return _canBeClass(Key.self) == 0 && _canBeClass(Value.self) == 0
  }

  @_transparent
  internal var _nativeIndex: _NativeIndex {
    switch _value {
    case ._native(let nativeIndex):
      return nativeIndex
    case ._cocoa:
      _sanityCheckFailure("internal error: does not contain a native index")
    }
  }

#if _runtime(_ObjC)
  @_transparent
  internal var _cocoaIndex: _CocoaIndex {
    switch _value {
    case ._native:
      _sanityCheckFailure("internal error: does not contain a Cocoa index")
    case ._cocoa(let cocoaIndex):
      return cocoaIndex
    }
  }
#endif
}

}

public typealias ${Self}Index<${TypeParametersDecl}> =
    ${Self}<${TypeParameters}>.Index

extension ${Self}.Index {
  public static func == (
    lhs: ${Self}<${TypeParameters}>.Index,
    rhs: ${Self}<${TypeParameters}>.Index
  ) -> Bool {
    if _fastPath(lhs._guaranteedNative) {
      return lhs._nativeIndex == rhs._nativeIndex
    }

    switch (lhs._value, rhs._value) {
    case (._native(let lhsNative), ._native(let rhsNative)):
      return lhsNative == rhsNative
    case (._cocoa(let lhsCocoa), ._cocoa(let rhsCocoa)):
  #if _runtime(_ObjC)
      return lhsCocoa == rhsCocoa
  #else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
  #endif
    default:
      _preconditionFailure("comparing indexes from different sets")
    }
  }

  public static func < (
    lhs: ${Self}<${TypeParameters}>.Index,
    rhs: ${Self}<${TypeParameters}>.Index
  ) -> Bool {
    if _fastPath(lhs._guaranteedNative) {
      return lhs._nativeIndex < rhs._nativeIndex
    }

    switch (lhs._value, rhs._value) {
    case (._native(let lhsNative), ._native(let rhsNative)):
      return lhsNative < rhsNative
    case (._cocoa(let lhsCocoa), ._cocoa(let rhsCocoa)):
  #if _runtime(_ObjC)
      return lhsCocoa < rhsCocoa
  #else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
  #endif
    default:
      _preconditionFailure("comparing indexes from different sets")
    }
  }
}

#if _runtime(_ObjC)
@_versioned
final internal class _Cocoa${Self}Iterator : IteratorProtocol {
  internal typealias Element = ${AnySequenceType}

  // Cocoa ${Self} iterator has to be a class, otherwise we cannot
  // guarantee that the fast enumeration struct is pinned to a certain memory
  // location.

  // This stored property should be stored at offset zero.  There's code below
  // relying on this.
  internal var _fastEnumerationState: _SwiftNSFastEnumerationState =
    _makeSwiftNSFastEnumerationState()

  // This stored property should be stored right after `_fastEnumerationState`.
  // There's code below relying on this.
  internal var _fastEnumerationStackBuf = _CocoaFastEnumerationStackBuf()

  internal let cocoa${Self}: _NS${Self}

  internal var _fastEnumerationStatePtr:
    UnsafeMutablePointer<_SwiftNSFastEnumerationState> {
    return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
      to: _SwiftNSFastEnumerationState.self)
  }

  internal var _fastEnumerationStackBufPtr:
    UnsafeMutablePointer<_CocoaFastEnumerationStackBuf> {
    return UnsafeMutableRawPointer(_fastEnumerationStatePtr + 1)
      .assumingMemoryBound(to: _CocoaFastEnumerationStackBuf.self)
  }

  // These members have to be word-sized integers, they cannot be limited to
  // Int8 just because our storage holds 16 elements: fast enumeration is
  // allowed to return inner pointers to the container, which can be much
  // larger.
  internal var itemIndex: Int = 0
  internal var itemCount: Int = 0

  @_versioned
  internal init(_ cocoa${Self}: _NS${Self}) {
    self.cocoa${Self} = cocoa${Self}
  }

  @_versioned
  internal func next() -> Element? {
    if itemIndex < 0 {
      return nil
    }
    let cocoa${Self} = self.cocoa${Self}
    if itemIndex == itemCount {
      let stackBufCount = _fastEnumerationStackBuf.count
      // We can't use `withUnsafeMutablePointer` here to get pointers to
      // properties, because doing so might introduce a writeback storage, but
      // fast enumeration relies on the pointer identity of the enumeration
      // state struct.
      itemCount = cocoa${Self}.countByEnumerating(
        with: _fastEnumerationStatePtr,
        objects: UnsafeMutableRawPointer(_fastEnumerationStackBufPtr)
          .assumingMemoryBound(to: AnyObject.self),
        count: stackBufCount)
      if itemCount == 0 {
        itemIndex = -1
        return nil
      }
      itemIndex = 0
    }
    let itemsPtrUP =
    UnsafeMutableRawPointer(_fastEnumerationState.itemsPtr!)
      .assumingMemoryBound(to: AnyObject.self)
    let itemsPtr = _UnmanagedAnyObjectArray(itemsPtrUP)
    let key: AnyObject = itemsPtr[itemIndex]
    itemIndex += 1
%if Self == 'Set':
    return key
%elif Self == 'Dictionary':
    let value: AnyObject = cocoa${Self}.objectFor(key)!
    return (key, value)
%end
  }
}
#else
final internal class _Cocoa${Self}Iterator {}
#endif

@_versioned
internal enum ${Self}IteratorRepresentation<${TypeParametersDecl}> {
  internal typealias _Iterator = ${Self}Iterator<${TypeParameters}>
  internal typealias _NativeBuffer =
    _Native${Self}Buffer<${TypeParameters}>
  internal typealias _NativeIndex = _Iterator._NativeIndex

  // For native buffer, we keep two indices to keep track of the iteration
  // progress and the buffer owner to make the buffer non-uniquely
  // referenced.
  //
  // Iterator is iterating over a frozen view of the collection
  // state, so it should keep its own reference to the buffer.
  case _native(
    start: _NativeIndex, end: _NativeIndex, buffer: _NativeBuffer)
  case _cocoa(_Cocoa${Self}Iterator)
}

/// An iterator over the members of a `${Self}<${TypeParameters}>`.
public struct ${Self}Iterator<${TypeParametersDecl}> : IteratorProtocol {
  // ${Self} has a separate IteratorProtocol and Index because of efficiency
  // and implementability reasons.
  //
  // Index for native buffer is efficient.  Index for bridged NS${Self} is
  // not.
  //
  // Even though fast enumeration is not suitable for implementing
  // Index, which is multi-pass, it is suitable for implementing a
  // IteratorProtocol, which is being consumed as iteration proceeds.

  internal typealias _NativeBuffer =
    _Native${Self}Buffer<${TypeParameters}>
  internal typealias _NativeIndex = _Native${Self}Index<${TypeParameters}>

  @_versioned
  internal var _state: ${Self}IteratorRepresentation<${TypeParameters}>

  @_versioned
  internal static func _native(
    start: _NativeIndex, end: _NativeIndex, buffer: _NativeBuffer
  ) -> ${Self}Iterator {
    return ${Self}Iterator(
      _state: ._native(start: start, end: end, buffer: buffer))
  }
#if _runtime(_ObjC)
  @_versioned
  internal static func _cocoa(
    _ iterator: _Cocoa${Self}Iterator
  ) -> ${Self}Iterator{
    return ${Self}Iterator(_state: ._cocoa(iterator))
  }
#endif

  @_versioned
  @_transparent
  internal var _guaranteedNative: Bool {
%if Self == 'Set':
    return _canBeClass(Element.self) == 0
%elif Self == 'Dictionary':
    return _canBeClass(Key.self) == 0 || _canBeClass(Value.self) == 0
%end
  }

  @_versioned
  internal mutating func _nativeNext() -> ${Sequence}? {
    switch _state {
    case ._native(let startIndex, let endIndex, let buffer):
      if startIndex == endIndex {
        return nil
      }
      let result = buffer.assertingGet(startIndex)
      _state =
        ._native(start: buffer.index(after: startIndex), end: endIndex, buffer: buffer)
      return result
    case ._cocoa:
      _sanityCheckFailure("internal error: not backed by NS${Self}")
    }
  }

  /// Advances to the next element and returns it, or `nil` if no next element
  /// exists.
  ///
  /// Once `nil` has been returned, all subsequent calls return `nil`.
  @inline(__always)
  public mutating func next() -> ${Sequence}? {
    if _fastPath(_guaranteedNative) {
      return _nativeNext()
    }

    switch _state {
    case ._native:
      return _nativeNext()
    case ._cocoa(let cocoaIterator):
#if _runtime(_ObjC)
%if Self == 'Set':
      if let anyObjectElement = cocoaIterator.next() {
        return _forceBridgeFromObjectiveC(anyObjectElement, Element.self)
      }
%elif Self == 'Dictionary':
      if let (anyObjectKey, anyObjectValue) = cocoaIterator.next() {
        let nativeKey = _forceBridgeFromObjectiveC(anyObjectKey, Key.self)
        let nativeValue = _forceBridgeFromObjectiveC(anyObjectValue, Value.self)
        return (nativeKey, nativeValue)
      }
%end
      return nil
#else
      _sanityCheckFailure("internal error: unexpected cocoa ${Self}")
#endif
    }
  }
}

extension ${Self}Iterator : CustomReflectable {
  /// A mirror that reflects the iterator.
  public var customMirror: Mirror {
    return Mirror(
      self,
      children: EmptyCollection<(label: String?, value: Any)>())
  }
}

extension ${Self} : CustomReflectable {
  /// A mirror that reflects the ${a_self}.
  public var customMirror: Mirror {
%if Self == 'Set':
    let style = Mirror.DisplayStyle.`set`
%elif Self == 'Dictionary':
    let style = Mirror.DisplayStyle.dictionary
%end
    return Mirror(self, unlabeledChildren: self, displayStyle: style)
  }
}

/// Initializes a `${Self}` from unique members.
///
/// Using a builder can be faster than inserting members into an empty
/// `${Self}`.
public struct _${Self}Builder<${TypeParametersDecl}> {
%if Self == 'Set':
  public typealias Key = ${TypeParameters}
  public typealias Value = ${TypeParameters}
%end

  internal var _result: ${Self}<${TypeParameters}>
  internal var _nativeBuffer: _Native${Self}Buffer<${TypeParameters}>
  internal let _requestedCount: Int
  internal var _actualCount: Int

  public init(count: Int) {
    let requiredCapacity =
      _Native${Self}Buffer<${TypeParameters}>.minimumCapacity(
        minimumCount: count,
        maxLoadFactorInverse: _hashContainerDefaultMaxLoadFactorInverse)
    _result = ${Self}<${TypeParameters}>(minimumCapacity: requiredCapacity)
    _nativeBuffer = _result._variantBuffer.asNative
    _requestedCount = count
    _actualCount = 0
  }

%if Self == 'Set':
  public mutating func add(member newKey: Key) {
    _nativeBuffer.unsafeAddNew(key: newKey)
    _actualCount += 1
  }
%elif Self == 'Dictionary':
  public mutating func add(key newKey: Key, value: Value) {
    _nativeBuffer.unsafeAddNew(key: newKey, value: value)
    _actualCount += 1
  }
%end

  public mutating func take() -> ${Self}<${TypeParameters}> {
    _precondition(_actualCount >= 0,
      "cannot take the result twice")
    _precondition(_actualCount == _requestedCount,
      "the number of members added does not match the promised count")

    // Finish building the `${Self}`.
    _nativeBuffer.count = _requestedCount

    // Prevent taking the result twice.
    _actualCount = -1
    return _result
  }
}

extension ${Self} {
%if Self == 'Set':
  /// Removes and returns the first element of the set.
  ///
  /// Because a set is not an ordered collection, the "first" element may not
  /// be the first element that was added to the set.
  ///
  /// - Returns: A member of the set. If the set is empty, returns `nil`.
%elif Self == 'Dictionary':
  /// Removes and returns the first key-value pair of the dictionary if the
  /// dictionary isn't empty.
  ///
  /// The first element of the dictionary is not necessarily the first element
  /// added. Don't expect any particular ordering of key-value pairs.
  ///
  /// - Returns: The first key-value pair of the dictionary if the dictionary
  ///   is not empty; otherwise, `nil`.
  ///
  /// - Complexity: Averages to O(1) over many calls to `popFirst()`.
%end
  @_inlineable
  public mutating func popFirst() -> Element? {
    guard !isEmpty else { return nil }
    return remove(at: startIndex)
  }
}

//===--- Bridging ---------------------------------------------------------===//

#if _runtime(_ObjC)
extension ${Self} {
  public func _bridgeToObjectiveCImpl() -> _NS${Self}Core {
    switch _variantBuffer {
    case _Variant${Self}Buffer.native(let buffer):
      return buffer.bridged()
    case _Variant${Self}Buffer.cocoa(let cocoaBuffer):
      return cocoaBuffer.cocoa${Self}
    }
  }

  /// Returns the native Dictionary hidden inside this NSDictionary;
  /// returns nil otherwise.
  public static func _bridgeFromObjectiveCAdoptingNativeStorageOf(
    _ s: AnyObject
  ) -> ${Self}<${TypeParameters}>? {

    // Try all three NS${Self} impls that we currently provide.

    if let deferredBuffer = s as? _SwiftDeferredNS${Self}<${TypeParameters}> {
      return ${Self}(_nativeBuffer: deferredBuffer.nativeBuffer)
    }

    if let nativeStorage = s as? _HashableTypedNative${Self}Storage<${TypeParameters}> {
      return ${Self}(_nativeBuffer: 
          _Native${Self}Buffer(_storage: nativeStorage))
    }

    if s === _RawNative${Self}Storage.empty {
      return ${Self}()
    }
    
    // FIXME: what if `s` is native storage, but for different key/value type?
    return nil
  }
}
#endif

%end

extension Set {
  /// Removes the elements of the given set from this set.
  ///
  /// In the following example, the elements of the `employees` set that are
  /// also members of the `neighbors` set are removed. In particular, the
  /// names `"Bethany"` and `"Eric"` are removed from `employees`.
  ///
  ///     var employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let neighbors: Set = ["Bethany", "Eric", "Forlani", "Greta"]
  ///     employees.subtract(neighbors)
  ///     print(employees)
  ///     // Prints "["Diana", "Chris", "Alicia"]"
  ///
  /// - Parameter other: Another set.
  public mutating func subtract(_ other: Set<Element>) {
    _subtract(other)
  }

  /// Returns a Boolean value that indicates whether this set is a subset of
  /// the given set.
  ///
  /// Set *A* is a subset of another set *B* if every member of *A* is also a
  /// member of *B*.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let attendees: Set = ["Alicia", "Bethany", "Diana"]
  ///     print(attendees.isSubset(of: employees))
  ///     // Prints "true"
  ///
  /// - Parameter other: Another set.
  /// - Returns: `true` if the set is a subset of `other`; otherwise, `false`.
  @_inlineable
  public func isSubset(of other: Set<Element>) -> Bool {
    let (isSubset, isEqual) = _compareSets(self, other)
    return isSubset || isEqual
  }

  /// Returns a Boolean value that indicates whether this set is a superset of
  /// the given set.
  ///
  /// Set *A* is a superset of another set *B* if every member of *B* is also a
  /// member of *A*.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let attendees: Set = ["Alicia", "Bethany", "Diana"]
  ///     print(employees.isSuperset(of: attendees))
  ///     // Prints "true"
  ///
  /// - Parameter other: Another set.
  /// - Returns: `true` if the set is a superset of `other`; otherwise,
  ///   `false`.
  @_inlineable
  public func isSuperset(of other: Set<Element>) -> Bool {
    return other.isSubset(of: self)
  }

  /// Returns a Boolean value that indicates whether this set has no members in
  /// common with the given set.
  ///
  /// In the following example, the `employees` set is disjoint with the
  /// `visitors` set because no name appears in both sets.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let visitors: Set = ["Marcia", "Nathaniel", "Olivia"]
  ///     print(employees.isDisjoint(with: visitors))
  ///     // Prints "true"
  ///
  /// - Parameter other: Another set.
  /// - Returns: `true` if the set has no elements in common with `other`;
  ///   otherwise, `false`.
  @_inlineable
  public func isDisjoint(with other: Set<Element>) -> Bool {
    for member in self {
      if other.contains(member) {
        return false
      }
    }
    return true
  }

  /// Returns a new set containing the elements of this set that do not occur
  /// in the given set.
  ///
  /// In the following example, the `nonNeighbors` set is made up of the
  /// elements of the `employees` set that are not elements of `neighbors`:
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let neighbors: Set = ["Bethany", "Eric", "Forlani", "Greta"]
  ///     let nonNeighbors = employees.subtracting(neighbors)
  ///     print(nonNeighbors)
  ///     // Prints "["Diana", "Chris", "Alicia"]"
  ///
  /// - Parameter other: Another set.
  /// - Returns: A new set.
  @_inlineable
  public func subtracting(_ other: Set<Element>) -> Set<Element> {
    return self._subtracting(other)
  }

  /// Returns a Boolean value that indicates whether the set is a strict
  /// superset of the given sequence.
  ///
  /// Set *A* is a strict superset of another set *B* if every member of *B* is
  /// also a member of *A* and *A* contains at least one element that is *not*
  /// a member of *B*.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let attendees: Set = ["Alicia", "Bethany", "Diana"]
  ///     print(employees.isStrictSuperset(of: attendees))
  ///     // Prints "true"
  ///     print(employees.isStrictSuperset(of: employees))
  ///     // Prints "false"
  ///
  /// - Parameter other: Another set.
  /// - Returns: `true` if the set is a strict superset of
  ///   `other`; otherwise, `false`.
  @_inlineable
  public func isStrictSuperset(of other: Set<Element>) -> Bool {
    return self.isSuperset(of: other) && self != other
  }

  /// Returns a Boolean value that indicates whether the set is a strict subset
  /// of the given sequence.
  ///
  /// 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 employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let attendees: Set = ["Alicia", "Bethany", "Diana"]
  ///     print(attendees.isStrictSubset(of: employees))
  ///     // Prints "true"
  ///
  ///     // A set is never a strict subset of itself:
  ///     print(attendees.isStrictSubset(of: attendees))
  ///     // Prints "false"
  ///
  /// - Parameter other: Another set.
  /// - Returns: `true` if the set is a strict subset of
  ///   `other`; otherwise, `false`.
  @_inlineable
  public func isStrictSubset(of other: Set<Element>) -> Bool {
    return other.isStrictSuperset(of: self)
  }

  /// Returns a new set with the elements that are common to both this set and
  /// the given sequence.
  ///
  /// In the following example, the `bothNeighborsAndEmployees` set is made up
  /// of the elements that are in *both* the `employees` and `neighbors` sets.
  /// Elements that are in only one or the other are left out of the result of
  /// the intersection.
  ///
  ///     let employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let neighbors: Set = ["Bethany", "Eric", "Forlani", "Greta"]
  ///     let bothNeighborsAndEmployees = employees.intersection(neighbors)
  ///     print(bothNeighborsAndEmployees)
  ///     // Prints "["Bethany", "Eric"]"
  ///
  /// - Parameter other: Another set.
  /// - Returns: A new set.
  @_inlineable
  public func intersection(_ other: Set<Element>) -> Set<Element> {
    var newSet = Set<Element>()
    for member in self {
      if other.contains(member) {
        newSet.insert(member)
      }
    }
    return newSet
  }

  /// Removes the elements of the set that are also in the given sequence and
  /// adds the members of the sequence that are not already in the set.
  ///
  /// In the following example, the elements of the `employees` set that are
  /// also members of `neighbors` are removed from `employees`, while the
  /// elements of `neighbors` that are not members of `employees` are added to
  /// `employees`. In particular, the names `"Alicia"`, `"Chris"`, and
  /// `"Diana"` are removed from `employees` while the names `"Forlani"` and
  /// `"Greta"` are added.
  ///
  ///     var employees: Set = ["Alicia", "Bethany", "Chris", "Diana", "Eric"]
  ///     let neighbors: Set = ["Bethany", "Eric", "Forlani", "Greta"]
  ///     employees.formSymmetricDifference(neighbors)
  ///     print(employees)
  ///     // Prints "["Diana", "Chris", "Forlani", "Alicia", "Greta"]"
  ///
  /// - Parameter other: Another set.
  @_inlineable
  public mutating func formSymmetricDifference(_ other: Set<Element>) {
    for member in other {
      if contains(member) {
        remove(member)
      } else {
        insert(member)
      }
    }
  }
}

extension Set {
  @available(*, unavailable, renamed: "remove(at:)")
  public mutating func removeAtIndex(_ index: Index) -> Element {
    Builtin.unreachable()
  }

  @available(*, unavailable, renamed: "makeIterator()")
  public func generate() -> SetIterator<Element> {
    Builtin.unreachable()
  }

  @available(*, unavailable, renamed: "index(of:)")
  public func indexOf(_ member: Element) -> Index? {
    Builtin.unreachable()
  }
}

extension Dictionary {
  @available(*, unavailable, renamed: "remove(at:)")
  public mutating func removeAtIndex(_ index: Index) -> Element {
    Builtin.unreachable()
  }

  @available(*, unavailable, renamed: "index(forKey:)")
  public func indexForKey(_ key: Key) -> Index? {
    Builtin.unreachable()
  }

  @available(*, unavailable, renamed: "removeValue(forKey:)")
  public mutating func removeValueForKey(_ key: Key) -> Value? {
    Builtin.unreachable()
  }

  @available(*, unavailable, renamed: "makeIterator()")
  public func generate() -> DictionaryIterator<Key, Value> {
    Builtin.unreachable()
  }
}
