00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stlib/SequenceableCollection.h>
00025
00026 #include <stlib/Array.h>
00027 #include <stlib/ByteArray.h>
00028 #include <stlib/CollectionIterator.h>
00029 #include <stlib/String.h>
00030 #include <stlib/ReadStream.h>
00031 #include <stlib/ReadAppendStream.h>
00032 #include <stlib/WriteStream.h>
00033
00034
00035 Object *SequenceableCollection::any(void)
00036 {
00037 return first();
00038 }
00039
00040 Object *SequenceableCollection::first(void)
00041 {
00042 emptyCheck();
00043 return at(0);
00044 }
00045
00046 Object *SequenceableCollection::last(void)
00047 {
00048 emptyCheck();
00049 return at(size()-1);
00050 }
00051
00052 void SequenceableCollection::replace(long start, long stop,
00053 const SequenceableCollection *collection)
00054 {
00055 if (collection->size() != stop - start)
00056 error(new String("Size of replacement doesn\'t match."),
00057 new String(__PRETTY_FUNCTION__));
00058 replace(start, stop, collection, 0);
00059 }
00060
00061 void SequenceableCollection::replace(long start, long stop,
00062 const SequenceableCollection *replacement,
00063 long repStart)
00064 {
00065 long repOff = repStart - start;
00066 if (this == replacement && repStart < start) {
00067
00068 for (long i = stop - 1; i >= start; i--)
00069 put(i, replacement->at(repOff + i));
00070 } else {
00071 for (long i = start; i < stop; i++)
00072 put(i, replacement->at(repOff + i));
00073 }
00074 }
00075
00076 void SequenceableCollection::replaceAll(Object *element, Object *replacement)
00077 {
00078 replaceAll(element, replacement, 0, size());
00079 }
00080
00081 void SequenceableCollection::replaceAll(Object *element, Object *replacement,
00082 long startIndex, long stopIndex)
00083 {
00084 long index = startIndex - 1;
00085
00086 while ((index = nextIndexOf(element, index+1, stopIndex)) < stopIndex) {
00087 put(index, replacement);
00088 }
00089 }
00090
00091 long SequenceableCollection::indexOf(Object *element) const
00092 {
00093 long index;
00094
00095 index = nextIndexOf(element, 0, size());
00096 if (index < 0 || index >= size()) index = -1;
00097 return index;
00098 }
00099
00100 long SequenceableCollection::lastIndexOf(Object *element) const
00101 {
00102 long index;
00103
00104 index = prevIndexOf(element, size(), 0);
00105 if (index < 0 || index >= size()) index = -1;
00106 return index;
00107 }
00108
00109 long SequenceableCollection::nextIndexOf(Object *element, long startIndex,
00110 long stopIndex) const
00111 {
00112 for (long index = startIndex; index < stopIndex; index++) {
00113 if (at(index)->isEqual(element))
00114 return index;
00115 }
00116 return stopIndex;
00117 }
00118
00119 long SequenceableCollection::prevIndexOf(Object *element, long startIndex,
00120 long stopIndex) const
00121 {
00122 for (long index = startIndex - 1; index >= stopIndex; index--) {
00123 if (at(index)->isEqual(element))
00124 return index;
00125 }
00126 return stopIndex - 1;
00127 }
00128
00129 long SequenceableCollection::indexOfSubCollection(SequenceableCollection *coll) const
00130 {
00131 return indexOfSubCollection(coll, 0);
00132 }
00133
00134 long SequenceableCollection::indexOfSubCollection(SequenceableCollection *coll,
00135 long startIndex) const
00136 {
00137 long subSize = coll->size();
00138 Object *firstElement;
00139 long len, matchIndex;
00140
00141 if (subSize == 0) return -1;
00142 if (subSize + startIndex > size()) return -1;
00143 firstElement = coll->at(0);
00144 len = size() - subSize + 1;
00145 matchIndex = nextIndexOf(firstElement, startIndex, len);
00146 if (subSize == 1)
00147 return (matchIndex >= 0 && matchIndex < len) ? matchIndex : -1;
00148 while (matchIndex < len) {
00149 long index = 1;
00150 while (this->at(matchIndex + index)->isEqual(coll->at(index))) {
00151 index++;
00152 if (index == subSize) return matchIndex;
00153 }
00154 matchIndex = nextIndexOf(firstElement, matchIndex + 1, len);
00155 }
00156 return -1;
00157 }
00158
00159
00160 void SequenceableCollection::grow(void)
00161 {
00162 changeSize(size() + growSize());
00163 }
00164
00165 void SequenceableCollection::growToAtLeast(long items)
00166 {
00167 if (items < size()) return;
00168 changeSize(items + growSize());
00169 }
00170
00171
00172 Array *SequenceableCollection::asArray(void)
00173 {
00174 Array *newArray = new Array(size());
00175 for (long i = 0; i < size(); i++) {
00176 newArray->put(i, at(i));
00177 }
00178 return newArray;
00179 }
00180
00181 ByteArray *SequenceableCollection::asByteArray(void)
00182 {
00183 shouldNotImplement(new String(__PRETTY_FUNCTION__));
00184 return nil;
00185 }
00186
00187 String *SequenceableCollection::asString(void)
00188 {
00189 shouldNotImplement(new String(__PRETTY_FUNCTION__));
00190 return nil;
00191 }
00192
00193 ReadStream *SequenceableCollection::readStream(void)
00194 {
00195 return new ReadStream(this);
00196 }
00197
00198 ReadAppendStream *SequenceableCollection::readAppendStream(void)
00199 {
00200 return new ReadAppendStream(this);
00201 }
00202
00203 WriteStream *SequenceableCollection::writeStream(void)
00204 {
00205 return new WriteStream(this);
00206 }
00207
00208
00213 Object *SequenceableCollection::copy(long from, long to)
00214 {
00215 SequenceableCollection *newColl;
00216 int newSize = to - from;
00217
00218 newColl = (SequenceableCollection *) copyEmpty(newSize);
00219 newColl->replace(0, newSize, this, from);
00220 return newColl;
00221 }
00222
00223 SequenceableCollection *SequenceableCollection::copyReplace(long from, long to,
00224 SequenceableCollection *replacement)
00225 {
00226 SequenceableCollection *newCollection;
00227 long newSize;
00228 long endReplacement;
00229
00230 newSize = size() - (to - from) + replacement->size();
00231 endReplacement = from + replacement->size();
00232 newCollection = (SequenceableCollection *) copyEmpty(newSize);
00233 newCollection->replace(0, from, this, 0);
00234 newCollection->replace(from, endReplacement, replacement, 0);
00235 newCollection->replace(endReplacement, newSize, this, to);
00236 return newCollection;
00237 }
00238
00239 SequenceableCollection &SequenceableCollection::operator+(SequenceableCollection &collection)
00240 {
00241 return *copyReplace(size(), size(), &collection);
00242 }
00243
00244
00245 Object *SequenceableCollection::remove(Object *)
00246 {
00247 shouldNotImplement(new String(__PRETTY_FUNCTION__));
00248 return nil;
00249 }
00250
00251
00252 bool SequenceableCollection::includesSubcollection(SequenceableCollection *coll) const
00253 {
00254 return indexOfSubCollection(coll) >= 0 || coll->isEmpty();
00255 }
00256
00257 bool SequenceableCollection::isSequenceable(void) const
00258 {
00259 return true;
00260 }
00261
00262 bool SequenceableCollection::startsWith(SequenceableCollection *coll) const
00263 {
00264 return indexOfSubCollection(coll) == 0 || coll->isEmpty();
00265 }
00266
00267 bool SequenceableCollection::endsWith(SequenceableCollection *coll) const
00268 {
00269 int start = size() - coll->size();
00270 if (start < 0) return false;
00271 return indexOfSubCollection(coll, start) >= 0 || coll->isEmpty();
00272 }
00273
00274
00275 Object *SequenceableCollection::privNextForIterator(CollectionIterator *iter) const
00276 {
00277 long index = iter->position();
00278 for (; index < size(); index += 1) {
00279 Object *item = at(index);
00280 if (item != nil) {
00281 iter->position(index);
00282 return item;
00283 }
00284 }
00285 iter->position(index);
00286 return nil;
00287 }