00001 /*************************************************************************** 00002 *cr 00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 00004 *cr University of Illinois 00005 *cr All Rights Reserved 00006 *cr 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * RCS INFORMATION: 00011 * 00012 * $RCSfile: ResizeArray.h,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.57 $ $Date: 2020年10月22日 03:42:04 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * Automatically-adjusting single-dim array template. 00019 * 00020 * LICENSE: 00021 * UIUC Open Source License 00022 * http://www.ks.uiuc.edu/Research/vmd/plugins/pluginlicense.html 00023 * 00024 ***************************************************************************/ 00025 #ifndef RESIZEARRAY_TEMPLATE_H 00026 #define RESIZEARRAY_TEMPLATE_H 00027 00028 #include <stddef.h> 00029 #include <string.h> 00030 00040 template<class T> 00041 class ResizeArray { 00042 private: 00043 T *allocate(size_t n) { return new T[n]; } 00044 void deallocate(T *p) { delete [] p; } 00045 00046 T *data; 00047 ptrdiff_t sz; 00048 ptrdiff_t currSize; 00049 00050 00051 public: 00056 ResizeArray(ptrdiff_t s = 3L) { 00057 currSize = 0; 00058 sz = (s > 0 ? s : 10L); 00059 data = allocate(sz); 00060 } 00061 00062 ~ResizeArray() { 00063 deallocate(data); 00064 } 00065 00066 ptrdiff_t num(void) const { return currSize; } 00067 T& operator[](ptrdiff_t N) { return data[N]; } 00068 T const& operator[](ptrdiff_t N) const { return data[N]; } 00069 00071 void set_size(ptrdiff_t N) { 00072 // extend size of array if necessary 00073 if (N > sz) { 00074 extend(N - sz + 1L); 00075 } 00076 currSize = N; 00077 } 00078 00079 00081 void extend(ptrdiff_t addN) { 00082 if ((currSize+addN) >= sz) { // extend size of array if necessary 00083 // guarantee minimum required size increase addN, since the scaled value 00084 // may truncate back to the original size value when the initial number 00085 // of elements is very small. 00086 ptrdiff_t newsize = (ptrdiff_t(float(sz) * 1.3f)) + addN; 00087 00088 // shallow copy data to a newly allocated block since we can't 00089 // use realloc() due to potential use of shared memory 00090 T *newdata = allocate(newsize); 00091 memcpy(newdata, data, currSize * sizeof(T)); 00092 deallocate(data); 00093 00094 // save new values 00095 data = newdata; 00096 sz = newsize; 00097 } 00098 } 00099 00100 00102 void append(const T& val) { 00103 if (currSize == sz) { // extend size of array if necessary 00104 #if 1 00105 ptrdiff_t newsize = ptrdiff_t(float(sz) * 1.3f); 00106 00107 // guarantee minimum required size increase, since the scaled value 00108 // may truncate back to the original size value when the initial number 00109 // of elements is very small. 00110 if (newsize == sz) 00111 newsize++; 00112 #else 00113 extend(1); 00114 #endif 00115 00116 // shallow copy data to a newly allocated block since we can't 00117 // use realloc() due to potential use of shared memory 00118 T *newdata = allocate(newsize); 00119 #if defined(_MSC_VER) 00120 memcpy((void *)newdata, (const void *)data, currSize * sizeof(T)); 00121 #else 00122 memcpy(static_cast<void *>(newdata), static_cast<const void *>(data), currSize * sizeof(T)); 00123 #endif 00124 deallocate(data); 00125 00126 // save new values 00127 data = newdata; 00128 sz = newsize; 00129 } 00130 data[currSize++] = val; 00131 } 00132 00133 00135 void append2(const T& vala, const T& valb) { 00136 extend(2); 00137 data[currSize++] = vala; 00138 data[currSize++] = valb; 00139 } 00140 00141 00143 void append3(const T& vala, const T& valb, const T& valc) { 00144 extend(3); 00145 data[currSize++] = vala; 00146 data[currSize++] = valb; 00147 data[currSize++] = valc; 00148 } 00149 00150 00152 void append4(const T& vala, const T& valb, const T& valc, const T& vald) { 00153 extend(4); 00154 data[currSize++] = vala; 00155 data[currSize++] = valb; 00156 data[currSize++] = valc; 00157 data[currSize++] = vald; 00158 } 00159 00160 00162 void appendN(const T& val, ptrdiff_t addN) { 00163 extend(addN); 00164 ptrdiff_t j; 00165 for (j=0; j<addN; j++) 00166 data[currSize++] = val; 00167 } 00168 00169 00171 void append3(const T *vals) { 00172 extend(3); 00173 data[currSize++] = vals[0]; 00174 data[currSize++] = vals[1]; 00175 data[currSize++] = vals[2]; 00176 } 00177 00178 00180 void append2x3(const T *valsa, const T *valsb) { 00181 extend(6); 00182 data[currSize++] = valsa[0]; 00183 data[currSize++] = valsa[1]; 00184 data[currSize++] = valsa[2]; 00185 00186 data[currSize++] = valsb[0]; 00187 data[currSize++] = valsb[1]; 00188 data[currSize++] = valsb[2]; 00189 } 00190 00191 00193 void append3x3(const T *valsa, const T *valsb, const T *valsc) { 00194 extend(9); 00195 data[currSize++] = valsa[0]; 00196 data[currSize++] = valsa[1]; 00197 data[currSize++] = valsa[2]; 00198 00199 data[currSize++] = valsb[0]; 00200 data[currSize++] = valsb[1]; 00201 data[currSize++] = valsb[2]; 00202 00203 data[currSize++] = valsc[0]; 00204 data[currSize++] = valsc[1]; 00205 data[currSize++] = valsc[2]; 00206 } 00207 00208 00211 void append9(const T *vals) { 00212 extend(9); 00213 data[currSize++] = vals[0]; 00214 data[currSize++] = vals[1]; 00215 data[currSize++] = vals[2]; 00216 data[currSize++] = vals[3]; 00217 data[currSize++] = vals[4]; 00218 data[currSize++] = vals[5]; 00219 data[currSize++] = vals[6]; 00220 data[currSize++] = vals[7]; 00221 data[currSize++] = vals[8]; 00222 } 00223 00224 00226 void appendlist(const T *vals, ptrdiff_t addN) { 00227 extend(addN); 00228 ptrdiff_t j; 00229 for (j=0; j<addN; j++) 00230 data[currSize++] = vals[j]; 00231 } 00232 00233 00235 void remove(ptrdiff_t n) { 00236 if (n < 0 || n >= currSize) return; 00237 for (ptrdiff_t i=n; i<currSize-1; i++) 00238 data[i] = data[i+1]; 00239 currSize--; 00240 } 00241 00243 T& pop() { 00244 currSize--; 00245 return data[currSize]; 00246 } 00247 00249 void clear() { 00250 currSize = 0; 00251 } 00252 00254 void truncatelastn(ptrdiff_t N) { 00255 currSize -= N; 00256 if (currSize < 0) 00257 currSize=0; 00258 } 00259 00262 ptrdiff_t find(const T& val) { 00263 ptrdiff_t i; 00264 00265 for (i=0; i < currSize; i++) { 00266 if (data[i] == val) 00267 return i; 00268 } 00269 00270 return -1; 00271 } 00272 }; 00273 00274 #endif 00275