File indexing completed on 2025-08-05 08:16:20
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 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
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
0168 if (pos > nItems)
0169 {
0170 std::cout << "PHPointerList<T>::insertAt: insert beyond nItems" << std::endl;
0171 return false;
0172 }
0173
0174
0175 append(item);
0176
0177
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
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