LTP GCOV extension - code coverage report
Current view: directory - include/utilib - LinkedList.h
Test: Acro
Date: 2008-08-19 Instrumented lines: 261
Code covered: 76.2 % Executed lines: 199

       1                 : /*  _________________________________________________________________________
       2                 :  *
       3                 :  *  UTILIB: A utility library for developing portable C++ codes.
       4                 :  *  Copyright (c) 2001, Sandia National Laboratories.
       5                 :  *  This software is distributed under the GNU Lesser General Public License.
       6                 :  *  For more information, see the README file in the top UTILIB directory.
       7                 :  *  _________________________________________________________________________
       8                 :  */
       9                 : 
      10                 : /**
      11                 :  * \file LinkedList.h
      12                 :  *
      13                 :  * Defines the utilib::ListItem and utilib::LinkedList classes
      14                 :  */
      15                 : 
      16                 : #ifndef utilib_LinkedList_h
      17                 : #define utilib_LinkedList_h
      18                 : 
      19                 : #include <utilib/std_headers.h>
      20                 : #include <utilib/exception_mngr.h>
      21                 : #include <utilib/CachedAllocator.h>
      22                 : #include <utilib/_generic.h>
      23                 : #include <utilib/PackBuf.h>
      24                 : 
      25                 : 
      26                 : namespace utilib {
      27                 : 
      28                 : using std::bidirectional_iterator_tag;
      29                 : 
      30                 : template <class T, class _Alloc>
      31                 : class LinkedItem;
      32                 : 
      33                 : template <class _Tp, class _Alloc>
      34                 : class LinkedList;
      35                 : 
      36                 : template<typename _Tp, typename _Ref, typename _Ptr, typename _Node,
      37                 :                         typename _NodeOpClass>
      38                 : class __LinkedList_iterator;
      39                 : 
      40                 : 
      41                 : /**
      42                 :  * A simple container class that is used by LinkedList.
      43                 :  *
      44                 :  * This code includes the management of a list of unused ListItem's,
      45                 :  * which are used first before new ListItem's are constructed.  The
      46                 :  * user can clear the unused items if that is desirable.
      47                 :  */
      48                 : template <class T>
      49                 : class ListItem : public CachedAllocatorObject<ListItem<T> >
      50                 : {
      51                 : 
      52                 :   #if !defined(DOXYGEN)
      53                 :   template <class wasT, class wasAlloc> friend class LinkedList;
      54                 :   #endif
      55                 : 
      56                 : public:
      57                 : 
      58                 :   /// Construct an item with the given data value.
      59                 :   ListItem( const T& Data_)
      60                 :                 : Data(Data_) {next = prev = 0;}
      61                 : 
      62                 :   /// Construct an item with the given data value.
      63          478364 :   ListItem( )
      64          478364 :                 {next = prev = 0;}
      65                 : 
      66                 :   /// Destructor
      67          478364 :   virtual ~ListItem() {}
      68                 : 
      69                 :   /// Return the item's data value.
      70          100671 :   T& data() 
      71          100671 :                 {return Data;}
      72                 : 
      73                 :   /// Return true if \a item equals the data value in the current item.
      74                 :   bool operator==(const ListItem<T>& item) 
      75                 :                 {return (Data == item.Data);}
      76                 : 
      77                 :   /// The item's data value.
      78                 :   T Data;
      79                 : 
      80                 :   /// The next item in the linked list
      81                 :   ListItem<T>* next;
      82                 : 
      83                 :   /// The previous item in the linked list
      84                 :   ListItem<T>* prev;
      85                 : 
      86                 :   ///
      87          497569 :   void deallocate_derived()
      88          497569 :         { CachedAllocator<ListItem<T> > :: deallocate_derived(this); }
      89                 : 
      90                 : };
      91                 : 
      92                 : 
      93                 : 
      94                 : /**
      95                 :  * Base class for __LinkedList_iterator that defines operations that
      96                 :  * are specific to the _Node object used to represent the elements of
      97                 :  * the linked list.
      98                 :  */
      99                 : template<typename _Tp, typename _Ref, typename _Ptr, typename _Node,
     100                 :                                         typename _NodeOpClass>
     101                 : class __LinkedList_iterator_base : public _NodeOpClass
     102                 : {
     103                 : public:
     104                 : 
     105                 :   /// Pointer to the data that is being iteratored through
     106                 :   _Node* _M_node;
     107                 : 
     108                 :   /// Constructor
     109           32017 :   __LinkedList_iterator_base()
     110           32017 :         : _M_node(0)
     111           32017 :         { }
     112                 : 
     113                 :   /// Constructor
     114         2456462 :   __LinkedList_iterator_base(_Node* __x)
     115         2456462 :         : _M_node(__x)
     116         2456462 :         { }
     117                 : 
     118                 :   /// Increment the iterator
     119          736615 :   void _M_incr()
     120          736615 :         { _M_node = _M_node->next; }
     121                 : 
     122                 :   /// Decrement the iterator
     123                 :   void _M_decr()
     124                 :         { _M_node = _M_node->prev; }
     125                 : 
     126                 :   /// Return a reference to the data
     127          800667 :   _Ref operator*() const  
     128          800667 :         { return value(_M_node); }
     129                 : 
     130                 :   /// Return a pointer to the data
     131           46277 :   _Ptr operator->() const
     132           46277 :         { _Ref tmp = this->operator*(); return &tmp; }
     133                 : 
     134                 : };
     135                 : 
     136                 : 
     137                 : 
     138                 : /**
     139                 :  * Base class for __LinkedList_iterator that a LinkedList can use
     140                 :  * as an iterator for the array
     141                 :  */
     142                 : template<typename _Ref, typename _Node>
     143                 : class __LinkedList_Standard_OpClass
     144         1498496 : {
     145                 : public:
     146                 : 
     147                 :   /// Return a reference to the data being passed in
     148          240069 :   _Ref value(_Node* node) const
     149                 :         {
     150          240069 :         if (!node)
     151               0 :            EXCEPTION_MNGR(runtime_error,"Accessing an invalid iterator.");
     152          240069 :         return node->Data;
     153                 :         }
     154                 : 
     155                 : };
     156                 : 
     157                 : 
     158                 : 
     159                 : /**
     160                 :  * Base class for __LinkedList_iterator that a LinkedList can use
     161                 :  * as an iterator for the array
     162                 :  */
     163                 : template<typename _Ref, typename _Node>
     164                 : class __LinkedList_Pointer_OpClass
     165          557815 : {
     166                 : public:
     167                 : 
     168                 :   /// Return a reference to the data being passed in
     169           38133 :   _Ref value(_Node* node) const
     170                 :         {
     171           38133 :         if (!node)
     172               0 :            EXCEPTION_MNGR(runtime_error,"Accessing an invalid iterator.");
     173           38133 :         return *(node->Data);
     174                 :         }
     175                 : 
     176                 : };
     177                 : 
     178                 : 
     179                 : /**
     180                 :  * class for __LinkedList_iterator that a LinkedList can use
     181                 :  * as an iterator for the array
     182                 :  */
     183                 : template<typename _Tp, typename _Ref, typename _Ptr, typename _Node,
     184                 :                                         typename _NodeOpClass>
     185                 : class __LinkedList_iterator : 
     186                 :         public __LinkedList_iterator_base<_Tp,_Ref,_Ptr,_Node,_NodeOpClass>
     187                 : {
     188                 : public:
     189                 : 
     190                 :   #if !defined(DOXYGEN)
     191                 :   ///
     192                 :   typedef size_t size_type;
     193                 : 
     194                 :   ///
     195                 :   typedef ptrdiff_t difference_type;
     196                 : 
     197                 :   ///
     198                 :   typedef bidirectional_iterator_tag iterator_category;
     199                 : 
     200                 :   ///
     201                 :   typedef _Tp value_type;
     202                 : 
     203                 :   ///
     204                 :   typedef _Ptr pointer;
     205                 : 
     206                 :   ///
     207                 :   typedef _Ref reference;
     208                 : 
     209                 :   ///
     210                 :   typedef __LinkedList_iterator<_Tp,_Ref,_Ptr,_Node,_NodeOpClass> iterator;
     211                 :   #endif
     212                 : 
     213                 :   /// Constructor
     214           32017 :   __LinkedList_iterator()
     215           32017 :         : __LinkedList_iterator_base<_Tp,_Ref,_Ptr,_Node,_NodeOpClass>() {}
     216                 : 
     217                 :   /// Constructor
     218         2456462 :   __LinkedList_iterator(_Node* __x)
     219         2456462 :         : __LinkedList_iterator_base<_Tp,_Ref,_Ptr,_Node,_NodeOpClass>(__x) {}
     220                 : 
     221                 :   /// Copy operator
     222           33932 :   iterator& operator=(const iterator& __x)
     223                 :         {
     224           33932 :         this->_M_node = __x._M_node;
     225           33932 :         return *this;
     226                 :         }
     227                 :   
     228                 :   /// Equality operator
     229           68858 :   bool operator==(const iterator& __x) const
     230           68858 :         { return this->_M_node == __x._M_node; }
     231                 : 
     232                 :   /// Inequality operator
     233         1201374 :   bool operator!=(const iterator& __x) const
     234         1201374 :         { return this->_M_node != __x._M_node; }
     235                 : 
     236                 :   /// Increment the iterator
     237                 :   iterator& operator++()
     238                 :         {
     239                 :         this->_M_incr();
     240                 :         return *this;
     241                 :         }
     242                 : 
     243                 :   /// Increment the iterator
     244          736615 :   iterator operator++(int)
     245                 :         {
     246          736615 :         iterator __tmp = *this;
     247          736615 :         this->_M_incr();
     248          736615 :         return __tmp;
     249                 :         }
     250                 : 
     251                 :   /// Decrement the iterator
     252                 :   iterator& operator--()
     253                 :         {
     254                 :         this->_M_decr();
     255                 :         return *this;
     256                 :         }
     257                 : 
     258                 :   /// Decrement the iterator
     259                 :   iterator operator--(int)
     260                 :         {
     261                 :         iterator __tmp = *this;
     262                 :         this->_M_decr();
     263                 :         return __tmp;
     264                 :         }
     265                 : 
     266                 : };
     267                 : 
     268                 : 
     269                 : /**
     270                 :  * class for __LinkedList_ptr_iterator that a LinkedList can use
     271                 :  * as an iterator for the array
     272                 :  */
     273                 : template<typename _Tp, typename _Ref, typename _Ptr, typename _Node,
     274                 :                                         typename _NodeOpClass>
     275                 : class __LinkedList_ptr_iterator : 
     276                 :         public __LinkedList_iterator_base<_Tp,_Ref,_Ptr,_Node,_NodeOpClass>
     277                 : {
     278                 : public:
     279                 : 
     280                 : #if !defined(DOXYGEN)
     281                 :   ///
     282                 :   typedef size_t size_type;
     283                 : 
     284                 :   ///
     285                 :   typedef ptrdiff_t difference_type;
     286                 : 
     287                 :   ///
     288                 :   typedef bidirectional_iterator_tag iterator_category;
     289                 : 
     290                 :   ///
     291                 :   typedef _Tp value_type;
     292                 : 
     293                 :   ///
     294                 :   typedef _Ptr pointer;
     295                 : 
     296                 :   ///
     297                 :   typedef _Ref reference;
     298                 : 
     299                 :   ///
     300                 :   typedef __LinkedList_ptr_iterator<_Tp,_Ref,_Ptr,_Node,_NodeOpClass> iterator;
     301                 : #endif
     302                 : 
     303                 :   /// Constructor
     304                 :   __LinkedList_ptr_iterator()
     305                 :         : __LinkedList_iterator_base<_Tp,_Ref,_Ptr,_Node,_NodeOpClass>() {}
     306                 : 
     307                 :   /// Constructor
     308                 :   __LinkedList_ptr_iterator(_Node* __x)
     309                 :         : __LinkedList_iterator_base<_Tp,_Ref,_Ptr,_Node,_NodeOpClass>(__x) {}
     310                 : 
     311                 :   /// Copy constructor
     312                 :   __LinkedList_ptr_iterator(const iterator& __x)
     313                 :         : __LinkedList_iterator_base<_Tp,_Ref,_Ptr,_Node,_NodeOpClass>(__x._M_node) {}
     314                 : 
     315                 :   /// Constructor
     316                 :   __LinkedList_ptr_iterator(const typename __LinkedList_iterator<_Tp*,_Ref,_Ptr,_Node,_NodeOpClass>::iterator& __x)
     317                 :         : __LinkedList_iterator_base<_Tp,_Ref,_Ptr,_Node,_NodeOpClass>(__x._M_node) {}
     318                 : 
     319                 :   /// Copy operator
     320                 :   iterator& operator=(const iterator& __x)
     321                 :         {
     322                 :         this->_M_node = __x._M_node;
     323                 :         return *this;
     324                 :         }
     325                 :   
     326                 :   /// Copy operator
     327                 :   iterator& operator=(const typename __LinkedList_iterator<_Tp*,_Tp*&,_Tp**,_Node,_NodeOpClass>::iterator& __x)
     328                 :         { this->_M_node = __x._M_node; return *this; }
     329                 : 
     330                 :   /// Copy operator
     331                 :   iterator& operator=(const typename __LinkedList_iterator<_Tp*,_Tp* const&,_Tp*const *,_Node,_NodeOpClass>::iterator& __x)
     332                 :         { this->_M_node = __x._M_node; return *this; }
     333                 : 
     334                 :   /// Returns true if the current iterator points to a value that differs
     335                 :   /// from the value returned by this iterator.
     336                 :   bool operator!=(const iterator& __x) const
     337                 :         { return this->_M_node != __x._M_node; }
     338                 : 
     339                 :   /// Increment the iterator
     340                 :   iterator& operator++()
     341                 :         {
     342                 :         this->_M_incr();
     343                 :         return *this;
     344                 :         }
     345                 : 
     346                 :   /// Increment the iterator
     347                 :   iterator operator++(int)
     348                 :         {
     349                 :         iterator __tmp = *this;
     350                 :         this->_M_incr();
     351                 :         return __tmp;
     352                 :         }
     353                 : 
     354                 :   /// Decrement the iterator
     355                 :   iterator& operator--()
     356                 :         {
     357                 :         this->_M_decr();
     358                 :         return *this;
     359                 :         }
     360                 : 
     361                 :   /// Decrement the iterator
     362                 :   iterator operator--(int)
     363                 :         {
     364                 :         iterator __tmp = *this;
     365                 :         this->_M_decr();
     366                 :         return __tmp;
     367                 :         }
     368                 : 
     369                 : };
     370                 : 
     371                 : 
     372                 : /**
     373                 :  * A class that defines a doubly-linked list.
     374                 :  *
     375                 :  * The design of this class was strongly influenced by
     376                 :  * Stanley B. Lippman, "C++ Primer, 2nd Edition."   Addison Wesley, 1991.
     377                 :  * This linked list code can be switched between use as a queue, stack or
     378                 :  * simple linked list by setting different `mode' values.  By default, a
     379                 :  * LinkedList object behaves like a queue.
     380                 :  */
     381                 : template <class _Tp, class _Alloc = std::allocator<_Tp> >
     382                 : class LinkedList
     383                 : {
     384                 : public:
     385                 : 
     386                 : #if !defined(DOXYGEN)
     387                 :   ///
     388                 :   typedef _Tp value_type;
     389                 : 
     390                 :   ///
     391                 :   typedef value_type* pointer;
     392                 : 
     393                 :   ///
     394                 :   typedef const value_type* const_pointer;
     395                 : 
     396                 :   ///
     397                 :   typedef value_type& reference;
     398                 : 
     399                 :   ///
     400                 :   typedef const value_type& const_reference;
     401                 : 
     402                 :   ///
     403                 :   typedef ListItem<_Tp> _Node;
     404                 : 
     405                 :   ///
     406                 :   typedef size_t size_type;
     407                 : 
     408                 :   ///
     409                 :   typedef ptrdiff_t difference_type;
     410                 : 
     411                 :   ///
     412                 :   typedef __LinkedList_iterator<_Tp,_Tp&,_Tp*,_Node,__LinkedList_Standard_OpClass<_Tp&,_Node> > iterator;
     413                 : 
     414                 :   ///
     415                 :   typedef __LinkedList_iterator<_Tp,const _Tp&,const _Tp*,_Node,__LinkedList_Standard_OpClass<_Tp&,_Node> > const_iterator;
     416                 : 
     417                 : /*
     418                 : ** TODO: What is the issue here?  namespace support?
     419                 : */
     420                 : #if defined(UTILIB_SOLARIS_CC)
     421                 :   ///
     422                 :   typedef std::__reverse_bi_iterator<const_iterator,
     423                 :       bidirectional_iterator_tag, value_type,
     424                 :       const_reference, const_pointer, difference_type>
     425                 :       const_reverse_iterator;
     426                 : 
     427                 :   ///
     428                 :   typedef std::__reverse_bi_iterator<iterator,
     429                 :       bidirectional_iterator_tag, value_type,
     430                 :       reference, pointer, difference_type>
     431                 :       reverse_iterator;
     432                 : #elif  defined(COUGAR) || defined(TFLOPS_SERVICE)
     433                 : 
     434                 : #if 0   /// disabled because the coompiler has problems...
     435                 :    ///
     436                 :    typedef reverse_bidirectional_iterator<const_iterator, value_type,
     437                 :                  const_reference, difference_type>
     438                 :         const_reverse_iterator;
     439                 : 
     440                 :    ///
     441                 :    typedef reverse_bidirectional_iterator<iterator, value_type, reference,
     442                 :                 difference_type>
     443                 :         reverse_iterator;
     444                 : #endif
     445                 : 
     446                 : #else
     447                 :   ///
     448                 :   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
     449                 : 
     450                 :   ///
     451                 :   typedef std::reverse_iterator<iterator> reverse_iterator;
     452                 : #endif
     453                 : #endif
     454                 : 
     455                 :   /// Empty constructor, which sets up an empty linked list.
     456          237234 :   LinkedList()
     457          237234 :         {
     458          237234 :         mode=queueLL;
     459          237234 :         counter++;
     460          237234 :         first = last = CachedAllocator<ListItem<_Tp> > :: allocate();
     461          237234 :         last->next = last->prev = 0;
     462          237234 :         Len=0;
     463          237234 :         validate_flag=false;
     464                 :         }
     465                 : 
     466                 :   /** 
     467                 :    * Destructor.
     468                 :    * After deleting the list, the destructor deletes the list of
     469                 :    * additional unused ListItem objects.
     470                 :    */
     471                 :   virtual ~LinkedList();
     472                 : 
     473                 :   /**
     474                 :    * Copy equal operator.
     475                 :    */
     476             100 :    LinkedList<_Tp,_Alloc>& operator=(const LinkedList<_Tp,_Alloc>& list_)
     477                 :         {
     478             100 :         validate_flag = list_.validate_flag;
     479             100 :         mode = list_.mode;
     480             100 :         clear();
     481             100 :         const_iterator curr = list_.begin();
     482             100 :         const_iterator end  = list_.end();
     483             335 :         while (curr != end) {
     484             135 :           push_back(*curr);
     485             135 :           curr++;
     486                 :           }
     487             100 :         return *this;
     488                 :         }
     489                 : 
     490                 :   /**
     491                 :    * Copy constructor.
     492                 :    */
     493             100 :    LinkedList(const LinkedList<_Tp,_Alloc>& list_)
     494             100 :         {
     495             100 :         mode=queueLL;
     496             100 :         counter++;
     497             100 :         first = last = CachedAllocator<ListItem<_Tp> > :: allocate();
     498             100 :         last->next = last->prev = 0;
     499             100 :         Len=0;
     500             100 :         validate_flag=false;
     501             100 :         *this = list_;
     502                 :         }
     503                 : 
     504                 :   /**
     505                 :    * Find the ListItem with value \a data in the list.
     506                 :    * If this data value is not found in the list, this method
     507                 :    * returns \c NULL.
     508                 :    */
     509                 :   ListItem<_Tp>* find(const _Tp& data);
     510                 : 
     511                 :   /// Returns the iterator that defines the beginning of the list
     512          425410 :   iterator begin()
     513          425410 :         { return first; }
     514                 : 
     515                 :   /// Returns the iterator that defines the ending of the list
     516          775817 :   iterator end()
     517          775817 :         { return last; }
     518                 : 
     519                 :   /// Returns the const iterator that defines the beginning of the list
     520             150 :   const_iterator begin() const
     521             150 :         { return first; }
     522                 : 
     523                 :   /// Returns the const iterator that defines the ending of the list
     524             150 :   const_iterator end() const
     525             150 :         { return last; }
     526                 :         //{ return const_cast<ListItem<_Tp>*>(last); }
     527                 : 
     528                 :   ///
     529                 :   /// Returns a reverse iterator to the last element of the list
     530                 :   reverse_iterator rbegin()
     531                 :         { return reverse_iterator(end()); }
     532                 : 
     533                 :   /// Returns a reverse iterator to the last element of the list
     534                 :   const_reverse_iterator rbegin() const
     535                 :         { return const_reverse_iterator(end()); }
     536                 : 
     537                 :   /// Returns a reverse iterator to the first element of the list
     538                 :   reverse_iterator rend()
     539                 :         { return reverse_iterator(begin()); }
     540                 : 
     541                 :   /// Returns a reverse iterator to the first element of the list
     542                 :   const_reverse_iterator rend() const
     543                 :         { return const_reverse_iterator(begin()); }
     544                 : 
     545                 :   /// Returns an iterator to the first element of the list
     546                 :   reference front()
     547                 :         {
     548                 :         if (Len == 0)
     549                 :            EXCEPTION_MNGR(runtime_error, "LinkedList::front() - empty list");
     550                 :         return *begin();
     551                 :         }
     552                 : 
     553                 :   /// Returns an iterator to the first element of the list
     554                 :   const_reference front() const
     555                 :         {
     556                 :         if (Len == 0)
     557                 :            EXCEPTION_MNGR(runtime_error, "LinkedList::front() - empty list");
     558                 :         return *begin();
     559                 :         }
     560                 : 
     561                 :   /// Returns an iterator to the last element of the list
     562                 :   reference back()
     563                 :         {
     564                 :         if (Len == 0)
     565                 :            EXCEPTION_MNGR(runtime_error, "LinkedList::back() - empty list");
     566                 :         return *(--end());
     567                 :         }
     568                 : 
     569                 :   /// Returns an iterator to the last element of the list
     570                 :   const_reference back() const
     571                 :         {
     572                 :         if (Len == 0)
     573                 :            EXCEPTION_MNGR(runtime_error, "LinkedList::back() - empty list");
     574                 :         return *(--end());
     575                 :         }
     576                 : 
     577                 :   /// Insert __x before the specified position
     578          239804 :   iterator insert(iterator __position, const _Tp& __x)
     579                 :         {
     580          239804 :         return insert_value(__x, __position._M_node);
     581                 :         }
     582                 : 
     583                 :   /// Insert an empty value before the specified position
     584                 :   iterator insert(iterator __position)
     585                 :         { return insert_value(__position._M_node); }
     586                 : 
     587                 :   /// Insert a value to the begining of the list
     588              10 :   void push_front(const _Tp& __x)
     589              10 :         { insert(begin(), __x); }
     590                 : 
     591                 :   /// Insert an empty element to the begining of the list
     592                 :   void push_front()
     593                 :         { insert(begin()); }
     594                 : 
     595                 :   /// Insert a value to the end of the list
     596          239794 :   void push_back(const _Tp& __x)
     597          239794 :         { insert(end(), __x); }
     598                 : 
     599                 :   /// Insert an empty element to the end of the list
     600                 :   void push_back()
     601                 :         { insert(end()); }
     602                 : 
     603                 :   /// Remove an element at the specified position
     604           19075 :   iterator erase(iterator __position)
     605                 :         {
     606           19075 :         ListItem<_Tp>* next = __position._M_node->next;
     607           19075 :         remove(__position._M_node);
     608           19075 :         return iterator(next);
     609                 :         }
     610                 : 
     611                 :   /// Clear the list
     612             104 :   void clear()
     613                 :         {
     614             238 :         while (!empty())
     615             134 :           pop_front();
     616                 :         }
     617                 : 
     618                 : 
     619                 :   /// Remove an item from the beginning
     620              30 :   void pop_front()
     621              30 :         { erase(begin()); }
     622                 : 
     623                 :   /// Remove an item from the end
     624                 :   void pop_back()
     625                 :         {
     626                 :         iterator __tmp = end();
     627                 :         erase(--__tmp);
     628                 :         }
     629                 : 
     630                 :   /// Returns the head of the linked list.
     631            2592 :   ListItem<_Tp>* head() const
     632            2592 :         {return (first == last ? 0 : first);}
     633                 : 
     634                 :   /// Returns the tail of the linked list.
     635                 :   ListItem<_Tp>* tail() const
     636                 :         {return last->prev;}
     637                 : 
     638                 :   /// Returns the next item in the list after \a item.
     639            7869 :   ListItem<_Tp>* next(ListItem<_Tp>* item) const
     640            7869 :                 {return (item->next == last ? 0 : item->next);}
     641                 : 
     642                 :   /// Returns the value of the next item that will be removed.
     643               0 :   _Tp& top()
     644                 :         {
     645               0 :         if (Len <= 0) {
     646               0 :            EXCEPTION_MNGR(runtime_error, "LinkedList::top -- Empty list");
     647               0 :            exit(0);
     648                 :            }
     649               0 :         if (mode == queueLL) return first->data();
     650               0 :         return last->prev->data();
     651                 :         }
     652                 : 
     653                 :   /**
     654                 :    * Adds a list item with data value \a data, and returns the ListItem
     655                 :    * object that is generated.
     656                 :    */
     657             115 :   ListItem<_Tp>* add(const _Tp& data)
     658             115 :         { return insert_value(data,0); }
     659                 : 
     660                 :   /**
     661                 :    * Adds a list item with data value \a data, which is inserted
     662                 :    * just before the given position.  Returns the ListItem 
     663                 :    * object in the \a item argument.
     664                 :    */
     665               0 :   ListItem<_Tp>* add(const _Tp& data, ListItem<_Tp>* position)
     666               0 :         { return insert_value(data,position); }
     667                 : 
     668                 :   /**
     669                 :    * Insert an item in the list with data value \a data.
     670                 :    * If \a item is not null, then the new item is inserted before
     671                 :    * \a next.  Otherwise, it is inserted at the end of the list.
     672                 :    */
     673          260235 :   ListItem<_Tp>* insert_value( const _Tp& data, ListItem<_Tp>* item)
     674                 :         {
     675          260235 :         ListItem<_Tp>* tmp = insert_value(item);
     676          260235 :         tmp->Data=data;
     677          260235 :         return tmp;
     678                 :         }
     679                 : 
     680                 :   /**
     681                 :    * Insert an empty item in the list.
     682                 :    * If \a item is not null, then the new item is inserted before
     683                 :    * \a next.  Otherwise, it is inserted at the end of the list.
     684                 :    */
     685                 :   ListItem<_Tp>* insert_value(ListItem<_Tp>* item);
     686                 : 
     687                 :   /// Removes the next list item and returns the data value in \a data.
     688              45 :   void remove( _Tp& data) 
     689                 :         {
     690              45 :         if (mode==queueLL) 
     691              45 :            extract(first,data); 
     692                 :         else
     693               0 :            extract(last->prev,data);
     694                 :         }
     695                 : 
     696                 :   /// Removes \a item from the list.
     697           20346 :   void remove( ListItem<_Tp>* item) 
     698           20346 :         {extract(item);}
     699                 : 
     700                 :   /// Removes \a item from the list and returns the data value in \a data.
     701               0 :   void remove(ListItem<_Tp>* item, _Tp& data) 
     702               0 :         {extract(item,data);}
     703                 : 
     704                 :   /// Returns true if the list is empty
     705                 :   bool empty() const;
     706                 : 
     707                 :   /// Returns true if the list is not empty
     708            1613 :   operator bool() const
     709            1613 :         {return (first == last ? false : true);}
     710                 : 
     711                 :   /// Returns the length of the list.
     712           70503 :   size_type size() const 
     713           70503 :         {return Len;}
     714                 : 
     715                 :   /// Sets the add/remove mode to operate a stack.
     716               0 :   void stack_mode()
     717               0 :         {mode = stackLL;}
     718                 : 
     719                 :   /// Sets the add/remove mode to operate a queue (the default).
     720               0 :   void queue_mode()
     721               0 :         {mode = queueLL;}
     722                 : 
     723                 :   /// If true, then validate extraction operations
     724                 :   bool validate_flag;
     725                 : 
     726                 :   /// Write this object to a stream
     727                 :   void write(std::ostream& os) const;
     728                 : 
     729                 :   /// Read this object from a stream
     730                 :   void read(std::istream& is);
     731                 : 
     732                 :   /// Write this object to a buffer
     733                 :   void write(PackBuffer& os) const;
     734                 : 
     735                 :   /// Read this object from a buffer
     736                 :   void read(UnPackBuffer& is);
     737                 : 
     738                 : protected:
     739                 : 
     740                 :   /// Defines the different modes that the LinkedList can operate
     741                 :   enum {
     742                 :         /// Adds items to the beginning; Removes items from the beginning
     743                 :         stackLL = 0,
     744                 :         /// Adds items to the end; Removes items from the beginning
     745                 :         queueLL = 1     
     746                 :         };
     747                 : 
     748                 :   /// The add/remove mode.
     749                 :   int mode;
     750                 : 
     751                 :   /// Removes an item from the list.
     752                 :   void extract(ListItem<_Tp>* item);
     753                 : 
     754                 :   /// Removes an item from the list and returns its value in \a data.
     755              45 :   void extract(ListItem<_Tp>* item, _Tp& data)
     756              45 :                 {data = item->Data; extract(item);}
     757                 : 
     758                 :   /// The first item in the list.
     759                 :   ListItem<_Tp> *first;
     760                 : 
     761                 :   /// The last item in the list.
     762                 :   ListItem<_Tp>* last;
     763                 : 
     764                 :   /// The length of the list.
     765                 :   size_type Len;
     766                 : 
     767                 :   /// The number of unused ListItem objects.
     768                 :   static int counter;
     769                 : 
     770                 :   /// A routine used to debug/validate the LinkedList class
     771                 :   void validate(ListItem<_Tp>* item=0);
     772                 : };
     773                 : 
     774                 : 
     775                 : 
     776                 : 
     777                 : 
     778                 : //
     779                 : // LinkedList methods
     780                 : //
     781                 : 
     782                 : template <class _Tp, class _Alloc>
     783                 : int LinkedList<_Tp,_Alloc>::counter=0;
     784                 : 
     785                 : 
     786                 : template <class _Tp, class _Alloc>
     787          237334 : LinkedList<_Tp,_Alloc>::~LinkedList()
     788                 : {
     789          714512 : while (!empty())
     790          239844 :   extract(first);
     791          237334 : counter--;
     792          237334 : CachedAllocator<ListItem<_Tp> > :: deallocate(last);
     793          237334 : last = 0;
     794                 : 
     795          237334 : if (!counter)
     796          237190 :    CachedAllocator<ListItem<_Tp> > :: delete_unused();
     797          237334 : }
     798                 : 
     799                 : 
     800                 : template <class _Tp, class _Alloc>
     801          737547 : bool LinkedList<_Tp,_Alloc>::empty() const
     802                 : {
     803          737547 : return (first == last ? true : false) ;
     804                 : }
     805                 : 
     806                 : 
     807                 : template <class _Tp, class _Alloc>
     808          260235 : void LinkedList<_Tp,_Alloc>::extract(ListItem<_Tp>* item)
     809                 : {
     810          260235 : if (item == last)
     811               0 :    EXCEPTION_MNGR(runtime_error, "LinkedList::extract - trying to erase 'last'");
     812          260235 : if (empty())
     813               0 :    EXCEPTION_MNGR(runtime_error, "LinkedList<_Tp,_Alloc>::extract : empty list");
     814                 : 
     815          260235 : if (validate_flag)
     816               0 :    validate(item);
     817                 : 
     818          260235 : if (item->prev) 
     819           17584 :    item->prev->next = item->next;
     820                 : else 
     821          242651 :    first = item->next;
     822                 : 
     823          260235 : item->next->prev = item->prev;
     824          260235 : Len--;
     825                 : 
     826          260235 : if (validate_flag)
     827               0 :    validate();
     828                 : 
     829          260235 : CachedAllocator<ListItem<_Tp> > :: deallocate(item);
     830          260235 : item = 0;
     831                 : }
     832                 : 
     833                 : 
     834                 : template <class _Tp, class _Alloc>
     835          260235 : ListItem<_Tp>* LinkedList<_Tp,_Alloc>::insert_value(ListItem<_Tp>* next)
     836                 : {
     837          260235 : ListItem<_Tp>* item = CachedAllocator<ListItem<_Tp> > :: allocate();
     838          260235 : item->next = item->prev = 0;
     839                 : 
     840          260235 : if (next) {
     841          241108 :    if (next->prev)
     842            3890 :       next->prev->next = item;
     843                 :    else
     844          237218 :       first = item;
     845          241108 :    item->next = next;
     846          241108 :    item->prev = next->prev;
     847          241108 :    next->prev = item;
     848                 :    }
     849                 : else {                  // appending to end of list 
     850           19127 :    if (last->prev) {
     851           18858 :       last->prev->next = item;
     852           18858 :       item->prev = last->prev;
     853           18858 :       item->next = last;
     854           18858 :       last->prev = item;
     855                 :       }
     856                 :    else {
     857             269 :       first = last->prev = item;
     858             269 :       first->next = last;
     859                 :       }
     860                 :    }
     861                 : 
     862          260235 : Len++;
     863          260235 : if (validate_flag)
     864               0 :    validate();
     865          260235 : return item;
     866                 : }
     867                 : 
     868                 : 
     869                 : template <class _Tp, class _Alloc>
     870           19045 : ListItem<_Tp>* LinkedList<_Tp,_Alloc>::find(const _Tp& data)
     871                 : {
     872           19045 : ListItem<_Tp>* curr = first; //(first == last ? 0 : first);
     873                 : 
     874           80930 : while (curr != last) {
     875           61885 :   if (data == curr->data()) break;
     876           42840 :   curr = curr->next;
     877                 :   }
     878                 : 
     879           19045 : return curr;
     880                 : }
     881                 : 
     882                 : template <class _Tp, class _Alloc>
     883               0 : void LinkedList<_Tp,_Alloc>::validate(ListItem<_Tp>*item)
     884                 : {
     885               0 : if (first == last) {
     886               0 :    if (Len != 0)
     887               0 :       EXCEPTION_MNGR(runtime_error, "Nonzero length but first==last");
     888               0 :    if (last->next || last->prev)
     889               0 :       EXCEPTION_MNGR(runtime_error, "Bad link pointers in last");
     890               0 :    return;
     891                 :    }
     892                 : 
     893               0 : if (last->next)
     894               0 :    EXCEPTION_MNGR(runtime_error, "Bad next pointers in last");
     895               0 : if (first->prev)
     896               0 :    EXCEPTION_MNGR(runtime_error, "Bad prev pointers in first");
     897                 : 
     898               0 : ListItem<_Tp>* curr = first;
     899               0 : unsigned int ctr=0;
     900               0 : while (curr != last) {
     901               0 :   ctr++;
     902               0 :   if (ctr > Len)
     903               0 :      EXCEPTION_MNGR(runtime_error, "More than Len items in the list");
     904               0 :   if ((curr != first) && (curr->prev == 0))
     905               0 :      EXCEPTION_MNGR(runtime_error, "Null prev ptr for non-first");
     906               0 :   if ((curr != last) && (curr->next == 0))
     907               0 :      EXCEPTION_MNGR(runtime_error, "Null next ptr for non-last");
     908               0 :   if ((curr->prev) && (curr->prev->next != curr))
     909               0 :      EXCEPTION_MNGR(runtime_error, "curr->prev->next != curr");
     910               0 :   if ((curr->next) && (curr->next->prev != curr))
     911               0 :      EXCEPTION_MNGR(runtime_error, "curr->next->prev != curr");
     912               0 :   curr = curr->next;
     913                 :   }
     914                 : 
     915               0 : if (!item) return;
     916                 : 
     917               0 : curr = first;
     918               0 : bool flag=false;
     919               0 : while (curr != last) {
     920               0 :   if (curr == item) {
     921               0 :      if (curr->next != item->next)
     922               0 :         EXCEPTION_MNGR(runtime_error, "curr->next != item->next");
     923               0 :      if (curr->prev != item->prev)
     924               0 :         EXCEPTION_MNGR(runtime_error, "curr->prev != item->prev");
     925               0 :      flag=true;
     926               0 :      break;
     927                 :      }
     928               0 :   curr = curr->next;
     929                 :   }
     930               0 : if (!flag)
     931               0 :    EXCEPTION_MNGR(runtime_error, "The given item is not in the list!");
     932                 : }
     933                 : 
     934                 : 
     935                 : template <class _Tp, class _Alloc>
     936             105 : void LinkedList<_Tp,_Alloc>::write(std::ostream& os) const
     937                 : {
     938             105 : utilib::ListItem<_Tp>* curr = (first == last ? 0 : first);
     939                 : 
     940             105 : os << size() << " : ";
     941             105 : if (size() == 0) return;
     942             325 : while (curr != last) {
     943             185 :   os << curr->data() << " ";
     944             185 :   curr = curr->next;
     945                 :   }
     946                 : }
     947                 : 
     948                 : 
     949                 : template <class _Tp, class _Alloc>
     950               1 : void LinkedList<_Tp,_Alloc>::write(utilib::PackBuffer& os) const
     951                 : {
     952               1 : utilib::ListItem<_Tp>* curr = (first == last ? 0 : first);
     953                 : 
     954               1 : os << size();
     955               1 : if (size() == 0) return;
     956              12 : while (curr != last) {
     957              10 :   os << curr->data();
     958              10 :   curr = curr->next;
     959                 :   }
     960                 : }
     961                 : 
     962                 : 
     963                 : template <class _Tp, class _Alloc>
     964               1 : void LinkedList<_Tp,_Alloc>::read(std::istream& is)
     965                 : {
     966                 : int tmp;
     967               1 : is >> tmp;
     968                 : char c;
     969               1 : is >> c;
     970              11 : for (int i=0; i<tmp; i++) {
     971                 :   _Tp item;
     972              10 :   is >> item;
     973              11 :   add(item);
     974                 :   }
     975                 : }
     976                 : 
     977                 : 
     978                 : template <class _Tp, class _Alloc>
     979               1 : void LinkedList<_Tp,_Alloc>::read(utilib::UnPackBuffer& is)
     980                 : {
     981                 : size_type tmp;
     982               1 : is >> tmp;
     983              11 : for (size_type i=0; i<tmp; i++) {
     984                 :   _Tp item;
     985              10 :   is >> item;
     986              11 :   add(item);
     987                 :   }
     988                 : }
     989                 : 
     990                 : 
     991                 : } // namespace utilib
     992                 : 
     993                 : /// Out-stream operator for removing data from a list
     994                 : template <class _Tp, class _Alloc>
     995              45 : inline utilib::LinkedList<_Tp,_Alloc>& operator>>(utilib::LinkedList<_Tp,_Alloc>& list, _Tp& data)
     996              45 : {list.remove(data); return list;}
     997                 : 
     998                 : /// Out-stream operator for adding data to a list
     999                 : template <class _Tp, class _Alloc>
    1000              65 : inline utilib::LinkedList<_Tp,_Alloc>& operator<<(utilib::LinkedList<_Tp,_Alloc>& list, const _Tp& data)
    1001              65 : {list.add(data); return list;}
    1002                 : 
    1003                 : /// Out-stream operator for writing the contents of a LinkedList
    1004                 : template <class _Tp, class _Alloc>
    1005                 : inline std::ostream& operator<<(std::ostream& os, 
    1006             105 :                                 const utilib::LinkedList<_Tp,_Alloc>& obj)
    1007             105 : { obj.write(os); return(os); }
    1008                 : 
    1009                 : /// Out-stream operator for writing the contents of a LinkedList
    1010                 : template <class _Tp, class _Alloc>
    1011                 : inline utilib::PackBuffer& operator<<(utilib::PackBuffer& os,
    1012               1 :                                 const utilib::LinkedList<_Tp,_Alloc>& obj)
    1013               1 : { obj.write(os); return(os); }
    1014                 : 
    1015                 : /// In-stream operator for reading the contents of a LinkedList
    1016                 : template <class _Tp, class _Alloc>
    1017                 : inline std::istream& operator>>(std::istream& is, 
    1018               1 :                                 utilib::LinkedList<_Tp,_Alloc>& obj)
    1019               1 : { obj.read(is); return(is); }
    1020                 : 
    1021                 : /// In-stream operator for reading the contents of a LinkedList
    1022                 : template <class _Tp, class _Alloc>
    1023                 : inline utilib::UnPackBuffer& operator>>(utilib::UnPackBuffer& is,
    1024               1 :                                 utilib::LinkedList<_Tp,_Alloc>& obj)
    1025               1 : { obj.read(is); return(is); }
    1026                 : 
    1027                 : #endif

Generated by: LTP GCOV extension version 1.4