assoc.cpp Stessa roba object.h Aggiunti distruttori virtuali printapp.cpp Sostituito == -1 con < 0 nei metodi set/get_cursor relation.cpp Riportate modifiche suggerite da Angelo string.* Aggiunti distruttori virtuali git-svn-id: svn://10.65.10.50/trunk@3740 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			778 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			778 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <ctype.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #include <strings.h>
 | |
| 
 | |
| void TContainer::for_each( OPERATION_FUNCTION op )
 | |
| {
 | |
|   TObject* curr = first_item();
 | |
|   while(curr)
 | |
|   {
 | |
|     op(*curr);
 | |
|     curr = succ_item();
 | |
|   } 
 | |
| }
 | |
| 
 | |
| void TContainer::for_each_that( OPERATION_FUNCTION op, CONDITION_FUNCTION match )
 | |
| {
 | |
|   TObject* curr =  first_that( match );
 | |
|   while( curr )
 | |
|   {
 | |
|     op( *curr );
 | |
|     curr = succ_that( );
 | |
|   } 
 | |
| }
 | |
| 
 | |
| TObject* TContainer::first_that( CONDITION_FUNCTION match )
 | |
| {
 | |
|   _last_condition = match;
 | |
|   if( _last_condition )
 | |
|   {
 | |
|     TObject* curr = first_item( );
 | |
|     while( curr && !_last_condition( *curr ) )
 | |
|       curr = succ_item( );
 | |
|     return curr;      
 | |
|   }
 | |
|   else
 | |
|     return first_item( );  
 | |
| }
 | |
| 
 | |
| TObject* TContainer::last_that( CONDITION_FUNCTION match )
 | |
| {
 | |
|   _last_condition = match;
 | |
|   if( _last_condition )
 | |
|   {
 | |
|     TObject* curr = last_item( );
 | |
|     while( curr && !_last_condition( *curr ) )
 | |
|       curr = pred_item( );
 | |
|     return curr;      
 | |
|   }
 | |
|   else
 | |
|     return last_item( );  
 | |
| }
 | |
| 
 | |
| TObject* TContainer::succ_that( )
 | |
| {
 | |
|   if( _last_condition )
 | |
|   {
 | |
|     TObject* curr = succ_item( );
 | |
|     while( curr && !_last_condition( *curr ) )
 | |
|       curr = succ_item( );
 | |
|     return curr;      
 | |
|   }
 | |
|   else
 | |
|     return succ_item( );
 | |
| }
 | |
| 
 | |
| TObject* TContainer::pred_that( )
 | |
| {
 | |
|   if( _last_condition )
 | |
|   {
 | |
|     TObject* curr = pred_item( );
 | |
|     while( curr && !_last_condition( *curr ) )
 | |
|       curr = pred_item( );
 | |
|     return curr;      
 | |
|   }
 | |
|   else
 | |
|     return pred_item( );
 | |
| }
 | |
| 
 | |
| long TContainer::count( CONDITION_FUNCTION match )
 | |
| {
 | |
|   long c = 0;
 | |
|   TObject* curr = first_item( );
 | |
|   while( curr )
 | |
|     if( match( *curr ) )
 | |
|       c++;
 | |
|   return c;    
 | |
| }
 | |
| 
 | |
| TObject* TArray::first_item( )
 | |
| {
 | |
|   _scanindex = first( ); 
 | |
|   return ( _scanindex == size( ) )?NULL:_data[ _scanindex ]; 
 | |
| };
 | |
| 
 | |
| TObject* TArray::last_item( )
 | |
| { 
 | |
|   _scanindex = last( ); 
 | |
|   return ( _scanindex == -1 )?NULL:_data[ _scanindex ]; 
 | |
| };
 | |
| 
 | |
| TObject* TArray::succ_item( )
 | |
| { 
 | |
|   _scanindex = succ( _scanindex ); 
 | |
|   return ( _scanindex == size( ))?NULL:_data[ _scanindex ]; 
 | |
| };
 | |
| 
 | |
| TObject* TArray::pred_item( )
 | |
| { 
 | |
|   _scanindex = pred( _scanindex ); 
 | |
|   return ( _scanindex == -1)?NULL:_data[ _scanindex ]; 
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Modifica la dimensione dell'array.
 | |
| void TArray::resize(
 | |
|   int arraysize) // @parm Indica la nuova dimensione che deve assumere l'array.
 | |
| 
 | |
|   // @comm Alloca la memoria necessaria per contentere i dati della nuova
 | |
|   //       dimensione inizializzando a NULL tutti i nuovi elementi aggiunti
 | |
|   //       all'array lasciando inalterati, sia in posizione che in
 | |
|   //       contenuto gli elementi gia' presenti.
 | |
|   //       <nl>Nel caso si cerchi di diminuire la dimensione viene dato un
 | |
|   //       messaggio di errore.
 | |
| 
 | |
| {
 | |
|   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;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Rimuove uno o tutti (default) gli elementi
 | |
| // @rdesc Ritorna uno dei seguenti parametri:
 | |
| //
 | |
| // @flag TRUE | Se l'operazione e' riuscita con successo
 | |
| // @flag FALSE | Se il numero di elementi e' rimasto invariato
 | |
| bool TArray::destroy(
 | |
|   int index, // @parm Numero dell'elemento da eliminare (default -1)
 | |
|   bool pack) // @parm Se true richiama la funzione <mf TArray::pack> per compattare gli elementi dell'array (default FALSE)
 | |
| 
 | |
|   // @comm Permette la rimozione di uno (index > 0 ) o di tutti (default) gli
 | |
|   //       elementi dell'array assegnandone il valore NULL.
 | |
|   //       <nl>Nel caso il parametro pack sia TRUE permette di rendere contigui
 | |
|   //       tutti gli elementi diversi da NULL tramite la chiamata alla funzione
 | |
|   //       <mf TArray::pack>.
 | |
|   
 | |
| {
 | |
|   const int old = _items;
 | |
| 
 | |
|   if (index < 0)
 | |
|   {
 | |
|     for (int i = size()-1; i >= 0; i--) if (_data[i] != NULL)
 | |
|     {
 | |
|       delete _data[i];
 | |
|       _data[i] = NULL;
 | |
|     }
 | |
|     _items = _next = 0;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     TObject* o = remove(index, pack);
 | |
|     if (o) delete o;
 | |
|   }
 | |
| 
 | |
|   return _items < old;
 | |
| }
 | |
| 
 | |
| 
 | |
| TArray::TArray(int arraysize)   
 | |
|       : _size(0), _items(0), _next(0), _data(NULL)
 | |
| {
 | |
|   if (arraysize) 
 | |
|     resize(arraysize);
 | |
| }
 | |
| 
 | |
| TArray::TArray() 
 | |
|       : _size(0), _items(0), _next(0), _data(NULL)
 | |
| {
 | |
| }
 | |
| 
 | |
| TArray::TArray(const TArray& a) 
 | |
|       : _size(0), _items(0), _next(0), _data(NULL)
 | |
| {
 | |
|   (*this) = a;
 | |
| }              
 | |
| 
 | |
| TArray& TArray::operator= (const TArray& a)
 | |
| {
 | |
|   destroy();
 | |
|   if (size() < a.size()) 
 | |
|     resize(a.size());
 | |
|   for (int i = a.size()-1; i >= 0; i--) 
 | |
|   {
 | |
|     const TObject* o = a.objptr(i);
 | |
|     if (o != NULL) _data[i] = o->dup();
 | |
|   }  
 | |
|   _items = ( int )a.items();
 | |
|   _next = ( int )a._next;  
 | |
|   
 | |
|   return *this;
 | |
| }              
 | |
| 
 | |
| TArray::~TArray()
 | |
| {
 | |
|   if (ok())
 | |
|   {
 | |
|     destroy();
 | |
|     delete _data;
 | |
|   }
 | |
| }
 | |
| 
 | |
| const char* TArray::class_name() const
 | |
| {
 | |
|   return "Array";
 | |
| }
 | |
| 
 | |
| 
 | |
| word TArray::class_id() const
 | |
| {
 | |
|   return CLASS_ARRAY;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Stampa un array
 | |
| void TArray::print_on(
 | |
|   ostream& out) const // @parm indica l'output sul quale reindirizzare la stampa (funzione standard del C++)
 | |
| 
 | |
|   // @comm Permette di stampare sull'output passato come parametro il contenuto
 | |
|   //       dell'array, preceduto dal numero dell'elemetno a cui si riferisce.
 | |
|   //       <nl>Nel caso vi siano degli elementi vuoti (valore = NULL) viene
 | |
|   //       stampato il valore (null).
 | |
| 
 | |
| {
 | |
|   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;
 | |
|   }
 | |
| }
 | |
|     
 | |
| // @doc EXTERNAL
 | |
|     
 | |
| // @mfunc Controlla se si tratta di un oggetto valido
 | |
| //
 | |
| // @rdesc Ritorna uno dei seguenti parametri:
 | |
| // @flag TRUE | Se l'array contiene degli elementi
 | |
| // @flag FALSE | Se l'array e' vuoto
 | |
| bool TArray::ok() const
 | |
| 
 | |
| // @comm Controlla se la dimensione dell'array e' uguale a 0 e se esistono
 | |
| //       degli elementi diversi da NULL
 | |
| 
 | |
| {
 | |
|   return(size() != 0 && (_data != NULL));
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Aggiunge un oggetto ad un array.
 | |
| //
 | |
| // @rdesc La funzione ritorna la posizione nella quale e' stato aggiunto
 | |
| //        l'oggetto.
 | |
| int TArray::add(
 | |
|   TObject *object, // @parm Oggetto da aggiungere nell'array
 | |
|   int index)       // @parm Posizione in cui aggiungere l'oggetto
 | |
|   // @parm TObject | &object | Oggetto da aggiungere nell'array. L'oggetto viene duplicato
 | |
| 
 | |
|   // @syntax add(TObject* object,int index);
 | |
|   // @syntax add(TObject& object,int index);
 | |
|   //
 | |
|   // @comm Nel caso venga passata una posizione minore di 0 l'elemento viene aggiunto
 | |
|   //       in coda all'array, diversamente viene l'elemento presente viene
 | |
|   //       sostitito con l'oggetto passato nei prametri.
 | |
|   //       <nl>Se e' stato passato un indice minore della dimensione dell'array,
 | |
|   //       viene aumentata automaticamente la dimensione dell'array stesso tramite
 | |
|   //       la chiamata alla funzione <mf TArray::resize>.
 | |
|   //       <nl><nl>ATTENZIONE: Nel caso si passi l'oggetto per indirizzo deve
 | |
|   //       essere definita la funzione <mf TObject::dup>.
 | |
|   //
 | |
|   // @xref <mf TArray::insert>
 | |
| {
 | |
|   if (index < 0) for (index = _next; index < size() && _data[index]; index++);
 | |
|   
 | |
|   if (index >= size()) resize(int(3L*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++;
 | |
|     _next = index+1;
 | |
|   }  
 | |
|   else
 | |
|   { 
 | |
|     if (index < _next)
 | |
|       _next = index;
 | |
|   }
 | |
|   return index;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Inserisce un elemento dell'array nella posizione index
 | |
| //
 | |
| // @rdesc La funzione ritorna la posizione nella quale e' stato inserito l'oggetto.
 | |
| int TArray::insert(
 | |
|   TObject *object, // @parm Oggetto da inserire nell'array
 | |
|   int index)       // @parm Posizione in cui inserire l'oggetto
 | |
|   // @parm TObject | &object | Oggetto da inserire nell'array. L'oggetto viene duplicato
 | |
| 
 | |
|   // @syntax insert(TObject* object, int index);
 | |
|   // @syntax insert(TObject& object, int index);
 | |
|   //
 | |
|   // @comm Nel caso l'elemento della posizione passata sia diverso da NULL vengono
 | |
|   //       spostati di una posizione tutti gli elementi presenti nell'array.
 | |
|   //       La dimensione dell'array viene automaticamente aumentata nel caso
 | |
|   //       la stessa non sia sufficiente a contenere il nuovo oggetto.
 | |
|   //       <nl><nl>ATTENZIONE: Nel caso si passi l'oggetto per indirizzo deve
 | |
|   //       essere definita la funzione <mf TObject::dup>.
 | |
|   //
 | |
|   // @xref <mf TArray::add>
 | |
| {
 | |
|   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);
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Elimina l'elemento nella posizione index dell'array
 | |
| //
 | |
| // @rdesc Ritorna l'elemento dell'array eliminato senza farne la delete
 | |
| TObject* TArray::remove(
 | |
|   int index,   // @parm Indica la posizione dell'elemento da eliminare
 | |
|   bool dopack) // @parm Indica se si vuole richiamare la funzione
 | |
|   //       <mf TArray::pack> (default FALSE) per spostare gli elementi successivi dell'array
 | |
| 
 | |
|   
 | |
| {     
 | |
|   CHECKD(index >= 0, "Can't remove array item ", index);
 | |
| 
 | |
|   TObject* o = objptr(index);
 | |
|   if (o)
 | |
|   {
 | |
|     _data[index] = NULL;
 | |
|     _items--;
 | |
|     if (index < _next)
 | |
|       _next = index;
 | |
|   }
 | |
|   if (dopack && index < size()) 
 | |
|   {                                 
 | |
|     const int last = size()-1;
 | |
|     for (int i = index ; i < last; i++)
 | |
|       _data[i] = _data[i+1];
 | |
|     _data[last] = NULL;  
 | |
|   }
 | |
|   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);
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Cerca il prossimo oggetto dell'array
 | |
| //
 | |
| // @rdesc Ritorna l'indice del prossimo elemento trovato o size() se non esiste
 | |
| int TArray::succ(int i) const
 | |
| 
 | |
| {               
 | |
|   CHECKD(i >= -1, "Bad array index ", i);
 | |
|   for (i++; i < size(); i++)
 | |
|     if (_data[i]) break;
 | |
|   return i;  
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Cerca il precedente oggetto dell'array
 | |
| //
 | |
| // @rdesc Ritorna l'indice dell'elemento precedente o -1 se non esiste
 | |
| int TArray::pred(int i) const
 | |
| 
 | |
| {
 | |
|   CHECKD(i <= size(), "Bad array index ", i);
 | |
|   for (i--; i >= 0; i--)
 | |
|     if (_data[i]) break;
 | |
|   return i;  
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Cerca il primo oggetto dell'array
 | |
| //
 | |
| // @rdesc Ritorna l'indice del primo elemento trovato o size() se l'array e' vuoto
 | |
| int TArray::first() const
 | |
| 
 | |
| {
 | |
|   return succ(-1);
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Cerca l'ultimo oggetto dell'array
 | |
| //
 | |
| // @rdesc Ritorna l'indice dell'ultimo elemento trovato o -1 se l'array e' vuoto
 | |
| int TArray::last() const
 | |
| 
 | |
| {
 | |
|   return pred(size());
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Rende contigui tutti gli elementi non nulli
 | |
| void TArray::pack()
 | |
| 
 | |
|   // @comm Riordina gli elementi dell'array facendo che tra di loro non ve ne
 | |
|   //       siano con valore uguale a NULL.
 | |
| {
 | |
|   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++;
 | |
|     }
 | |
|   }
 | |
|   _next = next;
 | |
| }
 | |
| 
 | |
| // @doc INTERNAL
 | |
| 
 | |
| // @func Funzione per permettere il confonto tra 2 oggetti.
 | |
| //
 | |
| // @rdesc Ritorna i seguenti valori
 | |
| //
 | |
| // @flag <gt>0 | se <p this> <gt> <p s>
 | |
| // @flag 0 | se <p this> == <p s>
 | |
| // @flag <lt>0 | se <p this> <lt> <p s>
 | |
| // @flag UNDEFINED | se l'ordine non e' definito  
 | |
| static int sortable_compare(
 | |
|   const TObject** o1, // @parm Primo oggetto da confrontare
 | |
|   const TObject** o2) // @parm Secondo oggetto da confrontare
 | |
| 
 | |
|   // @comm E' utilizzata dalla funzione <mf TArray::sort> come default per
 | |
|   //       stabilire il criteri di ordinamento degli oggetti passati.
 | |
| {                                             
 | |
|   if (o1 == o2)
 | |
|     return 0; // qsort a volte confronta un oggetto con se stesso: per cui ne approfitto!
 | |
| 
 | |
|   const TSortable* s1 = (const TSortable*)*o1;
 | |
|   const TSortable* s2 = (const TSortable*)*o2;
 | |
|   return s1->compare(*s2);
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Ordina i TObject secondo il criterio definito in <t COMPARE_FUNCTION>
 | |
| void TArray::sort(
 | |
|   COMPARE_FUNCTION compare) // @parm Funzione indicante il criterio di ordinamento (default TSortable)
 | |
| 
 | |
|   // @comm Nel caso non venga passata nessuna funzione che permetta di conforntare
 | |
|   //       i due oggetti viene utilizzato il criterio <c Tsortable>
 | |
| {
 | |
|   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));
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Copia l'array passato come parametro
 | |
| void TBit_array::copy(
 | |
|   const TBit_array& ba) // @parm Array da copiare
 | |
| 
 | |
|   // @comm Copia il contenuto dell'array passato come parametro.
 | |
| {
 | |
|   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%
 | |
| // @doc EXTERNAL
 | |
| //
 | |
| // @mfunc Modifica la dimensione dell'array.
 | |
| void TBit_array::resize(
 | |
|   word size) // @parm Indica la nuova dimensione che deve assumere l'array.
 | |
| 
 | |
|   // @comm Alloca la memoria necessaria per contentere i dati della nuova
 | |
|   //       dimensione inizializzando a NULL tutti i nuovi elementi aggiunti
 | |
|   //       all'array lasciando inalterati, sia in posizione che in
 | |
|   //       contenuto gli elementi gia' presenti.
 | |
| {
 | |
|   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 90%
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Ritorna il numero di 1 presenti nell'array
 | |
| //
 | |
| // @rdesc Numero di 1 trovati.
 | |
| long TBit_array::ones() const
 | |
| 
 | |
| // @comm Passa tutto l'array di bit e conta quanti degli elementi presenti sono
 | |
| //       settati ad 1.
 | |
| //
 | |
| // @xref <mf TBit_array::last_one> <mf TBit_array::first_one>
 | |
| {
 | |
|   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%
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Ritorna la posizione dell'ultimo 1 nell'array
 | |
| //
 | |
| // @rdesc Ritorna i seguenti valori:
 | |
| // @flag >0 | Posizione nella quale si trova l'ultimo 1
 | |
| // @flag -1 | Se non sono presenti bit settati ad 1
 | |
| 
 | |
| long TBit_array::last_one() const
 | |
| 
 | |
| // @comm Cerca all'interno dell'array di bit la posizione dell'ultimo bit
 | |
| //       settato ad 1
 | |
| //
 | |
| // @xref <mf TBit_array::first_one> <mf TBit_array::ones>
 | |
| {
 | |
|   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%
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Ritorna la posizione del primo 1 nell'array
 | |
| //
 | |
| // @rdesc Ritorna i seguenti valori:
 | |
| //
 | |
| // @flag >0 | Posizione nella quale si trova il primo 1
 | |
| // @flag -1 | Se non sono presenti bit settati ad 1
 | |
| 
 | |
| long TBit_array::first_one() const
 | |
| 
 | |
| // @comm Cerca all'interno dell'array di bit la posizione del primo bit
 | |
| //       settato ad 1
 | |
| //
 | |
| // @xref <mf TBit_array::last_one> <mf TBit_array::ones>
 | |
| {
 | |
|   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;
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| 
 | |
| // @mfunc Controlla se si tratta di un oggetto valido
 | |
| //
 | |
| // @rdesc Ritorna uno dei seguenti parametri:
 | |
| //
 | |
| // @flag TRUE | Se l'array contiene degli elementi
 | |
| // @flag FALSE | Se l'array e' vuoto
 | |
| bool TBit_array::ok() const
 | |
| 
 | |
| 
 | |
| // @comm Controlla se la dimensione dell'array e' maggiore di 0 e se esistono
 | |
| //       degli elementi diversi da NULL
 | |
| {
 | |
|   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));
 | |
| }
 | |
| 
 | |
| // @doc EXTERNAL
 | |
| //
 | |
| // @mfunc Stampa un array
 | |
| void TBit_array::print_on(
 | |
|   ostream& out) const // @parm Indica l'output sul quale reindirizzare la stampa (funzione standard del C++)
 | |
| 
 | |
|   // @comm Stampa tutti gli indici degli elementi diversi da 0
 | |
| {
 | |
|   const long last = _size<<3;
 | |
|   for (long i = 1; i < last; i++)
 | |
|     if (operator[](i)) out << ' ' << i;  
 | |
| }
 | |
| 
 | |
| 
 |