!=========================================================================
! Copyright (C) VMware, Inc. 1986-2011.  All Rights Reserved.
!
! $Id: orderedcollection.gs,v 1.8 2008-01-09 22:50:13 stever Exp $
!
! Superclass Hierarchy:
!   OrderedCollection, SequenceableCollection, Collection, Object.
!
!=========================================================================

expectvalue %String
run
SequenceableCollection _newKernelSubclass: 'OrderedCollection'
  instVarNames: #()
  classVars: #()
  classInstVars: #()
  poolDictionaries: #[]
  inDictionary: Globals
  constraints: #()
  instancesInvariant: false
  isModifiable: false
  reservedOop: 725
%

! remove existing behavior from OrderedCollection
removeallmethods OrderedCollection
removeallclassmethods OrderedCollection

! ------------------- Class methods for OrderedCollection
category: 'For Documentation Installation only'
classmethod: OrderedCollection
installDocumentation

| doc txt |
doc := GsClassDocumentation newForClass: self.

txt := (GsDocText new) details:
'An OrderedCollection is a SequenceableCollection that maintains the order of
 objects it contains.  In GemStone, OrderedCollections are very similar to
 Arrays.  They differ from Arrays in that they understand all of the messages
 that Smalltalk OrderedCollections implement.'.
doc documentClassWith: txt.

self description: doc.
%

category: 'Instance Creation'
classmethod: OrderedCollection
new: size

"This method is supplied for compatibility with other implementations of 
 Smalltalk.  Its behavior differs from other Smalltalks in that it ignores the
 extension and returns an instance with size 0.
 
 Other Smalltalks use an instance variable to keep track of the number of 
 elements in what are fixed-size instances.  GemStone objects are dynamically
 extensible and the size of the object is used to keep track of the number of
 elements in the collection."
 
| inst |
inst := super new.
^inst
%

! ------------------- Instance methods for OrderedCollection

category: 'Adding'
method: OrderedCollection
add: newObject after: targetObject

"Adds newObject to the receiver immediately following the first element that is
 equal to targetObject, and returns newObject.  If targetObject is not found, 
 reports an error."

| index |

index := self indexOf: targetObject 
             ifAbsent: [^ self _errorNotFound: targetObject].

^ self insertObject: newObject at: (index + 1).
%

category: 'Adding'
method: OrderedCollection
add: newObject afterIndex: anIndex

"Adds newObject to the receiver at the index immediately following anIndex."

^ self insertObject: newObject at: (anIndex + 1).
%

category: 'Adding'
method: OrderedCollection
add: newObject before: targetObject

"Adds newObject to the receiver immediately before the first element that is
 equal to targetObject, and returns newObject.  If targetObject is not found, 
 reports an error."

| index |

index := self indexOf: targetObject 
             ifAbsent: [^ self _errorNotFound: targetObject].

^ self insertObject: newObject at: index.
%

category: 'Adding'
method: OrderedCollection
add: newObject beforeIndex: anIndex

"Inserts newObject to the receiver at the index anIndex and returns newObject."

^ self insertObject: newObject at: anIndex.
%

category: 'Adding'
method: OrderedCollection
addAll: aCollection after: targetObject

"Adds each element of aCollection to the receiver immediately following the 
 first element of the receiver which is equal to targetObject.  Reports an error
 if targetObject is not found.  Returns aCollection."

| index |

index := self indexOf: targetObject 
             ifAbsent: [^ self _errorNotFound: targetObject].

^ self insertAll: aCollection at: (index + 1).
%

category: 'Adding'
method: OrderedCollection
addAll: aCollection afterIndex: anIndex

"Adds each element of aCollection to the receiver immediately after the element
 of the receiver at index anIndex.  Reports an error if targetObject is not
 found.   Returns aCollection."

^ self insertAll: aCollection at: (anIndex + 1).
%

category: 'Adding'
method: OrderedCollection
addAll: aCollection before: targetObject

"Adds each element of aCollection to the receiver immediately before the 
 first element of the receiver which is equal to targetObject.  Reports an error
 if targetObject is not found.  Returns aCollection."

| index |

index := self indexOf: targetObject 
             ifAbsent: [^ self _errorNotFound: targetObject].

^ self insertAll: aCollection at: index.
%

category: 'Adding'
method: OrderedCollection
addAll: aCollection beforeIndex: anIndex

"Adds each element of aCollection to the receiver immediately before the 
 element of the receiver at index anIndex.  Reports an error if targetObject is 
 not found.  Returns aCollection."

^ self insertAll: aCollection at: anIndex.
%

category: 'Adding'
method: OrderedCollection
addAllFirst: aCollection

"Inserts the given objects at the beginning of the receiver.  Returns the
 argument, aCollection."

self insertAll: aCollection at: 1.
^aCollection
%

category: 'Adding'
method: OrderedCollection
addAllLast: aCollection

"Appends the objects in aCollection to the receiver.  Returns aCollection."

self addAll: aCollection.
^aCollection
%

category: 'Adding'
method: OrderedCollection
addFirst: anObject

"Inserts the given object at the beginning of the receiver.  Returns the
 inserted object."

self insertObject: anObject at: 1.
^anObject
%

! add methods to call primitives for Array to improve performance.

! removeFrom: startIndex to: stopIndex inherited from SequenceableCollection

category: 'Adding'
method: OrderedCollection
addLast: newObject

"Adds newObject as the last element of the receiver and returns newObject."

"Note: In GemStone 4.1, this method returned the receiver."

<primitive: 203>
self _primitiveFailed: #addLast: .
self _uncontinuableError
%

category: 'Adding'
method: OrderedCollection
add: newObject

"(R) Makes newObject one of the receiver's elements and returns newObject.  The
 new element is actually added as the last element of the receiver.  This
 method is equivalent to #addLast:."

"Note: In GemStone 4.1, this method returned the receiver."

<primitive: 203>
self _primitiveFailed: #add: .
self _uncontinuableError
%

category: 'Adding'
method: OrderedCollection
addAll: aCollection

"(R) Adds all of the elements of aCollection to the receiver and returns
 aCollection."

| collectionSize |

(self == aCollection) ifTrue: [ ^ self addAll: (aCollection copy) ].

(aCollection isKindOf: SequenceableCollection) 
  ifTrue: [
    collectionSize := aCollection size.
    (collectionSize ~~ 0) ifTrue:[ 
      self insertAll: aCollection at: (self size + 1) 
      ].
    ^ aCollection.
    ]
  ifFalse: [
    ((aCollection isKindOf: IdentityBag) 
       _and: [ aCollection _isRcIdentityBag not ]) 
      ifTrue:[
        self _addAllFromNsc: aCollection .
        ^ aCollection.
        ]
      ifFalse: [
        aCollection do: [:each | self add: each ].
        ^ aCollection.
        ]
    ]
%
category: 'Adding'
method: OrderedCollection
_addAllFromNsc: aBag

""

<primitive: 202>
self _primitiveFailed: #_addAllFromNsc: .
self _uncontinuableError
%

category: 'Searching'
method: OrderedCollection
includesIdentical: anObject

"(R) Returns true if anObject is identical to one of the elements of the
 receiver.  Returns false otherwise."

<primitive: 59>
self _primitiveFailed: #includesIdentical:
%

category: 'Searching'
method: OrderedCollection
_indexOfIdentical: anObject

"Private.  Returns the index of the first element in the receiver that is
 identical to the argument.  If the receiver does not have any elements that are
 identical to the argument, returns zero."

<primitive: 494>
self _primitiveFailed: #_indexOfIdentical:
%

category: 'Copying'
method: OrderedCollection
copyFrom: index1 to: index2 into: aSeqColl startingAt: destIndex

"(R) Copies the elements of the receiver between index1 and index2, inclusive,
 into aSeqColl starting at destIndex, overwriting the previous contents.  If
 aSeqColl is the same object as the receiver, the source and destination blocks
 may overlap."

<primitive: 608 >

(index1 > index2)
  ifTrue:[ index1 _error: #rtErrBadCopyFromTo args: #[index2]].

(index1 < 1) ifTrue:[ self _errorIndexOutOfRange: index1].

(index2 > self size) ifTrue:[ self _errorIndexOutOfRange: index2].

aSeqColl _validateClass: SequenceableCollection.
((destIndex < 1) _or: [(destIndex > (aSeqColl size + 1))])
  ifTrue:[ aSeqColl _errorIndexOutOfRange: destIndex].
^super copyFrom: index1 to: index2 into: aSeqColl startingAt: destIndex
%

category: 'Comparing'
method: OrderedCollection
hasIdenticalContents: anArray

"Returns true if all of the following conditions are true:

 1.  The receiver and anArray are of the same class.
 2.  The two Arrays are the same size.
 3.  The corresponding elements of the receiver and anArray are equal.

 Returns false otherwise."

<primitive: 612 >

self _primitiveFailed: #hasIdenticalContents.
self _uncontinuableError
%


