SourceForge.jp

array_onebyone_mingw.hpp

説明を見る。
00001 
00026 #ifndef _dkutilTL_array_onebyone_mingw_hpp_
00027 #define _dkutilTL_array_onebyone_mingw_hpp_
00028 
00029 //#include "dKingyoMacro.h"
00030 
00031 
00032 
00033 namespace dkutil{
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00051 template<class T,typename A=std::allocator<T>,
00052     class VECTOR=std::vector<T,A> ,
00053     class DEQUE=std::deque<size_t,A> ,
00054     unsigned int SizeAfterInit=200>
00055 class array_onebyone_ex{
00056 public:
00057     enum{
00058         enuExtendSize = SizeAfterInit,
00059     };
00060     typedef A allocator_type;
00061   typedef _Tp value_type;
00062   typedef value_type* pointer;
00063   typedef const value_type* const_pointer;
00064   typedef value_type& reference;
00065   typedef const value_type& const_reference;
00066   typedef _List_node<_Tp> _Node;
00067   typedef size_t size_type;
00068   typedef ptrdiff_t difference_type;
00069     typedef size_type handle;
00070     typedef VECTOR VECTOR_TYPE;
00071     typedef DEQUE DEQUE_TYPE;
00072 #ifndef BOOST_NO_PRIVATE_IN_AGGREGATE //なぜか boost 対応・・・
00073 protected:
00074 #endif
00075     DEQUE mq;
00076     VECTOR mv;
00077     
00078     VECTOR_TYPE::size_type now_size;
00079 
00080 public:
00081     //array_onebyone_ex(){clear();now_size = 0;}
00082     array_onebyone_ex(size_type construct_size=enuExtendSize){
00083         clear();
00084         mv.reserve(construct_size);
00085         now_size = 0;
00086     }
00087 
00088 
00089     virtual ~array_onebyone_ex(){clear();}
00094 
00095     handle push(const T &x){
00096         
00097         now_size++;//今のサイズをいんくりめんとぉ!
00098         
00099         if(mq.empty())
00100         {//キューが空だったら? 
00101             //そのままvector配列にぶち込む
00102             mv.push_back(x);
00103             return (now_size - 1);
00104             //return (mv.size() - 1);//これでいいのかは不明・・・
00105         }
00106         else//キューの中身が空じゃなかったら
00107         {
00108             size_type temp;
00109             mv[temp = mq.front()]=x;//キューのフロントを参照して添え字を見つけ、データ挿入。
00110             mq.pop_front();//frontを削除
00111             return temp;//添え字をハンドルとして返す。
00112         }
00113         //実際、ありえないけど念のため書いておく^^;
00114         throw std::logic_error("array_onebyone_ex:push:logic error");
00115         return NULL;
00116     }
00117     
00119     void pop(const handle &h){
00120         if(now_size == UINT_MAX){//buffer overflow
00121             throw std::invalid_argument("buffer overflow ");
00122             return;
00123         }
00124         if(now_size ==0){
00125             throw std::invalid_argument("now_size == 0 push() is not called. ");
00126             return;
00127         }
00128         now_size--;
00129         //コンテナに入っているデストラクタは呼び出しておく・・・
00130         A alc = mv.get_allocator();
00131         alc.destroy(alc.address(mv.at(h)));
00132         //使われていないよキュー にぶち込む
00133         mq.push_back(h);
00134     }
00136     A get_allocator() const{return mv.get_allocator();} 
00138     size_type size()const{ 
00139         return now_size;//mv.size();
00140     }
00141     //size_type max_size()const{    return mv.max_size();}
00143     size_type capacity()const{  return mv.capacity();}
00145     VECTOR &get_vector()const{return mv;}
00147     DEQUE &get_deque()const{return mq;}
00148     bool empty()const{  //return (mv.empty() && mq.empty());
00149         return (now_size == 0);
00150         //return mv.empty();
00151     }
00152     void resize(size_type new_size,const T &x=T()){
00153         if(new_size < mv.size()){
00154             throw std::invalid_argument("resize member function :argument new_size is too small."));
00155             return;
00156         }
00157         mv.resize(new_size,x);
00158     }
00159     void reserve(size_type n){
00160         if(n < mv.size()){
00161             throw
00162                 std::invalid_argument("reserve member function :argument n is too small.");
00163             return;
00164         }
00165         mv.reserve(n);
00166     }
00167     bool empty_free_queue(){    return mp.empty();}
00168     //要素の参照
00170     reference at(size_type pos){return mv.at(pos);}
00172     T *at_ptr(size_type pos){return &at(pos);}
00173   const_reference at(size_type pos) const{return mv.at(pos);}
00175     reference operator[](size_type pos){return mv[pos]; }
00176   const_reference operator[](size_type pos)const{   return mv[pos]; }
00177     
00179     void insert(handle pos,T &x){
00180         //now_size ++;
00181 #   ifdef _DEBUG
00182         try{
00183             mv.at(pos);
00184         }catch(...){
00185             char *str="posが無効です。";
00186             DEBUGMB(str);
00187             ::assert(!str);
00188         }
00189 #   endif
00190         mv[pos] = x;
00191     } 
00192     
00193     void clear(){ now_size = 0;mv.clear(); mq.clear(); }
00194 
00195 };
00196 
00197 
00199 template<class T>
00200 inline int ReallocateByNew(T **before,DWORD oldcount,T **after,DWORD extend,UINT *aftercount)
00201 {
00202     DWORD total = oldcount + extend;//合計の新規確保分
00203     T *get = new T[total];//maxcountはここで更新
00204     if(get==NULL){
00205         return -1;//だめじゃん!!最悪〜〜
00206     }
00207     //メモリコピー
00208     for(DWORD i=0;i<oldcount;i++){
00209         get[i]=(*before)[i];
00210     }
00211     //memcpyはC++のオブジェクトも出来るかどうか分からないので^^;
00212 
00213     delete[] (*before);//元のは開放
00214     (*after) = get;//アドレスを入れる。
00215     (*aftercount) = total;//合計の確保した数を入れる
00216     return 0;
00217 }
00218 
00219 
00220 
00221 
00222 
00228 
00229 template <class T,unsigned int EXTEND_ARRAY=enuDefaultExpandSize,typename A = std::allocator<T> >
00230 class array_onebyone{
00231 public:
00232     typedef A allocator_type;
00233   typedef A::size_type size_type;
00234   typedef A::difference_type difference_type;
00235   typedef A::reference reference;
00236   typedef A::const_reference const_reference;
00237   typedef A::value_type value_type;
00238     typedef std::deque<unsigned int,A> DEQUE_TYPE;
00239 #ifndef BOOST_NO_PRIVATE_IN_AGGREGATE //なぜか boost 対応・・・
00240 protected:
00241 #endif
00242     A allocator;
00243 
00244     T *m;// Memory
00245     unsigned int maxcount;//配列の最大数
00246     unsigned int nowmp;//now  m point
00247     bool mflag;//is OK?)
00248     DEQUE_TYPE mp;//添え字のキュー
00249     enum{//,DWORD EXTEND_ARRAY=100
00250         enuExtendArray=EXTEND_ARRAY,
00251     };
00252     
00253 public:
00254     typedef unsigned int handle;
00255     explicit array_onebyone(){
00256         maxcount=NULL;
00257         //nowmp=NULL;rend();をサポートするため・・・ 0では困る。Initで1にしておく
00258         nowmp=0;
00259         m=NULL;
00260         mflag=false;
00261         Init(enuExtendArray);
00262     }
00263   array_onebyone(const array_onebyone<T,EXTEND_ARRAY,A> &a){
00264         mflag=false;
00265         maxcount = a.maxcount;
00266       nowmp = a.nowmp;
00267       //getflag = a.getflag;
00268       mp = a.mp;
00269         if(a.maxcount > 0){
00270             m = new T[a.maxcount];
00271             if(!m)
00272             {//例外発生しました!!
00273                 //ここでなぎぇたいのぬぃ〜〜〜!!!!
00274                 // throw std::domain_error("array_onebyone:copy constructor:memory allocate error");
00275                 return;
00276             }
00277             for(int i = 0; i < a.maxcount; i++){//メモリコピー
00278                  *(m + i) = *(a.m + i);
00279             }
00280             //memcpy(m, a.m, a.maxcount);これだとC++のオブジェクトも出来るかどうかは不明
00281         }
00282         else{
00283             m = NULL;
00284         }
00285         mflag=true;//初期化済み
00286     }
00287 
00288     bool empty_free_queue(){
00289         return mp.empty();
00290     }
00291 
00292   void resize(size_type n){
00293         if(maxcount >= n){
00294             std::domain_error("Size is not made small.");
00295         }
00296         ReallocateByNew<T>(&m,maxcount,&m,n,&maxcount);
00297     }
00298   size_type size() const{return nowmp-1;}
00299   size_type max_size() const{return maxcount;}
00300   bool empty() const{
00301         if((mp.empty() && nowmp<=1) || mp.size()==nowmp)
00302             return true;
00303         return false;
00304     }
00305   A get_allocator() const{return allocator;}
00306   reference at(size_type pos){
00307         if(nowmp <= pos){
00308             throw std::range_error("range error");
00309         }
00310         return m[pos];
00311     }
00312     
00313   const_reference at(size_type pos) const{
00314         if(nowmp <= pos){
00315             throw std::range_error("range error");
00316         }
00317         return m[pos];
00318     }
00319   reference operator[](size_type pos){return m[pos]; }
00320   const_reference operator[](size_type pos)const{   return m[pos]; }
00321   //reference front(){  return m;}
00322   //const_reference front() const;
00323   //reference back(){return m[nowmp-1];}
00324   //const_reference back() const;
00325   handle push(const T& x){
00326         if(mflag==false){
00327             Init(enuExtendArray);
00328         }
00329         if(nowmp>=maxcount)
00330         {//ちょっとこのままじゃアクセスバイオレーションだ〜よ!
00331             if(mp.empty())
00332             {//キューが空だったら? 
00333                 if(-1==Reallocate())//リアロックする。
00334                 {
00335                     return NULL;//最悪〜〜失敗。
00336                 }
00337                 else//上手くできたようなので
00338                 {
00339                     return push(x);//再起呼び出し
00340                 }
00341             }
00342             else//キューの中身が空じゃなかったら
00343             {
00344                 DWORD l_num;//配列の添え字をゲットする
00345                 l_num=(mp.front());//ってことでGET!
00346                 mp.pop_front();//削除する
00347                 m[l_num]=x;//データ挿入。
00348                 return l_num;//添え字をハンドルとして返す。
00349             }
00350         }else{
00351             m[nowmp] = x;//でーたを入れとく
00352             return nowmp++;//添え字をハンドルとして返す
00353         }
00354         //実際、ありえないけど念のため書いておく^^;
00355         return NULL;
00356     }
00357   void pop(handle item){mp.push_back(item);}
00358   //void assign(const_iterator first, const_iterator last);
00359   //void assign(size_type n, const T& x = T());
00360   //iterator insert(iterator it, const T& x = T());
00361   //void insert(iterator it, size_type n, const T& x);
00362   //void insert(iterator it,  const_iterator first, const_iterator last);
00363   //iterator erase(iterator it);
00364   //iterator erase(iterator first, iterator last);
00365   void clear(){
00366         if(m){
00367             delete[] m;
00368             m=NULL;
00369         }   
00370         maxcount=NULL;
00371         nowmp=NULL;
00372         m=NULL;
00373         mp.clear();//キューもすべて削除
00374         mflag=false;//フラグを下ろす
00375     }
00376   //void swap(deque x);
00377    
00378     virtual ~array_onebyone(){
00379         clear();
00380     }
00381 protected:
00385 
00386     int Init(size_t memory_count)
00387     {
00388         if(mflag==true)return 1;//もう一回呼び出しはダメです。
00389         maxcount=memory_count;
00390         //Dyanamic memoryだったらnewしかないでしょ^^;
00391         m = new T[memory_count];
00392         if(!m) return -1;//だめじゃんNULLじゃ
00393 
00394         nowmp=1;//rend()を使うため
00395         mflag=true;//フラグを立てる
00396         
00397         return 0;
00398     }
00400     int Reallocate(){
00401         if(mflag==false){
00402             if(-1==Init(100)){//百個くらい^^;
00403                 throw std::runtime_error("The worst error");
00404             }
00405         }
00406         return ReallocateByNew<T>(&m,maxcount,&m,enuExtendArray,&maxcount);
00407     }
00408 };
00409 
00410 }//end of dkutil namespace
00411 
00412 
00413 #endif // end of include once

dkutil 1.02リリース前 d金魚専用マニュアルバージョンに対してSun Dec 28 21:23:07 2003に生成されました。 doxygen 1.3.5