00001 // -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 //////////////////////////////////////////////////////////////////// 00003 // 00004 // Filename : array.h (base) 00005 // 00006 // This file is a part of the UPPAAL toolkit. 00007 // Copyright (c) 1995 - 2003, Uppsala University and Aalborg University. 00008 // All right reserved. 00009 // 00010 // $Id: array.h,v 1.6 2005/01/25 18:30:22 adavid Exp $ 00011 // 00012 /////////////////////////////////////////////////////////////////// 00013 00014 #ifndef INCLUDE_BASE_ARRAY_H 00015 #define INCLUDE_BASE_ARRAY_H 00016 00017 #include "base/pointer.h" 00018 00019 namespace base 00020 { 00021 /** This defines a simple array template that will work on scalar 00022 * types only. The idea is to be able to access the array randomly 00023 * even on non predefined position. The array will grow automatically. 00024 * This is not possible with std::vector: you have to define a loop and 00025 * use push_back() to fill the gaps. Besides, reading outside the 00026 * vector will seg-fault. 00027 * 00028 * Lower case name: basic template on basic scalar types only 00029 * this class is not supposed to have sub-classes 00030 */ 00031 template<class T> 00032 class array_t : public pointer_t<T> 00033 { 00034 public: 00035 00036 /** increase size step: at least 1 00037 */ 00038 enum { INC = 8 }; 00039 00040 /** constructor: alloc and init the array to 0 00041 * always at least 1 element. 00042 * @param initSize: initial size 00043 */ 00044 array_t(size_t initSize = 4) 00045 : pointer_t<T>(new T[initSize == 0 ? 1 : initSize], 00046 initSize == 0 ? 1 : initSize) 00047 { 00048 assert(INC > 0); 00049 pointer_t<T>::reset(); 00050 } 00051 00052 /** destructor: free the array 00053 */ 00054 ~array_t() { delete [] pointer_t<T>::data; } 00055 00056 00057 /** Copy constructor 00058 */ 00059 array_t(const array_t<T> &arr) 00060 : pointer_t<T>(new T[arr.capa], arr.capa) 00061 { 00062 copyFrom(arr); 00063 } 00064 00065 /** copy operator 00066 */ 00067 array_t& operator = (array_t<T> &arr) 00068 { 00069 if (pointer_t<T>::capa != arr.capa) 00070 { 00071 delete [] pointer_t<T>::data; 00072 pointer_t<T>::data = new T[arr.capa]; 00073 pointer_t<T>::capa = arr.capa; 00074 } 00075 copyFrom(arr); 00076 } 00077 00078 /** data read: test if outside bounds 00079 * @param at: where to read. 00080 * if at is outside limits then return 0. 00081 */ 00082 T get(size_t at) const 00083 { 00084 return at < pointer_t<T>::capa ? pointer_t<T>::data[at] : 0; 00085 } 00086 00087 /** data write: may increase array 00088 * @param at: where to write. 00089 * @param value: what to write. 00090 * if at is outside limits then the array is 00091 * increased. 00092 */ 00093 void set(size_t at, T value) 00094 { 00095 ensurePos(at); 00096 pointer_t<T>::data[at] = value; 00097 } 00098 00099 /** data read/write: may increase array 00100 * @param at: where to read and write. 00101 * @param value: what to write. 00102 * @return original value at position at. 00103 */ 00104 T replace(size_t at, T value) 00105 { 00106 ensurePos(at); 00107 T res = pointer_t<T>::data[at]; 00108 pointer_t<T>::data[at] = value; 00109 return res; 00110 } 00111 00112 /** addition with the given argument 00113 * @param at: where to add value 00114 * @param value: what to add 00115 */ 00116 void add(size_t at, T value) 00117 { 00118 ensurePos(at); 00119 pointer_t<T>::data[at] += value; 00120 } 00121 00122 private: 00123 00124 /** make sure position at may be accessed 00125 * @param at: position to be able to read. 00126 * @post data[at] is valid. 00127 */ 00128 void ensurePos(size_t at) 00129 { 00130 if (at >= pointer_t<T>::capa) 00131 { 00132 T* newData = new T[at+INC]; 00133 base_copySmall(newData, pointer_t<T>::data, pointer_t<T>::capa*intsizeof(T)); 00134 base_resetSmall(newData+pointer_t<T>::capa, (at+INC-pointer_t<T>::capa)*intsizeof(T)); 00135 delete [] pointer_t<T>::data; 00136 pointer_t<T>::data = newData; 00137 pointer_t<T>::capa = at+INC; 00138 } 00139 } 00140 00141 }; 00142 00143 } // namespace base 00144 00145 #endif // INCLUDE_BASE_ARRAY_H