AbstractList.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 _ABSTRACT_CLASS_BEE_UTIL_ABSTRACTLIST_H
00024 #define _ABSTRACT_CLASS_BEE_UTIL_ABSTRACTLIST_H
00025 
00026 #ifdef __cplusplus
00027 
00028 #include "beecrypt/c++/util/AbstractCollection.h"
00029 using beecrypt::util::AbstractCollection;
00030 #include "beecrypt/c++/util/List.h"
00031 using beecrypt::util::List;
00032 #include "beecrypt/c++/lang/IllegalStateException.h"
00033 using beecrypt::lang::IllegalStateException;
00034 #include "beecrypt/c++/util/ConcurrentModificationException.h"
00035 using beecrypt::util::ConcurrentModificationException;
00036 
00037 namespace beecrypt {
00038     namespace util {
00042         template<class E> class AbstractList : public AbstractCollection<E>, public virtual List<E>
00043         {
00044         private:
00045             class Iter : public Object, public virtual Iterator<E>
00046             {
00047             private:
00048                       AbstractList*       _list;
00049                 const AbstractList* _const_list;
00050                 jint _pos;
00051                 jint _last;
00052                 jint _expect;
00053 
00054             public:
00055                 Iter(AbstractList* list) : _list(list), _const_list(list)
00056                 {
00057                     _pos = 0;
00058                     _last = -1;
00059                     _expect = _const_list->modCount;
00060                 }
00061                 Iter(const AbstractList* list) : _list(0), _const_list(list)
00062                 {
00063                     _pos = 0;
00064                     _last = -1;
00065                     _expect = _const_list->modCount;
00066                 }
00067                 virtual ~Iter() {}
00068 
00069                 virtual bool hasNext() throw ()
00070                 {
00071                     return _pos < _const_list->size();
00072                 }
00073                 virtual E* next() throw (NoSuchElementException)
00074                 {
00075                     if (_expect != _const_list->modCount)
00076                         throw ConcurrentModificationException();
00077 
00078                     try
00079                     {
00080                         E* e = _const_list->get(_pos);
00081                         _last = _pos++;
00082                         return e;
00083                     }
00084                     catch (IndexOutOfBoundsException&)
00085                     {
00086                         if (_expect != _const_list->modCount)
00087                             throw ConcurrentModificationException();
00088 
00089                         throw NoSuchElementException();
00090                     }
00091                 }
00092                 virtual void remove()
00093                 {
00094                     if (!_list)
00095                         throw UnsupportedOperationException("Cannot remove items in a const iterator");
00096 
00097                     if (_last == -1)
00098                         throw IllegalStateException();
00099 
00100                     if (_expect != _list->modCount)
00101                         throw ConcurrentModificationException();
00102 
00103                     try
00104                     {
00105                         E* e = _list->remove(_last);
00106                         if (e)
00107                             collection_rcheck(e);
00108                         if (_last < _pos)
00109                             _pos--;
00110                         _last = -1;
00111                         _expect = _list->modCount;
00112                     }
00113                     catch (IndexOutOfBoundsException&)
00114                     {
00115                         throw ConcurrentModificationException();
00116                     }
00117                 }
00118             };
00119 
00120             class ListIter : public Object, public virtual ListIterator<E>
00121             {
00122             private:
00123                       AbstractList*       _list;
00124                 const AbstractList* _const_list;
00125                 jint _pos;
00126                 jint _last;
00127                 jint _expect;
00128 
00129             public:
00130                 ListIter(AbstractList* list, jint index) throw (IndexOutOfBoundsException) : _list(list), _const_list(list)
00131                 {
00132                     if (index < 0 || index > list->size())
00133                         throw IndexOutOfBoundsException();
00134 
00135                     _pos = index;
00136                     _last = -1;
00137                     _expect = _const_list->modCount;
00138                 }
00139                 ListIter(const AbstractList* list, jint index) throw (IndexOutOfBoundsException) : _list(0), _const_list(list)
00140                 {
00141                     if (index < 0 || index > list->size())
00142                         throw IndexOutOfBoundsException();
00143 
00144                     _pos = index;
00145                     _last = -1;
00146                     _expect = _const_list->modCount;
00147                 }
00148                 virtual ~ListIter() {}
00149 
00150                 virtual void add(E* e)
00151                 {
00152                     if (!_list)
00153                         throw UnsupportedOperationException("Cannot add items in a const iterator");
00154 
00155                     if (_expect != _list->modCount)
00156                         throw ConcurrentModificationException();
00157 
00158                     try
00159                     {
00160                         _list->add(_pos++, e);
00161                         _last = -1;
00162                         _expect = _list->modCount;
00163                     }
00164                     catch (IndexOutOfBoundsException&)
00165                     {
00166                         throw ConcurrentModificationException();
00167                     }
00168                 }
00169                 virtual bool hasNext() throw ()
00170                 {
00171                     return _pos < _const_list->size();
00172                 }
00173                 virtual bool hasPrevious() throw ()
00174                 {
00175                     return _pos > 0;
00176                 }
00177                 virtual E* next() throw (NoSuchElementException)
00178                 {
00179                     if (_expect != _const_list->modCount)
00180                         throw ConcurrentModificationException();
00181 
00182                     try
00183                     {
00184                         E* e = _const_list->get(_pos);
00185                         _last = _pos++;
00186                         return e;
00187                     }
00188                     catch (IndexOutOfBoundsException&)
00189                     {
00190                         if (_expect != _const_list->modCount)
00191                             throw ConcurrentModificationException();
00192 
00193                         throw NoSuchElementException();
00194                     }
00195                 }
00196                 virtual jint nextIndex() throw ()
00197                 {
00198                     return _pos;
00199                 }
00200                 virtual E* previous() throw (NoSuchElementException)
00201                 {
00202                     if (_expect != _const_list->modCount)
00203                         throw ConcurrentModificationException();
00204 
00205                     try
00206                     {
00207                         E* e = _const_list->get(_pos-1);
00208                         _last = _pos--;
00209                         return e;
00210                     }
00211                     catch (IndexOutOfBoundsException&)
00212                     {
00213                         if (_expect != _const_list->modCount)
00214                             throw ConcurrentModificationException();
00215 
00216                         throw NoSuchElementException();
00217                     }
00218                 }
00219                 virtual jint previousIndex() throw ()
00220                 {
00221                     return _pos-1;
00222                 }
00223                 virtual void remove()
00224                 {
00225                     if (!_list)
00226                         throw UnsupportedOperationException("Cannot remove items in a const iterator");
00227 
00228                     if (_last == -1)
00229                         throw IllegalStateException();
00230 
00231                     if (_expect != _list->modCount)
00232                         throw ConcurrentModificationException();
00233 
00234                     try
00235                     {
00236                         E* e = _list->remove(_last);
00237                         if (e)
00238                             collection_rcheck(e);
00239                         if (_last < _pos)
00240                             _pos--;
00241                         _last = -1;
00242                         _expect = _list->modCount;
00243                     }
00244                     catch (IndexOutOfBoundsException&)
00245                     {
00246                         throw ConcurrentModificationException();
00247                     }
00248                 }
00249                 virtual void set(E* e)
00250                 {
00251                     if (!_list)
00252                         throw UnsupportedOperationException("Cannot set items in a const iterator");
00253 
00254                     if (_last == -1)
00255                         throw IllegalStateException();
00256 
00257                     if (_expect != _list->modCount)
00258                         throw ConcurrentModificationException();
00259 
00260                     try
00261                     {
00262                         _list->set(_last, e);
00263                         _expect = _list->modCount;
00264                     }
00265                     catch (IndexOutOfBoundsException&)
00266                     {
00267                         throw ConcurrentModificationException();
00268                     }
00269                 }
00270             };
00271 
00272         protected:
00273             jint modCount;
00274 
00275         protected:
00276             AbstractList()
00277             {
00278                 modCount = 0;
00279             }
00280 
00281         public:
00282             virtual ~AbstractList() {}
00283 
00284             virtual bool add(E* e)
00285             {
00286                 add(size(), e);
00287                 return true;
00288             }
00289             virtual void add(jint index, E* e)
00290             {
00291                 throw UnsupportedOperationException();
00292             }
00293             virtual bool addAll(jint index, const Collection<E>& c)
00294             {
00295                 bool result = false;
00296                 jint pos = c.size();
00297                 Iterator<E>* cit = c.iterator();
00298                 assert(cit != 0);
00299                 while (--pos >= 0)
00300                 {
00301                     add(index++, cit->next());
00302                     result = true;
00303                 }
00304                 delete cit;
00305                 return result;
00306             }
00307             virtual void clear()
00308             {
00309                 while (size())
00310                 {
00311                     E* e = remove(0);
00312                     if (e)
00313                         collection_rcheck(e);
00314                 }
00315             }
00316             virtual bool equals(const Object* obj) const throw ()
00317             {
00318                 if (this == obj)
00319                     return true;
00320 
00321                 if (obj)
00322                 {
00323                     const AbstractList<E>* abs = dynamic_cast<const AbstractList<E>*>(obj);
00324                     if (abs)
00325                     {
00326                         bool result = true;
00327 
00328                         jint pos1 = size(), pos2 = abs->size();
00329 
00330                         ListIterator<E>* lit1 = listIterator();
00331                         assert(lit1 != 0);
00332                         ListIterator<E>* lit2 = abs->listIterator();
00333                         assert(lit2 != 0);
00334 
00335                         while (--pos1 >= 0 && --pos2 >= 0)
00336                         {
00337                             if (!AbstractCollection<E>::equals(lit1->next(), lit2->next()))
00338                             {
00339                                 result = false;
00340                                 break;
00341                             }
00342                         }
00343 
00344                         if (result)
00345                         {
00346                             // if either of the iterators has any elements left, the lists differ
00347                             result = (pos1 < 0) && (pos2 < 0);
00348                         }
00349 
00350                         delete lit1;
00351                         delete lit2;
00352 
00353                         return result;
00354                     }
00355                 }
00356                 return false;
00357             }
00358             virtual E* get(jint index) const throw (IndexOutOfBoundsException) = 0;
00359             virtual jint hashCode() const throw ()
00360             {
00361                 register jint pos = size(), result = 1;
00362                 Iterator<E>* it = iterator();
00363                 assert(it != 0);
00364                 while (--pos >= 0)
00365                 {
00366                     E* e = it->next();
00367                     result *= 31;
00368                     if (e)
00369                         result += e->hashCode();
00370                 }
00371                 delete it;
00372                 return result;
00373             }
00374             virtual jint indexOf(const E* e) const
00375             {
00376                 jint pos = size(), result = -1;
00377                 ListIterator<E>* lit = listIterator();
00378                 assert(lit != 0);
00379                 while (--pos >= 0)
00380                 {
00381                     if (AbstractCollection<E>::equals(e, lit->next()))
00382                     {
00383                         result = lit->previousIndex();
00384                         break;
00385                     }
00386                 }
00387                 delete lit;
00388                 return result;
00389             }
00390             virtual Iterator<E>* iterator()
00391             {
00392                 return new Iter(this);
00393             }
00394             virtual Iterator<E>* iterator() const
00395             {
00396                 return new Iter(this);
00397             }
00398             virtual jint lastIndexOf(const E* e) const
00399             {
00400                 jint result = -1;
00401                 ListIterator<E>* lit = listIterator(size());
00402                 assert(lit != 0);
00403                 while (lit->hasPrevious())
00404                 {
00405                     if (AbstractCollection<E>::equals(e, lit->previous()))
00406                     {
00407                         result = lit->nextIndex();
00408                         break;
00409                     }
00410                 }
00411                 delete lit;
00412                 return result;
00413             }
00414             virtual ListIterator<E>* listIterator(jint index = 0) throw (IndexOutOfBoundsException)
00415             {
00416                 return new ListIter(this, index);
00417             }
00418             virtual ListIterator<E>* listIterator(jint index = 0) const throw (IndexOutOfBoundsException)
00419             {
00420                 return new ListIter(this, index);
00421             }
00422             virtual E* remove(jint index)
00423             {
00424                 throw UnsupportedOperationException();
00425             }
00426             virtual E* set(jint index, E* e)
00427             {
00428                 throw UnsupportedOperationException();
00429             }
00430             virtual jint size() const throw () = 0;
00431         };
00432     }
00433 }
00434 
00435 #endif
00436 
00437 #endif

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