Skip to content

Commit 8667046

Browse files
author
Joe Newton
committed
Added support for Linux
1 parent 2389c34 commit 8667046

17 files changed

+398
-143
lines changed

.github/workflows/swift.yml

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
name: Swift
22

3-
on: [push]
3+
on: [push, pull_request]
44

55
jobs:
66
build:
7-
8-
runs-on: macOS-latest
9-
7+
strategy:
8+
matrix:
9+
os: [macOS-latest, ubuntu-latest]
10+
swift: ["5.1"]
11+
runs-on: ${{ matrix.os }}
12+
env:
13+
SWIFT_VERSION: ${{ matrix.swift }}
14+
SWIFT_EXEC: .swiftenv/shims/swift
1015
steps:
1116
- uses: actions/checkout@v2
17+
- name: Install Swift
18+
run: |
19+
git clone https://github.com/kylef/swiftenv.git ~/.swiftenv
20+
~/.swiftenv/bin/swiftenv install $SWIFT_VERSION --skip-existing
21+
~/.swiftenv/bin/swiftenv rehash
1222
- name: Build
13-
run: swift build -v
14-
- name: Run Tests
15-
run: swift test -v
23+
run: |
24+
~/$SWIFT_EXEC --version
25+
~/$SWIFT_EXEC build -v
26+
- name: Test
27+
run: |
28+
~/$SWIFT_EXEC test -v

.swiftlint.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ opt_in_rules:
5757

5858
reporter: "xcode"
5959

60+
excluded:
61+
- Tests/LinuxMain.swift
62+
- Tests/ComplexTests/XCTestManifests.swift
63+
6064
identifier_name:
6165
excluded:
6266
- i

Complex.podspec

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ Pod::Spec.new do |s|
1818

1919
s.source = { :git => "https://github.com/SomeRandomiOSDev/Complex.git", :tag => s.version.to_s }
2020
s.source_files = 'Sources/**/*.swift'
21-
s.frameworks = 'Foundation'
22-
s.swift_versions = ['4.0', '4.2', '5.0']
21+
s.swift_versions = ['4.2', '5.0']
2322
s.cocoapods_version = '>= 1.7.3'
2423

2524
end

Complex.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
DDB8126F23FA2C210079FEB5 /* Functions.swift.gyb */ = {isa = PBXFileReference; explicitFileType = text.script.python; path = Functions.swift.gyb; sourceTree = "<group>"; };
173173
DDB8127123FA4DA50079FEB5 /* ATTRIBUTIONS */ = {isa = PBXFileReference; lastKnownFileType = text; path = ATTRIBUTIONS; sourceTree = "<group>"; };
174174
DDB8128523FB1A430079FEB5 /* FunctionsTests.swift.gyb */ = {isa = PBXFileReference; explicitFileType = text.script.python; path = FunctionsTests.swift.gyb; sourceTree = "<group>"; };
175+
DDC7FF972412922500A5832A /* Package@swift-4.2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Package@swift-4.2.swift"; sourceTree = "<group>"; };
175176
DDFEEC3323EF13900096015C /* Complex.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Complex.framework; sourceTree = BUILT_PRODUCTS_DIR; };
176177
DDFEEC3723EF13900096015C /* Complex-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Complex-Info.plist"; path = "Info/Complex-Info.plist"; sourceTree = "<group>"; };
177178
DDFEEC3C23EF13910096015C /* ComplexTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ComplexTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -325,6 +326,7 @@
325326
children = (
326327
DDFEECAB23F1BA550096015C /* Complex.podspec */,
327328
DDFEECAC23F1BA550096015C /* Package.swift */,
329+
DDC7FF972412922500A5832A /* Package@swift-4.2.swift */,
328330
DD6F08D02400808300749359 /* codecov.yml */,
329331
DDFEECAE23F1BA5E0096015C /* .swiftlint.yml */,
330332
DDFEECAD23F1BA5E0096015C /* .travis.yml */,

Package@swift-4.2.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// swift-tools-version:4.2
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "Complex",
6+
7+
products: [
8+
.library(name: "Complex", targets: ["Complex"])
9+
],
10+
11+
dependencies: [
12+
.package(url: "https://github.com/SomeRandomiOSDev/Half", from: "1.2.0")
13+
],
14+
15+
targets: [
16+
.target(name: "Complex"),
17+
.testTarget(name: "ComplexTests", dependencies: ["Complex", "Half"])
18+
],
19+
20+
swiftLanguageVersions: [.v4_2]
21+
)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Complex
55
[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/Complex.svg)](https://cocoapods.org/pods/Complex)
66
[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
77
[![Platform](https://img.shields.io/cocoapods/p/Complex.svg)](https://cocoapods.org/pods/Complex)
8+
![Linux](https://img.shields.io/badge/platform-linux-lightgrey)
89
[![Build](https://travis-ci.com/SomeRandomiOSDev/Complex.svg?branch=master)](https://travis-ci.com/SomeRandomiOSDev/Complex)
910
![Swift](https://github.com/SomeRandomiOSDev/Complex/workflows/Swift/badge.svg)
1011
[![Code Coverage](https://codecov.io/gh/SomeRandomiOSDev/Complex/branch/master/graph/badge.svg)](https://codecov.io/gh/SomeRandomiOSDev/Complex)

Sources/Complex/Complex.swift

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Foundation
99

1010
// MARK: - Complex Definition
1111

12+
#if swift(>=5.1)
1213
@frozen public struct Complex<Scalar: Numeric> {
1314

1415
// MARK: Public Properties
@@ -19,10 +20,30 @@ import Foundation
1920
// MARK: Initialization
2021

2122
@_transparent
22-
public init(real: Scalar = .zero, imaginary: Scalar = .zero) {
23+
public init(real: Scalar = 0, imaginary: Scalar = 0) {
2324
self.real = real
2425
self.imaginary = imaginary
2526
}
27+
}
28+
#else
29+
public struct Complex<Scalar: Numeric> {
30+
31+
// MARK: Public Properties
32+
33+
public var real: Scalar
34+
public var imaginary: Scalar
35+
36+
// MARK: Initialization
37+
38+
@_transparent
39+
public init(real: Scalar = 0, imaginary: Scalar = 0) {
40+
self.real = real
41+
self.imaginary = imaginary
42+
}
43+
}
44+
#endif // #if swift(>=5.1)
45+
46+
extension Complex {
2647

2748
@_transparent
2849
public init(_ other: Complex<Scalar>) {
@@ -32,7 +53,7 @@ import Foundation
3253

3354
@_transparent
3455
public init() {
35-
self.init(real: .zero, imaginary: .zero)
56+
self.init(real: 0, imaginary: 0)
3657
}
3758
}
3859

@@ -137,7 +158,7 @@ extension Complex where Scalar: FixedWidthInteger {
137158

138159
// MARK: - ExpressibleByArrayLiteral Protocol Conformance
139160

140-
extension Complex: ExpressibleByArrayLiteral where Scalar: AdditiveArithmetic {
161+
extension Complex: ExpressibleByArrayLiteral {
141162

142163
@_transparent
143164
public init(arrayLiteral elements: Scalar...) {
@@ -146,7 +167,7 @@ extension Complex: ExpressibleByArrayLiteral where Scalar: AdditiveArithmetic {
146167
if elements.isEmpty {
147168
self.init()
148169
} else if elements.count == 1 {
149-
self.init(real: elements[0], imaginary: .zero)
170+
self.init(real: elements[0], imaginary: 0)
150171
} else {
151172
self.init(real: elements[0], imaginary: elements[1])
152173
}
@@ -261,7 +282,7 @@ extension Complex where Scalar: FloatingPoint {
261282

262283
@_transparent
263284
public func rounded() -> Complex {
264-
rounded(.toNearestOrAwayFromZero)
285+
return rounded(.toNearestOrAwayFromZero)
265286
}
266287

267288
//
@@ -354,15 +375,15 @@ extension Complex {
354375

355376
@_transparent
356377
public static var i: Complex {
357-
return Complex(real: .zero, imaginary: 1)
378+
return Complex(real: 0, imaginary: 1)
358379
}
359380
}
360381

361382
extension Complex {
362383

363384
@_transparent
364385
public static var one: Complex {
365-
return Complex(real: 1, imaginary: .zero)
386+
return Complex(real: 1, imaginary: 0)
366387
}
367388
}
368389

Sources/Complex/ComplexArithmetic.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@
55
// Copyright © 2020 SomeRandomiOSDev. All rights reserved.
66
//
77

8-
import Foundation
9-
108
//swiftlint:disable shorthand_operator
119

1210
// MARK: - AdditiveArithmetic Protocol Conformance
1311

14-
extension Complex: AdditiveArithmetic {
12+
#if swift(>=5.0)
13+
extension Complex: AdditiveArithmetic { }
14+
#endif
15+
16+
extension Complex {
1517

1618
@_transparent
1719
public static var zero: Complex<Scalar> {
18-
return Complex<Scalar>(real: .zero, imaginary: .zero)
20+
return Complex<Scalar>(real: 0, imaginary: 0)
1921
}
2022

2123
@_transparent
@@ -163,7 +165,7 @@ extension Complex where Scalar: FixedWidthInteger {
163165

164166
@_transparent
165167
public static func &- (lhs: Scalar, rhs: Complex<Scalar>) -> Complex<Scalar> {
166-
return Complex<Scalar>(real: lhs &- rhs.real, imaginary: .zero &- rhs.imaginary)
168+
return Complex<Scalar>(real: lhs &- rhs.real, imaginary: 0 &- rhs.imaginary)
167169
}
168170

169171
@_transparent
@@ -325,7 +327,7 @@ extension Complex where Scalar: SignedInteger {
325327

326328
@_transparent
327329
public static func / (lhs: Scalar, rhs: Complex<Scalar>) -> Complex<Scalar> {
328-
return Complex<Scalar>(real: lhs, imaginary: .zero) / rhs
330+
return Complex<Scalar>(real: lhs, imaginary: 0) / rhs
329331
}
330332
}
331333

@@ -355,7 +357,7 @@ extension Complex where Scalar: FloatingPoint {
355357

356358
@_transparent
357359
public static func / (lhs: Scalar, rhs: Complex<Scalar>) -> Complex<Scalar> {
358-
return Complex<Scalar>(real: lhs, imaginary: .zero) / rhs
360+
return Complex<Scalar>(real: lhs, imaginary: 0) / rhs
359361
}
360362

361363
@_transparent

Sources/Complex/ComplexOverflowingArithmetic.swift

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
// Copyright © 2020 SomeRandomiOSDev. All rights reserved.
66
//
77

8-
import Foundation
9-
108
// MARK: Overflowing Addition
119

1210
extension Complex where Scalar: FixedWidthInteger {
@@ -127,7 +125,7 @@ extension Complex where Scalar: FixedWidthInteger {
127125
//swiftlint:disable identifier_name
128126
public func dividedReportingOverflow(by rhs: Complex<Scalar>) -> (partialValue: Complex<Scalar>, overflow: Bool) {
129127
// (a + bi) / (c + di) -> ((ac + bd) + (bc - ad)i) / (c^2 + d^2)
130-
guard rhs.real != .zero || rhs.imaginary != .zero else { return (rhs, true) }
128+
guard rhs.real != 0 || rhs.imaginary != 0 else { return (rhs, true) }
131129

132130
let ac = self.real.multipliedFullWidth(by: rhs.real)
133131
let ad = self.real.multipliedFullWidth(by: rhs.imaginary)
@@ -162,12 +160,12 @@ extension Complex where Scalar: FixedWidthInteger, Scalar: SignedInteger {
162160
let a = (high: (high: dividend.high.high.real, low: dividend.high.low.real), low: (high: dividend.low.high.real, low: dividend.low.low.real))
163161
let b = (high: (high: dividend.high.high.imaginary, low: dividend.high.low.imaginary), low: (high: dividend.low.high.imaginary, low: dividend.low.low.imaginary))
164162

165-
let ac = Complex<Scalar>.slowpathMultiply(real, a)
166-
let ad = Complex<Scalar>.slowpathMultiply(imaginary, a)
167-
let bc = Complex<Scalar>.slowpathMultiply(real, b)
168-
let bd = Complex<Scalar>.slowpathMultiply(imaginary, b)
169-
let cc = Complex<Scalar>.signExtend(real.multipliedFullWidth(by: real))
170-
let dd = Complex<Scalar>.signExtend(imaginary.multipliedFullWidth(by: imaginary))
163+
let ac = Complex<Scalar>.slowpathMultiply(self.real, a)
164+
let ad = Complex<Scalar>.slowpathMultiply(self.imaginary, a)
165+
let bc = Complex<Scalar>.slowpathMultiply(self.real, b)
166+
let bd = Complex<Scalar>.slowpathMultiply(self.imaginary, b)
167+
let cc = Complex<Scalar>.signExtend(self.real.multipliedFullWidth(by: self.real))
168+
let dd = Complex<Scalar>.signExtend(self.imaginary.multipliedFullWidth(by: self.imaginary))
171169

172170
let real = Complex<Scalar>.add(ac, bd)
173171
let imaginary = Complex<Scalar>.subtract(bc, ad)
@@ -197,7 +195,7 @@ extension Complex where Scalar: FixedWidthInteger {
197195
//
198196

199197
internal static func signExtend(_ value: Scalar) -> ExtendedScalar {
200-
let highHigh = (Scalar.isSigned && value.leadingZeroBitCount == 0) ? ~Scalar.zero : Scalar.zero
198+
let highHigh = (Scalar.isSigned && value.leadingZeroBitCount == 0) ? ~Scalar(0) : Scalar(0)
201199
let highLow = Scalar.Magnitude(truncatingIfNeeded: highHigh)
202200
let lowHigh = Scalar.Magnitude(truncatingIfNeeded: highLow)
203201
let lowLow = Scalar.Magnitude(truncatingIfNeeded: value)
@@ -206,7 +204,7 @@ extension Complex where Scalar: FixedWidthInteger {
206204
}
207205

208206
internal static func signExtend(_ value: (high: Scalar, low: Scalar.Magnitude)) -> ExtendedScalar {
209-
let highHigh = (Scalar.isSigned && value.high.leadingZeroBitCount == 0) ? ~Scalar.zero : Scalar.zero
207+
let highHigh = (Scalar.isSigned && value.high.leadingZeroBitCount == 0) ? ~Scalar(0) : Scalar(0)
210208
let highLow = Scalar.Magnitude(truncatingIfNeeded: highHigh)
211209
let lowHigh = Scalar.Magnitude(truncatingIfNeeded: value.high)
212210
let lowLow = value.low
@@ -276,10 +274,10 @@ extension Complex where Scalar: FixedWidthInteger {
276274
internal static func slowpathMultiply(_ lhs: ExtendedScalar, _ rhs: ExtendedScalar) -> ExtendedScalar {
277275
var result: ExtendedScalar = ((0, 0), (0, 0))
278276

279-
let lhsIsNegative = Scalar.isSigned && lhs.high.high < .zero
277+
let lhsIsNegative = Scalar.isSigned && lhs.high.high < 0
280278
let left = lhsIsNegative ? twosComplement(of: lhs) : lhs
281279

282-
let rhsIsNegative = Scalar.isSigned && rhs.high.high < .zero
280+
let rhsIsNegative = Scalar.isSigned && rhs.high.high < 0
283281
let right = rhsIsNegative ? twosComplement(of: rhs) : rhs
284282

285283
let (leftIsPowerOfTwo, lhsShift) = isPowerOfTwo(left)
@@ -295,7 +293,7 @@ extension Complex where Scalar: FixedWidthInteger {
295293
var shifted = right
296294
var bits = left
297295

298-
while bits.low.low != .zero || bits.low.high != .zero || bits.high.low != .zero || bits.high.high != .zero {
296+
while bits.low.low != 0 || bits.low.high != 0 || bits.high.low != 0 || bits.high.high != 0 {
299297
if (bits.low.low & 1) == 1 {
300298
shifted = leftShift(shifted, by: shift - lastShift)
301299
result = add(result, shifted)
@@ -316,7 +314,7 @@ extension Complex where Scalar: FixedWidthInteger {
316314
}
317315

318316
internal static func slowpathMultiply(_ lhs: Scalar, _ rhs: ExtendedScalar) -> ExtendedScalar {
319-
let lhsIsNegative = lhs < .zero
317+
let lhsIsNegative = lhs < 0
320318

321319
let extended = signExtend(lhs)
322320
var result = slowpathMultiply(lhsIsNegative ? twosComplement(of: extended) : extended, rhs)
@@ -329,10 +327,10 @@ extension Complex where Scalar: FixedWidthInteger {
329327
}
330328

331329
internal static func slowpathDivide(_ lhs: ExtendedScalar, _ rhs: ExtendedScalar) -> (quotient: ExtendedScalar, remainder: ExtendedScalar) {
332-
let dividendIsNegative = Scalar.isSigned && lhs.high.high < .zero
330+
let dividendIsNegative = Scalar.isSigned && lhs.high.high < 0
333331
var dividend = dividendIsNegative ? twosComplement(of: lhs) : lhs
334332

335-
let divisorIsNegative = Scalar.isSigned && rhs.high.high < .zero
333+
let divisorIsNegative = Scalar.isSigned && rhs.high.high < 0
336334
var divisor = divisorIsNegative ? twosComplement(of: rhs) : rhs
337335

338336
guard isLessThanOrEqual(divisor, to: dividend) else { return (quotient: ((0, 0), (0, 0)), remainder: lhs) }
@@ -469,7 +467,7 @@ extension Complex where Scalar: FixedWidthInteger {
469467
var bits = value
470468
var shift: Scalar.Magnitude = 0
471469

472-
while bits.low.low > 1 || bits.low.high != .zero || bits.high.low != .zero || bits.high.high != .zero {
470+
while bits.low.low > 1 || bits.low.high != 0 || bits.high.low != 0 || bits.high.high != 0 {
473471
bits = rightShift(bits, by: 1)
474472
shift += 1
475473
}
@@ -520,13 +518,13 @@ extension Complex where Scalar: FixedWidthInteger {
520518
// non-zero or if the most significant bit of the least significant word
521519
// is 1.
522520

523-
if value.high.high < .zero {
521+
if value.high.high < 0 {
524522
if value.high.high.nonzeroBitCount != Scalar.bitWidth || value.high.low.nonzeroBitCount != Scalar.bitWidth || value.low.high.nonzeroBitCount != Scalar.bitWidth {
525523
overflow = true
526524
} else if value.low.low.leadingZeroBitCount > 0 {
527525
overflow = true
528526
}
529-
} else if value.high.high != .zero || value.high.low != .zero || value.low.high != .zero {
527+
} else if value.high.high != 0 || value.high.low != 0 || value.low.high != 0 {
530528
overflow = true
531529
} else if value.low.low.leadingZeroBitCount == 0 {
532530
overflow = true
@@ -535,7 +533,7 @@ extension Complex where Scalar: FixedWidthInteger {
535533
// For unsigned integers overflow occurs when the any of the three most significant
536534
// words are non-zero.
537535

538-
overflow = (value.high.high > .zero) || (value.high.low > .zero) || (value.low.high > .zero)
536+
overflow = (value.high.high > 0) || (value.high.low > 0) || (value.low.high > 0)
539537
}
540538

541539
return (partialValue, overflow)

0 commit comments

Comments
 (0)