EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHPointerList.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHPointerList.h
1 #ifndef PHOOL_PHPOINTERLIST_H
2 #define PHOOL_PHPOINTERLIST_H
3 
4 // Purpose: a template list of pointers
5 //
6 // Description:
7 // - The items are held internally as an array of type T.
8 // - The list is initialized with a maximum size of 2
9 // per default, or with the number given as constructor
10 // argument.
11 // - If this size is exceeded in the append() function,
12 // the array is allocated anew with double size and the
13 // old list is copied into this new one.
14 // - clear() sets the number of items to zero.
15 // - clearAndDestroy() does the same AND deletes all items.
16 // - The [] operator always performs a bound-check.
17 // - removeLast() returns the pointer to the last item in the
18 // array and decrements size by one.
19 // - removeAt(i) returns the pointer at position i and rearranges
20 // the internal list. This can cost PERFORMANCE in your application.
21 // - The output operator '<<' is overloaded for this class.
22 // Therefore class T for which the PHPointerList is insantiated must
23 // also have an overloaded output operator.
24 //
25 // Author: Matthias Messer
26 
27 #include <iostream>
28 
29 template <class T>
31 {
32  public:
33  explicit PHPointerList(size_t = 2);
36  virtual ~PHPointerList();
37 
38  public:
39  T* operator[](size_t) const;
40  void clear();
41  void clearAndDestroy();
42  size_t length() const;
43  T* removeLast();
44  T* removeAt(size_t);
45  bool append(T*);
46  bool insertAt(T*, size_t);
47 
48  private:
49  bool grow(size_t = 0);
50 
51  private:
52  T** items;
53  size_t maxNItems;
54  size_t nItems;
55 };
56 
57 // Implementation of member functions
58 template <class T>
60 {
61  maxNItems = initialSize;
62  items = new T*[maxNItems];
63  nItems = 0;
64 }
65 
66 template <class T>
68 {
69  *this = l;
70 }
71 
72 template <class T>
75 {
76  if (this != &l)
77  {
78  maxNItems = l.maxNItems;
79  grow(l.maxNItems);
80  nItems = l.length();
81  for (size_t i = 0; i < nItems; ++i)
82  {
83  items[i] = l[i];
84  }
85  }
86  return *this;
87 }
88 
89 template <class T>
91 {
92  // This deletes the internal list of pointers and NOT the actual objects.
93  delete[] items;
94 }
95 
96 template <class T>
97 bool PHPointerList<T>::grow(size_t newSize)
98 {
99  if (newSize == 0)
100  {
101  newSize = maxNItems * 2;
102  }
103  T** buffer = items;
104  items = new T*[newSize];
105  if (items)
106  {
107  for (size_t i = 0; i < maxNItems; ++i)
108  {
109  items[i] = buffer[i];
110  }
111  delete[] buffer;
112  maxNItems = newSize;
113  }
114  else
115  {
116  std::cout << "PHPointerList<T>::grow: Out of memory?" << std::endl;
117  return false;
118  }
119 
120  return true;
121 }
122 
123 template <class T>
124 inline T* PHPointerList<T>::operator[](size_t i) const
125 {
126  if (i < nItems)
127  {
128  return items[i];
129  }
130  else
131  {
132  std::cout << "PHPointerList<T>::operator[]: nItems exceeded" << std::endl;
133  return 0;
134  }
135 }
136 
137 template <class T>
138 inline bool
140 {
141  if (nItems < maxNItems)
142  {
143  items[nItems] = item;
144  ++nItems;
145  return true;
146  }
147  else
148  {
149  if (grow())
150  {
151  items[nItems] = item;
152  ++nItems;
153  return true;
154  }
155  else
156  {
157  std::cout << "PHPointerList<T>::append: max nItems exceeded" << std::endl;
158  return false;
159  }
160  }
161 }
162 
163 template <class T>
164 inline bool
166 {
167  // This function inserts item at pos in the internal list
168  if (pos > nItems)
169  {
170  std::cout << "PHPointerList<T>::insertAt: insert beyond nItems" << std::endl;
171  return false;
172  }
173 
174  // Append is used here as a convenient way to let the list grow, if necessary.
175  append(item);
176 
177  // Now all items are shifted upwards in the list by one, starting at pos.
178  for (size_t i = nItems; i > pos; --i)
179  {
180  items[i] = items[i - 1];
181  }
182 
183  items[pos] = item;
184 
185  return true;
186 }
187 
188 template <class T>
189 inline void
191 {
192  nItems = 0;
193  items[nItems] = 0;
194 }
195 
196 template <class T>
197 inline void
199 {
200  for (size_t i = 0; i < nItems; ++i)
201  {
202  delete items[i];
203  }
204  nItems = 0;
205  items[nItems] = 0;
206 }
207 
208 template <class T>
209 inline size_t
211 {
212  return nItems;
213 }
214 
215 template <class T>
216 inline T*
218 {
219  if (nItems > 0)
220  {
221  return items[nItems--];
222  }
223  else
224  {
225  std::cout << "PHPointerList<T>::removeLast: no items in list" << std::endl;
226  return 0;
227  }
228 }
229 
230 template <class T>
231 inline T*
233 {
234  if (i > nItems)
235  {
236  return 0;
237  }
238 
239  T* item = items[i];
240 
241  for (size_t j = i; j < nItems - 1; ++j)
242  {
243  items[j] = items[j + 1];
244  }
245  --nItems;
246 
247  return item;
248 }
249 
250 // Implementation of external functions.
251 template <class T>
252 std::ostream&
253 operator<<(std::ostream& stream, const PHPointerList<T>& thislist)
254 {
255  for (size_t i = 0; i < thislist.length(); ++i)
256  {
257  stream << *(thislist[i]) << std::endl;
258  }
259 
260  return stream;
261 }
262 
263 #endif