Convenience functions for sum and product across a Collection type

Here’s an idea for integers.

We can count the number of overflows (with sign), and if it is zero then the sum using wrapping arithmetic is correct:

extension Sequence where Element: FixedWidthInteger & SignedInteger {
  func sum() -> Element {
    var result: Element = 0
    var overflow: Bool = false
    var totalOverflow: Int = 0

    for x in self {
      (result, overflow) = result.addingReportingOverflow(x)
      if overflow {
        totalOverflow += (x < 0) ? -1 : 1
      }
    }
    
    precondition(totalOverflow == 0)
    return result
  }
}

Of course, integers that are unsigned or variable-width can use the simple version:

extension Sequence where Element: BinaryInteger {
  func sum() -> Element {
    return self.reduce(0, +)
  }
}
3 Likes