PSCF v1.1
SSet.h
1#ifndef UTIL_S_SET_H
2#define UTIL_S_SET_H
3
4/*
5* Util Package - C++ Utilities for Scientific Computation
6*
7* Copyright 2010 - 2017, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include <util/containers/PArrayIterator.h>
12#include <util/containers/ConstPArrayIterator.h>
13#include <util/global.h>
14
15namespace Util
16{
17
42 template <typename Data, int Capacity>
43 class SSet
44 {
45
46 public:
47
51 SSet();
52
60 SSet(SSet<Data, Capacity> const & other);
61
68
72 ~SSet();
73
81 void append(Data &data);
82
93 void remove(Data const & data);
94
98 void clear();
99
103 int capacity() const;
104
108 int size() const;
109
115 bool isElement(Data const & data) const;
116
129 int index(Data const & data) const;
130
136 void begin(PArrayIterator<Data> &iterator);
137
143 void begin(ConstPArrayIterator<Data> &iterator) const;
144
151 Data& operator[] (int i);
152
159 Data const & operator[] (int i) const;
160
161 protected:
162
164 Data* ptrs_[Capacity];
165
167 int size_;
168
169 };
170
171 // Method definitions
172
173 /*
174 * Constructor.
175 */
176 template <typename Data, int Capacity>
178 : size_(0)
179 {}
180
181 /*
182 * Copy constructor, copy all pointers.
183 */
184 template<typename Data, int Capacity>
186 {
187
188 // Copy pointer values
189 int i;
190 for (i = 0; i < other.size_; ++i) {
191 ptrs_[i] = other.ptrs_[i];
192 }
193 size_ = other.size_;
194
195 // Nullify any unused elements
196 if (Capacity > size_) {
197 for (i = size_; i < Capacity; ++i) {
198 ptrs_[i] = 0;
199 }
200 }
201
202 }
203
204 /*
205 * Assignment, element by element.
206 */
207 template <typename Data, int Capacity>
210 {
211
212 // Check for self assignment
213 if (this == &other) return *this;
214
215 // Precondition
216 if (Capacity < other.size_) {
217 UTIL_THROW("LHS SSet is too small");
218 }
219
220 // Copy pointers
221 for (int i = 0; i < other.size_; ++i) {
222 ptrs_[i] = other[i];
223 }
224 size_ = other.size_;
225
226 // Nullify any unused elements
227 if (Capacity > size_) {
228 for (int i = size_; i < Capacity; ++i) {
229 ptrs_[i] = 0;
230 }
231 }
232
233 return *this;
234 }
235
236 /*
237 * Destructor.
238 */
239 template <typename Data, int Capacity>
241 {}
242
243 /*
244 * Return physical capacity of array.
245 */
246 template <typename Data, int Capacity>
248 { return Capacity; }
249
250 /*
251 * Return logical size of this array.
252 */
253 template <typename Data, int Capacity>
254 inline int SSet<Data, Capacity>::size() const
255 { return size_; }
256
257 /*
258 * Set a PArrayIterator to the beginning of this Array.
259 *
260 * \param iterator PArrayIterator, initialized on output.
261 */
262 template <typename Data, int Capacity>
264 {
265 iterator.setCurrent(const_cast<Data**>(ptrs_));
266 iterator.setEnd(const_cast<Data**>(ptrs_ + size_));
267 }
268
269 /*
270 * Set a PArrayIterator to the beginning of this Array.
271 */
272 template <typename Data, int Capacity>
273 inline
275 const
276 {
277 iterator.setCurrent(const_cast<Data**>(ptrs_));
278 iterator.setEnd(const_cast<Data**>(ptrs_ + size_));
279 }
280
281 /*
282 * Mimic C array subscripting.
283 */
284 template <typename Data, int Capacity>
286 {
287 assert(i < size_);
288 assert(i >= 0);
289 return *ptrs_[i];
290 }
291
292 /*
293 * Mimic C array subscripting.
294 */
295 template <typename Data, int Capacity>
296 inline Data const & SSet<Data, Capacity>::operator[] (int i) const
297 {
298 assert(i < size_);
299 assert(i >= 0 );
300 return *ptrs_[i];
301 }
302
303 /*
304 * Append data to the end of the array.
305 *
306 * \param data Data to add to end of array.
307 */
308 template <typename Data, int Capacity>
309 inline void SSet<Data, Capacity>::append(Data &data)
310 {
311 if (size_ == Capacity) {
312 UTIL_THROW("Attempt to add to full SSet");
313 }
314 ptrs_[size_] = &data;
315 ++size_;
316 }
317
318 /*
319 * Clear out the container.
320 */
321 template <typename Data, int Capacity>
323 {
324 size_ = 0;
325 for (int i=0; i < Capacity; ++i) {
326 ptrs_[i] = 0;
327 }
328 }
329
330 /*
331 * Remove an element from the set.
332 */
333 template <typename Data, int Capacity>
334 void SSet<Data, Capacity>::remove(Data const & data)
335 {
336 Data const * const ptr = &data;
337 int i;
338 bool found;
339
340 // Search for object
341 found = false;
342 for (i = 0; i < size_; ++i) {
343 if (ptr == ptrs_[i]) {
344 found = true;
345 break;
346 }
347 }
348
349 if (!found) {
350 UTIL_THROW("Element is not in set");
351 }
352
353 // Remove element
354 if (i != size_ - 1) {
355 ptrs_[i] = ptrs_[size_-1];
356 }
357 ptrs_[size_ - 1] = 0;
358 --size_;
359
360 }
361
362 /*
363 * Return true if an object is in the set, false otherwise.
364 */
365 template <typename Data, int Capacity>
366 bool SSet<Data, Capacity>::isElement(Data const & data) const
367 {
368 Data const * const ptr = &data;
369 bool found;
370
371 // Search for element in set
372 found = false;
373 for (int i = 0; i < size_; ++i) {
374 if (ptr == ptrs_[i]) {
375 found = true;
376 break;
377 }
378 }
379 return found;
380 }
381
386 template <typename Data, int Capacity>
387 int SSet<Data, Capacity>::index(Data const & data) const
388 {
389 Data const * const ptr = &data;
390 int i;
391 bool found;
392
393 // Search for element in set
394 found = false;
395 for (i = 0; i < size_; ++i) {
396 if (ptr == ptrs_[i]) {
397 found = true;
398 break;
399 }
400 }
401 if (found) {
402 return i;
403 } else {
404 return -1;
405 }
406 }
407
408}
409#endif
Forward iterator for a PArray.
void setEnd(Data **ptr)
Set the value of the end pointer.
void setCurrent(Data **ptr)
Set the current pointer value.
Forward iterator for a PArray.
void setEnd(Data **ptr)
Set the value of the end pointer.
void setCurrent(Data **ptr)
Set the current pointer value.
Statically allocated array of pointers to an unordered set.
Definition: SSet.h:44
SSet< Data, Capacity > & operator=(SSet< Data, Capacity > const &other)
Assignment, element by element.
Definition: SSet.h:209
SSet()
Default constructor.
Definition: SSet.h:177
~SSet()
Destructor.
Definition: SSet.h:240
void append(Data &data)
Add an object to the set.
Definition: SSet.h:309
Data & operator[](int i)
Mimic C array subscripting.
Definition: SSet.h:285
void clear()
Set logical size to zero and nullify all elements.
Definition: SSet.h:322
int index(Data const &data) const
Return the current index of an object within the set, if any.
Definition: SSet.h:387
bool isElement(Data const &data) const
Is an object an element of the set?
Definition: SSet.h:366
int size() const
Return logical size of this array.
Definition: SSet.h:254
int capacity() const
Return physical capacity of array.
Definition: SSet.h:247
Data * ptrs_[Capacity]
Array of pointers to Data objects.
Definition: SSet.h:164
void remove(Data const &data)
Remove an object from the set.
Definition: SSet.h:334
void begin(PArrayIterator< Data > &iterator)
Set a PArrayIterator to the beginning of this Array.
Definition: SSet.h:263
int size_
Logical size of array (number of elements in array).
Definition: SSet.h:167
File containing preprocessor macros for error handling.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
Utility classes for scientific computation.
Definition: accumulators.mod:1