Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-17 09:19:51

0001 #ifndef PHOOL_PHPOINTERLIST_H
0002 #define PHOOL_PHPOINTERLIST_H
0003 
0004 //  Purpose: a template list of pointers
0005 //
0006 //  Description:
0007 //       - The items are held internally as an array of type T.
0008 //       - The list is initialized with a maximum size of 2
0009 //         per default, or with the number given as constructor
0010 //         argument.
0011 //       - If this size is exceeded in the append() function,
0012 //         the array is allocated anew with double size and the
0013 //         old list is copied into this new one.
0014 //       - clear() sets the number of items to zero.
0015 //       - clearAndDestroy() does the same AND deletes all items.
0016 //       - The [] operator always performs a bound-check.
0017 //       - removeLast() returns the pointer to the last item in the
0018 //         array and decrements size by one.
0019 //       - removeAt(i) returns the pointer at position i and rearranges
0020 //         the internal list. This can cost PERFORMANCE in your application.
0021 //       - The output operator '<<' is overloaded for this class.
0022 //         Therefore class T for which the PHPointerList is insantiated must
0023 //         also have an overloaded output operator.
0024 //
0025 //  Author: Matthias Messer
0026 
0027 #include <iostream>
0028 
0029 template <class T>
0030 class PHPointerList
0031 {
0032  public:
0033   explicit PHPointerList(size_t = 2);
0034   PHPointerList(const PHPointerList<T>&);
0035   PHPointerList<T>& operator=(const PHPointerList<T>&);
0036   virtual ~PHPointerList();
0037 
0038  public:
0039   T* operator[](size_t) const;
0040   void clear();
0041   void clearAndDestroy();
0042   size_t length() const;
0043   T* removeLast();
0044   T* removeAt(size_t);
0045   bool append(T*);
0046   bool insertAt(T*, size_t);
0047 
0048  private:
0049   bool grow(size_t = 0);
0050 
0051  private:
0052   T** items;
0053   size_t maxNItems;
0054   size_t nItems;
0055 };
0056 
0057 // Implementation of member functions
0058 template <class T>
0059 PHPointerList<T>::PHPointerList(size_t initialSize)
0060 {
0061   maxNItems = initialSize;
0062   items = new T*[maxNItems];
0063   nItems = 0;
0064 }
0065 
0066 template <class T>
0067 PHPointerList<T>::PHPointerList(const PHPointerList<T>& l)
0068 {
0069   *this = l;
0070 }
0071 
0072 template <class T>
0073 PHPointerList<T>&
0074 PHPointerList<T>::operator=(const PHPointerList<T>& l)
0075 {
0076   if (this != &l)
0077   {
0078     maxNItems = l.maxNItems;
0079     if (maxNItems > 0)
0080     {
0081       grow(l.maxNItems);
0082     }
0083     else
0084     {
0085       items = nullptr;
0086     }
0087     nItems = l.length();
0088     for (size_t i = 0; i < nItems; ++i)
0089     {
0090       items[i] = l[i];
0091     }
0092   }
0093   return *this;
0094 }
0095 
0096 template <class T>
0097 PHPointerList<T>::~PHPointerList()
0098 {
0099   // This deletes the internal list of pointers and NOT the actual objects.
0100   delete[] items;
0101 }
0102 
0103 template <class T>
0104 bool PHPointerList<T>::grow(size_t newSize)
0105 {
0106   if (newSize == 0)
0107   {
0108     newSize = maxNItems * 2;
0109   }
0110   T** buffer = items;
0111   items = new T*[newSize];
0112   if (items)
0113   {
0114     for (size_t i = 0; i < maxNItems; ++i)
0115     {
0116       items[i] = buffer[i];
0117     }
0118     delete[] buffer;
0119     maxNItems = newSize;
0120   }
0121   else
0122   {
0123     std::cout << "PHPointerList<T>::grow: Out of memory?" << std::endl;
0124     return false;
0125   }
0126 
0127   return true;
0128 }
0129 
0130 template <class T>
0131 inline T* PHPointerList<T>::operator[](size_t i) const
0132 {
0133   if (i < nItems)
0134   {
0135     return items[i];
0136   }
0137   else
0138   {
0139     std::cout << "PHPointerList<T>::operator[]: nItems exceeded" << std::endl;
0140     return 0;
0141   }
0142 }
0143 
0144 template <class T>
0145 inline bool
0146 PHPointerList<T>::append(T* item)
0147 {
0148   if (nItems < maxNItems)
0149   {
0150     items[nItems] = item;
0151     ++nItems;
0152     return true;
0153   }
0154   else
0155   {
0156     if (grow())
0157     {
0158       items[nItems] = item;
0159       ++nItems;
0160       return true;
0161     }
0162     else
0163     {
0164       std::cout << "PHPointerList<T>::append: max nItems exceeded" << std::endl;
0165       return false;
0166     }
0167   }
0168 }
0169 
0170 template <class T>
0171 inline bool
0172 PHPointerList<T>::insertAt(T* item, size_t pos)
0173 {
0174   // This function inserts item at pos in the internal list
0175   if (pos > nItems)
0176   {
0177     std::cout << "PHPointerList<T>::insertAt: insert beyond nItems" << std::endl;
0178     return false;
0179   }
0180 
0181   // Append is used here as a convenient way to let the list grow, if necessary.
0182   append(item);
0183 
0184   // Now all items are shifted upwards in the list by one, starting at pos.
0185   for (size_t i = nItems; i > pos; --i)
0186   {
0187     items[i] = items[i - 1];
0188   }
0189 
0190   items[pos] = item;
0191 
0192   return true;
0193 }
0194 
0195 template <class T>
0196 inline void
0197 PHPointerList<T>::clear()
0198 {
0199   nItems = 0;
0200   items[nItems] = 0;
0201 }
0202 
0203 template <class T>
0204 inline void
0205 PHPointerList<T>::clearAndDestroy()
0206 {
0207   for (size_t i = 0; i < nItems; ++i)
0208   {
0209     delete items[i];
0210   }
0211   nItems = 0;
0212   items[nItems] = 0;
0213 }
0214 
0215 template <class T>
0216 inline size_t
0217 PHPointerList<T>::length() const
0218 {
0219   return nItems;
0220 }
0221 
0222 template <class T>
0223 inline T*
0224 PHPointerList<T>::removeLast()
0225 {
0226   if (nItems > 0)
0227   {
0228     return items[nItems--];
0229   }
0230   else
0231   {
0232     std::cout << "PHPointerList<T>::removeLast: no items in list" << std::endl;
0233     return 0;
0234   }
0235 }
0236 
0237 template <class T>
0238 inline T*
0239 PHPointerList<T>::removeAt(size_t i)
0240 {
0241   if (i > nItems)
0242   {
0243     return 0;
0244   }
0245 
0246   T* item = items[i];
0247 
0248   for (size_t j = i; j < nItems - 1; ++j)
0249   {
0250     items[j] = items[j + 1];
0251   }
0252   --nItems;
0253 
0254   return item;
0255 }
0256 
0257 // Implementation of external functions.
0258 template <class T>
0259 std::ostream&
0260 operator<<(std::ostream& stream, const PHPointerList<T>& thislist)
0261 {
0262   for (size_t i = 0; i < thislist.length(); ++i)
0263   {
0264     stream << *(thislist[i]) << std::endl;
0265   }
0266 
0267   return stream;
0268 }
0269 
0270 #endif