00001 /** @file 00002 00003 A brief file description 00004 00005 @section license License 00006 00007 Licensed to the Apache Software Foundation (ASF) under one 00008 or more contributor license agreements. See the NOTICE file 00009 distributed with this work for additional information 00010 regarding copyright ownership. The ASF licenses this file 00011 to you under the Apache License, Version 2.0 (the 00012 "License"); you may not use this file except in compliance 00013 with the License. You may obtain a copy of the License at 00014 00015 http://www.apache.org/licenses/LICENSE-2.0 00016 00017 Unless required by applicable law or agreed to in writing, software 00018 distributed under the License is distributed on an "AS IS" BASIS, 00019 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 See the License for the specific language governing permissions and 00021 limitations under the License. 00022 */ 00023 00024 #ifndef __CACHE_ARRAY_H__ 00025 #define __CACHE_ARRAY_H__ 00026 00027 #define FAST_DATA_SIZE 4 00028 00029 00030 template<class T> struct CacheArray 00031 { 00032 CacheArray(const T * val, int initial_size = 0); 00033 ~CacheArray(); 00034 00035 operator const T *() const; 00036 operator T *(); 00037 T & operator[] (int idx); 00038 T & operator() (int idx); 00039 T *detach(); 00040 int length(); 00041 void clear(); 00042 void set_length(int i) 00043 { 00044 pos = i - 1; 00045 } 00046 00047 void resize(int new_size); 00048 00049 T *data; 00050 T fast_data[FAST_DATA_SIZE]; 00051 const T *default_val; 00052 int size; 00053 int pos; 00054 }; 00055 00056 00057 template<class T> TS_INLINE CacheArray<T>::CacheArray(const T * val, int initial_size) 00058 : 00059 data(NULL), 00060 default_val(val), 00061 size(0), 00062 pos(-1) 00063 { 00064 if (initial_size > 0) { 00065 int i = 1; 00066 00067 while (i < initial_size) 00068 i <<= 1; 00069 00070 resize(i); 00071 } 00072 } 00073 00074 template<class T> TS_INLINE CacheArray<T>::~CacheArray() 00075 { 00076 if (data) { 00077 if (data != fast_data) { 00078 delete[]data; 00079 } 00080 } 00081 } 00082 00083 template<class T> TS_INLINE CacheArray<T>::operator const T *() 00084 const 00085 { 00086 return 00087 data; 00088 } 00089 00090 template <class T> TS_INLINE CacheArray <T>::operator T *() 00091 { 00092 return data; 00093 } 00094 00095 template<class T> TS_INLINE T & CacheArray<T>::operator [](int idx) { 00096 return data[idx]; 00097 } 00098 00099 template<class T> TS_INLINE T & CacheArray<T>::operator ()(int idx) { 00100 if (idx >= size) { 00101 int new_size; 00102 00103 if (size == 0) { 00104 new_size = FAST_DATA_SIZE; 00105 } else { 00106 new_size = size * 2; 00107 } 00108 00109 if (idx >= new_size) { 00110 new_size = idx + 1; 00111 } 00112 00113 resize(new_size); 00114 } 00115 00116 if (idx > pos) { 00117 pos = idx; 00118 } 00119 00120 return data[idx]; 00121 } 00122 00123 template<class T> TS_INLINE T * CacheArray<T>::detach() 00124 { 00125 T *d; 00126 00127 d = data; 00128 data = NULL; 00129 00130 return d; 00131 } 00132 00133 template<class T> TS_INLINE int CacheArray<T>::length() 00134 { 00135 return pos + 1; 00136 } 00137 00138 template<class T> TS_INLINE void CacheArray<T>::clear() 00139 { 00140 if (data) { 00141 if (data != fast_data) { 00142 delete[]data; 00143 } 00144 data = NULL; 00145 } 00146 00147 size = 0; 00148 pos = -1; 00149 } 00150 00151 template<class T> TS_INLINE void CacheArray<T>::resize(int new_size) 00152 { 00153 if (new_size > size) { 00154 T *new_data; 00155 int i; 00156 00157 if (new_size > FAST_DATA_SIZE) { 00158 new_data = new T[new_size]; 00159 } else { 00160 new_data = fast_data; 00161 } 00162 00163 for (i = 0; i < size; i++) { 00164 new_data[i] = data[i]; 00165 } 00166 00167 for (; i < new_size; i++) { 00168 new_data[i] = *default_val; 00169 } 00170 00171 if (data) { 00172 if (data != fast_data) { 00173 delete[]data; 00174 } 00175 } 00176 data = new_data; 00177 size = new_size; 00178 } 00179 } 00180 00181 00182 #endif /* __CACHE_ARRAY_H__ */