Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdlib.h>
00017 #include <shogun/lib/memory.h>
00018 #include <shogun/mathematics/Math.h>
00019
00020 #ifndef VARRAY_H__
00021 #define VARRAY_H__
00022
00023 namespace shogun
00024 {
00039 template<class T> class v_array
00040 {
00041 public:
00042
00047 v_array()
00048 {
00049 begin = NULL;
00050 end = NULL;
00051 end_array = NULL;
00052 }
00053
00058 ~v_array()
00059 {
00060 SG_FREE(begin);
00061 }
00062
00071 T& operator[](unsigned int i) { return begin[i]; }
00072
00078 inline T last() { return *(end-1); }
00079
00085 inline T pop() { return *(--end); }
00086
00092 inline bool empty() { return begin == end; }
00093
00098 inline void decr() { end--; }
00099
00105 inline unsigned int index() { return end-begin; }
00106
00111 inline void erase() { end = begin; }
00112
00118 void push(const T &new_elem);
00119
00126 void push_many(const T* new_elem, size_t num);
00127
00134 void reserve(size_t length);
00135
00142 void calloc_reserve(size_t length);
00143
00150 v_array<T> pop(v_array< v_array<T> > &stack);
00151
00152 public:
00153
00155 T* begin;
00156
00158 T* end;
00159
00161 T* end_array;
00162
00163 };
00164
00165 template<class T>
00166 inline void v_array<T>::push(const T &new_elem)
00167 {
00168 if(end == end_array)
00169 {
00170 size_t old_length = end_array - begin;
00171 size_t new_length = 2 * old_length + 3;
00172
00173 begin = SG_REALLOC(T, begin, new_length);
00174 end = begin + old_length;
00175 end_array = begin + new_length;
00176 }
00177 *(end++) = new_elem;
00178 }
00179
00180 template<class T>
00181 inline void v_array<T>::push_many(const T* new_elem, size_t num)
00182 {
00183 if(end+num >= end_array)
00184 {
00185 size_t length = end - begin;
00186 size_t new_length = CMath::max(2 * (size_t)(end_array - begin) + 3,
00187 end - begin + num);
00188 begin = SG_REALLOC(T, begin, new_length);
00189 end = begin + length;
00190 end_array = begin + new_length;
00191 }
00192 memcpy(end, new_elem, num * sizeof(T));
00193 end += num;
00194 }
00195
00196 template<class T>
00197 inline void v_array<T>::reserve(size_t length)
00198 {
00199 size_t old_length = end_array-begin;
00200 begin = SG_REALLOC(T, begin, length);
00201 if (old_length < length)
00202 memset(begin + old_length, 0, (length - old_length)*sizeof(T));
00203
00204 end = begin;
00205 end_array = begin + length;
00206 }
00207
00208 template<class T>
00209 inline void v_array<T>::calloc_reserve(size_t length)
00210 {
00211 begin = SG_CALLOC(T, length);
00212 end = begin;
00213 end_array = begin + length;
00214 }
00215
00216 template<class T>
00217 inline v_array<T> v_array<T>::pop(v_array< v_array<T> > &stack)
00218 {
00219 if (stack.end != stack.begin)
00220 return *(--stack.end);
00221 else
00222 return v_array<T>();
00223 }
00224 }
00225 #endif // VARRAY_H__