qmemarray.h

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *                          Q t   A r r a y   t h u n k                          *
00004 *                                                                               *
00005 *********************************************************************************
00006 *        Copyright (C) 2003 by Niall Douglas.   All Rights Reserved.            *
00007 *       NOTE THAT I DO NOT PERMIT ANY OF MY CODE TO BE PROMOTED TO THE GPL      *
00008 *********************************************************************************
00009 * This code is free software; you can redistribute it and/or modify it under    *
00010 * the terms of the GNU Library General Public License v2.1 as published by the  *
00011 * Free Software Foundation EXCEPT that clause 3 does not apply ie; you may not  *
00012 * "upgrade" this code to the GPL without my prior written permission.           *
00013 * Please consult the file "License_Addendum2.txt" accompanying this file.       *
00014 *                                                                               *
00015 * This code is distributed in the hope that it will be useful,                  *
00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                          *
00018 *********************************************************************************
00019 * $Id:                                                                          *
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     //using Base::clear;
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     {   // God damn std::binary_search doesn't return the position :(
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 } // namespace
00313 
00314 #endif

(C) 2002-2009 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Nov 20 18:31:26 2009 for TnFOX by doxygen v1.4.7