00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef QMEMARRAY_H
00023 #define QMEMARRAY_H
00024
00025 #include <vector>
00026 #include <algorithm>
00027 #include "fxdefs.h"
00028 #include "FXException.h"
00029 #include "FXStream.h"
00030
00031 namespace FX {
00032
00033 #if _MSC_VER==1200
00034 #pragma warning(disable: 4786)
00035 #endif
00036
00041 namespace QGArray {
00042 typedef int Optimization;
00043 }
00044
00059 template<typename type, class allocator> class QMemArray : private std::vector<type, allocator>
00060 {
00061 typedef std::vector<type, allocator> Base;
00062 private:
00063 type *extArray;
00064 FXuval extArrayLen;
00065 bool noDeleteExtArray;
00066 typename Base::const_iterator int_retIndex(const type &d) const
00067 {
00068 typename Base::const_iterator it;
00069 for(it=begin(); it!=end(); ++it)
00070 if(*it==d) return it;
00071 return it;
00072 }
00073 public:
00074 typedef type * Iterator;
00075 typedef type * iterator;
00076 typedef const type * ConstIterator;
00077 typedef const type * const_iterator;
00078 typedef type ValueType;
00080 QMemArray() : extArray(0), extArrayLen(0), noDeleteExtArray(false), Base() { }
00081 ~QMemArray()
00082 {
00083 if(extArray && !noDeleteExtArray)
00084 {
00085 delete[] extArray;
00086 extArray=0;
00087 }
00088 }
00090 QMemArray(FXuval size) : extArray(0), extArrayLen(0), noDeleteExtArray(false), Base(size) { }
00092 QMemArray(type *a, FXuval n, bool _noDeleteExtArray=true) : extArray(a), extArrayLen(n), noDeleteExtArray(_noDeleteExtArray) { }
00093 QMemArray(const QMemArray<type, allocator> &o) : extArray(o.extArray), extArrayLen(o.extArrayLen), noDeleteExtArray(o.noDeleteExtArray), Base(o) { }
00094 QMemArray<type, allocator> &operator=(const QMemArray<type, allocator> &o) { extArray=o.extArray; extArrayLen=o.extArrayLen; noDeleteExtArray=o.noDeleteExtArray; Base::operator=(o); return *this; }
00095 FXADDMOVEBASECLASS(QMemArray, Base)
00096
00097 using Base::capacity;
00098
00099 using Base::empty;
00100 using Base::reserve;
00101
00103 type *data() const { return (extArray) ? extArray : const_cast<type *>(&Base::front()); }
00105 operator const type *() const { return data(); }
00107 FXuval size() const { return (extArray) ? extArrayLen : Base::size(); }
00109 FXuval count() const { return (extArray) ? extArrayLen : Base::size(); }
00111 bool isEmpty() const { return isNull(); }
00113 bool isNull() const { return (extArray) ? extArrayLen!=0 : Base::empty(); }
00115 bool resize(FXuval size) { FXEXCEPTION_STL1 { Base::resize(size); } FXEXCEPTION_STL2; return true; }
00117 bool resize(FXuval size, QGArray::Optimization optim) { Base::resize(size); return true; }
00119 bool truncate(FXuval pos) { FXEXCEPTION_STL1 { Base::resize(pos); } FXEXCEPTION_STL2; return true; }
00121 void swap(QMemArray<type, allocator> &o)
00122 {
00123 Base::swap(o);
00124 type *_extArray=o.extArray;
00125 FXuval _extArrayLen=o.extArrayLen;
00126 bool _noDeleteExtArray=o.noDeleteExtArray;
00127 o.extArray=extArray;
00128 o.extArrayLen=extArrayLen;
00129 o.noDeleteExtArray=noDeleteExtArray;
00130 extArray=_extArray;
00131 extArrayLen=_extArrayLen;
00132 noDeleteExtArray=_noDeleteExtArray;
00133 }
00135 bool fill(const type &val, int newsize=-1)
00136 {
00137 if(-1!=newsize) resize(newsize);
00138 for(FXuval n=0; n<size(); n++)
00139 {
00140 at(n)=val;
00141 }
00142 return true;
00143 }
00145 FXDEPRECATEDEXT void detach() { }
00147 FXDEPRECATEDEXT QMemArray<type, allocator> copy() const { return *this; }
00149 FXDEPRECATEDEXT QMemArray<type, allocator> &assign(const QMemArray<type, allocator> &o) { Base::operator=(o); return *this; }
00151 FXDEPRECATEDEXT QMemArray<type, allocator> &assign(const type *a, FXuval n) { return setRawData(a, n); }
00153 FXDEPRECATEDEXT QMemArray<type, allocator> &duplicate(const QMemArray<type, allocator> &o) { Base::operator=(o); return *this; }
00155 FXDEPRECATEDEXT QMemArray<type, allocator> &duplicate(const type *a, FXuval n) { return setRawData(a, n); }
00161 QMemArray<type, allocator> &setRawData(const type *a, FXuval n, bool _noDeleteExtArray=false)
00162 {
00163 extArray=const_cast<type *>(a); extArrayLen=n;
00164 noDeleteExtArray=_noDeleteExtArray;
00165 return *this;
00166 }
00168 void resetRawData(const type *a, FXuval n) { extArray=0; extArrayLen=0; noDeleteExtArray=false; }
00170 FXival find(const type &val, FXuval i=0) const
00171 {
00172 for(; i<size(); i++)
00173 {
00174 if(at(i)==val) return i;
00175 }
00176 return -1;
00177 }
00179 FXival contains(const type &val) const
00180 {
00181 FXuval count=0;
00182 for(FXuval n=0; n<size(); n++)
00183 {
00184 if(at(n)==val) count++;
00185 }
00186 return count;
00187 }
00188 private:
00189 static bool sortPredicate(const type &a, const type &b)
00190 {
00191 return a<b;
00192 }
00193 public:
00195 void sort()
00196 {
00197 if(extArray) throw "Not implemented for external arrays";
00198 std::sort(Base::begin(), Base::end(), sortPredicate);
00199 }
00201 int bsearch(const type &val) const
00202 {
00203 int lbound=0, ubound=(int)size()-1, c;
00204 while(lbound<=ubound)
00205 {
00206 c=(lbound+ubound)/2;
00207 const type &cval=at(c);
00208 if(val==cval)
00209 return c;
00210 else if(val<cval)
00211 ubound=c-1;
00212 else
00213 lbound=c+1;
00214 }
00215 return -1;
00216 }
00218 type &at(FXuval i) const { return (extArray) ? extArray[i] : const_cast<type &>(Base::at(i)); }
00220 type &operator[](FXuint i) const { return at(i); }
00222 type &operator[](int i) const { return at((FXuval) i); }
00223 bool operator==(const QMemArray<type, allocator> &o) const
00224 {
00225 if(extArray) throw "Not implemented for external arrays";
00226 const Base &me=*this;
00227 return me==o;
00228 }
00229 bool operator!=(const QMemArray<type, allocator> &o) const
00230 {
00231 if(extArray) throw "Not implemented for external arrays";
00232 const Base &me=*this;
00233 return me!=o;
00234 }
00236 Iterator begin() { return data(); }
00238 Iterator end() { return data()+size(); }
00240 ConstIterator begin() const { return data(); }
00242 ConstIterator end() const { return data()+size(); }
00243
00245 void push_back(const type &v) { FXEXCEPTION_STL1 { Base::push_back(v); } FXEXCEPTION_STL2; }
00247 void append(const type &v) { push_back(v); }
00249 using Base::pop_back;
00250 };
00251
00252 namespace QMemArrayImpl
00253 {
00254 template<bool isPOD, typename type, class allocator> struct Serialise
00255 {
00256 Serialise(FXStream &s, const QMemArray<type, allocator> &a)
00257 {
00258 FXulong mysize=a.size();
00259 s << mysize;
00260 for(FXuval i=0; i<mysize; i++)
00261 s << a.at(i);
00262 }
00263 };
00264 template<typename type, class allocator> struct Serialise<true, type, allocator>
00265 {
00266 Serialise(FXStream &s, const QMemArray<type, allocator> &a)
00267 {
00268 FXulong mysize=a.size();
00269 s << mysize;
00270 s.save(a.data(), (unsigned long) mysize);
00271 }
00272 };
00273 template<bool isPOD, typename type, class allocator> struct Deserialise
00274 {
00275 Deserialise(FXStream &s, QMemArray<type, allocator> &a)
00276 {
00277 FXulong mysize;
00278 s >> mysize;
00279 a.resize((FXuval)mysize);
00280 for(FXuval i=0; i<mysize; i++)
00281 s >> a.at(i);
00282 }
00283 };
00284 template<typename type, class allocator> struct Deserialise<true, type, allocator>
00285 {
00286 Deserialise(FXStream &s, QMemArray<type, allocator> &a)
00287 {
00288 FXulong mysize;
00289 s >> mysize;
00290 a.resize((FXuval)mysize);
00291 s.load(a.data(), (unsigned long) mysize);
00292 }
00293 };
00294 }
00295
00297 template<typename type, class allocator> FXStream &operator<<(FXStream &s, const QMemArray<type, allocator> &a)
00298 {
00299 QMemArrayImpl::Serialise<Generic::TraitsBasic<type>::isPOD, type, allocator>(s, a);
00300 return s;
00301 }
00303 template<typename type, class allocator> FXStream &operator>>(FXStream &s, QMemArray<type, allocator> &a)
00304 {
00305 QMemArrayImpl::Deserialise<Generic::TraitsBasic<type>::isPOD, type, allocator>(s, a);
00306 return s;
00307 }
00308
00310 #define QArray QMemArray
00311
00312 }
00313
00314 #endif