├── script
├── schemes.awk
├── xctool.awk
├── bootstrap
├── LICENSE.md
├── README.md
└── cibuild
├── FingerTree.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ ├── FingerTreeTest.xcscheme
│ │ └── FingerTree.xcscheme
└── project.pbxproj
├── FingerTree
├── TODO.txt
├── main.swift
├── Node.swift
├── Measure.swift
├── Affix.swift
├── Split.swift
├── Collection.swift
├── TreeView.swift
└── FingerTree.swift
├── .travis.yml
├── README.md
├── .gitignore
├── FingerTreeTest
├── Info.plist
├── FingerTreeTest.swift
├── NodeTest.swift
└── AffixTest.swift
└── LICENSE
/script/schemes.awk:
--------------------------------------------------------------------------------
1 | BEGIN {
2 | FS = "\n";
3 | }
4 |
5 | /Schemes:/ {
6 | while (getline && $0 != "") {
7 | sub(/^ +/, "");
8 | print "'" $0 "'";
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/FingerTree.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FingerTree/TODO.txt:
--------------------------------------------------------------------------------
1 | TODO:
2 | - Complete test coverage
3 | - Clean up API and code/style
4 | - Prevent unnecessary copying of objects
5 | - Don't use sub-Arrays (getting a Slice and converting to Array)
6 | - Profile performance
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode9
3 | git:
4 | submodules: false
5 | branches:
6 | only:
7 | - master
8 | script: script/cibuild
9 | notifications:
10 | email: true
11 | before_install:
12 | - brew update
13 | after_success:
14 | - bash <(curl -s https://codecov.io/bash)
15 |
16 |
--------------------------------------------------------------------------------
/script/xctool.awk:
--------------------------------------------------------------------------------
1 | # Exit statuses:
2 | #
3 | # 0 - No errors found.
4 | # 1 - Wrong SDK. Retry with SDK `iphonesimulator`.
5 | # 2 - Missing target.
6 |
7 | BEGIN {
8 | status = 0;
9 | }
10 |
11 | {
12 | print;
13 | }
14 |
15 | /Testing with the '(.+)' SDK is not yet supported/ {
16 | status = 1;
17 | }
18 |
19 | /does not contain a target named/ {
20 | status = 2;
21 | }
22 |
23 | END {
24 | exit status;
25 | }
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | FingerTree [](https://travis-ci.org/lazytype/FingerTree) [](https://coveralls.io/github/lazytype/FingerTree?branch=master)
2 | ==========
3 |
4 | Implementation of a generic 2-3 finger tree in Swift based on the Haskell implementation demonstrated in http://andrew.gibiansky.com/blog/haskell/finger-trees
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 | .DS_Store
20 |
21 | # CocoaPods
22 | #
23 | # We recommend against adding the Pods directory to your .gitignore. However
24 | # you should judge for yourself, the pros and cons are mentioned at:
25 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
26 | #
27 | # Pods/
28 |
--------------------------------------------------------------------------------
/FingerTreeTest/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/script/bootstrap:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | export SCRIPT_DIR=$(dirname "$0")
4 |
5 | ##
6 | ## Bootstrap Process
7 | ##
8 |
9 | main ()
10 | {
11 | local submodules=$(git submodule status)
12 | local result=$?
13 |
14 | if [ "$result" -ne "0" ]
15 | then
16 | exit $result
17 | fi
18 |
19 | if [ -n "$submodules" ]
20 | then
21 | echo "*** Updating submodules..."
22 | update_submodules
23 | fi
24 | }
25 |
26 | bootstrap_submodule ()
27 | {
28 | local bootstrap="script/bootstrap"
29 |
30 | if [ -e "$bootstrap" ]
31 | then
32 | echo "*** Bootstrapping $name..."
33 | "$bootstrap" >/dev/null
34 | else
35 | update_submodules
36 | fi
37 | }
38 |
39 | update_submodules ()
40 | {
41 | git submodule sync --quiet && git submodule update --init && git submodule foreach --quiet bootstrap_submodule
42 | }
43 |
44 | export -f bootstrap_submodule
45 | export -f update_submodules
46 |
47 | main
48 |
--------------------------------------------------------------------------------
/script/LICENSE.md:
--------------------------------------------------------------------------------
1 | **Copyright (c) 2013 Justin Spahr-Summers**
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so,
8 | subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-Present, Michael Mitchell
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | and associated documentation files (the "Software"), to deal in the Software without
7 | restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or
12 | substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/FingerTree/main.swift:
--------------------------------------------------------------------------------
1 | // main.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/FingerTreeTest/FingerTreeTest.swift:
--------------------------------------------------------------------------------
1 | // FingerTreeTest.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | import XCTest
21 |
22 | class FingerTreeTest: XCTestCase {
23 | }
24 |
--------------------------------------------------------------------------------
/FingerTreeTest/NodeTest.swift:
--------------------------------------------------------------------------------
1 | // NodeTest.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | import XCTest
21 |
22 | class NodeTwoTest: XCTestCase {
23 | var node: Node, Size> {
24 | return Node.branch2(Value("a").makeElement(), Value("b").makeElement(), Size(2))
25 | }
26 |
27 | var array: [Character] {
28 | return ["a", "b"]
29 | }
30 |
31 | func testToArray() {
32 | XCTAssertEqual(node.makeArray().map {$0.value!.value}, array)
33 | }
34 |
35 | func testMeasure() {
36 | XCTAssertEqual(node.measure, 2)
37 | }
38 |
39 | func testGenerate() {
40 | XCTAssertEqual(node.makeIterator().map {$0.value!.value}, array)
41 | }
42 | }
43 |
44 | class NodeThreeTest: XCTestCase {
45 | var node: Node, Size> {
46 | return Node.branch3(Value("a").makeElement(), Value("b").makeElement(), Value("c").makeElement(), Size(3))
47 | }
48 |
49 | var array: [Character] {
50 | return ["a", "b", "c"]
51 | }
52 |
53 | func testToArray() {
54 | XCTAssertEqual(node.makeArray().map {$0.value!.value}, array)
55 | }
56 |
57 | func testMeasure() {
58 | XCTAssertEqual(node.measure, 3)
59 | }
60 |
61 | func testGenerate() {
62 | XCTAssertEqual(node.makeIterator().map {$0.value!.value}, array)
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/FingerTree/Node.swift:
--------------------------------------------------------------------------------
1 | // Node.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | enum TreeElement
21 | : Measurable where TAnnotation == TValue.Annotation {
22 |
23 | case aValue(TValue)
24 | case aNode(Node)
25 |
26 | var node: Node? {
27 | if case let .aNode(node) = self {
28 | return node
29 | }
30 |
31 | return nil
32 | }
33 |
34 | var value: TValue? {
35 | if case let .aValue(value) = self {
36 | return value
37 | }
38 |
39 | return nil
40 | }
41 |
42 | var measure: TAnnotation {
43 | switch self {
44 | case let .aNode(node):
45 | return node.measure
46 | case let .aValue(value):
47 | return value.measure
48 | }
49 | }
50 | }
51 |
52 | enum Node
53 | : Measurable, Sequence where TAnnotation == TValue.Annotation {
54 |
55 | typealias Element = TreeElement
56 |
57 | indirect case branch2(Element, Element, TAnnotation)
58 | indirect case branch3(Element, Element, Element, TAnnotation)
59 |
60 | var measure: TAnnotation {
61 | switch self {
62 | case let .branch2(_, _, annotation):
63 | return annotation
64 | case let .branch3(_, _, _, annotation):
65 | return annotation
66 | }
67 | }
68 |
69 | func makeArray() -> [Element] {
70 | switch self {
71 | case let .branch2(a, b, _):
72 | return [a, b]
73 | case let .branch3(a, b, c, _):
74 | return [a, b, c]
75 | }
76 | }
77 |
78 | func makeElement() -> Element {
79 | return Element.aNode(self)
80 | }
81 |
82 | func makeIterator() -> IndexingIterator<[Element]> {
83 | return makeArray().makeIterator()
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/script/README.md:
--------------------------------------------------------------------------------
1 | # objc-build-scripts
2 |
3 | This project is a collection of scripts created with two goals:
4 |
5 | 1. To standardize how Objective-C projects are bootstrapped after cloning
6 | 1. To easily build Objective-C projects on continuous integration servers
7 |
8 | ## Scripts
9 |
10 | Right now, there are two important scripts: [`bootstrap`](#bootstrap) and
11 | [`cibuild`](#cibuild). Both are Bash scripts, to maximize compatibility and
12 | eliminate pesky system configuration issues (like setting up a working Ruby
13 | environment).
14 |
15 | The structure of the scripts on disk is meant to follow that of a typical Ruby
16 | project:
17 |
18 | ```
19 | script/
20 | bootstrap
21 | cibuild
22 | ```
23 |
24 | ### bootstrap
25 |
26 | This script is responsible for bootstrapping (initializing) your project after
27 | it's been checked out. Here, you should install or clone any dependencies that
28 | are required for a working build and development environment.
29 |
30 | By default, the script will verify that [xctool][] is installed, then initialize
31 | and update submodules recursively. If any submodules contain `script/bootstrap`,
32 | that will be run as well.
33 |
34 | To check that other tools are installed, you can set the `REQUIRED_TOOLS`
35 | environment variable before running `script/bootstrap`, or edit it within the
36 | script directly. Note that no installation is performed automatically, though
37 | this can always be added within your specific project.
38 |
39 | ### cibuild
40 |
41 | This script is responsible for building the project, as you would want it built
42 | for continuous integration. This is preferable to putting the logic on the CI
43 | server itself, since it ensures that any changes are versioned along with the
44 | source.
45 |
46 | By default, the script will run [`bootstrap`](#bootstrap), look for any Xcode
47 | workspace or project in the working directory, then build all targets/schemes
48 | (as found by `xcodebuild -list`) using [xctool][].
49 |
50 | You can also specify the schemes to build by passing them into the script:
51 |
52 | ```sh
53 | script/cibuild ReactiveCocoa-Mac ReactiveCocoa-iOS
54 | ```
55 |
56 | As with the `bootstrap` script, there are several environment variables that can
57 | be used to customize behavior. They can be set on the command line before
58 | invoking the script, or the defaults changed within the script directly.
59 |
60 | ## Getting Started
61 |
62 | To add the scripts to your project, read the contents of this repository into
63 | a `script` folder:
64 |
65 | ```
66 | $ git remote add objc-build-scripts https://github.com/jspahrsummers/objc-build-scripts.git
67 | $ git fetch objc-build-scripts
68 | $ git read-tree --prefix=script/ -u objc-build-scripts/master
69 | ```
70 |
71 | Then commit the changes, to incorporate the scripts into your own repository's
72 | history. You can also freely tweak the scripts for your specific project's
73 | needs.
74 |
75 | To merge in upstream changes later:
76 |
77 | ```
78 | $ git fetch -p objc-build-scripts
79 | $ git merge --ff --squash -Xsubtree=script objc-build-scripts/master
80 | ```
81 |
82 | [xctool]: https://github.com/facebook/xctool
83 |
--------------------------------------------------------------------------------
/FingerTree/Measure.swift:
--------------------------------------------------------------------------------
1 | // Measure.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | protocol Monoid {
21 | static var identity: Self {get}
22 | func append(_ other: Self) -> Self
23 | }
24 |
25 | precedencegroup Additive {
26 | associativity: left
27 | }
28 |
29 | infix operator <> : Additive
30 | internal func <> (lhs: TAnnotation, rhs: TAnnotation) -> TAnnotation {
31 | return lhs.append(rhs)
32 | }
33 |
34 | internal protocol Measurable {
35 | associatedtype Annotation: Monoid
36 | var measure: Annotation {get}
37 | }
38 |
39 | struct Value: Measurable, CustomStringConvertible {
40 | typealias Annotation = Size
41 |
42 | let value: T
43 |
44 | init(_ value: T) {
45 | self.value = value
46 | }
47 |
48 | var measure: Size {
49 | return 1
50 | }
51 |
52 | var description: String {
53 | return "'\(value)'"
54 | }
55 | }
56 |
57 | extension Measurable {
58 | func makeElement() -> TreeElement {
59 | return TreeElement.aValue(self)
60 | }
61 | }
62 |
63 | typealias Size = Int
64 |
65 | extension Size: Monoid {
66 | static var identity: Size = 0
67 |
68 | func append(_ other: Size) -> Size {
69 | return self + other
70 | }
71 | }
72 |
73 | struct Prioritized: Measurable {
74 | typealias Annotation = Priority
75 |
76 | let value: T
77 | let priority: Int
78 |
79 | init(_ value: T, priority: Int) {
80 | self.value = value
81 | self.priority = priority
82 | }
83 |
84 | var measure: Priority {
85 | return Priority.value(priority)
86 | }
87 | }
88 |
89 | enum Priority: Monoid {
90 | case negativeInfinity
91 | case value(Int)
92 |
93 | static var identity: Priority {
94 | return Priority.negativeInfinity
95 | }
96 |
97 | func append(_ other: Priority) -> Priority {
98 | switch (self, other) {
99 | case (.negativeInfinity, _):
100 | return other
101 | case (_, .negativeInfinity):
102 | return self
103 | case let (.value(value), .value(otherValue)):
104 | return value > otherValue ? self : other
105 | default:
106 | // All cases have actually been exhausted. Remove when the compiler is smarter about this.
107 | return self
108 | }
109 | }
110 | }
111 |
112 | func == (lhs: Priority, rhs: Priority) -> Bool {
113 | switch (lhs, rhs) {
114 | case (.negativeInfinity, .negativeInfinity):
115 | return true
116 | case let (.value(lvalue), .value(rvalue)):
117 | return lvalue == rvalue
118 | default:
119 | return false
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/FingerTree.xcodeproj/xcshareddata/xcschemes/FingerTreeTest.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
32 |
33 |
35 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
58 |
59 |
65 |
66 |
67 |
68 |
69 |
70 |
76 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/FingerTree/Affix.swift:
--------------------------------------------------------------------------------
1 | // Affix.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | enum AffixError: Error {
21 | case tooLarge
22 | }
23 |
24 | enum Affix
25 | : Measurable, Sequence where TAnnotation == TValue.Annotation {
26 |
27 | typealias Element = TreeElement
28 |
29 | case one(Element)
30 | case two(Element, Element)
31 | case three(Element, Element, Element)
32 | case four(Element, Element, Element, Element)
33 |
34 | var viewFirst: (Element, Affix?) {
35 | switch self {
36 | case let .one(a):
37 | return (a, nil)
38 | case let .two(a, b):
39 | return (a, Affix.one(b))
40 | case let .three(a, b, c):
41 | return (a, Affix.two(b, c))
42 | case let .four(a, b, c, d):
43 | return (a, Affix.three(b, c, d))
44 | }
45 | }
46 |
47 | var viewLast: (Affix?, Element) {
48 | switch self {
49 | case let .one(a):
50 | return (nil, a)
51 | case let .two(a, b):
52 | return (Affix.one(a), b)
53 | case let .three(a, b, c):
54 | return (Affix.two(a, b), c)
55 | case let .four(a, b, c, d):
56 | return (Affix.three(a, b, c), d)
57 | }
58 | }
59 |
60 | var measure: TAnnotation {
61 | switch self {
62 | case let .one(a):
63 | return a.measure
64 | case let .two(a, b):
65 | return a.measure <> b.measure
66 | case let .three(a, b, c):
67 | return a.measure <> b.measure <> c.measure
68 | case let .four(a, b, c, d):
69 | return a.measure <> b.measure <> c.measure <> d.measure
70 | }
71 | }
72 |
73 | func preface(_ element: Element) throws -> Affix {
74 | switch self {
75 | case let .one(a):
76 | return Affix.two(element, a)
77 | case let .two(a, b):
78 | return Affix.three(element, a, b)
79 | case let .three(a, b, c):
80 | return Affix.four(element, a, b, c)
81 | case .four:
82 | throw AffixError.tooLarge
83 | }
84 | }
85 |
86 | func append(_ element: Element) throws -> Affix {
87 | switch self {
88 | case let .one(a):
89 | return Affix.two(a, element)
90 | case let .two(a, b):
91 | return Affix.three(a, b, element)
92 | case let .three(a, b, c):
93 | return Affix.four(a, b, c, element)
94 | case .four:
95 | throw AffixError.tooLarge
96 | }
97 | }
98 |
99 | func makeArray() -> [Element] {
100 | switch self {
101 | case let .one(a):
102 | return [a]
103 | case let .two(a, b):
104 | return [a, b]
105 | case let .three(a, b, c):
106 | return [a, b, c]
107 | case let .four(a, b, c, d):
108 | return [a, b, c, d]
109 | }
110 | }
111 |
112 | func makeIterator() -> IndexingIterator<[Element]> {
113 | return makeArray().makeIterator()
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/FingerTree/Split.swift:
--------------------------------------------------------------------------------
1 | // Split.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | enum SplitError: Error {
21 | case notFound
22 | }
23 |
24 | extension FingerTree {
25 | func split(
26 | predicate: (TAnnotation) -> Bool,
27 | startAnnotation: TAnnotation
28 | ) throws -> (FingerTree, FingerTree) {
29 | switch self {
30 | case .empty:
31 | break
32 | case .single:
33 | if predicate(startAnnotation <> measure) {
34 | return (FingerTree.empty, self)
35 | }
36 | case let .deep(prefix, deeper, suffix, _):
37 | if !predicate(startAnnotation <> measure) {
38 | throw SplitError.notFound
39 | }
40 |
41 | let startToPrefix = startAnnotation <> prefix.measure
42 | if predicate(startToPrefix) {
43 | if let (before, after) = FingerTree.splitList(
44 | predicate: predicate,
45 | startAnnotation: startAnnotation,
46 | values: prefix
47 | ) {
48 | let left: FingerTree
49 | if let affix: Affix = before {
50 | left = affix.makeFingerTree()
51 | } else {
52 | left = FingerTree.empty
53 | }
54 |
55 | return (left, FingerTree.createDeep(prefix: after, deeper: deeper, suffix: suffix))
56 | }
57 | } else if predicate(startToPrefix <> deeper.measure) {
58 | let (left, right) = try! deeper.split(predicate: predicate, startAnnotation: startToPrefix)
59 | let (element, rest) = right.viewLeft!
60 |
61 | if let (beforeNode, afterNode) = FingerTree.splitList(
62 | predicate: predicate,
63 | startAnnotation: startToPrefix <> left.measure,
64 | values: element.node!.makeAffix()
65 | ) {
66 | return (
67 | FingerTree.createDeep(prefix: prefix, deeper: left, suffix: beforeNode),
68 | FingerTree.createDeep(prefix: afterNode, deeper: rest, suffix: suffix)
69 | )
70 | }
71 | } else if let (before, after) = FingerTree.splitList(
72 | predicate: predicate,
73 | startAnnotation: startToPrefix <> deeper.measure,
74 | values: suffix
75 | ) {
76 | return (
77 | FingerTree.createDeep(prefix: prefix, deeper: deeper, suffix: before),
78 | after.makeFingerTree()
79 | )
80 | }
81 | }
82 |
83 | throw SplitError.notFound
84 | }
85 |
86 | private static func splitList(
87 | predicate: (TAnnotation) -> Bool,
88 | startAnnotation: TAnnotation,
89 | values: Affix
90 | ) -> (Affix?, Affix)? {
91 | let (first, rest) = values.viewFirst
92 |
93 | let start = startAnnotation <> first.measure
94 |
95 | if predicate(start) {
96 | return (nil, values)
97 | }
98 |
99 | if rest == nil {
100 | return nil
101 | }
102 |
103 | if let (before, after) = splitList(
104 | predicate: predicate,
105 | startAnnotation: start,
106 | values: rest!
107 | ) {
108 | if before == nil {
109 | return (Affix.one(first), after)
110 | }
111 |
112 | return (try! before!.preface(first), after)
113 | }
114 |
115 | return nil
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/script/cibuild:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | export SCRIPT_DIR=$(dirname "$0")
4 |
5 | ##
6 | ## Configuration Variables
7 | ##
8 |
9 | SCHEMES="$@"
10 |
11 | config ()
12 | {
13 | # The workspace to build.
14 | #
15 | # If not set and no workspace is found, the -workspace flag will not be passed
16 | # to `xctool`.
17 | #
18 | # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will
19 | # take precedence.
20 | : ${XCWORKSPACE=$(find_pattern "*.xcworkspace")}
21 |
22 | # The project to build.
23 | #
24 | # If not set and no project is found, the -project flag will not be passed
25 | # to `xctool`.
26 | #
27 | # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will
28 | # take precedence.
29 | : ${XCODEPROJ=$(find_pattern "*.xcodeproj")}
30 |
31 | # A bootstrap script to run before building.
32 | #
33 | # If this file does not exist, it is not considered an error.
34 | : ${BOOTSTRAP="$SCRIPT_DIR/bootstrap"}
35 |
36 | # Extra options to pass to xctool.
37 | : ${XCTOOL_OPTIONS="RUN_CLANG_STATIC_ANALYZER=NO"}
38 |
39 | # A whitespace-separated list of default schemes to build.
40 | #
41 | # Individual names can be quoted to avoid word splitting.
42 | : ${SCHEMES:=$(xcodebuild -list -project "$XCODEPROJ" 2>/dev/null | awk -f "$SCRIPT_DIR/schemes.awk")}
43 |
44 | # A whitespace-separated list of executables that must be present and locatable.
45 | : ${REQUIRED_TOOLS="xctool"}
46 |
47 | export XCWORKSPACE
48 | export XCODEPROJ
49 | export BOOTSTRAP
50 | export XCTOOL_OPTIONS
51 | export SCHEMES
52 | export REQUIRED_TOOLS
53 | }
54 |
55 | ##
56 | ## Build Process
57 | ##
58 |
59 | main ()
60 | {
61 | config
62 |
63 | if [ -n "$REQUIRED_TOOLS" ]
64 | then
65 | echo "*** Checking dependencies..."
66 | check_deps
67 | fi
68 |
69 | if [ -f "$BOOTSTRAP" ]
70 | then
71 | echo "*** Bootstrapping..."
72 | "$BOOTSTRAP" || exit $?
73 | fi
74 |
75 | echo "*** The following schemes will be built:"
76 | echo "$SCHEMES" | xargs -n 1 echo " "
77 | echo
78 |
79 | echo "$SCHEMES" | xargs -n 1 | (
80 | local status=0
81 |
82 | while read scheme
83 | do
84 | build_scheme "$scheme" || status=1
85 | done
86 |
87 | exit $status
88 | )
89 | }
90 |
91 | check_deps ()
92 | {
93 | for tool in $REQUIRED_TOOLS
94 | do
95 | which -s "$tool"
96 | if [ "$?" -ne "0" ]
97 | then
98 | echo "*** Error: $tool not found. Please install it and cibuild again."
99 | exit 1
100 | fi
101 | done
102 | }
103 |
104 | find_pattern ()
105 | {
106 | ls -d $1 2>/dev/null | head -n 1
107 | }
108 |
109 | run_xctool ()
110 | {
111 | if [ -n "$XCWORKSPACE" ]
112 | then
113 | xctool -workspace "$XCWORKSPACE" $XCTOOL_OPTIONS "$@" 2>&1
114 | elif [ -n "$XCODEPROJ" ]
115 | then
116 | xctool -project "$XCODEPROJ" $XCTOOL_OPTIONS "$@" 2>&1
117 | else
118 | echo "*** No workspace or project file found."
119 | exit 1
120 | fi
121 | }
122 |
123 | parse_build ()
124 | {
125 | awk -f "$SCRIPT_DIR/xctool.awk" 2>&1 >/dev/null
126 | }
127 |
128 | build_scheme ()
129 | {
130 | local scheme=$1
131 |
132 | echo "*** Building and testing $scheme..."
133 | echo
134 |
135 | local sdkflag=
136 | local action=test
137 |
138 | # Determine whether we can run unit tests for this target.
139 | run_xctool -scheme "$scheme" run-tests | parse_build
140 |
141 | local awkstatus=$?
142 |
143 | if [ "$awkstatus" -eq "1" ]
144 | then
145 | # SDK not found, try for iphonesimulator.
146 | sdkflag="-sdk iphonesimulator"
147 |
148 | # Determine whether the unit tests will run with iphonesimulator
149 | run_xctool $sdkflag -scheme "$scheme" run-tests | parse_build
150 |
151 | awkstatus=$?
152 |
153 | if [ "$awkstatus" -ne "0" ]
154 | then
155 | # Unit tests will not run on iphonesimulator.
156 | sdkflag=""
157 | fi
158 | fi
159 |
160 | if [ "$awkstatus" -ne "0" ]
161 | then
162 | # Unit tests aren't supported.
163 | action=build
164 | fi
165 |
166 | run_xctool $sdkflag -scheme "$scheme" $action
167 | }
168 |
169 | export -f build_scheme
170 | export -f run_xctool
171 | export -f parse_build
172 |
173 | main
174 |
--------------------------------------------------------------------------------
/FingerTree.xcodeproj/xcshareddata/xcschemes/FingerTree.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
32 |
33 |
35 |
41 |
42 |
43 |
44 |
45 |
51 |
52 |
53 |
54 |
55 |
56 |
67 |
69 |
75 |
76 |
77 |
78 |
79 |
82 |
83 |
84 |
90 |
92 |
98 |
99 |
100 |
101 |
103 |
104 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/FingerTreeTest/AffixTest.swift:
--------------------------------------------------------------------------------
1 | // AffixTest.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | import XCTest
21 |
22 |
23 | class AffixOneTest: XCTestCase {
24 | var affix: Affix, Size> {
25 | return Affix.one(Value("a").makeElement())
26 | }
27 |
28 | var array: [Character] {
29 | return ["a"]
30 | }
31 |
32 | func testToArray() {
33 | XCTAssertEqual(affix.makeArray().map {$0.value!.value}, array)
34 | }
35 |
36 | func testPreface() {
37 | var array = self.array;
38 | array.insert("x", at: 0)
39 |
40 | XCTAssertEqual(try! affix.preface(Value("x").makeElement()).makeArray().map {$0.value!.value}, array)
41 | }
42 |
43 | func testAppend() {
44 | var array = self.array
45 | array.append("x")
46 |
47 | XCTAssertEqual(try! affix.append(Value("x").makeElement()).makeArray().map {$0.value!.value}, array)
48 | }
49 |
50 | func testMeasure() {
51 | XCTAssertEqual(affix.measure, array.count)
52 | }
53 |
54 | func testGenerate() {
55 | XCTAssertEqual(affix.makeIterator().map {$0.value!.value}, array)
56 | }
57 | }
58 |
59 | class AffixTwoTest: AffixOneTest {
60 | override var affix: Affix, Size> {
61 | return Affix.two(Value("a").makeElement(), Value("b").makeElement())
62 | }
63 |
64 | override var array: [Character] {
65 | return ["a", "b"]
66 | }
67 |
68 | override func testToArray() {
69 | XCTAssertEqual(affix.makeArray().map {$0.value!.value}, self.array)
70 | }
71 | }
72 |
73 | class AffixThreeTest: AffixOneTest {
74 | override var affix: Affix, Size> {
75 | return Affix.three(Value("a").makeElement(), Value("b").makeElement(), Value("c").makeElement())
76 | }
77 |
78 | override var array: [Character] {
79 | return ["a", "b", "c"]
80 | }
81 | }
82 |
83 | class AffixFourTest: AffixOneTest {
84 | override var affix: Affix, Size> {
85 | return Affix.four(
86 | Value("a").makeElement(),
87 | Value("b").makeElement(),
88 | Value("c").makeElement(),
89 | Value("d").makeElement()
90 | )
91 | }
92 |
93 | override var array: [Character] {
94 | return ["a", "b", "c", "d"]
95 | }
96 |
97 | override func testPreface() {
98 | do {
99 | _ = try affix.preface(Value("x").makeElement())
100 | } catch AffixError.tooLarge {
101 | return
102 | } catch {}
103 |
104 | XCTFail("preface() should throw AffixError.TooLarge")
105 | }
106 |
107 | override func testAppend() {
108 | do {
109 | _ = try affix.append(Value("x").makeElement())
110 | } catch AffixError.tooLarge {
111 | return
112 | } catch {}
113 |
114 | XCTFail("append() should throw AffixError.TooLarge")
115 | }
116 | }
117 |
118 | class AffixTest: XCTestCase {
119 | func testViewFirst() {
120 | let array = ["a", "b", "c", "d"]
121 | var affix: Affix? = Affix.four(
122 | Value("a").makeElement(),
123 | Value("b").makeElement(),
124 | Value("c").makeElement(),
125 | Value("d").makeElement()
126 | )
127 | for value in array {
128 | let (first, rest) = affix!.viewFirst
129 |
130 | affix = rest
131 | XCTAssert(value == first.value!.value)
132 | }
133 |
134 | XCTAssert(affix == nil)
135 | }
136 |
137 | func testViewLast() {
138 | let array = ["a", "b", "c", "d"]
139 | var affix: Affix? = Affix.four(
140 | Value("a").makeElement(),
141 | Value("b").makeElement(),
142 | Value("c").makeElement(),
143 | Value("d").makeElement()
144 | )
145 | for value in array.reversed() {
146 | let (rest, last) = affix!.viewLast
147 |
148 | affix = rest
149 | XCTAssert(value == last.value!.value)
150 | }
151 |
152 | XCTAssert(affix == nil)
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/FingerTree/Collection.swift:
--------------------------------------------------------------------------------
1 | // Collection.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | public struct ImmutableCollection: Collection {
21 | private let tree: FingerTree, Size>
22 |
23 | init(_ tree: FingerTree, Size> = FingerTree.empty) {
24 | self.tree = tree
25 | }
26 |
27 | public let startIndex: Int = 0
28 |
29 | public var endIndex: Int {
30 | return tree.measure
31 | }
32 |
33 | public subscript(index: Int) -> T {
34 | let (_, right) = try! tree.split(
35 | predicate: {$0 > index && index >= 0},
36 | startAnnotation: Size.identity
37 | )
38 |
39 | let (element, _) = right.viewLeft!
40 | return element.value!.value
41 | }
42 |
43 | public func index(after i: Int) -> Int {
44 | precondition(i < endIndex, "Can't advance beyond endIndex")
45 | return i + 1
46 | }
47 |
48 | public func makeIterator() -> AnyIterator {
49 | return AnyIterator(tree.makeIterator().lazy.map {$0.value!.value}.makeIterator())
50 | }
51 |
52 | public func reversed() -> AnyIterator {
53 | return AnyIterator(tree.reversed().lazy.map {$0.value!.value}.makeIterator())
54 | }
55 |
56 | public func preface(_ element: T) -> ImmutableCollection {
57 | return ImmutableCollection(tree.preface(Value(element).makeElement()))
58 | }
59 |
60 | public func append(_ element: T) -> ImmutableCollection {
61 | return ImmutableCollection(tree.append(Value(element).makeElement()))
62 | }
63 |
64 | func insert(_ element: T, atIndex: Int) -> ImmutableCollection {
65 | do {
66 | let (left, right) = try tree.split(
67 | predicate: {$0 > atIndex && atIndex >= 0},
68 | startAnnotation: Size.identity
69 | )
70 | let middle = [Value(element).makeElement()]
71 | let newTree = FingerTree.concatenate(middle: middle, left: left, right: right)
72 |
73 | return ImmutableCollection(newTree)
74 | } catch {
75 | return ImmutableCollection(FingerTree.single(Value(element).makeElement()))
76 | }
77 | }
78 | }
79 |
80 | public struct PriorityQueue {
81 | let tree: FingerTree, Priority>
82 |
83 | init(_ tree: FingerTree, Priority>) {
84 | self.tree = tree
85 | }
86 |
87 | public func pop() -> (T, PriorityQueue) {
88 | let (left, right) = try! tree.split(
89 | predicate: {$0 == self.tree.measure},
90 | startAnnotation: Priority.negativeInfinity
91 | )
92 |
93 | let (element, rest) = right.viewLeft!
94 |
95 | let newTree = left.extend(rest) // wrong!
96 |
97 | return (element.value!.value, PriorityQueue(newTree))
98 | }
99 |
100 | public func push(_ element: T, value: Int) -> PriorityQueue {
101 | let prioritized = Prioritized(element, priority: value)
102 | let newTree: FingerTree, Priority>
103 |
104 | switch tree {
105 | case .empty:
106 | newTree = FingerTree, Priority>.single(prioritized.makeElement())
107 | case let .single(a):
108 | newTree = FingerTree.createDeep(
109 | prefix: Affix, Priority>.one(a),
110 | deeper: FingerTree, Priority>.empty,
111 | suffix: Affix, Priority>.one(prioritized.makeElement())
112 | )
113 | case let .deep(prefix, deeper, suffix, annotation):
114 | switch prefix {
115 | case let .four(a, b, c, d):
116 | newTree = FingerTree, Priority>.deep(
117 | prefix: Affix.two(prioritized.makeElement(), a),
118 | deeper: deeper.preface(
119 | Node.branch3(b, c, d, b.measure <> c.measure <> d.measure).makeElement()
120 | ),
121 | suffix: suffix,
122 | prioritized.measure <> annotation
123 | )
124 | default:
125 | newTree = FingerTree.deep(
126 | prefix: try! prefix.preface(prioritized.makeElement()),
127 | deeper: deeper,
128 | suffix: suffix,
129 | prioritized.measure <> annotation
130 | )
131 | }
132 | }
133 |
134 | return PriorityQueue(newTree)
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/FingerTree/TreeView.swift:
--------------------------------------------------------------------------------
1 | // TreeView.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | extension FingerTree {
21 | var viewLeft: (Element, FingerTree)? {
22 | switch self {
23 | case .empty:
24 | return nil
25 | case let .single(a):
26 | return (a, FingerTree.empty)
27 | case let .deep(.one(a), deeper, suffix, _):
28 | let rest: FingerTree
29 |
30 | if let (element, deeperRest) = deeper.viewLeft {
31 | rest = FingerTree.deep(
32 | prefix: element.node!.makeAffix(),
33 | deeper: deeperRest,
34 | suffix: suffix,
35 | deeper.measure <> suffix.measure
36 | )
37 | } else {
38 | rest = suffix.makeFingerTree()
39 | }
40 |
41 | return (a, rest)
42 |
43 | case let .deep(prefix, deeper, suffix, _):
44 | let (first, rest) = prefix.viewFirst
45 | let annotation = rest!.measure <> deeper.measure <> suffix.measure
46 | return (first, FingerTree.deep(prefix: rest!, deeper: deeper, suffix: suffix, annotation))
47 | }
48 | }
49 |
50 | var viewRight: (FingerTree, Element)? {
51 | switch self {
52 | case .empty:
53 | return nil
54 | case let .single(a):
55 | return (FingerTree.empty, a)
56 | case let .deep(prefix, deeper, .one(a), _):
57 | let rest: FingerTree
58 |
59 | if let (deeperRest, element) = deeper.viewRight {
60 | rest = FingerTree.deep(
61 | prefix: prefix,
62 | deeper: deeperRest,
63 | suffix: element.node!.makeAffix(),
64 | prefix.measure <> deeper.measure
65 | )
66 | } else {
67 | rest = prefix.makeFingerTree()
68 | }
69 |
70 | return (rest, a)
71 |
72 | case let .deep(prefix, deeper, suffix, _):
73 | let (rest, last) = suffix.viewLast
74 | let annotation = prefix.measure <> deeper.measure <> rest!.measure
75 | return (FingerTree.deep(prefix: prefix, deeper: deeper, suffix: rest!, annotation), last)
76 | }
77 | }
78 | }
79 |
80 | extension Affix {
81 | func makeFingerTree() -> FingerTree {
82 | switch self {
83 | case let .one(a):
84 | return FingerTree.single(a)
85 | case let .two(a, b):
86 | return FingerTree.deep(
87 | prefix: Affix.one(a),
88 | deeper: FingerTree.empty,
89 | suffix: Affix.one(b),
90 | a.measure <> b.measure
91 | )
92 | case let .three(a, b, c):
93 | return FingerTree.deep(
94 | prefix: Affix.two(a, b),
95 | deeper: FingerTree.empty,
96 | suffix: Affix.one(c),
97 | a.measure <> b.measure <> c.measure
98 | )
99 | case let .four(a, b, c, d):
100 | return FingerTree.deep(
101 | prefix: Affix.two(a, b),
102 | deeper: FingerTree.empty,
103 | suffix: Affix.two(c, d),
104 | a.measure <> b.measure <> c.measure <> d.measure
105 | )
106 | }
107 | }
108 | }
109 |
110 | extension Node {
111 | func makeAffix() -> Affix {
112 | switch self {
113 | case let .branch2(a, b, _):
114 | return Affix.two(a, b)
115 | case let .branch3(a, b, c, _):
116 | return Affix.three(a, b, c)
117 | }
118 | }
119 | }
120 |
121 | extension FingerTree {
122 | static func createDeep(
123 | prefix: Affix?,
124 | deeper: FingerTree,
125 | suffix: Affix?
126 | ) -> FingerTree {
127 | if prefix == nil && suffix == nil {
128 | if let (element, rest) = deeper.viewLeft {
129 | return createDeep(prefix: element.node!.makeAffix(), deeper: rest, suffix: nil)
130 | } else {
131 | return FingerTree.empty
132 | }
133 | } else if prefix == nil {
134 | if let (rest, element) = deeper.viewRight {
135 | return createDeep(prefix: element.node!.makeAffix(), deeper: rest, suffix: suffix)
136 | } else {
137 | return suffix!.makeFingerTree()
138 | }
139 | } else if suffix == nil {
140 | if let (rest, element) = deeper.viewRight {
141 | return createDeep(prefix: prefix, deeper: rest, suffix: element.node!.makeAffix())
142 | } else {
143 | return prefix!.makeFingerTree()
144 | }
145 | } else {
146 | let annotation = prefix!.measure <> deeper.measure <> suffix!.measure
147 | return FingerTree.deep(prefix: prefix!, deeper: deeper, suffix: suffix!, annotation)
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/FingerTree/FingerTree.swift:
--------------------------------------------------------------------------------
1 | // FingerTree.swift
2 | //
3 | // Copyright (c) 2015-Present, Michael Mitchell
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 | // and associated documentation files (the "Software"), to deal in the Software without
7 | // restriction, including without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
9 | // Software is furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all copies or
12 | // substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
15 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
20 | enum FingerTree
21 | : Measurable where TAnnotation == TValue.Annotation {
22 |
23 | typealias Element = TreeElement
24 |
25 | case empty
26 | case single(Element)
27 | indirect case deep(
28 | prefix: Affix,
29 | deeper: FingerTree,
30 | suffix: Affix,
31 | TAnnotation
32 | )
33 |
34 | var measure: TAnnotation {
35 | switch self {
36 | case .empty:
37 | return TAnnotation.identity
38 | case let .single(a):
39 | return a.measure
40 | case let .deep(_, _, _, annotation):
41 | return annotation
42 | }
43 | }
44 |
45 | func preface(_ element: Element) -> FingerTree {
46 | switch self {
47 | case .empty:
48 | return FingerTree.single(element)
49 | case let .single(a):
50 | return FingerTree.deep(
51 | prefix: Affix.one(element),
52 | deeper: FingerTree.empty,
53 | suffix: Affix.one(a),
54 | element.measure <> a.measure
55 | )
56 | case let .deep(.four(a, b, c, d), deeper, suffix, annotation):
57 | return FingerTree.deep(
58 | prefix: Affix.two(element, a),
59 | deeper: deeper.preface(
60 | Node.branch3(b, c, d, b.measure <> c.measure <> d.measure).makeElement()
61 | ),
62 | suffix: suffix,
63 | element.measure <> annotation
64 | )
65 | case let .deep(prefix, deeper, suffix, annotation):
66 | return FingerTree.deep(
67 | prefix: try! prefix.preface(element),
68 | deeper: deeper,
69 | suffix: suffix,
70 | element.measure <> annotation
71 | )
72 | }
73 | }
74 |
75 | func append(_ element: Element) -> FingerTree {
76 | switch self {
77 | case .empty:
78 | return FingerTree.single(element)
79 | case let .single(a):
80 | return FingerTree.deep(
81 | prefix: Affix.one(a),
82 | deeper: FingerTree.empty,
83 | suffix: Affix.one(element),
84 | a.measure <> element.measure
85 | )
86 | case let .deep(prefix, deeper, .four(a, b, c, d), annotation):
87 | return FingerTree.deep(
88 | prefix: prefix,
89 | deeper: deeper.append(
90 | Node.branch3(a, b, c, a.measure <> b.measure <> c.measure).makeElement()
91 | ),
92 | suffix: Affix.two(d, element),
93 | annotation <> element.measure
94 | )
95 | case let .deep(prefix, deeper, suffix, annotation):
96 | return FingerTree.deep(
97 | prefix: prefix,
98 | deeper: deeper,
99 | suffix: try! suffix.append(element),
100 | annotation <> element.measure
101 | )
102 | }
103 | }
104 |
105 | private static func nodes(_ array: [Element]) -> [Element]? {
106 | switch array.count {
107 | case 1:
108 | return nil
109 | case 2:
110 | let annotation = array[0].measure <> array[1].measure
111 | return [Node.branch2(array[0], array[1], annotation).makeElement()]
112 | case 3:
113 | let annotation = array[0].measure <> array[1].measure <> array[2].measure
114 | return [Node.branch3(array[0], array[1], array[2], annotation).makeElement()]
115 | default:
116 | var nodeArray = nodes(Array(array[0..<(array.count - 2)]))
117 | let annotation = array[array.count - 2].measure <> array[array.count - 1].measure
118 | nodeArray!.append(
119 | Node.branch2(array[array.count - 2], array[array.count - 1], annotation).makeElement()
120 | )
121 | return nodeArray
122 | }
123 | }
124 |
125 | static func concatenate(middle: [Element], left: FingerTree, right: FingerTree) -> FingerTree {
126 | switch (middle, left, right) {
127 | case (_, .empty, _) where middle.isEmpty:
128 | return right
129 |
130 | case (_, _, .empty) where middle.isEmpty:
131 | return left
132 |
133 | case (_, .empty, _):
134 | let middle = Array(middle[1.. deeper.measure <> rightSuffix.measure
157 | return FingerTree.deep(prefix: leftPrefix, deeper: deeper, suffix: rightSuffix, annotation)
158 |
159 | default:
160 | // All cases have actually been exhausted. Remove when the compiler is smarter about this.
161 | return FingerTree.empty
162 | }
163 | }
164 |
165 | func extend(_ tree: FingerTree) -> FingerTree {
166 | return FingerTree.concatenate(middle: [], left: self, right: tree)
167 | }
168 |
169 | func makeIterator() -> AnyIterator {
170 | switch self {
171 | case .empty:
172 | return AnyIterator(EmptyIterator())
173 | case let .single(a):
174 | return AnyIterator(IteratorOverOne(_elements: a))
175 | case let .deep(prefix, deeper, suffix, _):
176 | var (prefixIter, deeperIter, suffixIter) = (
177 | prefix.makeIterator(),
178 | deeper.makeIterator(),
179 | suffix.makeIterator()
180 | )
181 |
182 | var nodeIter = deeperIter.next()?.node!.makeIterator()
183 |
184 | return AnyIterator {
185 | if let value = prefixIter.next() {
186 | return value
187 | }
188 |
189 | repeat {
190 | if let value = nodeIter?.next() {
191 | return value
192 | }
193 |
194 | nodeIter = deeperIter.next()?.node!.makeIterator()
195 | } while nodeIter != nil
196 |
197 | if let value = suffixIter.next() {
198 | return value
199 | }
200 |
201 | return nil
202 | }
203 | }
204 | }
205 |
206 | func reversed() -> AnyIterator {
207 | switch self {
208 | case .empty:
209 | return AnyIterator(EmptyIterator())
210 | case let .single(a):
211 | return AnyIterator(IteratorOverOne(_elements: a))
212 | case let .deep(prefix, deeper, suffix, _):
213 | var (prefixIter, deeperIter, suffixIter) = (
214 | prefix.reversed().makeIterator(),
215 | deeper.reversed(),
216 | suffix.reversed().makeIterator()
217 | )
218 |
219 | var nodeIter = deeperIter.next()?.node!.makeIterator()
220 |
221 | return AnyIterator {
222 | if let value = suffixIter.next() {
223 | return value
224 | }
225 |
226 | repeat {
227 | if let value = nodeIter?.next() {
228 | return value
229 | }
230 |
231 | nodeIter = deeperIter.next()?.node!.makeIterator()
232 | } while nodeIter != nil
233 |
234 | return prefixIter.next()
235 | }
236 | }
237 | }
238 | }
239 |
--------------------------------------------------------------------------------
/FingerTree.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 47;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 22DE31BA22EAD8EF74655BC6 /* Split.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DE346643185F70CBED1D22 /* Split.swift */; };
11 | 22DE35CD6B042406277DD9FC /* TreeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DE369326DC5EABE49EECFE /* TreeView.swift */; };
12 | 850503C91B6DA453004C5B1A /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850503C81B6DA453004C5B1A /* Collection.swift */; };
13 | 850996581C36B13300FF7FD5 /* NodeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850996571C36B13300FF7FD5 /* NodeTest.swift */; };
14 | 852DB6AE1B9D277F004FD22D /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852DB6AD1B9D277F004FD22D /* main.swift */; };
15 | 852DB6AF1B9D277F004FD22D /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 852DB6AD1B9D277F004FD22D /* main.swift */; };
16 | 8557DBCE1B76E238005E5CDD /* FingerTreeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8557DBCD1B76E238005E5CDD /* FingerTreeTest.swift */; };
17 | 8557DBD81B76E7F1005E5CDD /* FingerTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 858F87011A07714A0074F885 /* FingerTree.swift */; };
18 | 8557DBD91B76E80A005E5CDD /* Measure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 858F87031A0774040074F885 /* Measure.swift */; };
19 | 8557DBDA1B76E80A005E5CDD /* TreeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DE369326DC5EABE49EECFE /* TreeView.swift */; };
20 | 8557DBDB1B76E80A005E5CDD /* Split.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DE346643185F70CBED1D22 /* Split.swift */; };
21 | 8557DBDE1B76E80A005E5CDD /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850503C81B6DA453004C5B1A /* Collection.swift */; };
22 | 8557DBE01B77435D005E5CDD /* AffixTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8557DBDF1B77435D005E5CDD /* AffixTest.swift */; };
23 | 8557DBE41B7744E5005E5CDD /* Affix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8557DBE31B7744E5005E5CDD /* Affix.swift */; };
24 | 8557DBE51B7744E5005E5CDD /* Affix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8557DBE31B7744E5005E5CDD /* Affix.swift */; };
25 | 8557DBE71B774569005E5CDD /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8557DBE61B774569005E5CDD /* Node.swift */; };
26 | 8557DBE81B774569005E5CDD /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8557DBE61B774569005E5CDD /* Node.swift */; };
27 | 858F87021A07714A0074F885 /* FingerTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 858F87011A07714A0074F885 /* FingerTree.swift */; };
28 | 858F87041A0774040074F885 /* Measure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 858F87031A0774040074F885 /* Measure.swift */; };
29 | /* End PBXBuildFile section */
30 |
31 | /* Begin PBXCopyFilesBuildPhase section */
32 | 858F86F51A07711D0074F885 /* CopyFiles */ = {
33 | isa = PBXCopyFilesBuildPhase;
34 | buildActionMask = 2147483647;
35 | dstPath = /usr/share/man/man1/;
36 | dstSubfolderSpec = 0;
37 | files = (
38 | );
39 | runOnlyForDeploymentPostprocessing = 1;
40 | };
41 | /* End PBXCopyFilesBuildPhase section */
42 |
43 | /* Begin PBXFileReference section */
44 | 22DE32A13C4CEEB93C6D442B /* TODO.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TODO.txt; sourceTree = ""; };
45 | 22DE346643185F70CBED1D22 /* Split.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Split.swift; sourceTree = ""; };
46 | 22DE369326DC5EABE49EECFE /* TreeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TreeView.swift; sourceTree = ""; };
47 | 850503C81B6DA453004C5B1A /* Collection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Collection.swift; sourceTree = ""; };
48 | 850996571C36B13300FF7FD5 /* NodeTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = NodeTest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
49 | 852DB6AD1B9D277F004FD22D /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
50 | 8557DBCB1B76E238005E5CDD /* FingerTreeTest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FingerTreeTest.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
51 | 8557DBCD1B76E238005E5CDD /* FingerTreeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FingerTreeTest.swift; sourceTree = ""; };
52 | 8557DBCF1B76E238005E5CDD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
53 | 8557DBD71B76E7BF005E5CDD /* FingerTree */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = FingerTree; sourceTree = BUILT_PRODUCTS_DIR; };
54 | 8557DBDF1B77435D005E5CDD /* AffixTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AffixTest.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
55 | 8557DBE31B7744E5005E5CDD /* Affix.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Affix.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
56 | 8557DBE61B774569005E5CDD /* Node.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Node.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
57 | 858F87011A07714A0074F885 /* FingerTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = FingerTree.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
58 | 858F87031A0774040074F885 /* Measure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Measure.swift; sourceTree = ""; };
59 | /* End PBXFileReference section */
60 |
61 | /* Begin PBXFrameworksBuildPhase section */
62 | 8557DBC81B76E238005E5CDD /* Frameworks */ = {
63 | isa = PBXFrameworksBuildPhase;
64 | buildActionMask = 2147483647;
65 | files = (
66 | );
67 | runOnlyForDeploymentPostprocessing = 0;
68 | };
69 | 858F86F41A07711D0074F885 /* Frameworks */ = {
70 | isa = PBXFrameworksBuildPhase;
71 | buildActionMask = 2147483647;
72 | files = (
73 | );
74 | runOnlyForDeploymentPostprocessing = 0;
75 | };
76 | /* End PBXFrameworksBuildPhase section */
77 |
78 | /* Begin PBXGroup section */
79 | 8557DBCC1B76E238005E5CDD /* FingerTreeTest */ = {
80 | isa = PBXGroup;
81 | children = (
82 | 8557DBCD1B76E238005E5CDD /* FingerTreeTest.swift */,
83 | 8557DBDF1B77435D005E5CDD /* AffixTest.swift */,
84 | 850996571C36B13300FF7FD5 /* NodeTest.swift */,
85 | 8557DBCF1B76E238005E5CDD /* Info.plist */,
86 | );
87 | path = FingerTreeTest;
88 | sourceTree = "";
89 | };
90 | 858F86EE1A07711D0074F885 = {
91 | isa = PBXGroup;
92 | children = (
93 | 858F86F91A07711D0074F885 /* FingerTree */,
94 | 8557DBCC1B76E238005E5CDD /* FingerTreeTest */,
95 | 8557DBD71B76E7BF005E5CDD /* FingerTree */,
96 | 8557DBCB1B76E238005E5CDD /* FingerTreeTest.xctest */,
97 | );
98 | sourceTree = "";
99 | };
100 | 858F86F91A07711D0074F885 /* FingerTree */ = {
101 | isa = PBXGroup;
102 | children = (
103 | 858F87011A07714A0074F885 /* FingerTree.swift */,
104 | 858F87031A0774040074F885 /* Measure.swift */,
105 | 22DE369326DC5EABE49EECFE /* TreeView.swift */,
106 | 22DE346643185F70CBED1D22 /* Split.swift */,
107 | 850503C81B6DA453004C5B1A /* Collection.swift */,
108 | 8557DBE31B7744E5005E5CDD /* Affix.swift */,
109 | 8557DBE61B774569005E5CDD /* Node.swift */,
110 | 22DE32A13C4CEEB93C6D442B /* TODO.txt */,
111 | 852DB6AD1B9D277F004FD22D /* main.swift */,
112 | );
113 | path = FingerTree;
114 | sourceTree = "";
115 | };
116 | /* End PBXGroup section */
117 |
118 | /* Begin PBXNativeTarget section */
119 | 8557DBCA1B76E238005E5CDD /* FingerTreeTest */ = {
120 | isa = PBXNativeTarget;
121 | buildConfigurationList = 8557DBD01B76E238005E5CDD /* Build configuration list for PBXNativeTarget "FingerTreeTest" */;
122 | buildPhases = (
123 | 8557DBC71B76E238005E5CDD /* Sources */,
124 | 8557DBC81B76E238005E5CDD /* Frameworks */,
125 | 8557DBC91B76E238005E5CDD /* Resources */,
126 | );
127 | buildRules = (
128 | );
129 | dependencies = (
130 | );
131 | name = FingerTreeTest;
132 | productName = FingerTreeTest;
133 | productReference = 8557DBCB1B76E238005E5CDD /* FingerTreeTest.xctest */;
134 | productType = "com.apple.product-type.bundle.unit-test";
135 | };
136 | 858F86F61A07711D0074F885 /* FingerTree */ = {
137 | isa = PBXNativeTarget;
138 | buildConfigurationList = 858F86FE1A07711D0074F885 /* Build configuration list for PBXNativeTarget "FingerTree" */;
139 | buildPhases = (
140 | 858F86F31A07711D0074F885 /* Sources */,
141 | 858F86F41A07711D0074F885 /* Frameworks */,
142 | 858F86F51A07711D0074F885 /* CopyFiles */,
143 | );
144 | buildRules = (
145 | );
146 | dependencies = (
147 | );
148 | name = FingerTree;
149 | productName = FingerTree;
150 | productReference = 8557DBD71B76E7BF005E5CDD /* FingerTree */;
151 | productType = "com.apple.product-type.tool";
152 | };
153 | /* End PBXNativeTarget section */
154 |
155 | /* Begin PBXProject section */
156 | 858F86EF1A07711D0074F885 /* Project object */ = {
157 | isa = PBXProject;
158 | attributes = {
159 | LastSwiftUpdateCheck = 0700;
160 | LastUpgradeCheck = 0900;
161 | TargetAttributes = {
162 | 8557DBCA1B76E238005E5CDD = {
163 | CreatedOnToolsVersion = 7.0;
164 | LastSwiftMigration = 0900;
165 | };
166 | 858F86F61A07711D0074F885 = {
167 | CreatedOnToolsVersion = 6.1;
168 | LastSwiftMigration = 0900;
169 | };
170 | };
171 | };
172 | buildConfigurationList = 858F86F21A07711D0074F885 /* Build configuration list for PBXProject "FingerTree" */;
173 | compatibilityVersion = "Xcode 6.3";
174 | developmentRegion = English;
175 | hasScannedForEncodings = 0;
176 | knownRegions = (
177 | en,
178 | );
179 | mainGroup = 858F86EE1A07711D0074F885;
180 | productRefGroup = 858F86EE1A07711D0074F885;
181 | projectDirPath = "";
182 | projectRoot = "";
183 | targets = (
184 | 858F86F61A07711D0074F885 /* FingerTree */,
185 | 8557DBCA1B76E238005E5CDD /* FingerTreeTest */,
186 | );
187 | };
188 | /* End PBXProject section */
189 |
190 | /* Begin PBXResourcesBuildPhase section */
191 | 8557DBC91B76E238005E5CDD /* Resources */ = {
192 | isa = PBXResourcesBuildPhase;
193 | buildActionMask = 2147483647;
194 | files = (
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | /* End PBXResourcesBuildPhase section */
199 |
200 | /* Begin PBXSourcesBuildPhase section */
201 | 8557DBC71B76E238005E5CDD /* Sources */ = {
202 | isa = PBXSourcesBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | 8557DBE01B77435D005E5CDD /* AffixTest.swift in Sources */,
206 | 8557DBD81B76E7F1005E5CDD /* FingerTree.swift in Sources */,
207 | 8557DBDA1B76E80A005E5CDD /* TreeView.swift in Sources */,
208 | 8557DBE81B774569005E5CDD /* Node.swift in Sources */,
209 | 8557DBE51B7744E5005E5CDD /* Affix.swift in Sources */,
210 | 8557DBDE1B76E80A005E5CDD /* Collection.swift in Sources */,
211 | 8557DBCE1B76E238005E5CDD /* FingerTreeTest.swift in Sources */,
212 | 852DB6AF1B9D277F004FD22D /* main.swift in Sources */,
213 | 850996581C36B13300FF7FD5 /* NodeTest.swift in Sources */,
214 | 8557DBD91B76E80A005E5CDD /* Measure.swift in Sources */,
215 | 8557DBDB1B76E80A005E5CDD /* Split.swift in Sources */,
216 | );
217 | runOnlyForDeploymentPostprocessing = 0;
218 | };
219 | 858F86F31A07711D0074F885 /* Sources */ = {
220 | isa = PBXSourcesBuildPhase;
221 | buildActionMask = 2147483647;
222 | files = (
223 | 858F87021A07714A0074F885 /* FingerTree.swift in Sources */,
224 | 852DB6AE1B9D277F004FD22D /* main.swift in Sources */,
225 | 850503C91B6DA453004C5B1A /* Collection.swift in Sources */,
226 | 8557DBE71B774569005E5CDD /* Node.swift in Sources */,
227 | 858F87041A0774040074F885 /* Measure.swift in Sources */,
228 | 8557DBE41B7744E5005E5CDD /* Affix.swift in Sources */,
229 | 22DE35CD6B042406277DD9FC /* TreeView.swift in Sources */,
230 | 22DE31BA22EAD8EF74655BC6 /* Split.swift in Sources */,
231 | );
232 | runOnlyForDeploymentPostprocessing = 0;
233 | };
234 | /* End PBXSourcesBuildPhase section */
235 |
236 | /* Begin XCBuildConfiguration section */
237 | 8557DBD11B76E238005E5CDD /* Debug */ = {
238 | isa = XCBuildConfiguration;
239 | buildSettings = {
240 | COMBINE_HIDPI_IMAGES = YES;
241 | DEBUG_INFORMATION_FORMAT = dwarf;
242 | GCC_NO_COMMON_BLOCKS = YES;
243 | INFOPLIST_FILE = FingerTreeTest/Info.plist;
244 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
245 | PRODUCT_BUNDLE_IDENTIFIER = lazytype.FingerTreeTest;
246 | PRODUCT_NAME = "$(TARGET_NAME)";
247 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
248 | SWIFT_VERSION = 4.0;
249 | };
250 | name = Debug;
251 | };
252 | 8557DBD21B76E238005E5CDD /* Release */ = {
253 | isa = XCBuildConfiguration;
254 | buildSettings = {
255 | COMBINE_HIDPI_IMAGES = YES;
256 | COPY_PHASE_STRIP = NO;
257 | GCC_NO_COMMON_BLOCKS = YES;
258 | INFOPLIST_FILE = FingerTreeTest/Info.plist;
259 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
260 | PRODUCT_BUNDLE_IDENTIFIER = lazytype.FingerTreeTest;
261 | PRODUCT_NAME = "$(TARGET_NAME)";
262 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
263 | SWIFT_VERSION = 4.0;
264 | };
265 | name = Release;
266 | };
267 | 858F86FC1A07711D0074F885 /* Debug */ = {
268 | isa = XCBuildConfiguration;
269 | buildSettings = {
270 | ALWAYS_SEARCH_USER_PATHS = NO;
271 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
272 | CLANG_CXX_LIBRARY = "libc++";
273 | CLANG_ENABLE_MODULES = YES;
274 | CLANG_ENABLE_OBJC_ARC = YES;
275 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
276 | CLANG_WARN_BOOL_CONVERSION = YES;
277 | CLANG_WARN_COMMA = YES;
278 | CLANG_WARN_CONSTANT_CONVERSION = YES;
279 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
280 | CLANG_WARN_EMPTY_BODY = YES;
281 | CLANG_WARN_ENUM_CONVERSION = YES;
282 | CLANG_WARN_INFINITE_RECURSION = YES;
283 | CLANG_WARN_INT_CONVERSION = YES;
284 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
285 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
286 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
287 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
288 | CLANG_WARN_STRICT_PROTOTYPES = YES;
289 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
290 | CLANG_WARN_UNREACHABLE_CODE = YES;
291 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
292 | COPY_PHASE_STRIP = NO;
293 | ENABLE_STRICT_OBJC_MSGSEND = YES;
294 | ENABLE_TESTABILITY = YES;
295 | GCC_C_LANGUAGE_STANDARD = gnu99;
296 | GCC_DYNAMIC_NO_PIC = NO;
297 | GCC_NO_COMMON_BLOCKS = YES;
298 | GCC_OPTIMIZATION_LEVEL = fast;
299 | GCC_PREPROCESSOR_DEFINITIONS = (
300 | "DEBUG=1",
301 | "$(inherited)",
302 | );
303 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
304 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
305 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
306 | GCC_WARN_UNDECLARED_SELECTOR = YES;
307 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
308 | GCC_WARN_UNUSED_FUNCTION = YES;
309 | GCC_WARN_UNUSED_VARIABLE = YES;
310 | MACOSX_DEPLOYMENT_TARGET = 10.11;
311 | MTL_ENABLE_DEBUG_INFO = YES;
312 | ONLY_ACTIVE_ARCH = YES;
313 | SDKROOT = macosx;
314 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
315 | SWIFT_VERSION = 4.0;
316 | };
317 | name = Debug;
318 | };
319 | 858F86FD1A07711D0074F885 /* Release */ = {
320 | isa = XCBuildConfiguration;
321 | buildSettings = {
322 | ALWAYS_SEARCH_USER_PATHS = NO;
323 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
324 | CLANG_CXX_LIBRARY = "libc++";
325 | CLANG_ENABLE_MODULES = YES;
326 | CLANG_ENABLE_OBJC_ARC = YES;
327 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
328 | CLANG_WARN_BOOL_CONVERSION = YES;
329 | CLANG_WARN_COMMA = YES;
330 | CLANG_WARN_CONSTANT_CONVERSION = YES;
331 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
332 | CLANG_WARN_EMPTY_BODY = YES;
333 | CLANG_WARN_ENUM_CONVERSION = YES;
334 | CLANG_WARN_INFINITE_RECURSION = YES;
335 | CLANG_WARN_INT_CONVERSION = YES;
336 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
337 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
338 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
339 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
340 | CLANG_WARN_STRICT_PROTOTYPES = YES;
341 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
342 | CLANG_WARN_UNREACHABLE_CODE = YES;
343 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
344 | COPY_PHASE_STRIP = YES;
345 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
346 | ENABLE_NS_ASSERTIONS = NO;
347 | ENABLE_STRICT_OBJC_MSGSEND = YES;
348 | GCC_C_LANGUAGE_STANDARD = gnu99;
349 | GCC_NO_COMMON_BLOCKS = YES;
350 | GCC_OPTIMIZATION_LEVEL = fast;
351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
353 | GCC_WARN_UNDECLARED_SELECTOR = YES;
354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
355 | GCC_WARN_UNUSED_FUNCTION = YES;
356 | GCC_WARN_UNUSED_VARIABLE = YES;
357 | MACOSX_DEPLOYMENT_TARGET = 10.11;
358 | MTL_ENABLE_DEBUG_INFO = NO;
359 | ONLY_ACTIVE_ARCH = YES;
360 | SDKROOT = macosx;
361 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
362 | SWIFT_VERSION = 4.0;
363 | };
364 | name = Release;
365 | };
366 | 858F86FF1A07711D0074F885 /* Debug */ = {
367 | isa = XCBuildConfiguration;
368 | buildSettings = {
369 | CLANG_USE_OPTIMIZATION_PROFILE = YES;
370 | DEFINES_MODULE = YES;
371 | GCC_OPTIMIZATION_LEVEL = fast;
372 | LLVM_LTO = YES;
373 | PRODUCT_NAME = "$(TARGET_NAME)";
374 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
375 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
376 | SWIFT_VERSION = 4.0;
377 | };
378 | name = Debug;
379 | };
380 | 858F87001A07711D0074F885 /* Release */ = {
381 | isa = XCBuildConfiguration;
382 | buildSettings = {
383 | CLANG_USE_OPTIMIZATION_PROFILE = YES;
384 | DEFINES_MODULE = YES;
385 | GCC_OPTIMIZATION_LEVEL = fast;
386 | LLVM_LTO = YES;
387 | PRODUCT_NAME = "$(TARGET_NAME)";
388 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
389 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
390 | SWIFT_VERSION = 4.0;
391 | };
392 | name = Release;
393 | };
394 | /* End XCBuildConfiguration section */
395 |
396 | /* Begin XCConfigurationList section */
397 | 8557DBD01B76E238005E5CDD /* Build configuration list for PBXNativeTarget "FingerTreeTest" */ = {
398 | isa = XCConfigurationList;
399 | buildConfigurations = (
400 | 8557DBD11B76E238005E5CDD /* Debug */,
401 | 8557DBD21B76E238005E5CDD /* Release */,
402 | );
403 | defaultConfigurationIsVisible = 0;
404 | defaultConfigurationName = Release;
405 | };
406 | 858F86F21A07711D0074F885 /* Build configuration list for PBXProject "FingerTree" */ = {
407 | isa = XCConfigurationList;
408 | buildConfigurations = (
409 | 858F86FC1A07711D0074F885 /* Debug */,
410 | 858F86FD1A07711D0074F885 /* Release */,
411 | );
412 | defaultConfigurationIsVisible = 0;
413 | defaultConfigurationName = Release;
414 | };
415 | 858F86FE1A07711D0074F885 /* Build configuration list for PBXNativeTarget "FingerTree" */ = {
416 | isa = XCConfigurationList;
417 | buildConfigurations = (
418 | 858F86FF1A07711D0074F885 /* Debug */,
419 | 858F87001A07711D0074F885 /* Release */,
420 | );
421 | defaultConfigurationIsVisible = 0;
422 | defaultConfigurationName = Release;
423 | };
424 | /* End XCConfigurationList section */
425 | };
426 | rootObject = 858F86EF1A07711D0074F885 /* Project object */;
427 | }
428 |
--------------------------------------------------------------------------------