JAM_ControlledVector<T,Mem>::JAM_ControlledVector(size_t length, size_t allocated) { //### if (JAM_NewLog::activate()) JAM_NewLog::log() << "constructing vector " << (void*)this << "\n"; //### JAM_assert(allocated>=length); _allocated = allocated; _length = length; if (_allocated) { _arr = (T*)Mem::alloc(_allocated*sizeof(T)); JAM_assert(_arr!=0); // construct each element with default ctor for (size_t i=0; i<_length; ++i) JAM_construct(_arr[i]); } else { _arr = 0; } }
template<class T, class Comp> int JAM_OrdSetComp<T,Comp>::find(const T& item, size_t& pos) const { /* binary search for item, return success and pos is at correct place */ JAM_assert(_data.allocated()!=size_t(-1)); //### if (num()==0) { pos = 0; return 0; } size_t left = 0; size_t right = num()-1; for (;;) { /*assert(left<=right); sanity check */ pos = (right-left)/2 + left; if (Comp::equal(_data[pos],item)) return 1; else if (Comp::lessthan(_data[pos],item)) { if (pos==right) { ++pos; return 0; } else left = pos+1; } else /* (_data[pos]>item) */ { if (pos==left) { /* pos is at correct place for item */ return 0; } else right = pos-1; } } /* forever */ }
int JAM_ControlledVoidPtrSet<Mem>::contains(void* p) const { JAM_assert(p!=0); size_t n = _arr.length(); for (size_t i=0; i<n; ++i) if (_arr[i]==p) return 1; return 0; }
void JAM_ControlledVector<T,Mem>::clear() { JAM_assert(_allocated!=size_t(-1)); //### size_t i=_length; while (i>0) JAM_destroy(_arr[--i]); _length = 0; }
size_t JAM_ControlledVoidPtrSet<Mem>::prevelem(size_t start) const { JAM_assert(start<_arr.length()); while (_arr[start]==0) { if (start==0) return size_t(-1); else --start; } return start; }
ostream& operator<<(ostream& os, const JAM_ControlledVector<T, Mem>& array) { JAM_assert(array._allocated!=size_t(-1)); //### size_t n = array.length(); os << '[' << n << ']'; for (size_t i=0; i<n; i++) os << ' ' << array[i]; return os; }
JAM_ControlledVector<T,Mem>::~JAM_ControlledVector() { JAM_assert(_allocated!=size_t(-1)); //### //### if (JAM_NewLog::activate()) JAM_NewLog::log() << "deleting vector " << (void*)this << "\n"; //### if (_allocated) { size_t i=_length; while (i>0) JAM_destroy(_arr[--i]); Mem::free(_arr); } _allocated = size_t(-1); //### }
JAM_ControlledArray<T,Mem>::JAM_ControlledArray(const JAM_ControlledArray<T,Mem>& array) { _length = array._length; if (_length>0) { _arr = (T*)Mem::alloc(_length*sizeof(T)); JAM_assert(_arr!=0); for (size_t i=0; i<_length; ++i) JAM_construct(_arr[i], array._arr[i]); } else { _arr = 0; } }
template<class T, class Comp> void JAM_OrdSetComp<T,Comp>::remove(const T& beg, const T& end) { JAM_assert(!Comp::lessthan(end,beg)); size_t begpos, endpos; find(beg, begpos); if (begpos<_data.length()) { if (!find(end, endpos)) { if (endpos==0) return; // beg..end range is not in _data else --endpos; } _data.remove(begpos, endpos); // remove elements inclusively } }
JAM_ControlledArray<T,Mem>::JAM_ControlledArray(size_t length, const T& init) { _length = length; if (_length) { _arr = (T*)Mem::alloc(_length*sizeof(T)); JAM_assert(_arr!=0); // construct each element with copy ctor for (size_t i=0; i<_length; ++i) JAM_construct(_arr[i], init); } else { _arr = 0; } }
void JAM_ControlledVector<T,Mem>::resize(size_t new_length, const T& init) { //### dump(cout); cout << "resize(" << new_length << ", " << "init" << ")\n"; JAM_assert(_allocated!=size_t(-1)); //### JAM_assert(new_length<=max()); if (_allocated>=new_length) { // don't have to allocate new space if (_length<new_length) while (_length<new_length) JAM_construct(_arr[_length++], init); else // _length>=new_length while (_length>new_length) JAM_destroy(_arr[--_length]); } else { size_t min = (new_length<_length) ? new_length : _length; // destroy each old extra element size_t i=_length; while (i>min) JAM_destroy(_arr[--i]); T* new_arr = (new_length>0) ? (T*)Mem::alloc(new_length*sizeof(T)) : 0; JAM_assert(new_arr!=0); // copy construct each new element then destroy the original if (min) move(new_arr, _arr, min); // construct each new extra element with initial value for (i=min; i<new_length; ++i) JAM_construct(new_arr[i], init); // free space used by old array if (_arr) Mem::free(_arr); _arr = new_arr; _length = new_length; _allocated = new_length; } }
void JAM_ControlledVector<T,Mem>::insert(const T& item, size_t index) { //### dump(cout); cout << "insert(" << "item" << ", " << index << ")\n"; JAM_assert(_allocated!=size_t(-1)); //### JAM_assert(index<=_length); if (_allocated>_length) { move(&_arr[index+1], &_arr[index], _length-index, 1); // overlapping move //###here ??? JAM_construct(_arr[index], item); ++_length; } else { // need to allocate more space ++_allocated; T* new_arr = (T*)Mem::alloc(_allocated*sizeof(T)); if (index>0) move(new_arr, _arr, index); // copy 0..index-1 JAM_construct(new_arr[index], item); // copy index..length if (_length>index) move(&new_arr[index+1], &_arr[index], _length-index); // free space used by old array if (_arr) Mem::free(_arr); _arr = new_arr; ++_length; } }
JAM_ControlledVector<T,Mem>::JAM_ControlledVector(const JAM_ControlledVector<T,Mem>& array) { //### if (JAM_NewLog::activate()) JAM_NewLog::log() << "constructing vector " << (void*)this << "\n"; //### _allocated = array._length; _length = array._length; if (_allocated) { _arr = (T*)Mem::alloc(_allocated*sizeof(T)); JAM_assert(_arr!=0); for (size_t i=0; i<_length; ++i) JAM_construct(_arr[i], array._arr[i]); } else { _arr = 0; } }
void JAM_ControlledVector<T,Mem>::move(T* dst, T* src, size_t n, int overlap) { //### cout << "move(" << (void*)dst << ", " << (void*)src << ", " << n << ", " << overlap << ") " << "sizeof(T)=" << sizeof(T> ) << "\n"; // copy construct each new element and immediately destroy old if (overlap && dst>src) { // then go in reverse direction for (size_t i=n; i>0; ) { --i; JAM_construct(dst[i], src[i]); JAM_destroy(src[i]); } } else { JAM_assert(dst!=src); //### for (size_t i=0; i<n; ++i) { JAM_construct(dst[i], src[i]); JAM_destroy(src[i]); } } }
void JAM_ControlledVoidPtrSet<Mem>::enter(void* p) { JAM_assert(p!=0); if (!contains(p)) { size_t n = _arr.length(); size_t i = 0; while (i<n && _arr[i]!=0) ++i; if (i<n) { _arr[i] = p; // fill an empty slot } else { if (_arr.allocated()==n) { // need to grow array if (_arr.allocated()==_arr.max()) // can't increase size JAM_crash("JAM_ControlledVoidPtrSet is full."); else if (n>_arr.max()/2) _arr.allocate(_arr.max()); else _arr.allocate(n*2); } _arr.append(p); } } }
void JAM_ControlledArray<T,Mem>::operator=(const JAM_ControlledArray<T,Mem>& array) { if (this==&array) return; if (_length!=array._length) { // have to reallocate a new block size_t i=_length; while (i>0) JAM_destroy(_arr[--i]); // destroy each element Mem::free(_arr); _length = array._length; if (_length==0) { _arr = 0; } else { _arr = (T*)Mem::alloc(_length*sizeof(T)); JAM_assert(_arr!=0); // construct each element with default ctor for (size_t i=0; i<_length; ++i) JAM_construct(_arr[i]); } } for (size_t i=0; i<_length; ++i) _arr[i] = array._arr[i]; }