Skip to content

Commit 18a46e7

Browse files
Added array private extension to wrap indexes, added Sequence conformance, simplified read and write implementations, nilling out value when reading.
1 parent a346fa9 commit 18a46e7

File tree

2 files changed

+65
-31
lines changed

2 files changed

+65
-31
lines changed

Ring Buffer/RingBuffer.playground/Contents.swift

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,20 @@ public struct RingBuffer<T> {
99
array = [T?](repeating: nil, count: count)
1010
}
1111

12+
/* Returns false if out of space. */
13+
@discardableResult
1214
public mutating func write(_ element: T) -> Bool {
13-
if !isFull {
14-
array[writeIndex % array.count] = element
15-
writeIndex += 1
16-
return true
17-
} else {
18-
return false
19-
}
15+
guard !isFull else { return false }
16+
defer { writeIndex += 1 }
17+
array[wrapped: writeIndex] = element
18+
return true
2019
}
21-
20+
21+
/* Returns nil if the buffer is empty. */
2222
public mutating func read() -> T? {
23-
if !isEmpty {
24-
let element = array[readIndex % array.count]
25-
readIndex += 1
26-
return element
27-
} else {
28-
return nil
29-
}
23+
guard !isEmpty else { return nil }
24+
defer { array[wrapped: readIndex] = nil ; readIndex += 1 }
25+
return array[wrapped: readIndex]
3026
}
3127

3228
fileprivate var availableSpaceForReading: Int {
@@ -46,6 +42,28 @@ public struct RingBuffer<T> {
4642
}
4743
}
4844

45+
extension RingBuffer: Sequence {
46+
public func makeIterator() -> AnyIterator<T> {
47+
var index = readIndex
48+
return AnyIterator {
49+
guard index < self.writeIndex else { return nil }
50+
defer { index += 1 }
51+
return self.array[wrapped: index]
52+
}
53+
}
54+
}
55+
56+
private extension Array {
57+
subscript (wrapped index: Int) -> Element {
58+
get {
59+
return self[index % count]
60+
}
61+
set {
62+
self[index % count] = newValue
63+
}
64+
}
65+
}
66+
4967
var buffer = RingBuffer<Int>(count: 5)
5068
buffer.array // [nil, nil, nil, nil, nil]
5169
buffer.readIndex // 0

Ring Buffer/RingBuffer.swift

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,23 @@ public struct RingBuffer<T> {
1616
private var writeIndex = 0
1717

1818
public init(count: Int) {
19-
array = [T?](count: count, repeatedValue: nil)
19+
array = [T?](repeating: nil, count: count)
2020
}
2121

2222
/* Returns false if out of space. */
23-
public mutating func write(element: T) -> Bool {
24-
if !isFull {
25-
array[writeIndex % array.count] = element
26-
writeIndex += 1
27-
return true
28-
} else {
29-
return false
30-
}
23+
@discardableResult
24+
public mutating func write(_ element: T) -> Bool {
25+
guard !isFull else { return false }
26+
defer { writeIndex += 1 }
27+
array[wrapped: writeIndex] = element
28+
return true
3129
}
3230

3331
/* Returns nil if the buffer is empty. */
3432
public mutating func read() -> T? {
35-
if !isEmpty {
36-
let element = array[readIndex % array.count]
37-
readIndex += 1
38-
return element
39-
} else {
40-
return nil
41-
}
33+
guard !isEmpty else { return nil }
34+
defer { array[wrapped: readIndex] = nil ; readIndex += 1 }
35+
return array[wrapped: readIndex]
4236
}
4337

4438
private var availableSpaceForReading: Int {
@@ -57,3 +51,25 @@ public struct RingBuffer<T> {
5751
return availableSpaceForWriting == 0
5852
}
5953
}
54+
55+
public extension RingBuffer: Sequence {
56+
public func makeIterator() -> AnyIterator<T> {
57+
var index = readIndex
58+
return AnyIterator {
59+
guard index < self.writeIndex else { return nil }
60+
defer { index += 1 }
61+
return self.array[wrapped: index]
62+
}
63+
}
64+
}
65+
66+
private extension Array {
67+
subscript (wrapped index: Int) -> Element {
68+
get {
69+
return self[index % count]
70+
}
71+
set {
72+
self[index % count] = newValue
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)