Simpatico  v1.10
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 
15 namespace Util
16 {
17 
42  template <typename Data, int Capacity>
43  class SSet
44  {
45 
46  public:
47 
51  SSet();
52 
60  SSet(const SSet<Data, Capacity>& other);
61 
68 
72  ~SSet();
73 
81  void append(Data &data);
82 
93  void remove(const Data& data);
94 
98  void clear();
99 
103  int capacity() const;
104 
108  int size() const;
109 
115  bool isElement(const Data& data) const;
116 
129  int index(const Data& 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  const Data& 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>
274  {
275  iterator.setCurrent(const_cast<Data**>(ptrs_));
276  iterator.setEnd(const_cast<Data**>(ptrs_ + size_));
277  }
278 
279  /*
280  * Mimic C array subscripting.
281  */
282  template <typename Data, int Capacity>
284  {
285  assert(i < size_);
286  assert(i >= 0);
287  return *ptrs_[i];
288  }
289 
290  /*
291  * Mimic C array subscripting.
292  */
293  template <typename Data, int Capacity>
294  inline const Data& SSet<Data, Capacity>::operator[] (int i) const
295  {
296  assert(i < size_);
297  assert(i >= 0 );
298  return *ptrs_[i];
299  }
300 
301  /*
302  * Append data to the end of the array.
303  *
304  * \param data Data to add to end of array.
305  */
306  template <typename Data, int Capacity>
307  inline void SSet<Data, Capacity>::append(Data &data)
308  {
309  if (size_ == Capacity) {
310  UTIL_THROW("Attempt to add to full SSet");
311  }
312  ptrs_[size_] = &data;
313  ++size_;
314  }
315 
316  /*
317  * Clear out the container.
318  */
319  template <typename Data, int Capacity>
321  {
322  size_ = 0;
323  for (int i=0; i < Capacity; ++i) {
324  ptrs_[i] = 0;
325  }
326  }
327 
328  /*
329  * Remove an element from the set.
330  */
331  template <typename Data, int Capacity>
332  void SSet<Data, Capacity>::remove(const Data& data)
333  {
334  const Data* const ptr = &data;
335  int i;
336  bool found;
337 
338  // Search for object
339  found = false;
340  for (i = 0; i < size_; ++i) {
341  if (ptr == ptrs_[i]) {
342  found = true;
343  break;
344  }
345  }
346 
347  if (!found) {
348  UTIL_THROW("Element is not in set");
349  }
350 
351  // Remove element
352  if (i != size_ - 1) {
353  ptrs_[i] = ptrs_[size_-1];
354  }
355  ptrs_[size_ - 1] = 0;
356  --size_;
357 
358  }
359 
360  /*
361  * Return true if an object is in the set, false otherwise.
362  */
363  template <typename Data, int Capacity>
364  bool SSet<Data, Capacity>::isElement(const Data& data) const
365  {
366  const Data* const ptr = &data;
367  bool found;
368 
369  // Search for element in set
370  found = false;
371  for (int i = 0; i < size_; ++i) {
372  if (ptr == ptrs_[i]) {
373  found = true;
374  break;
375  }
376  }
377  return found;
378  }
379 
384  template <typename Data, int Capacity>
385  int SSet<Data, Capacity>::index(const Data& data) const
386  {
387  const Data* const ptr = &data;
388  int i;
389  bool found;
390 
391  // Search for element in set
392  found = false;
393  for (i = 0; i < size_; ++i) {
394  if (ptr == ptrs_[i]) {
395  found = true;
396  break;
397  }
398  }
399  if (found) {
400  return i;
401  } else {
402  return -1;
403  }
404  }
405 
406 }
407 #endif
SSet< Data, Capacity > & operator=(const SSet< Data, Capacity > &other)
Assignment, element by element.
Definition: SSet.h:209
void clear()
Set logical size to zero and nullify all elements.
Definition: SSet.h:320
int size() const
Return logical size of this array.
Definition: SSet.h:254
Forward iterator for a PArray.
File containing preprocessor macros for error handling.
void setCurrent(Data **ptr)
Set the current pointer value.
Data * ptrs_[Capacity]
Array of pointers to Data objects.
Definition: SSet.h:164
Data & operator[](int i)
Mimic C array subscripting.
Definition: SSet.h:283
~SSet()
Destructor.
Definition: SSet.h:240
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
int index(const Data &data) const
Return the current index of an object within the set, if any.
Definition: SSet.h:385
void append(Data &data)
Add an object to the set.
Definition: SSet.h:307
void setEnd(Data **ptr)
Set the value of the end pointer.
Utility classes for scientific computation.
Definition: accumulators.mod:1
void begin(PArrayIterator< Data > &iterator)
Set a PArrayIterator to the beginning of this Array.
Definition: SSet.h:263
void remove(const Data &data)
Remove an object from the set.
Definition: SSet.h:332
Forward iterator for a PArray.
Definition: ArraySet.h:19
SSet()
Default constructor.
Definition: SSet.h:177
int capacity() const
Return physical capacity of array.
Definition: SSet.h:247
void setEnd(Data **ptr)
Set the value of the end pointer.
Statically allocated array of pointers to an unordered set.
Definition: SSet.h:43
bool isElement(const Data &data) const
Is an object an element of the set?
Definition: SSet.h:364
int size_
Logical size of array (number of elements in array).
Definition: SSet.h:167
void setCurrent(Data **ptr)
Set the current pointer value.