activemq-cpp-3.6.0
ArrayList.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef _DECAF_UTIL_ARRAYLIST_H_
19 #define _DECAF_UTIL_ARRAYLIST_H_
20 
21 #include <memory>
25 #include <decaf/lang/System.h>
26 #include <decaf/lang/Integer.h>
27 #include <decaf/util/Config.h>
28 #include <decaf/util/Iterator.h>
30 #include <decaf/util/List.h>
32 
33 namespace decaf {
34 namespace util {
35 
36  using decaf::lang::System;
37 
38  template< typename E >
40  private:
41 
42  E* elements;
43  int capacity;
44  int head;
45  int curSize;
46 
47  public:
48 
49  ArrayList() : AbstractList<E>(), elements( NULL ), capacity( 0 ), head( 0 ), curSize( 0 ) {
50  this->ensureCapacity( 10 );
51  }
52 
53  ArrayList( const Collection<E>& collection ) : AbstractList<E>(), elements( NULL ),
54  capacity( 0 ), head( 0 ), curSize( 0 ) {
55 
56  this->capacity = collection.size() + ( collection.size() / 10 );
57  this->elements = new E[this->capacity];
58 
59  std::auto_ptr< Iterator<E> > iter( collection.iterator() );
60  while( iter->hasNext() ) {
61  this->elements[this->head++] = iter->next();
62  this->curSize++;
63  }
64  }
65 
66  ArrayList( const ArrayList<E>& arrayList ) : AbstractList<E>(), elements( NULL ),
67  capacity( 0 ), head( 0 ), curSize( 0 ) {
68 
69  this->capacity = arrayList.size() + ( arrayList.size() / 10 );
70  this->elements = new E[this->capacity];
71 
72  std::auto_ptr< Iterator<E> > iter( arrayList.iterator() );
73  while( iter->hasNext() ) {
74  this->elements[this->head++] = iter->next();
75  this->curSize++;
76  }
77  }
78 
79  ArrayList( int initialCapacity ) : AbstractList<E>(), elements( NULL ),
80  capacity( initialCapacity ), head( 0 ), curSize( 0 ) {
81 
82  if( initialCapacity < 0 ) {
84  __FILE__, __LINE__, "Initial Capacity argument cannot be negative." );
85  }
86 
87  this->elements = new E[this->capacity];
88  }
89 
90  virtual ~ArrayList() {
91  try{
92  delete [] elements;
93  }
95  }
96 
97  public:
98 
100  this->clear();
101  this->addAll( list );
102  return *this;
103  }
104 
105  ArrayList<E>& operator= ( const Collection<E>& collection ) {
106  this->clear();
107  this->addAll( 0, collection );
108  return *this;
109  }
110 
111  public:
112 
122  void ensureCapacity( int minimumCapacity ) {
123 
124  if( minimumCapacity < 0 || this->capacity >= minimumCapacity ) {
125  return;
126  }
127 
128  int newCapacity = minimumCapacity == 0 ? 10 : minimumCapacity;
129 
130  E* newElements = new E[newCapacity];
131  if( this->curSize > 0 ) {
132  decaf::lang::System::arraycopy( this->elements, this->head, newElements, 0, this->curSize );
133  }
134  delete [] this->elements;
135  this->elements = newElements;
136  this->capacity = newCapacity;
138  }
139 
144  void trimToSize() {
145 
146  if( this->curSize < this->capacity ) {
147 
148  int newCapacity = this->curSize == 0 ? 10 : this->curSize;
149 
150  E* newElements = new E[newCapacity];
151  if( this->curSize > 0 ) {
152  System::arraycopy( this->elements, 0, newElements, 0, this->curSize );
153  }
154 
155  delete [] this->elements;
156  this->elements = newElements;
157  this->capacity = newCapacity;
158  }
159 
161  }
162 
163  public:
164 
165  virtual void clear() {
166  delete [] this->elements;
167  this->curSize = 0;
168  this->capacity = 10;
169  this->elements = new E[this->capacity];
171  }
172 
173  virtual bool isEmpty() const {
174  return this->curSize == 0;
175  }
176 
177  virtual int size() const {
178  return this->curSize;
179  }
180 
181  virtual E set( int index, const E& element ) {
182 
183  if( index < 0 || index >= this->curSize ) {
185  __FILE__, __LINE__,
186  "List::get - Index greater than size() or negative" );
187  }
188 
189  E oldValue = this->elements[index];
190  this->elements[index] = element;
191 
192  return oldValue;
193  }
194 
195  virtual E get( int index ) const {
196 
197  if( index < 0 || index >= this->curSize ) {
199  __FILE__, __LINE__,
200  "List::get - Index greater than size() or negative" );
201  }
202 
203  return this->elements[index];
204  }
205 
206  virtual bool add( const E& value ) {
207 
208  this->expandEnd( 1 );
209  this->elements[this->curSize++] = value;
211 
212  return true;
213  }
214 
215  virtual void add( int index, const E& element ) {
216 
217  if( index < 0 || index > this->curSize ) {
219  __FILE__, __LINE__,
220  "Index was negative or greater than size()" );
221  }
222 
223  if( index == 0 ) {
224  this->expandFront( 1 );
225  } else if( index == this->curSize ) {
226  this->expandEnd( 1 );
227  } else {
228  this->expandMiddle( index, 1 );
229  }
230 
231  this->elements[index] = element;
232  this->curSize++;
234  }
235 
236  virtual bool addAll( const Collection<E>& collection ) {
237 
238  int csize = collection.size();
239  if( csize == 0 ) {
240  return false;
241  }
242 
243  std::vector<E> array = collection.toArray();
244 
245  this->expandEnd( csize );
246 
247  for( int i = 0; i < csize; ++i ) {
248  this->elements[this->curSize++] = array[i];
249  }
250 
252 
253  return true;
254  }
255 
256  virtual bool addAll( int index, const Collection<E>& collection ) {
257 
258  if( index < 0 || index > this->curSize ) {
260  __FILE__, __LINE__,
261  "List::addAll - Index greater than size()" );
262  }
263 
264  int csize = collection.size();
265  if( csize == 0 ) {
266  return false;
267  }
268 
269  std::vector<E> array = collection.toArray();
270 
271  if( index == 0 ) {
272  this->expandFront( csize );
273  } else if( index == this->curSize ) {
274  this->expandEnd( csize );
275  } else {
276  this->expandMiddle( index, csize );
277  }
278 
279  for( int i = 0; i < csize; ++i, ++this->curSize ) {
280  this->elements[index++] = array[i];
281  }
282 
284 
285  return true;
286  }
287 
288  virtual bool remove( const E& value ) {
289 
290  int result = indexOf( value );
291  if( result != -1 ) {
292  this->removeAt( result );
293  return true;
294  }
295 
296  return false;
297  }
298 
299  virtual E removeAt( int index ) {
300 
301  if( index < 0 || index >= this->curSize ) {
303  __FILE__, __LINE__,
304  "List::removeAt - Index greater than size() or negative" );
305  }
306 
307  E old = this->elements[index];
308 
309  System::arraycopy( this->elements, 0, this->elements, 0, index );
310 
311  if( this->curSize > index ) {
312  System::arraycopy( this->elements, index + 1, this->elements, index, this->curSize - index - 1 );
313  }
314 
315  this->elements[--this->curSize] = E();
317 
318  return old;
319  }
320 
321  virtual bool contains( const E& value ) const {
322  return this->indexOf( value ) != -1;
323  }
324 
325  virtual int indexOf( const E& value ) const {
326 
327  for( int i = 0; i < this->curSize; ++i ) {
328  if( this->elements[i] == value ) {
329  return i;
330  }
331  }
332 
333  return -1;
334  }
335 
336  virtual int lastIndexOf( const E& value ) const {
337 
338  for( int i = this->curSize - 1; i >= 0 ; --i ) {
339  if( this->elements[i] == value ) {
340  return i;
341  }
342  }
343 
344  return -1;
345  }
346 
347  virtual std::vector<E> toArray() const {
348 
349  std::vector<E> result;
350 
351  for( int i = 0; i < this->curSize; ++i ) {
352  result.push_back( this->elements[i] );
353  }
354 
355  return result;
356  }
357 
358  virtual std::string toString() const {
359 
360  std::string result;
361 
362  result.append( "decaf::util::ArrayList [ size = " );
363  result.append( decaf::lang::Integer::toString( this->curSize ) );
364  result.append( " ]");
365 
366  return result;
367  }
368 
369  private:
370 
371  void expandFront( int amount ) {
372 
373  if( amount == 0 ) {
374  return;
375  }
376 
377  E* previous = this->elements;
378 
379  if( amount > this->capacity - this->curSize ) {
380  this->capacity = this->capacity + amount + 11;
381  this->elements = new E[this->capacity];
382  }
383 
384  if( this->curSize > 0 ) {
385  System::arraycopy( previous, 0, this->elements, amount, this->curSize );
386  }
387 
388  if( previous != this->elements ) {
389  delete [] previous;
390  }
391  }
392 
393  void expandEnd( int amount ) {
394 
395  if( amount == 0 ) {
396  return;
397  }
398 
399  E* previous = this->elements;
400 
401  if( amount > this->capacity - this->curSize ) {
402  this->capacity = this->capacity + amount + 11;
403  this->elements = new E[this->capacity];
404  System::arraycopy( previous, 0, this->elements, 0, this->curSize );
405  }
406 
407  if( previous != this->elements ) {
408  delete [] previous;
409  }
410  }
411 
412  void expandMiddle( int index, int amount ) {
413 
414  if( amount == 0 ) {
415  return;
416  }
417 
418  E* previous = this->elements;
419 
420  if( amount > this->capacity - this->curSize ) {
421  this->capacity = this->capacity + amount + 11;
422  this->elements = new E[this->capacity];
423  }
424 
425  if( this->curSize > 0 ) {
426  System::arraycopy( previous, 0, this->elements, 0, index );
427  }
428 
429  if( this->curSize > index ) {
430  System::arraycopy( previous, index, this->elements, index + amount, this->curSize - index );
431  }
432 
433  if( previous != this->elements ) {
434  delete [] previous;
435  }
436  }
437 
438  };
439 
440 }}
441 
442 #endif /* _DECAF_UTIL_ARRAYLIST_H_ */