Fixes to lists so an empty constructor is not needed + reenable debugging

git-svn-id: https://tesseract-ocr.googlecode.com/svn/trunk@207 d0cd1f9f-072b-0410-8dd7-cf729c803f20
This commit is contained in:
theraysmith 2008-12-30 18:15:44 +00:00
parent 04c462007f
commit 51ed03368d
23 changed files with 613 additions and 472 deletions

View File

@ -177,7 +177,7 @@ void fix_fuzzy_space_list( //space explorer
dump_words (current_perm, current_score, 2, improved);
if (current_score > best_score) {
best_perm.clear();
best_perm.deep_copy (&current_perm);
best_perm.deep_copy(&current_perm, &WERD_RES::deep_copy);
best_score = current_score;
improved = TRUE;
}
@ -312,7 +312,8 @@ inT16 eval_word_spacing(WERD_RES_LIST &word_res_list) {
}
if (fixsp_prefer_joined_1s) {
/* Add 1 to total score for every joined 1 regardless of context and rejtn */
/* Add 1 to total score for every joined 1 regardless of context and
rejtn */
for (i = 0, prev_char_1 = FALSE; i < word_len; i++) {
current_char_1 = word->best_choice->string ()[i] == '1';
@ -709,7 +710,7 @@ void fix_noisy_space_list(WERD_RES_LIST &best_perm, ROW *row) {
dump_words (current_perm, current_score, 2, improved);
if (current_score > best_score) {
best_perm.clear();
best_perm.deep_copy (&current_perm);
best_perm.deep_copy(&current_perm, &WERD_RES::deep_copy);
best_score = current_score;
improved = TRUE;
}

View File

@ -92,7 +92,7 @@ WERD_CHOICE *recog_word( //recog one owrd
ASSERT_HOST (word_choice->lengths ().length () == blob_choices->length ());
/* Copy any reject blobs into the outword */
outword->rej_blob_list ()->deep_copy (word->rej_blob_list ());
outword->rej_blob_list()->deep_copy(word->rej_blob_list(), &PBLOB::deep_copy);
if (tessedit_override_permuter) {
/* Override the permuter type if a straight dictionary check disagrees. */

View File

@ -160,32 +160,42 @@ C_OUTLINE::C_OUTLINE( //constructor
pos += srcline->step (stepindex);
destpos = pos;
destpos.rotate (rotation);
if (destpos.x () != prevpos.x () || destpos.y () != prevpos.y ()) {
// printf("%i %i %i %i ", destpos.x(), destpos.y(), pos.x(), pos.y());
while (destpos.x () != prevpos.x () || destpos.y () != prevpos.y ()) {
dir = DIR128 (FCOORD (destpos - prevpos));
dir += 64; //turn to step style
new_step = dir.get_dir ();
// printf(" %i\n", new_step);
if (new_step & 31) {
set_step(destindex++, dir + round1);
prevpos += step(destindex - 1);
if (destindex < 2
|| ((dirdiff =
step_dir (destindex - 1) - step_dir (destindex - 2)) !=
-64 && dirdiff != 64))
-64 && dirdiff != 64)) {
set_step(destindex++, dir + round2);
else {
prevpos += step(destindex - 1);
} else {
prevpos -= step(destindex - 1);
destindex--;
prevpos -= step(destindex - 1);
set_step(destindex - 1, dir + round2);
set_step(destindex++, dir + round1);
prevpos += step(destindex - 1);
}
}
else {
set_step(destindex++, dir);
if (destindex >= 2
&&
prevpos += step(destindex - 1);
}
while (destindex >= 2 &&
((dirdiff =
step_dir (destindex - 1) - step_dir (destindex - 2)) ==
-64 || dirdiff == 64))
step_dir (destindex - 1) - step_dir (destindex - 2)) == -64 ||
dirdiff == 64)) {
prevpos -= step(destindex - 1);
prevpos -= step(destindex - 2);
destindex -= 2; // Forget u turn
}
prevpos = destpos;
//ASSERT_HOST(prevpos.x() == destpos.x() && prevpos.y() == destpos.y());
new_box = TBOX (destpos, destpos);
box += new_box;
}
@ -243,6 +253,23 @@ inT32 C_OUTLINE::area() { //winding number
return total;
}
/**********************************************************************
* C_OUTLINE::perimeter
*
* Compute the perimeter of the outline and its first level children.
**********************************************************************/
inT32 C_OUTLINE::perimeter() {
inT32 total_steps; // Return value.
C_OUTLINE_IT it = child();
total_steps = pathlength();
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward())
total_steps += it.data()->pathlength(); // Add perimeters of children.
return total_steps;
}
/**********************************************************************
* C_OUTLINE::outer_area
@ -570,6 +597,10 @@ void C_OUTLINE::plot( //draw it
pos = start; //current position
window->Pen(colour);
if (stepcount == 0) {
window->Rectangle(box.left(), box.top(), box.right(), box.bottom());
return;
}
window->SetCursor(pos.x(), pos.y());
stepindex = 0;
@ -610,6 +641,10 @@ const C_OUTLINE & source //from this
memmove (steps, source.steps, step_mem());
if (!children.empty ())
children.clear ();
children.deep_copy (&source.children);
children.deep_copy(&source.children, &deep_copy);
return *this;
}
ICOORD C_OUTLINE::chain_step(int chaindir) {
return step_coords[chaindir % 4];
}

View File

@ -117,6 +117,7 @@ class DLLSYM C_OUTLINE:public ELIST_LINK
}
inT32 area(); //return area
inT32 perimeter(); // Total perimeter of self and 1st level children.
inT32 outer_area(); //return area
inT32 count_transitions( //count maxima
inT32 threshold); //size threshold
@ -159,8 +160,17 @@ class DLLSYM C_OUTLINE:public ELIST_LINK
}
//assignment
make_serialise (C_OUTLINE) C_OUTLINE & operator= (
const C_OUTLINE & source); //from this
make_serialise (C_OUTLINE)
C_OUTLINE& operator=(const C_OUTLINE& source);
static C_OUTLINE* deep_copy(const C_OUTLINE* src) {
C_OUTLINE* outline = new C_OUTLINE;
*outline = *src;
return outline;
}
static ICOORD chain_step(int chaindir);
private:
int step_mem() const { return (stepcount+3) / 4; }

View File

@ -216,15 +216,17 @@ class WERD_RES:public ELIST_LINK //word result
part_of_combo = FALSE;
reject_spaces = FALSE;
}
WERD_RES( //constr from WERD_RES
const WERD_RES &source) {
WERD_RES(const WERD_RES &source) {
*this = source; //see operator=
}
~WERD_RES (); //destructor
WERD_RES & operator= ( //assign word res
const WERD_RES & source); //from this
WERD_RES& operator=(const WERD_RES& source); //from this
static WERD_RES* deep_copy(const WERD_RES* src) {
return new WERD_RES(*src);
}
void copy_on( //copy blobs onto word
WERD_RES *word_res) { //from this word

View File

@ -144,7 +144,9 @@ void PDBLK::plot( //draw outline
window->Pen(colour);
window->TextAttributes("Times", BLOCK_LABEL_HEIGHT, false, false, false);
if (!leftside.empty ()) {
if (hand_poly != NULL) {
hand_poly->plot(window, colour, serial);
} else if (!leftside.empty ()) {
startpt = *(it.data ()); //bottom left corner
// tprintf("Block %d bottom left is (%d,%d)\n",
// serial,startpt.x(),startpt.y());
@ -179,10 +181,7 @@ void PDBLK::plot( //draw outline
}
//close boundary
window->DrawTo(endpt.x(), endpt.y());
if (hand_block != NULL)
hand_block->plot (window, colour, serial);
}
}
#endif
@ -227,8 +226,8 @@ const PDBLK & source //from this
leftside.clear ();
if (!rightside.empty ())
rightside.clear ();
leftside.deep_copy (&source.leftside);
rightside.deep_copy (&source.rightside);
leftside.deep_copy(&source.leftside, &ICOORDELT::deep_copy);
rightside.deep_copy(&source.rightside, &ICOORDELT::deep_copy);
box = source.box;
return *this;
}

View File

@ -128,6 +128,14 @@ class DLLSYM ICOORD //integer coordinate
void rotate( //rotate
const FCOORD& vec); //by vector
// Setup for iterating over the pixels in a vector by the well-known
// Bresenham rendering algorithm.
// Starting with major/2 in the accumulator, on each step move by
// major_step, and then add minor to the accumulator. When
// accumulator >= major subtract major and also move by minor_step.
void setup_render(ICOORD* major_step, ICOORD* minor_step,
int* major, int* minor);
void serialise_asc( //serialise to ascii
FILE *f);
void de_serialise_asc( //serialise from ascii
@ -170,8 +178,15 @@ class DLLSYM ICOORDELT:public ELIST_LINK, public ICOORD
}
//serialise to ascii
make_serialise (ICOORDELT) void serialise_asc (
FILE * f);
make_serialise(ICOORDELT)
static ICOORDELT* deep_copy(const ICOORDELT* src) {
ICOORDELT* elt = new ICOORDELT;
*elt = *src;
return elt;
}
void serialise_asc(FILE * f);
void de_serialise_asc( //serialise from ascii
FILE *f);

View File

@ -326,6 +326,19 @@ void PBLOB::scale( // scale blob
it.data ()->scale (vec); // scale each outline
}
/**********************************************************************
* PBLOB::rotate
*
* Rotate PBLOB 90 deg anti
**********************************************************************/
void PBLOB::rotate() { // Rotate 90 deg anti
OUTLINE_IT it(&outlines); // iterator
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
it.data ()->rotate (FCOORD(0.0f, 1.0f)); // rotate each outline
}
}
/**********************************************************************
* PBLOB::plot

View File

@ -61,6 +61,7 @@ class PBLOB:public ELIST_LINK
const float f); // by multiplier
void scale( // scale blob
const FCOORD vec); // by FLOAT vector
void rotate(); // Rotate 90 deg anti
void prep_serialise() { //set ptrs to counts
outlines.prep_serialise ();
@ -77,15 +78,22 @@ class PBLOB:public ELIST_LINK
}
//assignment
make_serialise (PBLOB) PBLOB & operator= (
const PBLOB & source) { //from this
make_serialise(PBLOB)
PBLOB& operator=(const PBLOB & source) {
if (!outlines.empty ())
outlines.clear ();
outlines.deep_copy (&source.outlines);
outlines.deep_copy(&source.outlines, &OUTLINE::deep_copy);
return *this;
}
static PBLOB* deep_copy(const PBLOB* src) {
PBLOB* blob = new PBLOB;
*blob = *src;
return blob;
}
private:
OUTLINE_LIST outlines; //master elements
};

View File

@ -43,8 +43,14 @@ class POLYPT:public ELIST2_LINK
void de_dump( //read external bits
FILE *) {
}
static POLYPT* deep_copy(const POLYPT* src) {
return new POLYPT(*src);
}
//really simple
make_serialise (POLYPT) FCOORD pos;
make_serialise (POLYPT)
FCOORD pos;
FCOORD vec; //vector to next
};

View File

@ -360,6 +360,35 @@ void OUTLINE::scale( // scale OUTLINE
child_it.data ()->scale (vector);
}
/**********************************************************************
* OUTLINE::rotate
*
* Rotate OUTLINE by the given vector
**********************************************************************/
void OUTLINE::rotate(
const FCOORD vector //by fcoord
) {
//child outline itertr
OUTLINE_IT child_it(&children);
POLYPT_IT poly_it(&outline); //outline point itertr
POLYPT *pt;
box.rotate(vector);
start.rotate(vector);
for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) {
pt = poly_it.data ();
pt->pos.rotate(vector);
pt->vec.rotate(vector);
}
for (child_it.mark_cycle_pt (); !child_it.cycled_list ();
child_it.forward ())
//scale child outlines
child_it.data ()->rotate(vector);
}
/**********************************************************************
* OUTLINE::plot
@ -404,9 +433,9 @@ const OUTLINE & source //from this
start = source.start;
if (!outline.empty())
outline.clear();
outline.deep_copy (&source.outline);
outline.deep_copy(&source.outline, &POLYPT::deep_copy);
if (!children.empty())
children.clear();
children.deep_copy (&source.children);
children.deep_copy(&source.children, &OUTLINE::deep_copy);
return *this;
}

View File

@ -81,6 +81,9 @@ class OUTLINE:public ELIST_LINK
void scale( // scale outline
const FCOORD vec); // by FLOAT vector
void rotate( // rotate outline
const FCOORD vector); // by fcoord
void plot( //draw one
ScrollView* window, //window to draw in
ScrollView::Color colour); //colour to draw it
@ -103,8 +106,15 @@ class OUTLINE:public ELIST_LINK
}
//assignment
make_serialise (OUTLINE) OUTLINE & operator= (
const OUTLINE & source); //from this
make_serialise(OUTLINE)
OUTLINE& operator=(const OUTLINE& source);
static OUTLINE* deep_copy(const OUTLINE* src) {
OUTLINE* outline = new OUTLINE;
*outline = *src;
return outline;
}
private:
TBOX box; //boudning box

View File

@ -141,7 +141,8 @@ const WERD_CHOICE & second //second word
second_word_blob_choices_it.forward()) {
BLOB_CHOICE_LIST* blob_choices_copy = new BLOB_CHOICE_LIST();
blob_choices_copy->deep_copy(second_word_blob_choices_it.data());
blob_choices_copy->deep_copy(second_word_blob_choices_it.data(),
&BLOB_CHOICE::deep_copy);
this_word_blob_choices_it.add_after_then_move(blob_choices_copy);
}
@ -180,7 +181,8 @@ WERD_CHOICE& WERD_CHOICE::operator= (const WERD_CHOICE& source) {
source_word_blob_choices_it.forward()) {
BLOB_CHOICE_LIST* blob_choices_copy = new BLOB_CHOICE_LIST();
blob_choices_copy->deep_copy(source_word_blob_choices_it.data());
blob_choices_copy->deep_copy(source_word_blob_choices_it.data(),
&BLOB_CHOICE::deep_copy);
this_word_blob_choices_it.add_after_then_move(blob_choices_copy);
}

View File

@ -64,6 +64,12 @@ class BLOB_CHOICE:public ELIST_LINK
blob_script = newscript;
}
static BLOB_CHOICE* deep_copy(const BLOB_CHOICE* src) {
BLOB_CHOICE* choice = new BLOB_CHOICE;
*choice = *src;
return choice;
}
const char* const unichar() const { //access function
return blob_unichar;
}

View File

@ -200,6 +200,25 @@ inT32 C_BLOB::area() { //area
return total;
}
/**********************************************************************
* C_BLOB::perimeter
*
* Return the perimeter of the top and 2nd level outlines.
**********************************************************************/
inT32 C_BLOB::perimeter() {
C_OUTLINE *outline; // current outline
C_OUTLINE_IT it = &outlines; // outlines of blob
inT32 total; // total perimeter
total = 0;
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
outline = it.data();
total += outline->perimeter();
}
return total;
}
/**********************************************************************
* C_BLOB::outer_area

View File

@ -37,6 +37,7 @@ class C_BLOB:public ELIST_LINK
TBOX bounding_box(); //compute bounding box
inT32 area(); //compute area
inT32 perimeter(); // Total perimeter of outlines and 1st level children.
inT32 outer_area(); //compute area
inT32 count_transitions( //count maxima
inT32 threshold); //size threshold
@ -64,15 +65,21 @@ class C_BLOB:public ELIST_LINK
}
//assignment
make_serialise (C_BLOB) C_BLOB & operator= (
const C_BLOB & source) { //from this
make_serialise(C_BLOB)
C_BLOB& operator= (const C_BLOB & source) {
if (!outlines.empty ())
outlines.clear();
outlines.deep_copy (&source.outlines);
outlines.deep_copy(&source.outlines, &C_OUTLINE::deep_copy);
return *this;
}
static C_BLOB* deep_copy(const C_BLOB* src) {
C_BLOB* blob = new C_BLOB;
*blob = *src;
return blob;
}
private:
C_OUTLINE_LIST outlines; //master elements
};

View File

@ -404,24 +404,15 @@ void WERD::copy_on( //copy blobs
// blob iterator
PBLOB_LIST blobs;
blobs.deep_copy ((PBLOB_LIST *) (&other->cblobs));
blobs.deep_copy(reinterpret_cast<PBLOB_LIST*>(&other->cblobs),
&PBLOB::deep_copy);
blob_it.move_to_last();
blob_it.add_list_after(&blobs);
}
// else if (flags.bit(W_LINEARC))
// {
// LARC_BLOB_IT larc_blob_it( (LARC_BLOB_LIST*)&cblobs );
// LARC_BLOB_LIST larc_blobs;
// larc_blobs.deep_copy((LARC_BLOB_LIST*)(&other->cblobs));
// larc_blob_it.move_to_last();
// larc_blob_it.add_list_after( &larc_blobs );
// }
else {
} else {
C_BLOB_IT c_blob_it(&cblobs);
C_BLOB_LIST c_blobs;
c_blobs.deep_copy (&other->cblobs);
c_blobs.deep_copy(&other->cblobs, &C_BLOB::deep_copy);
c_blob_it.move_to_last ();
c_blob_it.add_list_after (&c_blobs);
}
@ -429,7 +420,7 @@ void WERD::copy_on( //copy blobs
C_BLOB_IT rej_c_blob_it(&rej_cblobs);
C_BLOB_LIST new_rej_c_blobs;
new_rej_c_blobs.deep_copy (&other->rej_cblobs);
new_rej_c_blobs.deep_copy(&other->rej_cblobs, &C_BLOB::deep_copy);
rej_c_blob_it.move_to_last ();
rej_c_blob_it.add_list_after (&new_rej_c_blobs);
}
@ -890,17 +881,7 @@ void WERD::plot_rej_blobs( //draw it
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
it.data ()->plot (window, ScrollView::GREY, ScrollView::GREY);
}
}
// else if (flags.bit(W_LINEARC))
// {
// LARC_BLOB_IT it=(LARC_BLOB_LIST*)(&rej_cblobs);
// for ( it.mark_cycle_pt(); !it.cycled_list(); it.forward() )
// {
// it.data()->plot(window,solid,GREY,solid ? BLACK : GREY);
// }
// }
else {
} else {
C_BLOB_IT it = &rej_cblobs; //blobs of WERD
for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
@ -944,34 +925,23 @@ const WERD & source //from this
correct = source.correct;
if (flags.bit (W_POLYGON)) {
if (!cblobs.empty())
((PBLOB_LIST *) (&cblobs))->clear ();
((PBLOB_LIST *) (&cblobs))->deep_copy ((PBLOB_LIST *) (&source.cblobs));
reinterpret_cast<PBLOB_LIST*>(&cblobs)->clear();
reinterpret_cast<PBLOB_LIST*>(&cblobs)->deep_copy(
reinterpret_cast<const PBLOB_LIST*>(&source.cblobs), &PBLOB::deep_copy);
if (!rej_cblobs.empty())
((PBLOB_LIST *) (&rej_cblobs))->clear ();
((PBLOB_LIST *) (&rej_cblobs))->deep_copy ((PBLOB_LIST *) (&source.
rej_cblobs));
}
// else if (flags.bit(W_LINEARC))
// {
// if ( !cblobs.empty() )
// ((LARC_BLOB_LIST*)(&cblobs))->clear();
// ((LARC_BLOB_LIST*)(&cblobs))->deep_copy(
// (LARC_BLOB_LIST*)(&source.cblobs));
// if ( !rej_cblobs.empty() )
// rej_cblobs.clear();
// rej_cblobs.deep_copy( &source.rej_cblobs );
// }
else {
reinterpret_cast<PBLOB_LIST*>(&rej_cblobs)->clear();
reinterpret_cast<PBLOB_LIST*>(&rej_cblobs)->deep_copy(
reinterpret_cast<const PBLOB_LIST*>(&source.rej_cblobs),
&PBLOB::deep_copy);
} else {
if (!cblobs.empty ())
cblobs.clear ();
cblobs.deep_copy (&source.cblobs);
cblobs.deep_copy(&source.cblobs, &C_BLOB::deep_copy);
if (!rej_cblobs.empty ())
rej_cblobs.clear ();
rej_cblobs.deep_copy (&source.rej_cblobs);
rej_cblobs.deep_copy(&source.rej_cblobs, &C_BLOB::deep_copy);
}
return *this;
}

View File

@ -44,7 +44,7 @@ void (*zapper) (void *)) { //ptr to zapper functn
CLIST_LINK *ptr;
CLIST_LINK *next;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST::internal_deep_clear", ABORT, NULL);
#endif
@ -76,7 +76,7 @@ void CLIST::shallow_clear() { //destroy all links
CLIST_LINK *ptr;
CLIST_LINK *next;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST::shallow_clear", ABORT, NULL);
#endif
@ -110,7 +110,7 @@ const CLIST * list) { //list being copied
CLIST_ITERATOR from_it ((CLIST *) list);
CLIST_ITERATOR to_it(this);
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST::internal_deep_copy", ABORT, NULL);
if (!list)
@ -142,7 +142,7 @@ void CLIST::assign_to_sublist( //to this list
const ERRCODE LIST_NOT_EMPTY =
"Destination list must be empty before extracting a sublist";
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST::assign_to_sublist", ABORT, NULL);
#endif
@ -164,7 +164,7 @@ inT32 CLIST::length() { //count elements
CLIST_ITERATOR it(this);
inT32 count = 0;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST::length", ABORT, NULL);
#endif
@ -191,7 +191,7 @@ const void *, const void *)) {
void **current;
inT32 i;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST::sort", ABORT, NULL);
#endif
@ -219,6 +219,41 @@ const void *, const void *)) {
free(base);
}
// Assuming list has been sorted already, insert new_data to
// keep the list sorted according to the same comparison function.
// Comparision function is the same as used by sort, i.e. uses double
// indirection. Time is O(1) to add to beginning or end.
// Time is linear to add pre-sorted items to an empty list.
// If unique, then don't add duplicate entries.
void CLIST::add_sorted(int comparator(const void*, const void*),
bool unique, void* new_data) {
// Check for adding at the end.
if (last == NULL || comparator(&last->data, &new_data) < 0) {
CLIST_LINK* new_element = new CLIST_LINK;
new_element->data = new_data;
if (last == NULL) {
new_element->next = new_element;
} else {
new_element->next = last->next;
last->next = new_element;
}
last = new_element;
} else if (!unique || last->data != new_data) {
// Need to use an iterator.
CLIST_ITERATOR it(this);
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
void* data = it.data();
if (data == new_data && unique)
return;
if (comparator(&data, &new_data) > 0)
break;
}
if (it.cycled_list())
it.add_to_end(new_data);
else
it.add_before_then_move(new_data);
}
}
/***********************************************************************
* CLIST::prep_serialise
@ -233,7 +268,7 @@ void CLIST::prep_serialise() {
CLIST_ITERATOR this_it(this);
inT32 count = 0;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST::prep_serialise", ABORT, NULL);
#endif
@ -260,7 +295,7 @@ void
CLIST::internal_dump (FILE * f, void element_serialiser (FILE *, void *)) {
CLIST_ITERATOR this_it(this);
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST::internal_dump", ABORT, NULL);
#endif
@ -286,7 +321,7 @@ CLIST::internal_de_dump (FILE * f, void *element_de_serialiser (FILE *)) {
inT32 count = (ptrdiff_t) last;
CLIST_ITERATOR this_it;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST::internal_de_dump", ABORT, NULL);
#endif
@ -311,7 +346,7 @@ CLIST::internal_de_dump (FILE * f, void *element_de_serialiser (FILE *)) {
**********************************************************************/
void *CLIST_ITERATOR::forward() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::forward", ABORT, NULL);
if (!list)
@ -324,21 +359,21 @@ void *CLIST_ITERATOR::forward() {
//set previous
prev = current;
started_cycling = TRUE;
}
else {
// In case next is deleted by another iterator, get next from current.
current = current->next;
} else {
if (ex_current_was_cycle_pt)
cycle_pt = next;
}
current = next;
}
next = current->next;
#ifdef _DEBUG
#ifndef NDEBUG
if (!current)
NULL_DATA.error ("CLIST_ITERATOR::forward", ABORT, NULL);
if (!next)
NULL_NEXT.error ("CLIST_ITERATOR::forward", ABORT,
"This is: %i Current is: %i",
(int) this, (int) current);
"This is: %p Current is: %p", this, current);
#endif
return current->data;
}
@ -356,7 +391,7 @@ void *CLIST_ITERATOR::data_relative( //get data + or - ...
inT8 offset) { //offset from current
CLIST_LINK *ptr;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::data_relative", ABORT, NULL);
if (!list)
@ -373,7 +408,7 @@ void *CLIST_ITERATOR::data_relative( //get data + or - ...
else
for (ptr = current ? current : prev; offset-- > 0; ptr = ptr->next);
#ifdef _DEBUG
#ifndef NDEBUG
if (!ptr)
NULL_DATA.error ("CLIST_ITERATOR::data_relative", ABORT, NULL);
#endif
@ -391,7 +426,7 @@ void *CLIST_ITERATOR::data_relative( //get data + or - ...
**********************************************************************/
void *CLIST_ITERATOR::move_to_last() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::move_to_last", ABORT, NULL);
if (!list)
@ -425,7 +460,7 @@ void CLIST_ITERATOR::exchange( //positions of 2 link
CLIST_LINK *old_current;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::exchange", ABORT, NULL);
if (!list)
@ -524,7 +559,7 @@ CLIST_LINK *CLIST_ITERATOR::extract_sublist( //from
CLIST_LINK *end_of_new_list;
const ERRCODE BAD_SUBLIST = "Can't find sublist end point in original list";
#ifdef _DEBUG
#ifndef NDEBUG
const ERRCODE BAD_EXTRACTION_PTS =
"Can't extract sublist from points on different lists";
const ERRCODE DONT_EXTRACT_DELETED =

View File

@ -123,6 +123,15 @@ class DLLSYM CLIST
int comparator ( //comparison routine
const void *, const void *));
// Assuming list has been sorted already, insert new_data to
// keep the list sorted according to the same comparison function.
// Comparision function is the same as used by sort, i.e. uses double
// indirection. Time is O(1) to add to beginning or end.
// Time is linear to add pre-sorted items to an empty list.
// If unique, then don't add duplicate entries.
void add_sorted(int comparator(const void*, const void*),
bool unique, void* new_data);
void internal_dump ( //serialise each elem
FILE * f, //to this file
void element_serialiser ( //using this function
@ -198,7 +207,7 @@ class DLLSYM CLIST_ITERATOR
CLIST *list_to_add); //move to it 1st item
void *data() { //get current data
#ifdef _DEBUG
#ifndef NDEBUG
if (!list)
NO_LIST.error ("CLIST_ITERATOR::data", ABORT, NULL);
if (!current)
@ -221,7 +230,7 @@ class DLLSYM CLIST_ITERATOR
void mark_cycle_pt(); //remember current
BOOL8 empty() { //is list empty?
#ifdef _DEBUG
#ifndef NDEBUG
if (!list)
NO_LIST.error ("CLIST_ITERATOR::empty", ABORT, NULL);
#endif
@ -261,7 +270,7 @@ class DLLSYM CLIST_ITERATOR
inline void CLIST_ITERATOR::set_to_list( //change list
CLIST *list_to_iterate) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::set_to_list", ABORT, NULL);
if (!list_to_iterate)
@ -302,7 +311,7 @@ inline void CLIST_ITERATOR::add_after_then_move( // element to add
void *new_data) {
CLIST_LINK *new_element;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::add_after_then_move", ABORT, NULL);
if (!list)
@ -352,7 +361,7 @@ inline void CLIST_ITERATOR::add_after_stay_put( // element to add
void *new_data) {
CLIST_LINK *new_element;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::add_after_stay_put", ABORT, NULL);
if (!list)
@ -405,7 +414,7 @@ inline void CLIST_ITERATOR::add_before_then_move( // element to add
void *new_data) {
CLIST_LINK *new_element;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::add_before_then_move", ABORT, NULL);
if (!list)
@ -452,7 +461,7 @@ inline void CLIST_ITERATOR::add_before_stay_put( // element to add
void *new_data) {
CLIST_LINK *new_element;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::add_before_stay_put", ABORT, NULL);
if (!list)
@ -497,7 +506,7 @@ inline void CLIST_ITERATOR::add_before_stay_put( // element to add
**********************************************************************/
inline void CLIST_ITERATOR::add_list_after(CLIST *list_to_add) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::add_list_after", ABORT, NULL);
if (!list)
@ -547,7 +556,7 @@ inline void CLIST_ITERATOR::add_list_after(CLIST *list_to_add) {
**********************************************************************/
inline void CLIST_ITERATOR::add_list_before(CLIST *list_to_add) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::add_list_before", ABORT, NULL);
if (!list)
@ -597,7 +606,7 @@ inline void CLIST_ITERATOR::add_list_before(CLIST *list_to_add) {
inline void *CLIST_ITERATOR::extract() {
void *extracted_data;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::extract", ABORT, NULL);
if (!list)
@ -608,23 +617,21 @@ inline void *CLIST_ITERATOR::extract() {
ABORT, NULL);
#endif
if (list->singleton ()) //special case where
//we do need to
if (list->singleton()) {
// Special case where we do need to change the iterator.
prev = next = list->last = NULL;
// change the iterator
else {
} else {
prev->next = next; //remove from list
if (current == list->last) {
list->last = prev;
ex_current_was_last = TRUE;
}
else
} else {
ex_current_was_last = FALSE;
ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
}
}
// Always set ex_current_was_cycle_pt so an add/forward will work in a loop.
ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
extracted_data = current->data;
delete(current); //destroy CONS cell
current = NULL;
@ -640,7 +647,7 @@ inline void *CLIST_ITERATOR::extract() {
**********************************************************************/
inline void *CLIST_ITERATOR::move_to_first() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::move_to_first", ABORT, NULL);
if (!list)
@ -666,7 +673,7 @@ inline void *CLIST_ITERATOR::move_to_first() {
**********************************************************************/
inline void CLIST_ITERATOR::mark_cycle_pt() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::mark_cycle_pt", ABORT, NULL);
if (!list)
@ -689,7 +696,7 @@ inline void CLIST_ITERATOR::mark_cycle_pt() {
**********************************************************************/
inline BOOL8 CLIST_ITERATOR::at_first() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::at_first", ABORT, NULL);
if (!list)
@ -711,7 +718,7 @@ inline BOOL8 CLIST_ITERATOR::at_first() {
**********************************************************************/
inline BOOL8 CLIST_ITERATOR::at_last() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::at_last", ABORT, NULL);
if (!list)
@ -733,7 +740,7 @@ inline BOOL8 CLIST_ITERATOR::at_last() {
**********************************************************************/
inline BOOL8 CLIST_ITERATOR::cycled_list() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::cycled_list", ABORT, NULL);
if (!list)
@ -753,7 +760,7 @@ inline BOOL8 CLIST_ITERATOR::cycled_list() {
**********************************************************************/
inline inT32 CLIST_ITERATOR::length() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::length", ABORT, NULL);
if (!list)
@ -775,7 +782,7 @@ inline void
CLIST_ITERATOR::sort ( //sort elements
int comparator ( //comparison routine
const void *, const void *)) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::sort", ABORT, NULL);
if (!list)
@ -801,7 +808,7 @@ inline void CLIST_ITERATOR::add_to_end( // element to add
void *new_data) {
CLIST_LINK *new_element;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("CLIST_ITERATOR::add_to_end", ABORT, NULL);
if (!list)

View File

@ -70,7 +70,7 @@ void (*zapper) (ELIST_LINK *)) {
ELIST_LINK *ptr;
ELIST_LINK *next;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST::internal_clear", ABORT, NULL);
#endif
@ -87,36 +87,6 @@ void (*zapper) (ELIST_LINK *)) {
}
}
/***********************************************************************
* ELIST::internal_deep_copy
*
* Used during explict deep copy of a list. The "copier" function passed
* allows each element to be correctly deep copied (assuming that each class
* in the inheritance hierarchy does properly deep copies its members). The
* function passing technique is as for "internal_clear".
**********************************************************************/
void
//ptr to copier functn
ELIST::internal_deep_copy (ELIST_LINK * (*copier) (ELIST_LINK *),
const ELIST * list) { //list being copied
ELIST_ITERATOR from_it ((ELIST *) list);
ELIST_ITERATOR to_it(this);
#ifdef _DEBUG
if (!this)
NULL_OBJECT.error ("ELIST::internal_deep_copy", ABORT, NULL);
if (!list)
BAD_PARAMETER.error ("ELIST::internal_deep_copy", ABORT,
"source list is NULL");
#endif
for (from_it.mark_cycle_pt (); !from_it.cycled_list (); from_it.forward ())
to_it.add_after_then_move (copier (from_it.data ()));
}
/***********************************************************************
* ELIST::assign_to_sublist
*
@ -136,7 +106,7 @@ void ELIST::assign_to_sublist( //to this list
const ERRCODE LIST_NOT_EMPTY =
"Destination list must be empty before extracting a sublist";
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST::assign_to_sublist", ABORT, NULL);
#endif
@ -158,7 +128,7 @@ inT32 ELIST::length() { //count elements
ELIST_ITERATOR it(this);
inT32 count = 0;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST::length", ABORT, NULL);
#endif
@ -187,7 +157,7 @@ const void *, const void *)) {
ELIST_LINK **current;
inT32 i;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST::sort", ABORT, NULL);
#endif
@ -215,6 +185,36 @@ const void *, const void *)) {
free(base);
}
// Assuming list has been sorted already, insert new_link to
// keep the list sorted according to the same comparison function.
// Comparision function is the same as used by sort, i.e. uses double
// indirection. Time is O(1) to add to beginning or end.
// Time is linear to add pre-sorted items to an empty list.
void ELIST::add_sorted(int comparator(const void*, const void*),
ELIST_LINK* new_link) {
// Check for adding at the end.
if (last == NULL || comparator(&last, &new_link) < 0) {
if (last == NULL) {
new_link->next = new_link;
} else {
new_link->next = last->next;
last->next = new_link;
}
last = new_link;
} else {
// Need to use an iterator.
ELIST_ITERATOR it(this);
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
ELIST_LINK* link = it.data();
if (comparator(&link, &new_link) > 0)
break;
}
if (it.cycled_list())
it.add_to_end(new_link);
else
it.add_before_then_move(new_link);
}
}
/***********************************************************************
* ELIST::prep_serialise
@ -229,7 +229,7 @@ void ELIST::prep_serialise() {
ELIST_ITERATOR this_it(this);
inT32 count = 0;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST::prep_serialise", ABORT, NULL);
#endif
@ -257,7 +257,7 @@ ELIST::internal_dump (FILE * f,
void element_serialiser (FILE *, ELIST_LINK *)) {
ELIST_ITERATOR this_it(this);
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST::internal_dump", ABORT, NULL);
#endif
@ -285,7 +285,7 @@ ELIST_LINK * element_de_serialiser (FILE *)) {
ELIST_ITERATOR this_it;
ELIST_LINK *de_serialised_element;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST::internal_de_dump", ABORT, NULL);
#endif
@ -314,7 +314,7 @@ ELIST_LINK * element_de_serialiser (FILE *)) {
**********************************************************************/
ELIST_LINK *ELIST_ITERATOR::forward() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::forward", ABORT, NULL);
if (!list)
@ -327,21 +327,21 @@ ELIST_LINK *ELIST_ITERATOR::forward() {
//set previous
prev = current;
started_cycling = TRUE;
}
else {
// In case next is deleted by another iterator, get next from current.
current = current->next;
} else {
if (ex_current_was_cycle_pt)
cycle_pt = next;
}
current = next;
}
next = current->next;
#ifdef _DEBUG
#ifndef NDEBUG
if (!current)
NULL_DATA.error ("ELIST_ITERATOR::forward", ABORT, NULL);
if (!next)
NULL_NEXT.error ("ELIST_ITERATOR::forward", ABORT,
"This is: %i Current is: %i",
(int) this, (int) current);
"This is: %p Current is: %p", this, current);
#endif
return current;
}
@ -359,7 +359,7 @@ ELIST_LINK *ELIST_ITERATOR::data_relative( //get data + or - ...
inT8 offset) { //offset from current
ELIST_LINK *ptr;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::data_relative", ABORT, NULL);
if (!list)
@ -376,7 +376,7 @@ ELIST_LINK *ELIST_ITERATOR::data_relative( //get data + or - ...
else
for (ptr = current ? current : prev; offset-- > 0; ptr = ptr->next);
#ifdef _DEBUG
#ifndef NDEBUG
if (!ptr)
NULL_DATA.error ("ELIST_ITERATOR::data_relative", ABORT, NULL);
#endif
@ -394,7 +394,7 @@ ELIST_LINK *ELIST_ITERATOR::data_relative( //get data + or - ...
**********************************************************************/
ELIST_LINK *ELIST_ITERATOR::move_to_last() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::move_to_last", ABORT, NULL);
if (!list)
@ -425,7 +425,7 @@ void ELIST_ITERATOR::exchange( //positions of 2 link
ELIST_LINK *old_current;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::exchange", ABORT, NULL);
if (!list)
@ -520,7 +520,7 @@ void ELIST_ITERATOR::exchange( //positions of 2 link
ELIST_LINK *ELIST_ITERATOR::extract_sublist( //from this current
ELIST_ITERATOR *other_it) { //to other current
#ifdef _DEBUG
#ifndef NDEBUG
const ERRCODE BAD_EXTRACTION_PTS =
"Can't extract sublist from points on different lists";
const ERRCODE DONT_EXTRACT_DELETED =
@ -531,7 +531,7 @@ ELIST_LINK *ELIST_ITERATOR::extract_sublist( //from
ELIST_ITERATOR temp_it = *this;
ELIST_LINK *end_of_new_list;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::extract_sublist", ABORT, NULL);
if (!other_it)

View File

@ -168,6 +168,14 @@ class DLLSYM ELIST
int comparator ( //comparison routine
const void *, const void *));
// Assuming list has been sorted already, insert new_link to
// keep the list sorted according to the same comparison function.
// Comparision function is the same as used by sort, i.e. uses double
// indirection. Time is O(1) to add to beginning or end.
// Time is linear to add pre-sorted items to an empty list.
void add_sorted(int comparator(const void*, const void*),
ELIST_LINK* new_link);
void internal_dump ( //serialise each elem
FILE * f, //to this file
void element_serialiser ( //using this function
@ -244,7 +252,7 @@ class DLLSYM ELIST_ITERATOR
ELIST *list_to_add); //move to it 1st item
ELIST_LINK *data() { //get current data
#ifdef _DEBUG
#ifndef NDEBUG
if (!list)
NO_LIST.error ("ELIST_ITERATOR::data", ABORT, NULL);
if (!current)
@ -267,7 +275,7 @@ class DLLSYM ELIST_ITERATOR
void mark_cycle_pt(); //remember current
BOOL8 empty() { //is list empty?
#ifdef _DEBUG
#ifndef NDEBUG
if (!list)
NO_LIST.error ("ELIST_ITERATOR::empty", ABORT, NULL);
#endif
@ -307,7 +315,7 @@ class DLLSYM ELIST_ITERATOR
inline void ELIST_ITERATOR::set_to_list( //change list
ELIST *list_to_iterate) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::set_to_list", ABORT, NULL);
if (!list_to_iterate)
@ -346,7 +354,7 @@ inline ELIST_ITERATOR::ELIST_ITERATOR(ELIST *list_to_iterate) {
inline void ELIST_ITERATOR::add_after_then_move( // element to add
ELIST_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::add_after_then_move", ABORT, NULL);
if (!list)
@ -393,7 +401,7 @@ inline void ELIST_ITERATOR::add_after_then_move( // element to add
inline void ELIST_ITERATOR::add_after_stay_put( // element to add
ELIST_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::add_after_stay_put", ABORT, NULL);
if (!list)
@ -443,7 +451,7 @@ inline void ELIST_ITERATOR::add_after_stay_put( // element to add
inline void ELIST_ITERATOR::add_before_then_move( // element to add
ELIST_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::add_before_then_move", ABORT, NULL);
if (!list)
@ -487,7 +495,7 @@ inline void ELIST_ITERATOR::add_before_then_move( // element to add
inline void ELIST_ITERATOR::add_before_stay_put( // element to add
ELIST_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::add_before_stay_put", ABORT, NULL);
if (!list)
@ -531,7 +539,7 @@ inline void ELIST_ITERATOR::add_before_stay_put( // element to add
**********************************************************************/
inline void ELIST_ITERATOR::add_list_after(ELIST *list_to_add) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::add_list_after", ABORT, NULL);
if (!list)
@ -581,7 +589,7 @@ inline void ELIST_ITERATOR::add_list_after(ELIST *list_to_add) {
**********************************************************************/
inline void ELIST_ITERATOR::add_list_before(ELIST *list_to_add) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::add_list_before", ABORT, NULL);
if (!list)
@ -631,7 +639,7 @@ inline void ELIST_ITERATOR::add_list_before(ELIST *list_to_add) {
inline ELIST_LINK *ELIST_ITERATOR::extract() {
ELIST_LINK *extracted_link;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::extract", ABORT, NULL);
if (!list)
@ -642,23 +650,21 @@ inline ELIST_LINK *ELIST_ITERATOR::extract() {
ABORT, NULL);
#endif
if (list->singleton ()) //special case where
//we do need to
if (list->singleton()) {
// Special case where we do need to change the iterator.
prev = next = list->last = NULL;
// change the iterator
else {
} else {
prev->next = next; //remove from list
if (current == list->last) {
list->last = prev;
ex_current_was_last = TRUE;
}
else
} else {
ex_current_was_last = FALSE;
ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
}
}
// Always set ex_current_was_cycle_pt so an add/forward will work in a loop.
ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
extracted_link = current;
extracted_link->next = NULL; //for safety
current = NULL;
@ -674,7 +680,7 @@ inline ELIST_LINK *ELIST_ITERATOR::extract() {
**********************************************************************/
inline ELIST_LINK *ELIST_ITERATOR::move_to_first() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::move_to_first", ABORT, NULL);
if (!list)
@ -700,7 +706,7 @@ inline ELIST_LINK *ELIST_ITERATOR::move_to_first() {
**********************************************************************/
inline void ELIST_ITERATOR::mark_cycle_pt() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::mark_cycle_pt", ABORT, NULL);
if (!list)
@ -723,7 +729,7 @@ inline void ELIST_ITERATOR::mark_cycle_pt() {
**********************************************************************/
inline BOOL8 ELIST_ITERATOR::at_first() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::at_first", ABORT, NULL);
if (!list)
@ -745,7 +751,7 @@ inline BOOL8 ELIST_ITERATOR::at_first() {
**********************************************************************/
inline BOOL8 ELIST_ITERATOR::at_last() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::at_last", ABORT, NULL);
if (!list)
@ -767,7 +773,7 @@ inline BOOL8 ELIST_ITERATOR::at_last() {
**********************************************************************/
inline BOOL8 ELIST_ITERATOR::cycled_list() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::cycled_list", ABORT, NULL);
if (!list)
@ -787,7 +793,7 @@ inline BOOL8 ELIST_ITERATOR::cycled_list() {
**********************************************************************/
inline inT32 ELIST_ITERATOR::length() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::length", ABORT, NULL);
if (!list)
@ -809,7 +815,7 @@ inline void
ELIST_ITERATOR::sort ( //sort elements
int comparator ( //comparison routine
const void *, const void *)) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::sort", ABORT, NULL);
if (!list)
@ -833,7 +839,7 @@ const void *, const void *)) {
inline void ELIST_ITERATOR::add_to_end( // element to add
ELIST_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST_ITERATOR::add_to_end", ABORT, NULL);
if (!list)
@ -886,7 +892,6 @@ will NOT work correctly for classes derived from this.
The macros generate:
- An element deletion function: CLASSNAME##_zapper
- An element copier function: CLASSNAME##_copier
- An element serialiser function" CLASSNAME##_serialiser
- An element de-serialiser function" CLASSNAME##_de_serialiser
- An E_LIST subclass: CLASSNAME##_LIST
@ -914,11 +919,7 @@ ELISTIZEH_S has some additional bits thrown in the gaps.
#define ELISTIZEH_A(CLASSNAME) \
\
extern DLLSYM void CLASSNAME##_zapper( /*delete a link*/ \
ELIST_LINK* link); /*link to delete*/ \
\
extern DLLSYM ELIST_LINK* CLASSNAME##_copier( /*deep copy a link*/ \
ELIST_LINK* old_element); /*source link */
extern DLLSYM void CLASSNAME##_zapper(ELIST_LINK* link);
#define ELISTIZEH_B(CLASSNAME) \
\
@ -946,9 +947,9 @@ void clear() /* delete elements */\
~CLASSNAME##_LIST() /* destructor */ \
{ clear(); } \
\
void deep_copy( /* become a deep */ \
const CLASSNAME##_LIST* list) /* copy of src list*/\
{ ELIST::internal_deep_copy( &CLASSNAME##_copier, list ); } \
/* Become a deep copy of src_list*/ \
void deep_copy(const CLASSNAME##_LIST* src_list, \
CLASSNAME* (*copier)(const CLASSNAME*)); \
\
void operator=( /* prevent assign */ \
const CLASSNAME##_LIST&) \
@ -1053,39 +1054,26 @@ ELISTIZE_S is a simple extension to ELISTIZE
* though we dont use a virtual destructor function. \
**********************************************************************/ \
\
DLLSYM void CLASSNAME##_zapper( /*delete a link*/ \
ELIST_LINK* link) /*link to delete*/ \
{ \
delete (CLASSNAME *) link; \
DLLSYM void CLASSNAME##_zapper(ELIST_LINK* link) { \
delete reinterpret_cast<CLASSNAME*>(link); \
} \
\
/*********************************************************************** \
* CLASSNAME##_copier \
* \
* A function which can generate a new, deep copy of a CLASSNAME element. \
* This is passed to the generic deep copy list member function so that when \
* a list is copied the elements on the list are properly copied from the \
* base class, even though we dont use a virtual function. \
**********************************************************************/ \
/* Become a deep copy of src_list*/ \
void CLASSNAME##_LIST::deep_copy(const CLASSNAME##_LIST* src_list, \
CLASSNAME* (*copier)(const CLASSNAME*)) { \
\
DLLSYM ELIST_LINK* CLASSNAME##_copier( /*deep copy a link*/ \
ELIST_LINK* old_element) /*source link*/ \
{ \
CLASSNAME* new_element; \
CLASSNAME##_IT from_it(const_cast<CLASSNAME##_LIST*>(src_list)); \
CLASSNAME##_IT to_it(this); \
\
new_element = new CLASSNAME; \
*new_element = *reinterpret_cast<CLASSNAME*>(old_element); \
return (ELIST_LINK*) new_element; \
for (from_it.mark_cycle_pt(); !from_it.cycled_list(); from_it.forward()) \
to_it.add_after_then_move((*copier)(from_it.data())); \
}
#define ELISTIZE_S(CLASSNAME) \
\
ELISTIZE(CLASSNAME) \
\
void CLASSNAME##_LIST::serialise_asc( \
/*dump to ascii*/ \
FILE* f) \
{ \
void CLASSNAME##_LIST::serialise_asc(FILE* f) { \
CLASSNAME##_IT it(this); \
\
serialise_INT32(f, length()); \
@ -1093,18 +1081,14 @@ ELISTIZE( CLASSNAME )
it.data()->serialise_asc(f); /*serialise the list*/ \
} \
\
void CLASSNAME##_LIST::de_serialise_asc( \
/*de-dump from ascii*/\
FILE* f) \
{ \
void CLASSNAME##_LIST::de_serialise_asc(FILE* f) { \
inT32 len; /*length to retrive*/ \
CLASSNAME##_IT it; \
CLASSNAME* new_elt = NULL; /*list element*/ \
\
len = de_serialise_INT32(f); \
it.set_to_list(this); \
for (;len>0;len--) \
{ \
for (; len > 0; len--) { \
new_elt = new CLASSNAME; \
new_elt->de_serialise_asc(f); \
it.add_to_end(new_elt); /*put on the list*/ \
@ -1121,11 +1105,8 @@ ELISTIZE( CLASSNAME )
* serialised the elements on the list are properly serialised. \
**********************************************************************/ \
\
DLLSYM void CLASSNAME##_serialiser( \
FILE* f, \
ELIST_LINK* element) \
{ \
((CLASSNAME*) element)->serialise( f ); \
DLLSYM void CLASSNAME##_serialiser(FILE* f, ELIST_LINK* element) { \
reinterpret_cast<CLASSNAME*>(element)->serialise(f); \
} \
\
\
@ -1138,9 +1119,7 @@ ELIST_LINK* element)
* is de-serialised the elements on the list are properly de-serialised. \
**********************************************************************/ \
\
DLLSYM ELIST_LINK* CLASSNAME##_de_serialiser( \
FILE* f) \
{ \
DLLSYM ELIST_LINK* CLASSNAME##_de_serialiser(FILE* f) { \
return (ELIST_LINK*) CLASSNAME::de_serialise(f); \
}
#endif

View File

@ -46,7 +46,7 @@ void (*zapper) (ELIST2_LINK *)) {
ELIST2_LINK *ptr;
ELIST2_LINK *next;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2::internal_clear", ABORT, NULL);
#endif
@ -63,36 +63,6 @@ void (*zapper) (ELIST2_LINK *)) {
}
}
/***********************************************************************
* ELIST2::internal_deep_copy
*
* Used during explict deep copy of a list. The "copier" function passed
* allows each element to be correctly deep copied (assuming that each class
* in the inheritance hierarchy does properly deep copies its members). The
* function passing technique is as for "internal_clear".
**********************************************************************/
void
//ptr to copier functn
ELIST2::internal_deep_copy (ELIST2_LINK * (*copier) (ELIST2_LINK *),
const ELIST2 * list) { //list being copied
ELIST2_ITERATOR from_it ((ELIST2 *) list);
ELIST2_ITERATOR to_it(this);
#ifdef _DEBUG
if (!this)
NULL_OBJECT.error ("ELIST2::internal_deep_copy", ABORT, NULL);
if (!list)
BAD_PARAMETER.error ("ELIST2::internal_deep_copy", ABORT,
"source list is NULL");
#endif
for (from_it.mark_cycle_pt (); !from_it.cycled_list (); from_it.forward ())
to_it.add_after_then_move (copier (from_it.data ()));
}
/***********************************************************************
* ELIST2::assign_to_sublist
*
@ -112,7 +82,7 @@ void ELIST2::assign_to_sublist( //to this list
const ERRCODE LIST_NOT_EMPTY =
"Destination list must be empty before extracting a sublist";
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2::assign_to_sublist", ABORT, NULL);
#endif
@ -134,7 +104,7 @@ inT32 ELIST2::length() { //count elements
ELIST2_ITERATOR it(this);
inT32 count = 0;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2::length", ABORT, NULL);
#endif
@ -163,7 +133,7 @@ const void *, const void *)) {
ELIST2_LINK **current;
inT32 i;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2::sort", ABORT, NULL);
#endif
@ -191,6 +161,39 @@ const void *, const void *)) {
free(base);
}
// Assuming list has been sorted already, insert new_link to
// keep the list sorted according to the same comparison function.
// Comparision function is the same as used by sort, i.e. uses double
// indirection. Time is O(1) to add to beginning or end.
// Time is linear to add pre-sorted items to an empty list.
void ELIST2::add_sorted(int comparator(const void*, const void*),
ELIST2_LINK* new_link) {
// Check for adding at the end.
if (last == NULL || comparator(&last, &new_link) < 0) {
if (last == NULL) {
new_link->next = new_link;
new_link->prev = new_link;
} else {
new_link->next = last->next;
new_link->prev = last;
last->next = new_link;
new_link->next->prev = new_link;
}
last = new_link;
} else {
// Need to use an iterator.
ELIST2_ITERATOR it(this);
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
ELIST2_LINK* link = it.data();
if (comparator(&link, &new_link) > 0)
break;
}
if (it.cycled_list())
it.add_to_end(new_link);
else
it.add_before_then_move(new_link);
}
}
/***********************************************************************
* ELIST2::prep_serialise
@ -205,7 +208,7 @@ void ELIST2::prep_serialise() {
ELIST2_ITERATOR this_it(this);
inT32 count = 0;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2::prep_serialise", ABORT, NULL);
#endif
@ -233,7 +236,7 @@ ELIST2::internal_dump (FILE * f,
void element_serialiser (FILE *, ELIST2_LINK *)) {
ELIST2_ITERATOR this_it(this);
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2::internal_dump", ABORT, NULL);
#endif
@ -261,7 +264,7 @@ ELIST2_LINK * element_de_serialiser (FILE *)) {
ELIST2_ITERATOR this_it;
ELIST2_LINK *de_serialised_element;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2::internal_de_dump", ABORT, NULL);
#endif
@ -292,7 +295,7 @@ ELIST2_LINK * element_de_serialiser (FILE *)) {
**********************************************************************/
ELIST2_LINK *ELIST2_ITERATOR::forward() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::forward", ABORT, NULL);
if (!list)
@ -305,21 +308,22 @@ ELIST2_LINK *ELIST2_ITERATOR::forward() {
//set previous
prev = current;
started_cycling = TRUE;
// In case next is deleted by another iterator, get it from the current.
current = current->next;
}
else {
if (ex_current_was_cycle_pt)
cycle_pt = next;
}
current = next;
}
next = current->next;
#ifdef _DEBUG
#ifndef NDEBUG
if (!current)
NULL_DATA.error ("ELIST2_ITERATOR::forward", ABORT, NULL);
if (!next)
NULL_NEXT.error ("ELIST2_ITERATOR::forward", ABORT,
"This is: %i Current is: %i",
(int) this, (int) current);
"This is: %p Current is: %p", this, current);
#endif
return current;
}
@ -333,7 +337,7 @@ ELIST2_LINK *ELIST2_ITERATOR::forward() {
**********************************************************************/
ELIST2_LINK *ELIST2_ITERATOR::backward() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::backward", ABORT, NULL);
if (!list)
@ -346,21 +350,21 @@ ELIST2_LINK *ELIST2_ITERATOR::backward() {
//set previous
next = current;
started_cycling = TRUE;
}
else {
// In case prev is deleted by another iterator, get it from current.
current = current->prev;
} else {
if (ex_current_was_cycle_pt)
cycle_pt = prev;
}
current = prev;
}
prev = current->prev;
#ifdef _DEBUG
#ifndef NDEBUG
if (!current)
NULL_DATA.error ("ELIST2_ITERATOR::backward", ABORT, NULL);
if (!prev)
NULL_PREV.error ("ELIST2_ITERATOR::backward", ABORT,
"This is: %i Current is: %i",
(int) this, (int) current);
"This is: %p Current is: %p", this, current);
#endif
return current;
}
@ -377,7 +381,7 @@ ELIST2_LINK *ELIST2_ITERATOR::data_relative( //get data + or - ..
inT8 offset) { //offset from current
ELIST2_LINK *ptr;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::data_relative", ABORT, NULL);
if (!list)
@ -391,7 +395,7 @@ ELIST2_LINK *ELIST2_ITERATOR::data_relative( //get data + or - ..
else
for (ptr = current ? current : prev; offset-- > 0; ptr = ptr->next);
#ifdef _DEBUG
#ifndef NDEBUG
if (!ptr)
NULL_DATA.error ("ELIST2_ITERATOR::data_relative", ABORT, NULL);
#endif
@ -417,7 +421,7 @@ void ELIST2_ITERATOR::exchange( //positions of 2 li
ELIST2_LINK *old_current;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::exchange", ABORT, NULL);
if (!list)
@ -524,7 +528,7 @@ void ELIST2_ITERATOR::exchange( //positions of 2 li
ELIST2_LINK *ELIST2_ITERATOR::extract_sublist( //from this current
ELIST2_ITERATOR *other_it) { //to other current
#ifdef _DEBUG
#ifndef NDEBUG
const ERRCODE BAD_EXTRACTION_PTS =
"Can't extract sublist from points on different lists";
const ERRCODE DONT_EXTRACT_DELETED =
@ -535,7 +539,7 @@ ELIST2_LINK *ELIST2_ITERATOR::extract_sublist( //fr
ELIST2_ITERATOR temp_it = *this;
ELIST2_LINK *end_of_new_list;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::extract_sublist", ABORT, NULL);
if (!other_it)

View File

@ -137,6 +137,14 @@ class DLLSYM ELIST2
int comparator ( //comparison routine
const void *, const void *));
// Assuming list has been sorted already, insert new_link to
// keep the list sorted according to the same comparison function.
// Comparision function is the same as used by sort, i.e. uses double
// indirection. Time is O(1) to add to beginning or end.
// Time is linear to add pre-sorted items to an empty list.
void add_sorted(int comparator(const void*, const void*),
ELIST2_LINK* new_link);
void internal_dump ( //serialise each elem
FILE * f, //to this file
void element_serialiser ( //using this function
@ -213,7 +221,7 @@ class DLLSYM ELIST2_ITERATOR
ELIST2 *list_to_add); //move to it 1st item
ELIST2_LINK *data() { //get current data
#ifdef _DEBUG
#ifndef NDEBUG
if (!current)
NULL_DATA.error ("ELIST2_ITERATOR::data", ABORT, NULL);
if (!list)
@ -239,7 +247,7 @@ class DLLSYM ELIST2_ITERATOR
void mark_cycle_pt(); //remember current
BOOL8 empty() { //is list empty?
#ifdef _DEBUG
#ifndef NDEBUG
if (!list)
NO_LIST.error ("ELIST2_ITERATOR::empty", ABORT, NULL);
#endif
@ -279,7 +287,7 @@ class DLLSYM ELIST2_ITERATOR
inline void ELIST2_ITERATOR::set_to_list( //change list
ELIST2 *list_to_iterate) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::set_to_list", ABORT, NULL);
if (!list_to_iterate)
@ -318,7 +326,7 @@ inline ELIST2_ITERATOR::ELIST2_ITERATOR(ELIST2 *list_to_iterate) {
inline void ELIST2_ITERATOR::add_after_then_move( // element to add
ELIST2_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::add_after_then_move", ABORT, NULL);
if (!list)
@ -369,7 +377,7 @@ inline void ELIST2_ITERATOR::add_after_then_move( // element to add
inline void ELIST2_ITERATOR::add_after_stay_put( // element to add
ELIST2_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::add_after_stay_put", ABORT, NULL);
if (!list)
@ -423,7 +431,7 @@ inline void ELIST2_ITERATOR::add_after_stay_put( // element to add
inline void ELIST2_ITERATOR::add_before_then_move( // element to add
ELIST2_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::add_before_then_move", ABORT, NULL);
if (!list)
@ -472,7 +480,7 @@ inline void ELIST2_ITERATOR::add_before_then_move( // element to add
inline void ELIST2_ITERATOR::add_before_stay_put( // element to add
ELIST2_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::add_before_stay_put", ABORT, NULL);
if (!list)
@ -521,7 +529,7 @@ inline void ELIST2_ITERATOR::add_before_stay_put( // element to add
**********************************************************************/
inline void ELIST2_ITERATOR::add_list_after(ELIST2 *list_to_add) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::add_list_after", ABORT, NULL);
if (!list)
@ -575,7 +583,7 @@ inline void ELIST2_ITERATOR::add_list_after(ELIST2 *list_to_add) {
**********************************************************************/
inline void ELIST2_ITERATOR::add_list_before(ELIST2 *list_to_add) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::add_list_before", ABORT, NULL);
if (!list)
@ -629,7 +637,7 @@ inline void ELIST2_ITERATOR::add_list_before(ELIST2 *list_to_add) {
inline ELIST2_LINK *ELIST2_ITERATOR::extract() {
ELIST2_LINK *extracted_link;
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::extract", ABORT, NULL);
if (!list)
@ -640,24 +648,22 @@ inline ELIST2_LINK *ELIST2_ITERATOR::extract() {
ABORT, NULL);
#endif
if (list->singleton ()) //special case where
//we do need to
if (list->singleton()) {
// Special case where we do need to change the iterator.
prev = next = list->last = NULL;
//change the iterator
else {
} else {
prev->next = next; //remove from list
next->prev = prev;
if (current == list->last) {
list->last = prev;
ex_current_was_last = TRUE;
}
else
} else {
ex_current_was_last = FALSE;
ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
}
}
// Always set ex_current_was_cycle_pt so an add/forward will work in a loop.
ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
extracted_link = current;
extracted_link->next = NULL; //for safety
extracted_link->prev = NULL; //for safety
@ -674,7 +680,7 @@ inline ELIST2_LINK *ELIST2_ITERATOR::extract() {
**********************************************************************/
inline ELIST2_LINK *ELIST2_ITERATOR::move_to_first() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::move_to_first", ABORT, NULL);
if (!list)
@ -696,7 +702,7 @@ inline ELIST2_LINK *ELIST2_ITERATOR::move_to_first() {
**********************************************************************/
inline ELIST2_LINK *ELIST2_ITERATOR::move_to_last() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::move_to_last", ABORT, NULL);
if (!list)
@ -722,7 +728,7 @@ inline ELIST2_LINK *ELIST2_ITERATOR::move_to_last() {
**********************************************************************/
inline void ELIST2_ITERATOR::mark_cycle_pt() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::mark_cycle_pt", ABORT, NULL);
if (!list)
@ -745,7 +751,7 @@ inline void ELIST2_ITERATOR::mark_cycle_pt() {
**********************************************************************/
inline BOOL8 ELIST2_ITERATOR::at_first() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::at_first", ABORT, NULL);
if (!list)
@ -767,7 +773,7 @@ inline BOOL8 ELIST2_ITERATOR::at_first() {
**********************************************************************/
inline BOOL8 ELIST2_ITERATOR::at_last() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::at_last", ABORT, NULL);
if (!list)
@ -789,7 +795,7 @@ inline BOOL8 ELIST2_ITERATOR::at_last() {
**********************************************************************/
inline BOOL8 ELIST2_ITERATOR::cycled_list() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::cycled_list", ABORT, NULL);
if (!list)
@ -809,7 +815,7 @@ inline BOOL8 ELIST2_ITERATOR::cycled_list() {
**********************************************************************/
inline inT32 ELIST2_ITERATOR::length() {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::length", ABORT, NULL);
if (!list)
@ -831,7 +837,7 @@ inline void
ELIST2_ITERATOR::sort ( //sort elements
int comparator ( //comparison routine
const void *, const void *)) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::sort", ABORT, NULL);
if (!list)
@ -855,7 +861,7 @@ const void *, const void *)) {
inline void ELIST2_ITERATOR::add_to_end( // element to add
ELIST2_LINK *new_element) {
#ifdef _DEBUG
#ifndef NDEBUG
if (!this)
NULL_OBJECT.error ("ELIST2_ITERATOR::add_to_end", ABORT, NULL);
if (!list)
@ -906,8 +912,6 @@ will NOT work correctly for classes derived from this.
The macro generates:
- An element deletion function: CLASSNAME##_zapper
- An element copier function:
CLASSNAME##_copier
- An element serialiser function" CLASSNAME##_serialiser
- An element de-serialiser function" CLASSNAME##_de_serialiser
- An E_LIST2 subclass: CLASSNAME##_LIST
@ -937,10 +941,7 @@ ELIST2IZEH_S has some additional bits thrown in the gaps.
#define ELIST2IZEH_A( CLASSNAME ) \
\
extern DLLSYM void CLASSNAME##_zapper( /*delete a link*/ \
ELIST2_LINK* link); /*link to delete*/ \
\
extern DLLSYM ELIST2_LINK* CLASSNAME##_copier( /*deep copy a link*/ \
ELIST2_LINK* old_element); /*source link */
ELIST2_LINK* link); /*link to delete*/
#define ELIST2IZEH_B( CLASSNAME ) \
\
@ -968,9 +969,9 @@ void clear() /* delete elements */\
~CLASSNAME##_LIST() /* destructor */ \
{ clear(); } \
\
void deep_copy( /* become a deep */ \
const CLASSNAME##_LIST* list) /* copy of src list*/\
{ ELIST2::internal_deep_copy( &CLASSNAME##_copier, list ); } \
/* Become a deep copy of src_list*/ \
void deep_copy(const CLASSNAME##_LIST* src_list, \
CLASSNAME* (*copier)(const CLASSNAME*)); \
\
void operator=( /* prevent assign */ \
const CLASSNAME##_LIST&) \
@ -1079,25 +1080,15 @@ ELIST2_LINK* link) /*link to delete*/ \
delete (CLASSNAME *) link; \
} \
\
/* Become a deep copy of src_list*/ \
void CLASSNAME##_LIST::deep_copy(const CLASSNAME##_LIST* src_list, \
CLASSNAME* (*copier)(const CLASSNAME*)) { \
\
CLASSNAME##_IT from_it(const_cast<CLASSNAME##_LIST*>(src_list)); \
CLASSNAME##_IT to_it(this); \
\
/*********************************************************************** \
* CLASSNAME##_copier \
* \
* A function which can generate a new, deep copy of a CLASSNAME element. \
* This is passed to the generic deep copy list member function so that when \
* a list is copied the elements on the list are properly copied from the \
* base class, even though we dont use a virtual function. \
**********************************************************************/ \
\
DLLSYM ELIST2_LINK* CLASSNAME##_copier( /*deep copy a link*/ \
ELIST2_LINK* old_element) /*source link*/ \
{ \
CLASSNAME* new_element; \
\
new_element = new CLASSNAME; \
*new_element = *((CLASSNAME*) old_element); \
return (ELIST2_LINK*) new_element; \
for (from_it.mark_cycle_pt(); !from_it.cycled_list(); from_it.forward()) \
to_it.add_after_then_move((*copier)(from_it.data())); \
}
#define ELIST2IZE_S(CLASSNAME) \
@ -1112,15 +1103,10 @@ ELIST2IZE( CLASSNAME ) \
* serialised the elements on the list are properly serialised. \
**********************************************************************/ \
\
DLLSYM void CLASSNAME##_serialiser( \
FILE* f, \
ELIST2_LINK* element) \
{ \
((CLASSNAME*) element)->serialise( f ); \
DLLSYM void CLASSNAME##_serialiser(FILE* f, ELIST2_LINK* element) { \
reinterpret_cast<CLASSNAME*>(element)->serialise(f); \
} \
\
\
\
/*********************************************************************** \
* CLASSNAME##_de_serialiser \
* \
@ -1129,9 +1115,7 @@ ELIST2_LINK* element) \
* is de-serialised the elements on the list are properly de-serialised. \
**********************************************************************/ \
\
DLLSYM ELIST2_LINK* CLASSNAME##_de_serialiser( \
FILE* f) \
{ \
return (ELIST2_LINK*) CLASSNAME::de_serialise( f ); \
DLLSYM ELIST2_LINK* CLASSNAME##_de_serialiser(FILE* f) { \
return reinterpret_cast<ELIST2_LINK*>(CLASSNAME::de_serialise(f)); \
}
#endif