func emitTupleStruct()

in Sources/VariadicsGenerator/VariadicsGenerator.swift [142:206]


  func emitTupleStruct(arity: Int) {
    output("""
      @frozen @dynamicMemberLookup
      public struct Tuple\(arity)<
      """)
    outputForEach(0..<arity, separator: ", ") {
      "_\($0)"
    }
    output("> {")
    // `public typealias Tuple = (_0, ...)`
    output("\n  public typealias Tuple = (")
    outputForEach(0..<arity, separator: ", ") { "_\($0)" }
    output(")")
    // `public var tuple: Tuple`
    output("\n  public var tuple: Tuple\n")
    // `subscript(dynamicMember:)`
    output("""
        public subscript<T>(dynamicMember keyPath: WritableKeyPath<Tuple, T>) -> T {
          get { tuple[keyPath: keyPath] }
          _modify { yield &tuple[keyPath: keyPath] }
        }
      """)
    output("\n}\n")
    output("extension Tuple\(arity): \(emptyProtocolName) where ")
    outputForEach(1..<arity, separator: ", ") {
      "_\($0): \(emptyProtocolName)"
    }
    output(" {}\n")
    output("extension Tuple\(arity): MatchProtocol {\n")
    output("  public typealias Capture = ")
    if arity == 2 {
      output("_1")
    } else {
      output("Tuple\(arity-1)<")
      outputForEach(1..<arity, separator: ", ") {
        "_\($0)"
      }
      output(">")
    }
    output("\n  public init(_ tuple: Tuple) { self.tuple = tuple }")
    // `public init(_0: _0, ...) { ... }`
    output("\n  public init(")
    outputForEach(0..<arity, separator: ", ") {
      "_ _\($0): _\($0)"
    }
    output(") {\n")
    output("    self.init((")
    outputForEach(0..<arity, separator: ", ") { "_\($0)" }
    output("))\n")
    output("  }")
    output("\n}\n")
    // Equatable
    output("extension Tuple\(arity): Equatable where ")
    outputForEach(0..<arity, separator: ", ") {
      "_\($0): Equatable"
    }
    output(" {\n")
    output("  public static func == (lhs: Self, rhs: Self) -> Bool {\n")
    output("    ")
    outputForEach(0..<arity, separator: " && ") {
      "lhs.tuple.\($0) == rhs.tuple.\($0)"
    }
    output("\n  }\n")
    output("}\n")
  }