Skip to content

Commit 327666d

Browse files
committed
Update api to use safe: subscript
1 parent c843e3e commit 327666d

2 files changed

Lines changed: 18 additions & 228 deletions

File tree

Sources/SafeIndex/SafeIndex.swift

Lines changed: 8 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -1,185 +1,21 @@
1-
// The MIT License (MIT)
2-
//
3-
// Copyright (c) 2016 Suyeol Jeon (xoul.kr)
4-
//
5-
// Permission is hereby granted, free of charge, to any person obtaining a copy
6-
// of this software and associated documentation files (the "Software"), to deal
7-
// in the Software without restriction, including without limitation the rights
8-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9-
// copies of the Software, and to permit persons to whom the Software is
10-
// furnished to do so, subject to the following conditions:
11-
//
12-
// The above copyright notice and this permission notice shall be included in all
13-
// copies or substantial portions of the Software.
14-
//
15-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
// SOFTWARE.
22-
23-
public struct SafeIndex<T: Comparable> {
24-
public var index: T
25-
public init(_ index: T) {
26-
self.index = index
27-
}
28-
}
29-
30-
extension SafeIndex: CustomStringConvertible {
31-
public var description: String {
32-
return "^\(self.index)"
33-
}
34-
}
35-
36-
extension SafeIndex: CustomDebugStringConvertible {
37-
public var debugDescription: String {
38-
return "^\(self.index)"
39-
}
40-
}
41-
42-
extension SafeIndex: Equatable {
43-
public static func == (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> Bool {
44-
return lhs.index == rhs.index
45-
}
46-
public static func == (lhs: SafeIndex<T>, rhs: T) -> Bool {
47-
return lhs.index == rhs
48-
}
49-
public static func == (lhs: T, rhs: SafeIndex<T>) -> Bool {
50-
return lhs == rhs.index
51-
}
52-
}
53-
54-
extension SafeIndex: Comparable {
55-
public static func < (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> Bool {
56-
return lhs.index < rhs.index
57-
}
58-
public static func < (lhs: SafeIndex<T>, rhs: T) -> Bool {
59-
return lhs.index < rhs
60-
}
61-
public static func < (lhs: T, rhs: SafeIndex<T>) -> Bool {
62-
return lhs < rhs.index
63-
}
64-
65-
public static func <= (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> Bool {
66-
return lhs.index <= rhs.index
67-
}
68-
public static func <= (lhs: SafeIndex<T>, rhs: T) -> Bool {
69-
return lhs.index <= rhs
70-
}
71-
public static func <= (lhs: T, rhs: SafeIndex<T>) -> Bool {
72-
return lhs <= rhs.index
73-
}
74-
75-
public static func >= (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> Bool {
76-
return lhs.index >= rhs.index
77-
}
78-
public static func >= (lhs: SafeIndex<T>, rhs: T) -> Bool {
79-
return lhs.index >= rhs
80-
}
81-
public static func >= (lhs: T, rhs: SafeIndex<T>) -> Bool {
82-
return lhs >= rhs.index
83-
}
84-
85-
public static func > (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> Bool {
86-
return lhs.index > rhs.index
87-
}
88-
public static func > (lhs: SafeIndex<T>, rhs: T) -> Bool {
89-
return lhs.index > rhs
90-
}
91-
public static func > (lhs: T, rhs: SafeIndex<T>) -> Bool {
92-
return lhs > rhs.index
93-
}
94-
}
95-
96-
extension SafeIndex where T: BinaryInteger {
97-
public static func + (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> SafeIndex<T> {
98-
return SafeIndex(lhs.index + rhs.index)
99-
}
100-
public static func + (lhs: SafeIndex<T>, rhs: T) -> SafeIndex<T> {
101-
return SafeIndex(lhs.index + rhs)
102-
}
103-
public static func + (lhs: T, rhs: SafeIndex<T>) -> SafeIndex<T> {
104-
return SafeIndex(lhs + rhs.index)
105-
}
106-
107-
public static func - (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> SafeIndex<T> {
108-
return SafeIndex(lhs.index - rhs.index)
109-
}
110-
public static func - (lhs: SafeIndex<T>, rhs: T) -> SafeIndex<T> {
111-
return SafeIndex(lhs.index - rhs)
112-
}
113-
public static func - (lhs: T, rhs: SafeIndex<T>) -> SafeIndex<T> {
114-
return SafeIndex(lhs - rhs.index)
115-
}
116-
117-
public static func * (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> SafeIndex<T> {
118-
return SafeIndex(lhs.index * rhs.index)
119-
}
120-
public static func * (lhs: SafeIndex<T>, rhs: T) -> SafeIndex<T> {
121-
return SafeIndex(lhs.index * rhs)
122-
}
123-
public static func * (lhs: T, rhs: SafeIndex<T>) -> SafeIndex<T> {
124-
return SafeIndex(lhs * rhs.index)
125-
}
126-
127-
public static func / (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> SafeIndex<T> {
128-
return SafeIndex(lhs.index / rhs.index)
129-
}
130-
public static func / (lhs: SafeIndex<T>, rhs: T) -> SafeIndex<T> {
131-
return SafeIndex(lhs.index / rhs)
132-
}
133-
public static func / (lhs: T, rhs: SafeIndex<T>) -> SafeIndex<T> {
134-
return SafeIndex(lhs / rhs.index)
135-
}
136-
137-
public static func % (lhs: SafeIndex<T>, rhs: SafeIndex<T>) -> SafeIndex<T> {
138-
return SafeIndex(lhs.index % rhs.index)
139-
}
140-
public static func % (lhs: SafeIndex<T>, rhs: T) -> SafeIndex<T> {
141-
return SafeIndex(lhs.index % rhs)
142-
}
143-
public static func % (lhs: T, rhs: SafeIndex<T>) -> SafeIndex<T> {
144-
return SafeIndex(lhs % rhs.index)
145-
}
146-
147-
public func toIntMax() -> Int64 {
148-
return Int64(self.index)
149-
}
150-
}
151-
152-
prefix operator ^
153-
public prefix func ^ <T: Comparable>(index: T) -> SafeIndex<T> {
154-
return SafeIndex(index)
155-
}
156-
157-
prefix operator ^-
158-
public prefix func ^- <T: BinaryInteger>(index: T) -> SafeIndex<T> {
159-
return SafeIndex(-1 * index)
160-
}
161-
1621
public extension Collection {
163-
public subscript(safe: SafeIndex<Self.Index>?) -> Self.Element? {
2+
public subscript(safe index: Self.Index?) -> Self.Element? {
1643
get {
165-
guard let safe = safe else { return nil }
166-
return (self.startIndex..<self.endIndex).contains(safe.index) ? self[safe.index] : nil
4+
guard let index = index else { return nil }
5+
return (self.startIndex..<self.endIndex).contains(index) ? self[index] : nil
1676
}
1687
}
1698
}
1709

17110
public extension MutableCollection {
172-
public subscript(safe: SafeIndex<Self.Index>?) -> Self.Element? {
11+
public subscript(safe index: Self.Index?) -> Self.Element? {
17312
get {
174-
guard let safe = safe else { return nil }
175-
return (self.startIndex..<self.endIndex).contains(safe.index) ? self[safe.index] : nil
13+
guard let index = index else { return nil }
14+
return (self.startIndex..<self.endIndex).contains(index) ? self[index] : nil
17615
}
17716
set {
178-
guard let safe = safe,
179-
let value = newValue,
180-
self.startIndex..<self.endIndex ~= safe.index
181-
else { return }
182-
self[safe.index] = value
17+
guard let index = index, let value = newValue, (self.startIndex..<self.endIndex).contains(index) else { return }
18+
self[index] = value
18319
}
18420
}
18521
}

Tests/SafeIndexTests/SafeIndexTests.swift

Lines changed: 10 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -26,63 +26,17 @@ import SafeIndex
2626
class SafeIndexTests: XCTestCase {
2727
func testSafeIndex() {
2828
let arr = ["A", "B", "C"]
29-
XCTAssertEqual(arr[^0], "A")
30-
XCTAssertEqual(arr[^1], "B")
31-
XCTAssertEqual(arr[^2], "C")
32-
XCTAssertNil(arr[^3])
29+
XCTAssertEqual(arr[safe: 0], "A")
30+
XCTAssertEqual(arr[safe: 1], "B")
31+
XCTAssertEqual(arr[safe: 2], "C")
32+
XCTAssertNil(arr[safe: 3])
3333

3434
var mutableArr = ["A", "B", "C"]
35-
XCTAssertEqual(mutableArr[^0], "A")
36-
XCTAssertEqual(mutableArr[^1], "B")
37-
XCTAssertEqual(mutableArr[^2], "C")
38-
XCTAssertNil(mutableArr[^3])
39-
mutableArr[^2] = "D"
40-
XCTAssertEqual(mutableArr[^2], "D")
41-
}
42-
43-
func testSafeIndexMinus() {
44-
XCTAssertEqual(^-5, ^(-5))
45-
}
46-
47-
func testSafeIndexEquatable() {
48-
XCTAssertTrue(^5 == ^5)
49-
XCTAssertTrue(^3 == 3)
50-
XCTAssertTrue(2 == ^2)
51-
}
52-
53-
func testSafeIndexComparable() {
54-
XCTAssertTrue(^5 > ^4)
55-
XCTAssertTrue(5 > 4)
56-
XCTAssertTrue(5 > ^4)
57-
58-
XCTAssertTrue(^3 >= ^3)
59-
XCTAssertTrue(^3 >= 3)
60-
XCTAssertTrue(3 >= ^3)
61-
62-
XCTAssertTrue(^4 < ^6)
63-
XCTAssertTrue(^4 < 6)
64-
XCTAssertTrue(4 < ^6)
65-
66-
XCTAssertTrue(^6 <= ^6)
67-
XCTAssertTrue(^6 <= 6)
68-
XCTAssertTrue(6 <= ^6)
69-
}
70-
71-
func testSafeIndexArithmetic() {
72-
XCTAssertEqual(^5, ^2 + ^3)
73-
XCTAssertEqual(^11, ^10 + 1)
74-
XCTAssertEqual(^12, 2 + ^10)
75-
76-
XCTAssertEqual(^1, ^3 - ^2)
77-
XCTAssertEqual(^9, ^10 - 1)
78-
XCTAssertEqual(^3, 11 - ^8)
79-
80-
XCTAssertEqual(^6, ^2 * ^3)
81-
XCTAssertEqual(^20, ^10 * 2)
82-
XCTAssertEqual(^30, 3 * ^10)
83-
84-
XCTAssertEqual(^2, ^6 / ^3)
85-
XCTAssertEqual(^3, ^10 / 3)
86-
XCTAssertEqual(^6, 20 / ^3)
35+
XCTAssertEqual(mutableArr[safe: 0], "A")
36+
XCTAssertEqual(mutableArr[safe: 1], "B")
37+
XCTAssertEqual(mutableArr[safe: 2], "C")
38+
XCTAssertNil(mutableArr[safe: 3])
39+
mutableArr[safe: 2] = "D"
40+
XCTAssertEqual(mutableArr[safe: 2], "D")
8741
}
8842
}

0 commit comments

Comments
 (0)