Skip to content

Commit

Permalink
Made all numeric types support protocol Codable.
Browse files Browse the repository at this point in the history
  • Loading branch information
objecthub committed Feb 8, 2020
1 parent ebb6c28 commit 4df321e
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 18 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 2.3.3 (2020-02-09)
- Made all numeric types support protocol `Codable`
- Migrated project to Xcode 11.3

## 2.3.2 (2019-10-20)
- Migrated project to Xcode 11.1
- Removed non-shared scheme from project
Expand Down
8 changes: 6 additions & 2 deletions NumberKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
CC99F56C1B7AA81500355E1E /* BigInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC99F56B1B7AA81500355E1E /* BigInt.swift */; };
CC99F56E1B7AAAA300355E1E /* NumberUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC99F56D1B7AAAA300355E1E /* NumberUtil.swift */; };
CC99F5701B7AAB5300355E1E /* NumberUtilTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC99F56F1B7AAB5300355E1E /* NumberUtilTests.swift */; };
CCA2651723EF73B700483329 /* CodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA2651623EF73B700483329 /* CodableTests.swift */; };
CCA8E8111F7780C800927A41 /* FloatingPointNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA8E8101F7780C800927A41 /* FloatingPointNumber.swift */; };
CCA8E8131F77814F00927A41 /* IntegerNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA8E8121F77814F00927A41 /* IntegerNumber.swift */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -48,6 +49,7 @@
CC99F56F1B7AAB5300355E1E /* NumberUtilTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberUtilTests.swift; sourceTree = "<group>"; };
CC99F5711B7AB5E600355E1E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
CC99F5721B7AB66E00355E1E /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
CCA2651623EF73B700483329 /* CodableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableTests.swift; sourceTree = "<group>"; };
CCA8E8101F7780C800927A41 /* FloatingPointNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatingPointNumber.swift; sourceTree = "<group>"; };
CCA8E8121F77814F00927A41 /* IntegerNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegerNumber.swift; sourceTree = "<group>"; };
CCB691501EB7710700B32D55 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -122,6 +124,7 @@
CC99F5691B7AA76600355E1E /* BigIntTests.swift */,
CC07415A1B813A0600406A43 /* RationalTests.swift */,
CC07415C1B813B0300406A43 /* ComplexTests.swift */,
CCA2651623EF73B700483329 /* CodableTests.swift */,
CC5E473320C428D500F21B03 /* LinuxMain.swift */,
CC99F5601B7AA6E200355E1E /* Info.plist */,
);
Expand Down Expand Up @@ -255,6 +258,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CCA2651723EF73B700483329 /* CodableTests.swift in Sources */,
CC07415D1B813B0300406A43 /* ComplexTests.swift in Sources */,
CC99F5701B7AAB5300355E1E /* NumberUtilTests.swift in Sources */,
CC99F56A1B7AA76600355E1E /* BigIntTests.swift in Sources */,
Expand Down Expand Up @@ -397,7 +401,7 @@
INFOPLIST_FILE = "$(SRCROOT)/Sources/NumberKit/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 2.3.2;
MARKETING_VERSION = 2.3.3;
PRODUCT_BUNDLE_IDENTIFIER = net.objecthub.NumberKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
Expand All @@ -419,7 +423,7 @@
INFOPLIST_FILE = "$(SRCROOT)/Sources/NumberKit/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 2.3.2;
MARKETING_VERSION = 2.3.3;
PRODUCT_BUNDLE_IDENTIFIER = net.objecthub.NumberKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
<p>
<a href="https://developer.apple.com/osx/"><img src="https://img.shields.io/badge/Platform-macOS-blue.svg?style=flat" alt="Platform: macOS" /></a>
<a href="https://developer.apple.com/swift/"><img src="https://img.shields.io/badge/Language-Swift%205.1-green.svg?style=flat" alt="Language: Swift 5.1" /></a>
<a href="https://developer.apple.com/xcode/"><img src="https://img.shields.io/badge/IDE-Xcode%2011.1-orange.svg?style=flat" alt="IDE: Xcode 11.1" /></a>
<a href="https://developer.apple.com/xcode/"><img src="https://img.shields.io/badge/IDE-Xcode%2011.3-orange.svg?style=flat" alt="IDE: Xcode 11.3" /></a>
<a href="https://raw.githubusercontent.com/objecthub/swift-lispkit/master/LICENSE"><img src="http://img.shields.io/badge/License-Apache-lightgrey.svg?style=flat" alt="License: Apache" /></a>
</p>


## Overview

This is a framework implementing advanced numeric data types for the Swift programming
Expand All @@ -17,7 +18,7 @@ language. Currently, the framework provides three new numeric types, each repres
3. `Complex`: complex floating-point numbers

**Requirements**:
- Xcode 11.1
- Xcode 11.3
- Swift 5.1
- macOS with Xcode or Swift Package Manager
- Linux with Swift Package Manager
Expand Down
7 changes: 7 additions & 0 deletions Sources/NumberKit/BigInt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,16 @@ import Foundation
/// representing a `UInt64` value as a `BigInt` will result in an object that
/// requires more memory than the corresponding `UInt64` integer.
public struct BigInt: Hashable,
Codable,
CustomStringConvertible,
CustomDebugStringConvertible {

// Redefine the coding key names.
enum CodingKeys: String, CodingKey {
case uwords = "words"
case negative
}

// This is an array of `UInt32` words. The lowest significant word comes first in
// the array.
private let uwords: ContiguousArray<UInt32>
Expand Down
18 changes: 14 additions & 4 deletions Sources/NumberKit/Complex.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ public protocol ComplexNumber: Equatable {
/// implement a complex number as it does not define interfaces for trigonometric
/// functions.
public struct Complex<T: FloatingPointNumber>: ComplexNumber,
Hashable,
ExpressibleByIntegerLiteral,
ExpressibleByFloatLiteral,
CustomStringConvertible {
Hashable,
ExpressibleByIntegerLiteral,
ExpressibleByFloatLiteral,
CustomStringConvertible {

/// The real part of thix complex number.
public let re: T
Expand Down Expand Up @@ -569,3 +569,13 @@ public func atanh<C: ComplexNumber>(_ z: C) -> C {
return log(x.divided(by: y)).divided(by: C.Float(2))
}

/// This extension implements the logic to make `Complex<T>` codable if `T` is codable.
extension Complex: Codable where T: Codable {

// Make coding key names explicit to avoid automatic extension.
enum CodingKeys: String, CodingKey {
case re = "real"
case im = "imaginary"
}

}
2 changes: 1 addition & 1 deletion Sources/NumberKit/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015–2019 Matthias Zenger. All rights reserved.</string>
<string>Copyright © 2015–2020 Matthias Zenger. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
Expand Down
11 changes: 11 additions & 0 deletions Sources/NumberKit/Rational.swift
Original file line number Diff line number Diff line change
Expand Up @@ -559,5 +559,16 @@ public func != <R: RationalNumber>(lhs: R, rhs: R) -> Bool {
return lhs.compare(to: rhs) != 0
}

/// This extension implements the logic to make `Rational<T>` codable if `T` is codable.
extension Rational: Codable where T: Codable {

// Make coding key names explicit to avoid automatic extension.
enum CodingKeys: String, CodingKey {
case numerator
case denominator
}

}

// TODO: make this a static member of `Rational` once this is supported
private let rationalSeparator: Character = "/"
1 change: 1 addition & 0 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ XCTMain(
testCase(ComplexTests.allTests),
testCase(RationalTests.allTests),
testCase(NumberUtilTests.allTests),
testCase(CodableTests.allTests),
]
)

Expand Down
3 changes: 1 addition & 2 deletions Tests/NumberKitTests/BigIntTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// NumberKit
//
// Created by Matthias Zenger on 11/08/2015.
// Copyright © 2015-2019 Matthias Zenger. All rights reserved.
// Copyright © 2015-2020 Matthias Zenger. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -21,7 +21,6 @@
import XCTest
@testable import NumberKit


class BigIntTests: XCTestCase {

func testConstructors() {
Expand Down
79 changes: 79 additions & 0 deletions Tests/NumberKitTests/CodableTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// CodableTests.swift
// NumberKitTests
//
// Created by Matthias Zenger on 08/02/2020.
// Copyright © 2020 Matthias Zenger. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import XCTest
@testable import NumberKit

class CodableTests: XCTestCase {

func testComplexCodable() {
let c1: Complex<Double> = 987654.41 - 2.0.i
XCTAssertEqual(self.recodeJSON(c1), c1)
let c2: Complex<Double> = 1.5.i
XCTAssertEqual(self.recodeJSON(c2), c2)
let c3: Complex<Double> = 0.0
XCTAssertEqual(self.recodeJSON(c3), c3)
}

func testRationalCodable() {
let r1: Rational<Int> = 7/2
XCTAssertEqual(self.recodeJSON(r1), r1)
let r2: Rational<Int> = 7654321
XCTAssertEqual(self.recodeJSON(r2), r2)
let r3: Rational<Int> = 0
XCTAssertEqual(self.recodeJSON(r3), r3)
}

func testBigIntCodable() {
let x1: BigInt = "811248574598402980294572048572242498127"
XCTAssertEqual(self.recodeJSON(x1), x1)
let x2: BigInt = "847597200"
XCTAssertEqual(self.recodeJSON(x2), x2)
let x3: BigInt = "-75537574353998534693615828134454330968785329792741330257228043492082567"
XCTAssertEqual(self.recodeJSON(x3), x3)
}

private func recodeJSON<T: Codable>(_ obj: T) -> T? {
guard let encodedObj = self.encodeJSON(obj) else {
return nil
}
return self.decodeJSON(type(of: obj), encodedObj)
}

private func encodeJSON<T: Codable>(_ obj: T) -> String? {
guard let encodedObj = try? JSONEncoder().encode(obj) else {
return nil
}
guard let res = String(data: encodedObj, encoding: .utf8) else {
return nil
}
return res
}

private func decodeJSON<T: Codable>(_ type: T.Type, _ str: String) -> T? {
return try? JSONDecoder().decode(type, from: str.data(using: .utf8)!)
}

static let allTests = [
("testComplexCodable", testComplexCodable),
("testRationalCodable", testRationalCodable),
("testBigIntCodable", testBigIntCodable),
]
}
3 changes: 1 addition & 2 deletions Tests/NumberKitTests/ComplexTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// NumberKit
//
// Created by Matthias Zenger on 16/08/2015.
// Copyright © 2015-2019 Matthias Zenger. All rights reserved.
// Copyright © 2015-2020 Matthias Zenger. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -21,7 +21,6 @@
import XCTest
@testable import NumberKit


class ComplexTests: XCTestCase {

func testConstructors() {
Expand Down
4 changes: 3 additions & 1 deletion Tests/NumberKitTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>2.3.2</string>
<string>2.3.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015–2020 Matthias Zenger. All rights reserved.</string>
</dict>
</plist>
3 changes: 1 addition & 2 deletions Tests/NumberKitTests/NumberUtilTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// NumberKit
//
// Created by Matthias Zenger on 12/08/2015.
// Copyright © 2015-2019 Matthias Zenger. All rights reserved.
// Copyright © 2015-2020 Matthias Zenger. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -21,7 +21,6 @@
import XCTest
@testable import NumberKit


class NumberUtilTests: XCTestCase {

func testPow() {
Expand Down
3 changes: 1 addition & 2 deletions Tests/NumberKitTests/RationalTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// NumberKit
//
// Created by Matthias Zenger on 16/08/2015.
// Copyright © 2015-2019 Matthias Zenger. All rights reserved.
// Copyright © 2015-2020 Matthias Zenger. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -21,7 +21,6 @@
import XCTest
@testable import NumberKit


class RationalTests: XCTestCase {

func testConstructors() {
Expand Down

0 comments on commit 4df321e

Please sign in to comment.