Skip to content

Commit 88fbb7d

Browse files
authored
Expose Tree to @Inlinable (#162)
1 parent 591b1de commit 88fbb7d

File tree

4 files changed

+67
-4
lines changed

4 files changed

+67
-4
lines changed

Sources/DataStructures/SingleTypedTree.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extension Tree where Branch == Leaf {
1111
// MARK: - Single-Typed Tree
1212

1313
/// The payload of a given `Tree`.
14+
@inlinable
1415
public var value: Leaf {
1516
switch self {
1617
case .leaf(let value):
@@ -31,6 +32,7 @@ extension Tree where Branch == Leaf {
3132
///
3233
/// self = .branch(value, [.leaf(value)])
3334
///
35+
@inlinable
3436
public init <S: Sequence> (_ value: Leaf, _ sequence: S) where S.Element == Leaf {
3537

3638
if let array = sequence as? Array<Leaf>, array.isEmpty {
@@ -42,6 +44,7 @@ extension Tree where Branch == Leaf {
4244
}
4345

4446
/// - Returns: A new `Tree` with the given `value` as payload.
47+
@inlinable
4548
public func updating(value: Leaf) -> Tree {
4649
switch self {
4750
case .leaf:
@@ -52,6 +55,7 @@ extension Tree where Branch == Leaf {
5255
}
5356

5457
/// Apply a given `transform` to all nodes in a `Tree`.
58+
@inlinable
5559
public func map <Result> (_ transform: (Leaf) -> Result) -> Tree<Result,Result> {
5660
switch self {
5761
case .leaf(let value):

Sources/DataStructures/Tree.swift

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,19 @@ extension Tree {
6262
/// ])
6363
/// tree.leaves // => [0,1,2]
6464
///
65+
@inlinable
6566
public var leaves: [Leaf] {
66-
func flattened(accum: [Leaf], tree: Tree) -> [Leaf] {
67+
func flatten(accum: inout [Leaf], tree: Tree) {
6768
switch tree {
6869
case .branch(_, let trees):
69-
return trees.reduce(accum, flattened)
70+
accum = trees.reduce(into: accum, flatten)
7071
case .leaf(let value):
71-
return accum + [value]
72+
accum.append(value)
7273
}
7374
}
74-
return flattened(accum: [], tree: self)
75+
var result: [Leaf] = []
76+
flatten(accum: &result, tree: self)
77+
return result
7578
}
7679

7780
/// - Returns: The number of edges on the longest path between the root and a leaf.
@@ -86,6 +89,7 @@ extension Tree {
8689
/// ])
8790
/// tree.height // => 2
8891
///
92+
@inlinable
8993
public var height: Int {
9094
func traverse(_ tree: Tree, height: Int) -> Int {
9195
switch tree {
@@ -211,6 +215,7 @@ extension Tree {
211215
}
212216

213217
/// - Returns: A `Tree` with leaves updated by the given `transform`.
218+
@inlinable
214219
public func mapLeaves <T> (_ transform: @escaping (Leaf) -> T) -> Tree<Branch,T> {
215220
switch self {
216221
case .leaf(let value):
@@ -221,13 +226,15 @@ extension Tree {
221226
}
222227

223228
/// - Returns: A `Tree` with its leaves replaced by the elements in the given `collection`.
229+
@inlinable
224230
public func zipLeaves <C: RangeReplaceableCollection> (_ collection: C)
225231
-> Tree<Branch, C.Element>
226232
{
227233
return zipLeaves(collection) { _, value in value }
228234
}
229235

230236
// FIXME: Instead of copying `collection`, increment an `index`, pointing to `collection`.
237+
@inlinable
231238
public func zipLeaves <C: RangeReplaceableCollection, T> (
232239
_ collection: C,
233240
_ transform: @escaping (Leaf, C.Element) -> T
@@ -268,6 +275,7 @@ extension Tree {
268275
}
269276

270277
/// - Returns: A `Tree` with its branches and leaves modified by the given `transform`.
278+
@inlinable
271279
public func map <B,L> (_ transform: Transform<B,L>) -> Tree<B,L> {
272280
switch self {
273281
case .leaf(let value):
@@ -299,9 +307,13 @@ extension Tree {
299307
/// Transforms for `branch` and `leaf` cases.
300308
public struct Transform <B,L> {
301309

310+
@usableFromInline
302311
let branch: (Branch) -> B
312+
313+
@usableFromInline
303314
let leaf: (Leaf) -> L
304315

316+
@inlinable
305317
public init(branch: @escaping (Branch) -> B, leaf: @escaping (Leaf) -> L) {
306318
self.branch = branch
307319
self.leaf = leaf
@@ -342,6 +354,7 @@ extension Tree: CustomStringConvertible {
342354
/// corresponding node in the given trees `a` and `b`.
343355
///
344356
/// - Invariant: `a` and `b` are the same shape.
357+
@inlinable
345358
public func zip <T,U,V> (_ a: Tree<T,T>, _ b: Tree<U,U>, _ f: (T, U) -> V) -> Tree<V,V> {
346359
switch (a,b) {
347360
case (.leaf(let a), .leaf(let b)):

Tests/DataStructuresTests/TreeTests.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,4 +404,48 @@ class TreeTests: XCTestCase {
404404

405405
XCTAssertEqual(zipped, expected)
406406
}
407+
408+
func testLeavesMany() {
409+
let tree = Tree.branch(0, [
410+
.leaf(1),
411+
.branch(0, [
412+
.leaf(2),
413+
.leaf(3),
414+
.leaf(4)
415+
]),
416+
.leaf(5),
417+
.branch(0, [
418+
.leaf(6),
419+
.branch(0, [
420+
.leaf(7),
421+
.leaf(8)
422+
])
423+
])
424+
])
425+
(0..<1_000_000).forEach { _ in
426+
_ = tree.leaves
427+
}
428+
}
429+
430+
func testHeightMany() {
431+
let tree = Tree.branch(0, [
432+
.leaf(1),
433+
.branch(0, [
434+
.leaf(2),
435+
.leaf(3),
436+
.leaf(4)
437+
]),
438+
.leaf(5),
439+
.branch(0, [
440+
.leaf(6),
441+
.branch(0, [
442+
.leaf(7),
443+
.leaf(8)
444+
])
445+
])
446+
])
447+
(0..<1_000_000).forEach { _ in
448+
_ = tree.leaves
449+
}
450+
}
407451
}

Tests/DataStructuresTests/XCTestManifests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ extension TreeTests {
412412
static let __allTests = [
413413
("testHeightBranchSingleDepthOne", testHeightBranchSingleDepthOne),
414414
("testHeightLeafZero", testHeightLeafZero),
415+
("testHeightMany", testHeightMany),
415416
("testHeightNested", testHeightNested),
416417
("testInitWithSequence", testInitWithSequence),
417418
("testInitWithValueAndEmptyArray", testInitWithValueAndEmptyArray),
@@ -426,6 +427,7 @@ extension TreeTests {
426427
("testLeavesBranchMultipleTrees", testLeavesBranchMultipleTrees),
427428
("testLeavesBranchSingleChild", testLeavesBranchSingleChild),
428429
("testLeavesLeaf", testLeavesLeaf),
430+
("testLeavesMany", testLeavesMany),
429431
("testLeavesMultipleDepth", testLeavesMultipleDepth),
430432
("testMap", testMap),
431433
("testPath", testPath),

0 commit comments

Comments
 (0)