#FEATURE by stefan
authorStefan Vogel <sv@exept.de>
Wed, 22 Feb 2017 15:32:46 +0100
changeset 4345 0000c66ef9f0
parent 4344 f0115b3b9a86
child 4346 7a4c996ac8f0
#FEATURE by stefan class: Queue add missing methods added: #addFirst: #findFirst:ifNone: #findLast:ifNone: #grow: #remove:ifAbsent: #reverseDo: changed: #do:
Queue.st
--- a/Queue.st	Wed Feb 22 15:32:00 2017 +0100
+++ b/Queue.st	Wed Feb 22 15:32:46 2017 +0100
@@ -192,6 +192,116 @@
     "
 !
 
+remove:anElement ifAbsent:exceptionalValue
+    "remove and return a particular element from the queue;
+     Return the value from exceptionalValue if the element is not in the queue"
+
+    |rPos "{ Class: SmallInteger }"
+     wPos "{ Class: SmallInteger }"
+     countRemoved
+     el sz|
+
+
+    (tally == 0) ifTrue:[
+        ^ exceptionalValue value
+    ].
+    sz := contentsArray size.
+
+    rPos := wPos := readPosition.
+
+    countRemoved := 0.
+
+    1 to:tally do:[:index|
+        el := contentsArray at:rPos.
+        el = anElement ifTrue:[
+            countRemoved := countRemoved + 1.
+            contentsArray at:wPos put:nil.
+        ] ifFalse:[
+            rPos ~~ wPos ifTrue:[
+                contentsArray at:wPos put:el.
+            ].
+            wPos == sz ifTrue:[
+                wPos := 1.
+            ] ifFalse:[
+                wPos := wPos + 1.
+            ].
+        ].
+        rPos == sz ifTrue:[
+            rPos := 1.
+        ] ifFalse:[
+            rPos := rPos + 1.
+        ].
+    ].
+    countRemoved == 0 ifTrue:[
+        ^ exceptionalValue value
+    ].
+
+    tally = countRemoved ifTrue:[
+        wPos := readPosition.
+    ].
+    writePosition := wPos.
+    tally := tally - countRemoved.
+    ^ el
+
+    "
+     |q|
+
+     q := Queue new:10.
+     q nextPut:1; nextPut:2; nextPutAll:(3 to:10).
+     q next.
+     q nextPut:11.
+     q next.
+     q nextPut:12.
+     q next.
+     q remove:5.
+     q
+
+     |q|
+
+     q := Queue new:10.
+     q nextPut:1; nextPut:2; nextPutAll:(3 to:8).
+     self assert:(q next == 1).
+     self assert:(q next == 2).
+     q removeIdentical:5.
+     self assert:(q next == 3).
+     self assert:(q next == 4).
+     self assert:(q next == 6).
+     self assert:(q next == 7).
+     self assert:(q next == 8).
+     self assert:(q isEmpty).
+     q
+
+     |q|
+
+     q := Queue new:10.
+     q nextPut:1; nextPut:2.
+     self assert:(q next == 1).
+     q remove:2.
+     self assert:(q isEmpty).
+     q nextPut:3.
+     self assert:(q isEmpty not).
+     self assert:(q next == 3).
+     self assert:(q isEmpty).
+
+     |q|
+
+     q := Queue new:10.
+     q nextPut:1; nextPut:2; nextPut:3.
+     self assert:(q next == 1).
+     q remove:3.
+     self assert:(q isEmpty not).
+     q nextPut:4.
+     q removeI:4.
+     q nextPut:5.
+     self assert:(q isEmpty not).
+     self assert:(q next == 2).
+     self assert:(q next == 5).
+     self assert:(q isEmpty).
+    "
+
+    "Created: / 22-02-2017 / 14:49:26 / stefan"
+!
+
 removeAll
     "remove all elements in the queue; return the receiver"
 
@@ -342,6 +452,15 @@
     ^ someObject
 !
 
+addFirst:someObject
+    "same as #nextPutFirst: - for protocol compatibility with other collections"
+
+    self nextPutFirst:someObject.
+    ^ someObject
+
+    "Created: / 22-02-2017 / 15:12:58 / stefan"
+!
+
 removeFirst
     "same as #next - for protocol compatibility with other collections"
 
@@ -455,19 +574,54 @@
     "evaluate the argument, aBlock for each element in the queue"
 
     |n   "{ Class: SmallInteger }"
-     pos "{ Class: SmallInteger }"|
+     pos "{ Class: SmallInteger }"
+     sz|
 
     pos := readPosition.
+    sz := contentsArray size.
     n := tally.
-    1 to:n do:[:i |
+    n timesRepeat:[
         aBlock value:(contentsArray at:pos).
         pos := pos + 1.
-        pos > contentsArray size ifTrue:[
-            pos := 1
+        pos > sz ifTrue:[
+            pos := 1.
         ]
     ]
 
-    "Modified: 18.10.1997 / 16:24:01 / cg"
+    "Modified: / 18-10-1997 / 16:24:01 / cg"
+    "Modified (format): / 22-02-2017 / 14:59:38 / stefan"
+!
+
+reverseDo:aBlock
+    "evaluate the argument, aBlock for each element in the queue"
+
+    |n   "{ Class: SmallInteger }"
+     pos "{ Class: SmallInteger }"
+     sz|
+
+    pos := writePosition.
+    sz := contentsArray size.
+    n := tally.
+    n timesRepeat:[
+        pos := pos - 1.
+        pos <= 0 ifTrue:[
+            pos := sz.
+        ].
+        aBlock value:(contentsArray at:pos).
+    ].
+
+    "
+     |q coll|
+
+     coll := OrderedCollection new.
+     q := Queue new:10.
+     q nextPut:1; nextPut:2; nextPutAll:(3 to:8).
+     q removeFirst; removeLast.
+     q reverseDo:[:el| coll add:el].
+     coll.
+    "
+
+    "Created: / 22-02-2017 / 15:03:02 / stefan"
 ! !
 
 !Queue methodsFor:'initialization'!
@@ -523,6 +677,26 @@
     tally := 0.
 ! !
 
+!Queue methodsFor:'not implemented'!
+
+findFirst:anObject ifNone:aBlock
+    ^ self shouldNotImplement.
+
+    "Created: / 22-02-2017 / 15:14:04 / stefan"
+!
+
+findLast:anObject ifNone:aBlock
+    ^ self shouldNotImplement.
+
+    "Created: / 22-02-2017 / 15:14:11 / stefan"
+!
+
+grow:newSize
+    ^ self shouldNotImplement.
+
+    "Created: / 22-02-2017 / 15:14:58 / stefan"
+! !
+
 !Queue methodsFor:'queries'!
 
 capacity