requires: {#Collection}. provides: {#LinkedCollection. #Link. #LinkedList}. collections addSlot: #LinkedCollection valued: Collection derive. "LinkedCollections are those whose elements include state that encodes the collection's structure. This includes linked-lists, trees, and graphs. The collection types may or may not have a facade object which is different from the elements and may keep track of circularities or such." "The general axioms for LinkedCollections are that they must be singly- connected (it's a topology term for all-in-one-piece), and that the results of 'c add: a' or 'c remove: a' will side-effect 'a'. Or if add: and remove: are not defined, consider it in terms of the change between include: results changing." lc@(LinkedCollection traits) newEmpty "This generally doesn't need to be overridden unless the collection type uses a facade." [ lc clone clear ]. lc@(LinkedCollection traits) newSize: _ "Links cannot be pre-allocated simply by overall size." [ lc newEmpty ]. collections addSlot: #Link valued: Cloneable derive. Link addSlot: #next. Link addSlot: #previous. collections addSlot: #LinkedList valued: (LinkedCollection deriveWith: {ExtensibleCollection. Sequence. Link}). ll@(LinkedList traits) do: block [| link | link: ll next. [link == ll] whileFalse: [ block value: link. link: link next ] ]. ll@(LinkedList traits) reverseDo: block [| link | link: ll previous. [link == ll] whileFalse: [ block value: link. link: link previous ] ]. ll@(LinkedList traits) clear [ ll next: ll. ll previous: ll. ll ]. ll@(LinkedList traits) isEmpty [ll next == ll]. ll@(LinkedList traits) first [ll next]. ll@(LinkedList traits) last [ll previous]. ll@(LinkedList traits) at: index [| position | position _ ll next. index timesRepeat: [position: position next]. position ]. ll@(LinkedList traits) add: newObject before: oldObject [ newObject next: oldObject. newObject previous: oldObject previous. oldObject previous: newObject. newObject previous next: newObject. newObject ]. ll@(LinkedList traits) add: newObject after: oldObject [ ll add: newObject before: oldObject next ]. ll@(LinkedList traits) addFirst: newObject [ ll add: newObject before: ll first ]. ll@(LinkedList traits) addLast: newObject [ ll add: newObject after: ll last ].