00001 #ifndef DIVINE_ARRAY_OF_ABSTRACT_HH
00002 #define DIVINE_ARRAY_OF_ABSTRACT_HH
00003
00013 #ifndef DOXYGEN_PROCESSING
00014 #include <iostream>
00015 #include "common/error.hh"
00016 #include "common/types.hh"
00017 #include "common/deb.hh"
00018
00019 namespace divine {
00020 using std::cerr; using std::endl;
00021 #endif //DOXYGEN_PROCESSING
00022
00023 template <class T, class ArrayIterator>
00024 class array_of_abstract_iterator_t
00025 {
00026 private:
00027 ArrayIterator p_item;
00028 public:
00029 array_of_abstract_iterator_t<T,ArrayIterator>() { p_item=0; }
00030 array_of_abstract_iterator_t<T,ArrayIterator>
00031 (const array_of_abstract_iterator_t & second)
00032 { p_item=second.p_item; }
00033 array_of_abstract_iterator_t<T,ArrayIterator>(const ArrayIterator iter)
00034 { p_item=iter; }
00035 T & operator*() { return (**p_item); }
00036 T * operator->() { return (*p_item); }
00037 array_of_abstract_iterator_t<T,ArrayIterator> operator+(const int i)
00038 { return array_of_abstract_iterator_t(p_item+i); }
00039 array_of_abstract_iterator_t<T,ArrayIterator> operator-(const int i)
00040 { return array_of_abstract_iterator_t(p_item-i); }
00041 array_of_abstract_iterator_t<T,ArrayIterator> operator++()
00042 { p_item = p_item + 1; return (*this); }
00043 array_of_abstract_iterator_t<T,ArrayIterator> operator--()
00044 { p_item = p_item - 1; return (*this); }
00045 array_of_abstract_iterator_t<T,ArrayIterator> operator++(int)
00046 { array_of_abstract_iterator_t<T,ArrayIterator> copy = (*this);
00047 p_item = p_item + 1; return copy; }
00048 array_of_abstract_iterator_t<T,ArrayIterator> operator--(int)
00049 { array_of_abstract_iterator_t<T,ArrayIterator> copy = (*this);
00050 p_item = p_item - 1; return copy; }
00051 bool operator==(const array_of_abstract_iterator_t second)
00052 { return (this->p_item==second.p_item); }
00053 bool operator!=(const array_of_abstract_iterator_t second)
00054 { return (this->p_item!=second.p_item); }
00055 };
00056
00057
00059
00078 template <class T, T* (*SingleAlloc)(const void * params) >
00079 class array_of_abstract_t
00080 {
00081 private:
00083 const void * parameters;
00084 array_t<T*> array;
00085 protected:
00087 T * field;
00088 public:
00090
00092 typedef array_of_abstract_iterator_t<T, T**> iterator;
00094
00097 typedef array_of_abstract_iterator_t<T, const T**> const_iterator;
00099
00100 iterator begin() { return iterator(array.begin()); }
00103
00104 iterator end() { return iterator(array.end()); }
00106
00107 iterator last() { return iterator(array.last()); }
00109
00110 const_iterator begin() const { return const_iterator(array.begin()); }
00113
00114 const_iterator end() const { return const_iterator(array.end()); }
00116
00117 const_iterator last() const { return const_iterator(array.last()); }
00119
00123 void assign_from(const array_of_abstract_t<T, SingleAlloc> & to_copy)
00124 {
00125 resize(to_copy.array.size());
00126 for (size_int_t i=0; i!=array.size(); ++i)
00127 (*array[i]) = (*to_copy.array[i]);
00128 }
00131
00132
00133
00134 array_of_abstract_t(const void * params,
00135 size_int_t allocate = 2, size_int_t step = 2):
00136 parameters(params), array(allocate, step)
00137 { for (size_int_t i=0; i!=array.get_allocated(); ++i)
00138 array[i] = SingleAlloc(parameters); }
00140
00141
00142
00143 array_of_abstract_t
00144 (const array_of_abstract_t<T, SingleAlloc> & to_copy)
00145 { assign_from(to_copy); }
00147 ~array_of_abstract_t()
00148 { for (size_int_t i=0; i!=array.get_allocated(); ++i) delete array[i]; }
00150
00154 void push_back(T what)
00155 {
00156 extend(1);
00157 (*array.back())=what;
00158 }
00160
00164 T pop_back()
00165 { T result = (*array[array.size()]);
00166 shrink_to(array.size()-1);
00167 return result; }
00169
00174 void resize(const size_int_t count)
00175 {
00176 const size_int_t initial_allocated = array.get_allocated();
00177 array.resize(count);
00178 const size_int_t currently_allocated = array.get_allocated();
00179 for (size_int_t i=initial_allocated; i<currently_allocated; ++i)
00180 array[i]=SingleAlloc(parameters);
00181 }
00183
00187 void shrink_to(const size_int_t count)
00188 { array.shrink_to(count); }
00190
00195 void extend_to(const size_int_t count)
00196 { extend(count-array.size()); }
00198
00202 void extend(const size_int_t count)
00203 {
00204 const size_int_t initial_allocated = array.get_allocated();
00205 array.extend(count);
00206 const size_int_t currently_allocated = array.get_allocated();
00207 for (size_int_t i=initial_allocated; i<currently_allocated; ++i)
00208 array[i]=SingleAlloc(parameters);
00209 }
00211 size_int_t size() const { return array.size(); }
00213
00215 size_int_t get_allocated() const { return array.get_allocated(); }
00217
00220 size_int_t get_alloc_step() const { return array.get_alloc_step(); }
00222
00225 void set_alloc_step(const size_int_t new_alloc_step)
00226 { array.set_alloc_step(new_alloc_step); }
00228 T & front() { return (*array.front()); }
00230 const T & front() const { return (*array.front()); }
00232 T & back() { return (*array.back()); }
00234 const T & back() const { return (*array.back()); }
00236 T & operator[](const size_int_t i)
00237 { return (*array[i]); }
00239 const T & operator[](const size_int_t i) const
00240 { return (*array[i]); }
00242
00246 void swap(array_of_abstract_t<T, SingleAlloc> & second)
00247 { array.swap(second.array); }
00249
00251 void clear() { array.clear(); }
00252 };
00253
00254
00255 #ifndef DOXYGEN_PROCESSING
00256 }
00257 #include "common/undeb.hh"
00258
00259 #endif //DOXYGEN_PROCESSING
00260
00261 #endif
00262