00001 #ifndef DIVINE_ARRAY_HH
00002 #define DIVINE_ARRAY_HH
00003
00013 #ifndef DOXYGEN_PROCESSING
00014 #include <iostream>
00015 #include <cstring>
00016 #include "common/error.hh"
00017 #include "common/types.hh"
00018 #include "common/deb.hh"
00019
00020 namespace divine {
00021 using std::cerr; using std::endl;
00022 #endif //DOXYGEN_PROCESSING
00023
00024 template <class T>
00025 T * default_new_field_of_objects(const size_int_t count)
00026 {
00027 return (new T[count]);
00028 }
00029
00030
00032
00057 template <class T, T* (*Alloc)(const size_int_t count) = default_new_field_of_objects<T> >
00058 class array_t
00059 {
00060 private:
00061 size_int_t allocated;
00062 size_int_t alloc_step;
00063 size_int_t my_size;
00064 protected:
00066 T * field;
00067 public:
00069
00071 typedef T * iterator;
00073
00076 typedef const T * const_iterator;
00078
00079 iterator begin() { return &field[0]; }
00082
00083 iterator end() { return &field[my_size]; }
00085
00086 iterator last() { return &field[my_size-1]; }
00088
00089 const_iterator begin() const { return &field[0]; }
00092
00093 const_iterator end() const { return &field[my_size]; }
00095
00096 const_iterator last() const { return &field[my_size-1]; }
00098
00102 void assign_from(const array_t<T, Alloc> & to_copy)
00103 {
00104 DEBFUNC(cerr << "BEGIN of array_t<T>::assign_from" << endl;)
00105 my_size = to_copy.size();
00106 alloc_step = to_copy.get_alloc_step();
00107 allocated = to_copy.get_allocated();
00108 if (field) delete [] field;
00109 field = allocated ? Alloc(allocated) : 0;
00110 for (size_int_t i = 0; i!=my_size; ++i)
00111 field[i] = to_copy[i];
00112 DEBFUNC(cerr << "END of array_t<T>::assign_from" << endl;)
00113 }
00115
00118 array_t(size_int_t allocate = 2, size_int_t step = 2)
00119 {
00120 allocated = allocate; alloc_step = step; my_size = 0;
00121 field = allocated ? Alloc(allocated) : 0;
00122 }
00124
00125
00126
00127 array_t(const array_t<T, Alloc> & to_copy)
00128 { field = 0; assign_from(to_copy); }
00130 ~array_t() { if (field) delete [] field; }
00132
00136 void push_back(T what)
00137 {
00138 if (my_size<allocated) { field[my_size] = what; ++my_size; }
00139 else { extend(1); field[my_size-1] = what; }
00140 }
00142
00146 T pop_back()
00147 { my_size--; return field[my_size]; }
00149
00154 void resize(const size_int_t count)
00155 { if (count<=my_size) shrink_to(count); else extend_to(count); }
00157
00161 void shrink_to(const size_int_t count)
00162 { my_size = count; }
00164
00169 void extend_to(const size_int_t count)
00170 { extend(count-my_size); }
00172
00176 void extend(const size_int_t count)
00177 {
00178 if ((my_size + count) > allocated)
00179 {
00180 allocated = (((my_size+count) / alloc_step) + 1)*alloc_step;
00181 DEB(cerr << "Newly allocated " << allocated << " " << sizeof(T))
00182 DEB( << "-bytes" << endl;)
00183 T * aux_pointer = Alloc(allocated);
00184 if (field)
00185 {
00186 memcpy(aux_pointer,field,my_size*sizeof(T));
00187 delete [] field;
00188 }
00189 field = aux_pointer;
00190 }
00191 my_size += count;
00192 }
00194 size_int_t size() const { return my_size; }
00196
00198 size_int_t get_allocated() const { return allocated; }
00200
00203 size_int_t get_alloc_step() const { return alloc_step; }
00205
00208 void set_alloc_step(const size_int_t new_alloc_step)
00209 { alloc_step = new_alloc_step; }
00211 T & front() { return field[0]; }
00213 const T & front() const { return field[0]; }
00215 T & back() { return field[my_size-1]; }
00217 const T & back() const { return field[my_size-1]; }
00219 T & operator[](const size_int_t i)
00220 { DEBCHECK(if (i>=my_size) gerr << "Indexing error" << thr();)
00221 return field[i]; }
00223 const T & operator[](const size_int_t i) const
00224 { DEBCHECK(if (i>=my_size) gerr << "Indexing error" << thr();)
00225 return field[i]; }
00227
00231 void swap(array_t<T, Alloc> & second)
00232 {
00233 DEBFUNC(cerr << "array_t<T>::swap called" << endl;)
00234
00235 T * aux_pointer = field;
00236 field = second.field;
00237 second.field = aux_pointer;
00238
00239 size_int_t aux;
00240 aux = allocated; allocated = second.allocated; second.allocated = aux;
00241 aux = alloc_step; alloc_step = second.alloc_step; second.alloc_step = aux;
00242 aux = my_size; my_size = second.my_size; second.my_size = aux;
00243 }
00245
00247 void clear() { my_size = 0; }
00248
00256 };
00257
00258
00259 #ifndef DOXYGEN_PROCESSING
00260 }
00261 #include "common/undeb.hh"
00262
00263 #endif //DOXYGEN_PROCESSING
00264
00265 #endif
00266