395 lines
6.4 KiB
C++
Executable File
395 lines
6.4 KiB
C++
Executable File
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <array.h>
|
|
#include <strings.h>
|
|
|
|
void TArray::resize(int arraysize)
|
|
|
|
{
|
|
CHECK(arraysize > size(), "Can't reduce array size.");
|
|
|
|
TObject** newdata = new TObject* [arraysize];
|
|
|
|
int i = 0;
|
|
if (_data != NULL)
|
|
for (i = 0; i < size(); i++) newdata[i] = _data[i];
|
|
|
|
while (i < arraysize) newdata[i++] = NULL;
|
|
|
|
if (_data != NULL) delete _data;
|
|
|
|
_size = arraysize;
|
|
_data = newdata;
|
|
}
|
|
|
|
|
|
bool TArray::destroy(int index, bool pack)
|
|
{
|
|
const int old = _items;
|
|
|
|
if (index < 0)
|
|
{
|
|
for (int i = size(); i--;) if (_data[i] != NULL)
|
|
{
|
|
delete _data[i];
|
|
_data[i] = NULL;
|
|
}
|
|
_items = 0;
|
|
}
|
|
else
|
|
{
|
|
TObject* o = remove(index, pack);
|
|
if (o) delete o;
|
|
}
|
|
|
|
return _items < old;
|
|
}
|
|
|
|
|
|
|
|
TArray::TArray(int arraysize) : _size(0), _items(0), _data(NULL)
|
|
|
|
{
|
|
if (arraysize) resize(arraysize);
|
|
}
|
|
|
|
TArray::TArray() : _size(0), _items(0), _data(NULL)
|
|
{
|
|
}
|
|
|
|
TArray::~TArray()
|
|
|
|
{
|
|
if (ok())
|
|
{
|
|
destroy();
|
|
delete _data;
|
|
}
|
|
}
|
|
|
|
|
|
const char* TArray::class_name() const
|
|
|
|
{
|
|
return "Array";
|
|
}
|
|
|
|
|
|
word TArray::class_id() const
|
|
|
|
{
|
|
return CLASS_ARRAY;
|
|
}
|
|
|
|
|
|
void TArray::print_on(ostream& out) const
|
|
|
|
{
|
|
for (int i = 0; i < size(); i++)
|
|
{
|
|
out.width(4);
|
|
out << i << ' ';
|
|
out.width();
|
|
if (_data[i] != NULL) out << *_data[i];
|
|
else out << "(null)";
|
|
out << endl;
|
|
}
|
|
}
|
|
|
|
|
|
bool TArray::ok() const
|
|
|
|
{
|
|
return(size() != 0 && (_data != NULL));
|
|
}
|
|
|
|
|
|
int TArray::add(TObject* object, int index)
|
|
{
|
|
if (index < 0) for (index = 0; index < size() && _data[index]; index++);
|
|
if (index >= size()) resize(3*index/2 + 1);
|
|
|
|
if (_data[index] != NULL)
|
|
{
|
|
#ifdef DBG
|
|
if (object == _data[index])
|
|
{
|
|
error_box("Iu ar traing tu overrait en arrei obgiect: %d", index);
|
|
return index;
|
|
}
|
|
#endif
|
|
delete _data[index];
|
|
_items--;
|
|
}
|
|
|
|
_data[index] = object;
|
|
if (object != NULL) _items++;
|
|
|
|
return index;
|
|
}
|
|
|
|
|
|
int TArray::insert(TObject* object, int index)
|
|
{
|
|
if (objptr(index))
|
|
{
|
|
if (items() == size()) add(NULL);
|
|
for (int i = size()-1; i >= index; i--)
|
|
_data[i] = _data[i-1];
|
|
_data[index] = NULL;
|
|
}
|
|
return add(object, index);
|
|
}
|
|
|
|
int TArray::add(const TObject& object, int index)
|
|
{
|
|
TObject* objptr = object.dup();
|
|
return add(objptr, index);
|
|
}
|
|
|
|
int TArray::insert(const TObject& object, int index)
|
|
{
|
|
TObject* objptr = object.dup();
|
|
return insert(objptr, index);
|
|
}
|
|
|
|
TObject* TArray::remove(int index, bool dopack)
|
|
{
|
|
TObject* o = objptr(index);
|
|
if (o)
|
|
{
|
|
_data[index] = NULL;
|
|
_items--;
|
|
}
|
|
if (dopack) pack();
|
|
return o;
|
|
}
|
|
|
|
void TArray::swap(int i1, int i2)
|
|
{
|
|
TObject* o1 = remove(i1, FALSE);
|
|
TObject* o2 = remove(i2, FALSE);
|
|
if (o1) add(o1, i2);
|
|
if (o2) add(o2, i1);
|
|
}
|
|
|
|
int TArray::last() const
|
|
{
|
|
for (int last = size(); --last >= 0; )
|
|
if (_data[last]) break;
|
|
return last;
|
|
}
|
|
|
|
|
|
void TArray::pack()
|
|
{
|
|
int next = 0;
|
|
for (int i = 0; i < size(); i++)
|
|
{
|
|
if (_data[i] != NULL)
|
|
{
|
|
if (next < i)
|
|
{
|
|
_data[next] = _data[i];
|
|
_data[i] = NULL;
|
|
}
|
|
next++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
HIDDEN int sortable_compare(const TObject** o1, const TObject** o2)
|
|
{
|
|
const TSortable* s1 = (const TSortable*)*o1;
|
|
const TSortable* s2 = (const TSortable*)*o2;
|
|
return s1->compare(*s2);
|
|
}
|
|
|
|
void TArray::sort(COMPARE_FUNCTION compare)
|
|
{
|
|
typedef int (*qsortfunc)(const void*, const void*);
|
|
if (compare == NULL) compare = sortable_compare;
|
|
|
|
pack();
|
|
qsort(_data, items(), sizeof(TObject*), (qsortfunc)compare);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TBit_array
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TBit_array::TBit_array(long size) : _bit(NULL), _size(0)
|
|
{
|
|
if (size) resize(index(size));
|
|
}
|
|
|
|
void TBit_array::copy(const TBit_array& ba)
|
|
{
|
|
if (_bit)
|
|
{
|
|
delete _bit;
|
|
_bit = NULL;
|
|
_size = 0;
|
|
}
|
|
resize(ba._size-1);
|
|
memcpy(_bit, ba._bit, _size);
|
|
}
|
|
|
|
TBit_array::TBit_array(const TBit_array& ba) : _bit(NULL), _size(0)
|
|
{ copy(ba); }
|
|
|
|
TBit_array& TBit_array::operator=(const TBit_array& ba)
|
|
{
|
|
copy(ba);
|
|
return *this;
|
|
}
|
|
|
|
|
|
TBit_array::~TBit_array()
|
|
{
|
|
if (_bit) delete _bit;
|
|
}
|
|
|
|
// Certified 100%
|
|
void TBit_array::set()
|
|
{
|
|
if (_bit) memset(_bit, 0xFF, _size);
|
|
}
|
|
|
|
// Certified 100%
|
|
void TBit_array::reset()
|
|
{
|
|
if (_bit) memset(_bit, 0x0, _size);
|
|
}
|
|
|
|
// Certified 99%
|
|
void TBit_array::resize(word size)
|
|
{
|
|
word oldsize = _size;
|
|
byte* oldbit = _bit;
|
|
|
|
_size = size+1;
|
|
_bit = new byte[_size];
|
|
reset();
|
|
|
|
if (oldsize)
|
|
{
|
|
memcpy(_bit, oldbit, oldsize);
|
|
delete oldbit;
|
|
}
|
|
}
|
|
|
|
|
|
bool TBit_array::operator[] (long n) const
|
|
{
|
|
const word i = index(n);
|
|
if (i >= _size) return FALSE;
|
|
return (_bit[i] & mask(n)) != 0;
|
|
}
|
|
|
|
// Certified 99%
|
|
TBit_array& TBit_array::operator|= (const TBit_array& ba)
|
|
{
|
|
CHECK(_size >= ba._size, "TBit_array |=: right operand too big");
|
|
|
|
for (word i = 0; i < _size; i++)
|
|
_bit[i] |= ba._bit[i];
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Certified 99%
|
|
void TBit_array::set(long n)
|
|
{
|
|
const word i = index(n);
|
|
if (i >= _size) resize(i);
|
|
_bit[i] |= mask(n);
|
|
}
|
|
|
|
// Certified 99%
|
|
void TBit_array::reset(long n)
|
|
{
|
|
const word i = index(n);
|
|
if (i < _size)
|
|
_bit[i] &= ~mask(n);
|
|
}
|
|
|
|
// Certified 99%
|
|
void TBit_array::not(long n)
|
|
{
|
|
const word i = index(n);
|
|
if (i >= _size) resize(i);
|
|
_bit[i] ^= mask(n);
|
|
}
|
|
|
|
// Certified 50%
|
|
long TBit_array::ones() const
|
|
{
|
|
long one = 0;
|
|
for (word i = 0; i < _size; i++)
|
|
{
|
|
const byte b = _bit[i];
|
|
if (b)
|
|
{
|
|
for (byte m = 1; m; m <<= 1)
|
|
if (b & m) one++;
|
|
}
|
|
}
|
|
return one;
|
|
}
|
|
|
|
// Certified 90%
|
|
long TBit_array::last_one() const
|
|
{
|
|
for (word i = _size; i--;)
|
|
{
|
|
const byte b = _bit[i];
|
|
if (b)
|
|
{
|
|
for (byte j = 8; j--;)
|
|
if ((1<<j) & b) return (long(i)<<3) + j;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// Certified 90%
|
|
long TBit_array::first_one() const
|
|
{
|
|
for (word i = 0; i < _size; i++)
|
|
{
|
|
const byte b = _bit[i];
|
|
if (b)
|
|
{
|
|
for (byte j = 0; j < 8; j++)
|
|
if ((1<<j) & b) return (long(i)<<3)+j;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
bool TBit_array::ok() const
|
|
{
|
|
return _bit != NULL && _size > 0;
|
|
}
|
|
|
|
|
|
void TBit_array::set(const char* numbers)
|
|
{
|
|
TToken_string s(numbers, ' ');
|
|
for (const char* n = s.get(0); n; n = s.get())
|
|
if (isdigit(*n)) set(atol(n));
|
|
}
|
|
|
|
|
|
void TBit_array::print_on(ostream& out) const
|
|
{
|
|
const long last = _size<<3;
|
|
for (long i = 1; i < last; i++)
|
|
if (operator[](i)) out << ' ' << i;
|
|
}
|
|
|
|
|