Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:16:20

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     grow(l.maxNItems);
0080     nItems = l.length();
0081     for (size_t i = 0; i < nItems; ++i)
0082     {
0083       items[i] = l[i];
0084     }
0085   }
0086   return *this;
0087 }
0088 
0089 template <class T>
0090 PHPointerList<T>::~PHPointerList()
0091 {
0092   // This deletes the internal list of pointers and NOT the actual objects.
0093   delete[] items;
0094 }
0095 
0096 template <class T>
0097 bool PHPointerList<T>::grow(size_t newSize)
0098 {
0099   if (newSize == 0)
0100   {
0101     newSize = maxNItems * 2;
0102   }
0103   T** buffer = items;
0104   items = new T*[newSize];
0105   if (items)
0106   {
0107     for (size_t i = 0; i < maxNItems; ++i)
0108     {
0109       items[i] = buffer[i];
0110     }
0111     delete[] buffer;
0112     maxNItems = newSize;
0113   }
0114   else
0115   {
0116     std::cout << "PHPointerList<T>::grow: Out of memory?" << std::endl;
0117     return false;
0118   }
0119 
0120   return true;
0121 }
0122 
0123 template <class T>
0124 inline T* PHPointerList<T>::operator[](size_t i) const
0125 {
0126   if (i < nItems)
0127   {
0128     return items[i];
0129   }
0130   else
0131   {
0132     std::cout << "PHPointerList<T>::operator[]: nItems exceeded" << std::endl;
0133     return 0;
0134   }
0135 }
0136 
0137 template <class T>
0138 inline bool
0139 PHPointerList<T>::append(T* item)
0140 {
0141   if (nItems < maxNItems)
0142   {
0143     items[nItems] = item;
0144     ++nItems;
0145     return true;
0146   }
0147   else
0148   {
0149     if (grow())
0150     {
0151       items[nItems] = item;
0152       ++nItems;
0153       return true;
0154     }
0155     else
0156     {
0157       std::cout << "PHPointerList<T>::append: max nItems exceeded" << std::endl;
0158       return false;
0159     }
0160   }
0161 }
0162 
0163 template <class T>
0164 inline bool
0165 PHPointerList<T>::insertAt(T* item, size_t pos)
0166 {
0167   // This function inserts item at pos in the internal list
0168   if (pos > nItems)
0169   {
0170     std::cout << "PHPointerList<T>::insertAt: insert beyond nItems" << std::endl;
0171     return false;
0172   }
0173 
0174   // Append is used here as a convenient way to let the list grow, if necessary.
0175   append(item);
0176 
0177   // Now all items are shifted upwards in the list by one, starting at pos.
0178   for (size_t i = nItems; i > pos; --i)
0179   {
0180     items[i] = items[i - 1];
0181   }
0182 
0183   items[pos] = item;
0184 
0185   return true;
0186 }
0187 
0188 template <class T>
0189 inline void
0190 PHPointerList<T>::clear()
0191 {
0192   nItems = 0;
0193   items[nItems] = 0;
0194 }
0195 
0196 template <class T>
0197 inline void
0198 PHPointerList<T>::clearAndDestroy()
0199 {
0200   for (size_t i = 0; i < nItems; ++i)
0201   {
0202     delete items[i];
0203   }
0204   nItems = 0;
0205   items[nItems] = 0;
0206 }
0207 
0208 template <class T>
0209 inline size_t
0210 PHPointerList<T>::length() const
0211 {
0212   return nItems;
0213 }
0214 
0215 template <class T>
0216 inline T*
0217 PHPointerList<T>::removeLast()
0218 {
0219   if (nItems > 0)
0220   {
0221     return items[nItems--];
0222   }
0223   else
0224   {
0225     std::cout << "PHPointerList<T>::removeLast: no items in list" << std::endl;
0226     return 0;
0227   }
0228 }
0229 
0230 template <class T>
0231 inline T*
0232 PHPointerList<T>::removeAt(size_t i)
0233 {
0234   if (i > nItems)
0235   {
0236     return 0;
0237   }
0238 
0239   T* item = items[i];
0240 
0241   for (size_t j = i; j < nItems - 1; ++j)
0242   {
0243     items[j] = items[j + 1];
0244   }
0245   --nItems;
0246 
0247   return item;
0248 }
0249 
0250 // Implementation of external functions.
0251 template <class T>
0252 std::ostream&
0253 operator<<(std::ostream& stream, const PHPointerList<T>& thislist)
0254 {
0255   for (size_t i = 0; i < thislist.length(); ++i)
0256   {
0257     stream << *(thislist[i]) << std::endl;
0258   }
0259 
0260   return stream;
0261 }
0262 
0263 #endif