File indexing completed on 2025-12-17 09:19:51
0001 #ifndef PHOOL_PHPOINTERLIST_H
0002 #define PHOOL_PHPOINTERLIST_H
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
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
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
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
0175 if (pos > nItems)
0176 {
0177 std::cout << "PHPointerList<T>::insertAt: insert beyond nItems" << std::endl;
0178 return false;
0179 }
0180
0181
0182 append(item);
0183
0184
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
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