1#ifndef UTIL_ARRAY_SET_H
2#define UTIL_ARRAY_SET_H
11#include <util/containers/Array.h>
12#include <util/containers/PArray.h>
13#include <util/misc/Memory.h>
19 template <
typename Data>
class PArrayIterator;
45 template <
typename Data>
111 void remove(Data
const & data);
144 int index(Data
const & data)
const;
172 int id(Data
const* ptr)
const;
186 template <
typename Data>
195 template <
typename Data>
199 Memory::deallocate<Data*>(ptrs_, capacity_);
202 Memory::deallocate<int>(tags_, capacity_);
209 template <
typename Data>
214 if (capacity == 0)
UTIL_THROW(
"Zero capacity");
215 if (capacity < 0)
UTIL_THROW(
"Negative capacity");
216 if (array == 0)
UTIL_THROW(
"Null array pointer");
217 if (ptrs_)
UTIL_THROW(
"ptrs_ array already allocated");
218 if (tags_)
UTIL_THROW(
"tags_ array already allocated");
221 Memory::allocate<Data*>(ptrs_, capacity);
222 Memory::allocate<int>(tags_, capacity);
223 capacity_ = capacity;
226 for (
int i = 0; i < capacity_; ++i) {
236 template <
typename Data>
238 { allocate(&array[0], array.
capacity()); }
243 template <
typename Data>
246 Data*
const ptr = &data;
249 if (ptr < data_ || ptr >= data_ + capacity_) {
252 int arrayId = id(ptr);
253 int setId = tags_[arrayId];
255 UTIL_THROW(
"Attempt to add element that is already in set");
260 tags_[id(ptr)] = size_;
267 template <
typename Data>
270 const Data*
const ptr = &data;
273 if (ptr < data_ || ptr >= data_ + capacity_) {
276 int arrayId = id(ptr);
277 int setId = tags_[arrayId];
283 assert(setId < capacity_);
284 assert(ptrs_[setId] == ptr);
288 if (setId != size_ - 1) {
289 ptrs_[setId] = ptrs_[size_-1];
290 tags_[id(ptrs_[setId])] = setId;
300 template <
typename Data>
305 UTIL_THROW(
"Attempt to pop from empty ArraySet");
308 Data* ptr = ptrs_[size_ - 1];
318 template <
typename Data>
324 for (
int i = 0; i < capacity_; ++i) {
334 template <
typename Data>
337 const Data*
const ptr = &data;
338 if (ptr < data_ || ptr >= data_ + capacity_) {
341 return tags_[id(ptr)];
347 template <
typename Data>
349 {
return ptrs_ != 0; }
354 template <
typename Data>
361 UTIL_THROW(
"ptrs_ is allocated but tags_ is not");
366 for (i = 0; i < capacity_ ; ++i) {
369 if (j >= capacity_) {
372 if (
id(ptrs_[j]) != i) {
379 UTIL_THROW(
"Number of nonnegative tags != size");
384 for (i = 0; i < size_ ; ++i) {
392 UTIL_THROW(
"Null pointer ptrs_[i] for i < size_");
396 UTIL_THROW(
"Number of non-Null pointers != size");
400 for (i = size_; i < capacity_ ; ++i) {
402 UTIL_THROW(
"Non-null pointer ptrs_[i] for i >= size_");
410 if (capacity_ != 0) {
422 template <
typename Data>
424 {
return int(ptr - data_); }
A set of pointers to a subset of elements of an array.
void remove(Data const &data)
Remove an element from the set.
virtual ~ArraySet()
Destructor.
void append(Data &data)
Append an element to the set.
bool isValid() const
Return true if the ArraySet is valid, or throw an exception.
void dump() const
Write the internal state of the ArraySet to std::cout.
bool isAllocated() const
Return true if the ArraySet is initialized, false otherwise.
void clear()
Reset to empty state.
void allocate(Data const *array, int capacity)
Associate with a C array and allocate required memory.
int index(Data const &data) const
Return the current index of an element within the set, if any.
Data & pop()
Pop the topmost element from the set.
Array container class template.
int capacity() const
Return allocated size.
An array that only holds pointers to its elements.
int capacity_
Allocated size of ptrs_ array.
int capacity() const
Return allocated size.
int size_
Logical size (number of elements with initialized data).
Data ** ptrs_
PArray of of pointers to Data objects.
File containing preprocessor macros for error handling.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Utility classes for scientific computation.