00001
00002
00003
00004
00005
00006
00007
00008 #ifndef ARRAYT_HPP_
00009 #define ARRAYT_HPP_
00010 #include <cstddef>
00011 #include <algorithm>
00012
00013 #include <vector>
00014 #include <stdexcept>
00015 #include"fv_compiler.h"
00016 #include"fv_exception.h"
00017 #include"ElemId.hpp"
00018 #include "uth_log.h"
00019 #ifdef FV_DEBUG
00020 #include<iostream>
00021 #endif
00022
00023 #define BOUND_ACTIVE 0
00024 #define ACTIVE_BOUND 1
00025
00026 namespace FemViewer {
00027 template< typename IdT, typename T = ElemId<IdT> >
00028 class ArrayT
00029 {
00030 public:
00031 typedef T value_type;
00032 typedef T* iterator;
00033 typedef const T* const_iterator;
00034 typedef T& reference;
00035 typedef const T& const_reference;
00036 typedef std::size_t size_type;
00037
00038 private:
00039 static const size_type default_size = 8;
00040 T* _data;
00041 size_type _max_size;
00042 size_type _next_idx;
00043 size_type _count;
00044 uint8_t _order_segregate;
00045 iterator& _sepIter1;
00046 iterator& _sepIter2;
00047
00048 inline T* _alloc(size_type n) { return reinterpret_cast<T*>( new char [ n * sizeof(T) ]); }
00049 inline void _check(size_type n) { if (n > _max_size) {
00050 char buf[24];
00051 sprintf(buf,"index: %u size %u\n",n,_max_size);
00052 throw std::out_of_range(buf); }
00053 }
00054
00055 public:
00056
00057 explicit ArrayT(size_type size_ = default_size)
00058 : _data( _alloc(size_) )
00059 , _max_size(size_)
00060 , _next_idx(0)
00061 , _count(0)
00062 , _sepIter1(_data)
00063 , _sepIter2(_data)
00064 {
00065
00066 size_type i(0);
00067 try {
00068 for(;i<_max_size;++i) new (_data+i) T();
00069 } catch (...)
00070 {
00071 for(;i>0;--i) (_data+i)->~T();
00072 FV_FREE_ARR((char*)_data);
00073 throw;
00074 }
00075 }
00076
00077 template<class U>
00078 ArrayT(const ArrayT<U>& ar)
00079 : _data(ar._data),
00080 _max_size(ar._max_size),
00081 _next_idx(ar._next_idx),
00082 _count(ar._count),
00083 _order_segregate(ar._order_segregate),
00084 _sepIter1(ar._sepIter1),
00085 _sepIter2(ar._sepIter1)
00086 {;}
00087
00088
00089 ~ArrayT() {
00090
00091 clear();
00092 }
00093
00094
00095 iterator begin() { return _data; }
00096 const_iterator begin() const { return _data; }
00097 iterator end() { return _data + _next_idx; }
00098 const_iterator end() const { return _data + _next_idx; }
00099
00100
00101
00102
00103 size_type capacity() const { return _max_size; }
00104 size_type size() const { return _next_idx; }
00105 size_type nbound() const { assert(_next_idx >= _count); return (_next_idx - _count); }
00106 size_type nactive() const {return _count; }
00107
00108 uint_t order() const { return _order_segregate; }
00109 void set_order(uint_t order_);
00110 bool is_empty() const { return (_next_idx == 0); }
00111
00112
00113 void clear()
00114 {
00115 for( size_type i(0); i < _max_size; ++i)
00116 (_data + i)->~T();
00117
00118 FV_FREE_ARR((char*)_data);
00119 _max_size = 0;
00120 _next_idx = 0;
00121 _count = 0;
00122 _order_segregate = 0x00;
00123 _sepIter1 = _sepIter2 = 0;
00124 }
00125
00126 void reserve(size_type capacity_);
00127 void resize(size_type nsize_);
00128 void insert(const T& it_,size_type idx_);
00129 void push_back(const T& it) { insert(it,_next_idx); }
00130 void segregate(uint_t order_=BOUND_ACTIVE);
00131
00132 reference fisrt() { return _data[0]; }
00133 const_reference fisrt() const { return _data[0]; }
00134
00135 reference last() { assert(_next_idx > 0); return _data[_next_idx-1]; }
00136 const_reference last() const { assert(_next_idx > 0); return _data[_next_idx-1]; }
00137
00138 reference at_pos(const size_type id_) {
00139 this->_check(id_);
00140 return *(this->begin() + id_);
00141 }
00142
00143 const_reference at_pos(const size_type id_) const {
00144 assert((id_ >= 0) && (id_ < _max_size));
00145 return *(this->_begin() + id_);
00146 }
00147
00148 reference operator[](const size_type id_) { ;return *(_sepIter1 + id_); }
00149 const_reference operator[](const size_type id_) const { return *(_sepIter1 + id_); }
00150
00151 reference operator()(const size_type id_) { return *(_sepIter2 + id_); }
00152 const_reference operator()(const size_type id_) const { return *(_sepIter2 + id_); }
00153
00154 reference next_boundary(const size_type idx_);
00155 const_reference next_boundary(const size_type idx_) const;
00156
00157 reference next_active(const size_type idx_);
00158 const_reference next_active(const size_type idx_) const;
00159 #ifdef FV_DEBUG
00160 void dumpArray() const
00161 {
00162 std::cout << "\tArray max size:\t\t" << _max_size
00163 << "\n\tArray next index\t\t" << _next_idx
00164 << "\n\tArray specific els:\t\t" << _count
00165 << std::endl;
00166 }
00167 #endif
00168 private:
00169
00170 void _extend_array();
00171
00172
00173
00174
00175 template<class U>
00176 ArrayT& operator=(const ArrayT<U>&);
00177
00178 };
00179
00180 template<typename IdT,typename T>
00181 void ArrayT<IdT,T>::set_order(uint_t order_)
00182 {
00183 _order_segregate = order_;
00184 segregate();
00185 }
00186
00187
00188 template<typename IdT,typename T>
00189 void ArrayT<IdT,T>::reserve(size_type size_)
00190 {
00191 assert(size_ > 0);
00192 if (size_ <= _max_size) return;
00193
00194 try {
00195 T* ptr(NULL);
00196 if ((ptr = this->_alloc(size_)) != NULL)
00197 {
00198 for(size_type i(0); i<_next_idx; ++i) {
00199 new(ptr + i) T(_data[i]);
00200 (_data+i)->~T();
00201 }
00202 FV_FREE_ARR((char*)_data);
00203 _data = ptr;
00204 _max_size = size_;
00205 }
00206
00207 }
00208 catch (std::bad_alloc&)
00209 {
00210 throw "Can't reserve memory for array!";
00211 }
00212 }
00213
00214 template<typename IdT,typename T>
00215 void ArrayT<IdT,T>::resize(size_type size_)
00216 {
00217 assert(size_ >= 0);
00218 this->reserve(size_);
00219 for (size_type i = _next_idx; i< size_;++i)
00220 new (_data+i) T();
00221 for(size_type i = size_; i< _next_idx; ++i)
00222 (_data+i)->~T();
00223 }
00224
00225 template<typename IdT,typename T>
00226 void ArrayT<IdT,T>::insert(const T& it_,size_type idx_)
00227 {
00228
00229 this->_check(idx_);
00230
00231 if (_max_size == _next_idx) _extend_array();
00232
00233 if (idx_ == _next_idx) {
00234 new(_data+idx_) T(it_);
00235 }
00236 else {
00237 new(_data + _next_idx) T(_data[_next_idx-1]);
00238 for(size_type i = _next_idx -1; i > idx_; --i)
00239 _data[i] = _data[i-1];
00240 _data[idx_] = it_;
00241 }
00242 ++_next_idx;
00243 if (IS_ACTIVE(it_.id)) ++_count;
00244 }
00245
00246 template<typename IdT,typename T>
00247 void ArrayT<IdT,T>::segregate(uint_t order_)
00248 {
00249
00250 if (_count == 0) return;
00251
00252
00253 if (order_!=BOUND_ACTIVE || order_!= ACTIVE_BOUND)
00254 throw fv_exception("Invalid order for segregation");
00255
00256 _order_segregate = order_;
00257 _sepIter1 = _sepIter2 = begin();
00258
00259 iterator it_ (begin()), _it (&last());
00260 assert(it_ < _it);
00261
00262 IdT first_mask(0), second_mask(0);
00263
00264 if (_order_segregate == BOUND_ACTIVE)
00265 {
00266 SET_BOUND(first_mask);
00267 SET_ACTIVE(second_mask);
00268 }
00269 else {
00270 SET_ACTIVE(first_mask);
00271 SET_BOUND(second_mask);
00272 }
00273 std::cout<<"przed pierwszym: it_= " << it_ << " "<< _it << "=_it\n";
00274
00275 while (it_ < _it) {
00276
00277 while (it_->is_bit(first_mask) && it_ < _it) ++it_;
00278 while (_it->is_bit_not(first_mask) && it_ < _it) --_it;
00279 if (it_ < _it) {
00280 std::swap(*it_,*_it);
00281 ++it_;
00282 --_it;
00283 }
00284 }
00285
00286
00287
00288
00289
00290 _it = (it_->is_bit(first_mask)) ? it_ : --it_;
00291
00292 if (_order_segregate == BOUND_ACTIVE) {
00293 _sepIter1 = begin();
00294 _sepIter2 = _it + 1;
00295 } else {
00296 _sepIter1 = _it + 1;
00297 _sepIter2 = begin();
00298 }
00299
00300 iterator it(_it);
00301 it_ = begin();
00302
00303 while (it_ < it) {
00304
00305 while (it_->is_bit_not(second_mask) && it_ < it) ++it_;
00306 while (it->is_bit(second_mask) && it_ < it) --it;
00307 if (it_ < it) {
00308 std::swap(*it_,*it);
00309 ++it_;
00310 --it;
00311 }
00312 }
00313
00314
00315
00316 it = it_->is_bit_not(second_mask) ? it_ : --it_;
00317
00318
00319
00320
00321
00322
00323
00324
00325 std::sort(++it,_it++);
00326
00327
00328 it = it_ = _it;
00329 _it = &last();
00330
00331
00332
00333 while (it_ < _it) {
00334
00335 while (it_->is_bit(second_mask) && it_ < _it) ++it_;
00336
00337 while (_it->is_bit_not(second_mask) && it_ < _it) --_it;
00338 if (it_ < _it) {
00339 std::swap(*it_,*_it);
00340 ++it_;
00341 --_it;
00342 }
00343 }
00344
00345
00346
00347
00348 if (it_->is_bit_not(second_mask)) --it_;
00349 _it = it_ + 1;
00350 std::sort(it,it_);
00351 std::sort(_it,&last());
00352 }
00353
00354 template<typename IdT,typename T>
00355 T& ArrayT<IdT,T>::next_boundary(const size_type idx_)
00356 {
00357 assert(idx_ < _next_idx);
00358 assert(_next_idx > 0);
00359 return *(this->_sepIter1 + idx_ + 1);;
00360 }
00361
00362 template<typename IdT,typename T>
00363 const T& ArrayT<IdT,T>::next_boundary(const size_type idx_) const {
00364 assert(idx_ < _next_idx);
00365 assert(_next_idx > 0);
00366 return *(this->_sepIter1 + idx_ + 1);
00367 }
00368
00369 template<typename IdT,typename T>
00370 T& ArrayT<IdT,T>::next_active(const size_type idx_) {
00371 assert(idx_ < _next_idx);
00372 assert(_next_idx > 0);
00373 return *(this->_sepIter2 + idx_ + 1);
00374 }
00375
00376 template<typename IdT,typename T>
00377 const T& ArrayT<IdT,T>::next_active(const size_type idx_) const {
00378 assert(idx_ < _next_idx);
00379 assert(_next_idx > 0);
00380 return *(this->_sepIter2 + idx_ + 1);
00381 }
00382
00383 template<typename IdT,typename T>
00384 void ArrayT<IdT,T>::_extend_array()
00385 {
00386
00387 size_type n(1);
00388 if (_max_size > 0)
00389 n = _max_size << 1;
00390 this->reserve(n);
00391 }
00392
00393 #undef BONUD_ACTIVE
00394 #undef ACTIVE_BOUND
00395
00396 }
00397 #endif