collections addPrototype: #Cord derivedFrom: {Sequence}. Cord addSlot: #split. "The index where the second half begins." Cord addSlot: #firstBranch. "The first half of the cord." Cord addSlot: #secondBranch. "The latter half of the cord." Cord addSlot: #depth valued: 1. "The default for a couple of strings ;;'d." Cord addSlot: #size. "The incrementally-calculated Cord size." c1@(Sequence traits) ;; c2@(Sequence traits) "Build a cord out of any 2 sequences." [| newC | c1 isEmpty ifTrue: [^ c2]. c2 isEmpty ifTrue: [^ c1]. newC: Cord clone. newC split: c1 size. newC firstBranch: c1. newC secondBranch: c2. newC size: c1 size + c2 size. newC ]. c1@(Sequence traits) ;; c2@(Cord traits) "Set up the depth if the second element is a cord." [| newC | newC: resend. newC depth: c2 depth + 1. newC ]. c1@(Cord traits) ;; c2@(Sequence traits) "Set up the depth if the first element is a cord." [| newC | newC: resend. newC depth: c1 depth + 1. newC ]. c1@(Cord traits) ;; c2@(Cord traits) "If both are cords, the deepest counts for the depth." [| newC | newC: resend. newC depth: (c1 depth max: c2 depth) + 1. newC ]. c@(Cord traits) at: n "Recursively descend the tree to find the element in the base sequences. Since this is ~O(log n) vs O(0), iterators need to avoid this and use do: or doWithIndex:." [ n < c split ifTrue: [c firstBranch at: n] ifFalse: [c secondBranch at: n - split] ]. c@(Cord traits) do: block "The major premise of this override is to avoid calling at: for each index, since it is more expensive for Cords to perform." [ c firstBranch do: block. c secondBranch do: block. c ]. c@(Cord traits) doWithIndex: block "Simulate an index during the traversal." [| idx | idx: 0. c do: [| :each | block applyWith: each with: idx. idx: idx + 1]. c ]. c@(Cord traits) as: sc@(Sequence traits) [| newSC | newSC: (sc newSizeOf: c). c doWithIndex: [| :each :index | newSC at: index put: each]. newSC ]. c@(Cord traits) as: sc@(ExtensibleArray traits) [| newOC | newOC: (oc newSizeOf: c). newOC addAllLast: c. newOC ]. c@(Cord traits) shouldBeFlattened "Pick a pretty small number that statistically is easier to just make a new sequence for, and make sure that it's not just a base Cord." [ c size < 20 and: [c depth >= 2] ]. c@(Cord traits) flatten [ c as: Array ]. c@(Cord traits) shouldBeBalanced [ c depth ]. c@(Cord traits) balance [ c notYetImplemented ].