Skip to content

Commit 734f4e6

Browse files
committed
Add initialisers and test coverage for Decimal
The Decimal type on Darwin is a packed structure, and so the implementation in Swift needs to follow the same packed layout to ensure that the values are truncated in the same way. Add test coverage for initialisers and verify the same test code passes on Swift on Darwin with the same results.
1 parent d32f2e1 commit 734f4e6

File tree

4 files changed

+160
-10
lines changed

4 files changed

+160
-10
lines changed

Foundation.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
/* Begin PBXBuildFile section */
1010
0383A1751D2E558A0052E5D1 /* TestNSStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0383A1741D2E558A0052E5D1 /* TestNSStream.swift */; };
1111
1520469B1D8AEABE00D02E36 /* HTTPServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1520469A1D8AEABE00D02E36 /* HTTPServer.swift */; };
12+
231503DB1D8AEE5D0061694D /* TestNSDecimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */; };
1213
294E3C1D1CC5E19300E4F44C /* TestNSAttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */; };
1314
2EBE67A51C77BF0E006583D5 /* TestNSDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */; };
1415
528776141BF2629700CB0090 /* FoundationErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522C253A1BF16E1600804FC6 /* FoundationErrors.swift */; };
@@ -455,6 +456,7 @@
455456
0383A1741D2E558A0052E5D1 /* TestNSStream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSStream.swift; sourceTree = "<group>"; };
456457
1520469A1D8AEABE00D02E36 /* HTTPServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPServer.swift; sourceTree = "<group>"; };
457458
22B9C1E01C165D7A00DECFF9 /* TestNSDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDate.swift; sourceTree = "<group>"; };
459+
231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDecimal.swift; sourceTree = "<group>"; };
458460
294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSAttributedString.swift; sourceTree = "<group>"; };
459461
2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDateFormatter.swift; sourceTree = "<group>"; };
460462
400E22641C1A4E58007C5933 /* TestNSProcessInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSProcessInfo.swift; sourceTree = "<group>"; };
@@ -1324,6 +1326,7 @@
13241326
DCDBB8321C1768AC00313299 /* TestNSData.swift */,
13251327
22B9C1E01C165D7A00DECFF9 /* TestNSDate.swift */,
13261328
2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */,
1329+
231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */,
13271330
EA66F63D1BF1619600136161 /* TestNSDictionary.swift */,
13281331
D512D17B1CD883F00032E6A5 /* TestNSFileHandle.swift */,
13291332
525AECEB1BF2C96400D15BB0 /* TestNSFileManager.swift */,
@@ -2216,6 +2219,7 @@
22162219
5B13B33E1C582D4C00651CE2 /* TestNSProcessInfo.swift in Sources */,
22172220
5B13B33F1C582D4C00651CE2 /* TestNSPropertyList.swift in Sources */,
22182221
5B13B32C1C582D4C00651CE2 /* TestNSDate.swift in Sources */,
2222+
231503DB1D8AEE5D0061694D /* TestNSDecimal.swift in Sources */,
22192223
7900433C1CACD33E00ECCBF1 /* TestNSPredicate.swift in Sources */,
22202224
5B13B33B1C582D4C00651CE2 /* TestNSNumberFormatter.swift in Sources */,
22212225
5B13B3301C582D4C00651CE2 /* TestNSHTTPCookie.swift in Sources */,

Foundation/NSDecimal.swift

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,89 @@
11
// This source file is part of the Swift.org open source project
22
//
3-
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
3+
// Copyright (c) 2016 Apple Inc. and the Swift project authors
44
// Licensed under Apache License v2.0 with Runtime Library Exception
55
//
66
// See http://swift.org/LICENSE.txt for license information
77
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
88
//
99

10-
public var NSDecimalMaxSize: Int32 { NSUnimplemented() }
10+
public var NSDecimalMaxSize: Int32 { return 8 }
1111
// Give a precision of at least 38 decimal digits, 128 binary positions.
1212

13-
public var NSDecimalNoScale: Int32 { NSUnimplemented() }
13+
public var NSDecimalNoScale: Int32 { return Int32(Int16.max) }
1414

1515
public struct Decimal {
16-
public var _exponent: Int32
17-
public var _length: UInt32 // length == 0 && isNegative -> NaN
18-
public var _isNegative: UInt32
19-
public var _isCompact: UInt32
20-
public var _reserved: UInt32
16+
fileprivate var __exponent: Int8
17+
fileprivate var __lengthAndFlags: UInt8
18+
fileprivate var __reserved: UInt16
19+
public var _exponent: Int32 {
20+
get {
21+
return Int32(__exponent)
22+
}
23+
set {
24+
__exponent = Int8(truncatingBitPattern: newValue)
25+
}
26+
}
27+
// length == 0 && isNegative -> NaN
28+
public var _length: UInt32 {
29+
get {
30+
return UInt32((__lengthAndFlags & 0b0000_1111))
31+
}
32+
set {
33+
__lengthAndFlags =
34+
(__lengthAndFlags & 0b1111_0000) |
35+
UInt8(newValue & 0b0000_1111)
36+
}
37+
}
38+
public var _isNegative: UInt32 {
39+
get {
40+
return UInt32(((__lengthAndFlags) & 0b0001_0000) >> 4)
41+
}
42+
set {
43+
__lengthAndFlags =
44+
(__lengthAndFlags & 0b1110_1111) |
45+
(UInt8(newValue & 0b0000_0001 ) << 4)
46+
}
47+
}
48+
public var _isCompact: UInt32 {
49+
get {
50+
return UInt32(((__lengthAndFlags) & 0b0010_0000) >> 5)
51+
}
52+
set {
53+
__lengthAndFlags =
54+
(__lengthAndFlags & 0b1101_1111) |
55+
(UInt8(newValue & 0b0000_00001 ) << 5)
56+
}
57+
}
58+
public var _reserved: UInt32 {
59+
get {
60+
return UInt32(UInt32(__lengthAndFlags & 0b1100_0000) << 10 | UInt32(__reserved))
61+
}
62+
set {
63+
__lengthAndFlags =
64+
(__lengthAndFlags & 0b0011_1111) |
65+
UInt8(UInt32(newValue & (0b11 << 16)) >> 10)
66+
__reserved = UInt16(newValue & 0b1111_1111_1111_1111)
67+
}
68+
}
2169
public var _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)
22-
public init() { NSUnimplemented() }
23-
public init(_exponent: Int32, _length: UInt32, _isNegative: UInt32, _isCompact: UInt32, _reserved: UInt32, _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)){ NSUnimplemented() }
70+
public init() {
71+
self._mantissa = (0,0,0,0,0,0,0,0)
72+
self.__exponent = 0
73+
self.__lengthAndFlags = 0
74+
self.__reserved = 0
75+
}
76+
77+
public init(_exponent: Int32, _length: UInt32, _isNegative: UInt32, _isCompact: UInt32, _reserved: UInt32, _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)){
78+
self._mantissa = _mantissa
79+
self.__exponent = Int8(truncatingBitPattern: _exponent)
80+
self.__lengthAndFlags = 0
81+
self.__reserved = 0
82+
self._length = _length
83+
self._isNegative = _isNegative
84+
self._isCompact = _isCompact
85+
self._reserved = _reserved
86+
}
2487
}
2588

2689
extension Decimal {

TestFoundation/TestNSDecimal.swift

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See http://swift.org/LICENSE.txt for license information
7+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
//
9+
10+
#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
11+
import Foundation
12+
import XCTest
13+
#else
14+
import SwiftFoundation
15+
import SwiftXCTest
16+
#endif
17+
18+
class TestNSDecimal: XCTestCase {
19+
20+
static var allTests : [(String, (TestNSDecimal) -> () throws -> Void)] {
21+
return [
22+
("test_BasicConstruction", test_BasicConstruction),
23+
("test_Constants", test_Constants),
24+
("test_ExplicitConstruction", test_ExplicitConstruction),
25+
]
26+
}
27+
28+
func test_BasicConstruction() {
29+
let zero = Decimal()
30+
XCTAssertEqual(20, MemoryLayout<Decimal>.size)
31+
XCTAssertEqual(0, zero._exponent)
32+
XCTAssertEqual(0, zero._length)
33+
XCTAssertEqual(0, zero._isNegative)
34+
XCTAssertEqual(0, zero._isCompact)
35+
XCTAssertEqual(0, zero._reserved)
36+
let (m0,m1,m2,m3,m4,m5,m6,m7) = zero._mantissa
37+
XCTAssertEqual(0, m0)
38+
XCTAssertEqual(0, m1)
39+
XCTAssertEqual(0, m2)
40+
XCTAssertEqual(0, m3)
41+
XCTAssertEqual(0, m4)
42+
XCTAssertEqual(0, m5)
43+
XCTAssertEqual(0, m6)
44+
XCTAssertEqual(0, m7)
45+
XCTAssertEqual(8, NSDecimalMaxSize)
46+
XCTAssertEqual(32767, NSDecimalNoScale)
47+
}
48+
49+
func test_Constants() {
50+
XCTAssertEqual(8,NSDecimalMaxSize)
51+
XCTAssertEqual(32767,NSDecimalNoScale)
52+
}
53+
54+
func test_ExplicitConstruction() {
55+
var explicit = Decimal(
56+
_exponent: 0x17f,
57+
_length: 0xff,
58+
_isNegative: 3,
59+
_isCompact: 4,
60+
_reserved: UInt32(1<<18 + 1<<17 + 1),
61+
_mantissa: (6,7,8,9,10,11,12,13)
62+
)
63+
XCTAssertEqual(0x7f, explicit._exponent)
64+
XCTAssertEqual(0x0f, explicit._length)
65+
XCTAssertEqual(1, explicit._isNegative)
66+
XCTAssertEqual(0, explicit._isCompact)
67+
XCTAssertEqual(UInt32(1<<17 + 1), explicit._reserved)
68+
let (m0,m1,m2,m3,m4,m5,m6,m7) = explicit._mantissa
69+
XCTAssertEqual(6, m0)
70+
XCTAssertEqual(7, m1)
71+
XCTAssertEqual(8, m2)
72+
XCTAssertEqual(9, m3)
73+
XCTAssertEqual(10, m4)
74+
XCTAssertEqual(11, m5)
75+
XCTAssertEqual(12, m6)
76+
XCTAssertEqual(13, m7)
77+
explicit._isCompact = 5
78+
explicit._isNegative = 6
79+
XCTAssertEqual(0, explicit._isNegative)
80+
XCTAssertEqual(1, explicit._isCompact)
81+
}
82+
}

TestFoundation/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ XCTMain([
3232
testCase(TestNSDate.allTests),
3333
testCase(TestNSDateComponents.allTests),
3434
testCase(TestNSDateFormatter.allTests),
35+
testCase(TestNSDecimal.allTests),
3536
testCase(TestNSDictionary.allTests),
3637
testCase(TestNSFileManager.allTests),
3738
testCase(TestNSGeometry.allTests),

0 commit comments

Comments
 (0)