ArrayList.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 X-Way Rights BV
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00023 #ifndef _CLASS_BEE_UTIL_ARRAYLIST_H
00024 #define _CLASS_BEE_UTIL_ARRAYLIST_H
00025 
00026 #ifdef __cplusplus
00027 
00028 #include "beecrypt/c++/util/AbstractList.h"
00029 using beecrypt::util::AbstractList;
00030 #include "beecrypt/c++/lang/Cloneable.h"
00031 using beecrypt::lang::Cloneable;
00032 #include "beecrypt/c++/lang/IllegalArgumentException.h"
00033 using beecrypt::lang::IllegalArgumentException;
00034 #include "beecrypt/c++/util/RandomAccess.h"
00035 using beecrypt::util::RandomAccess;
00036 
00037 namespace beecrypt {
00038     namespace util {
00042         template<class E> class ArrayList : public AbstractList<E>, public virtual RandomAccess, public virtual Cloneable
00043         {
00044         private:
00045             array<E*> _table;
00046             jint _count;
00047 
00048             void fastInsert(jint index)
00049             {
00050                 register jint move = _count - index;
00051                 if (move)
00052                     ::memmove(_table.data() + index + 1, _table.data() + index, move * sizeof(E*));
00053                 _table[index] = 0;
00054                 _count++;
00055             }
00056             void fastRemove(jint index)
00057             {
00058                 register jint move = _count - index - 1;
00059                 if (move)
00060                     ::memmove(_table.data() + index, _table.data() + index + 1, move * sizeof(E*));
00061                 _table[--_count] = 0;
00062             }
00063 
00064         public:
00065             ArrayList(jint initialCapacity = 10) :_table(initialCapacity)
00066             {
00067                 if (initialCapacity < 0)
00068                     throw IllegalArgumentException();
00069 
00070                 _count = 0;
00071             }
00072             ArrayList(Collection<E>& c) : _table(c.size())
00073             {
00074                 addAll(c);
00075             }
00076             ArrayList(const ArrayList& copy) : _table(copy._table), _count(copy._count)
00077             {
00078             }
00079             virtual ~ArrayList()
00080             {
00081                 clear();
00082             }
00083 
00084             virtual bool add(E* e)
00085             {
00086                 ensureCapacity(_count+1);
00087                 if ((_table[_count++] = e))
00088                     collection_attach(e);
00089                 return true;
00090             }
00091             virtual void add(jint index, E* e)
00092             {
00093                 if (index < 0 || index > _count)
00094                     throw IndexOutOfBoundsException();
00095 
00096                 ensureCapacity(_count+1);
00097                 fastInsert(index);
00098                 if ((_table[index] = e))
00099                     collection_attach(e);
00100             }
00101             virtual bool addAll(const Collection<E>& c)
00102             {
00103                 jint clen = c.size();
00104 
00105                 if (clen > 0)
00106                 {
00107                     ensureCapacity(_count + clen);
00108                     Iterator<E>* cit = c.iterator();
00109                     assert(cit != 0);
00110                     while (cit->hasNext())
00111                     {
00112                         E* tmp = cit->next();
00113                         if (tmp)
00114                             collection_attach(tmp);
00115                         _table[_count++] = tmp;
00116                     }
00117                     delete cit;
00118                     return true;
00119                 }
00120                 return false;
00121             }
00122             virtual Object* clone() const throw ()
00123             {
00124                 return new ArrayList<E>(*this);
00125             }
00126             virtual void clear()
00127             {
00128                 for (jint i = 0; i < _count; i++)
00129                 {
00130                     E* tmp = _table[i];
00131                     if (tmp)
00132                     {
00133                         collection_remove(tmp);
00134                         _table[i] = 0;
00135                     }
00136                 }
00137                 _count = 0;
00138                 _table.resize(10);
00139             }
00140             virtual bool contains(const E* e) const
00141             {
00142                 return indexOf(e) >= 0;
00143             }
00144             virtual void ensureCapacity(jint minimum)
00145             {
00146                 this->modCount++;
00147 
00148                 if (minimum > _table.size())
00149                 {
00150                     jint newcapacity = (_table.size() * 3) / 2 + 2;
00151 
00152                     if (minimum > newcapacity)
00153                         newcapacity = minimum;
00154 
00155                     _table.resize(newcapacity);
00156                 }
00157             }
00158             virtual E* get(jint index) const throw (IndexOutOfBoundsException)
00159             {
00160                 if (index < 0 || index >= _count)
00161                     throw IndexOutOfBoundsException();
00162 
00163                 return _table[index];
00164             }
00165             virtual jint indexOf(const E* e) const
00166             {
00167                 if (e)
00168                 {
00169                     for (jint i = 0; i < _count; i++)
00170                         if (_table[i] && _table[i]->equals(e))
00171                             return i;
00172                 }
00173                 else
00174                 {
00175                     for (jint i = 0; i < _count; i++)
00176                         if (!_table[i])
00177                             return i;
00178                 }
00179                 return -1;
00180             }
00181             virtual bool isEmpty() const throw ()
00182             {
00183                 return _count == 0;
00184             }
00185             virtual bool remove(const E* e)
00186             {
00187                 for (jint i = 0; i < _count; i++)
00188                 {
00189                     E* tmp = _table[i];
00190                     if (AbstractCollection<E>::equals(e, tmp))
00191                     {
00192                         fastRemove(i);
00193                         if (tmp)
00194                             collection_remove(tmp);
00195                         return true;
00196                     }
00197                 }
00198                 return false;
00199             }
00200             virtual E* remove(jint index) throw (IndexOutOfBoundsException)
00201             {
00202                 if (index < 0 || index >= _count)
00203                     throw IndexOutOfBoundsException();
00204 
00205                 E* tmp = _table[index];
00206                 fastRemove(index);
00207                 if (tmp)
00208                     collection_detach(tmp);
00209 
00210                 return tmp;
00211             }
00212             virtual jint size() const throw ()
00213             {
00214                 return _count;
00215             }
00216             virtual array<E*> toArray() const
00217             {
00218                 return array<E*>(_table.data(), _count);
00219             }
00220             virtual void trimToSize()
00221             {
00222                 _table.resize(_count);
00223             }
00224         };
00225     }
00226 }
00227 
00228 #endif
00229 
00230 #endif

Generated on Fri Jun 19 13:39:40 2009 for BeeCrypt C++ by  doxygen 1.5.8