mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2025-01-18 14:41:36 +08:00
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:
parent
04c462007f
commit
51ed03368d
@ -176,8 +176,8 @@ void fix_fuzzy_space_list( //space explorer
|
||||
current_score = eval_word_spacing (current_perm);
|
||||
dump_words (current_perm, current_score, 2, improved);
|
||||
if (current_score > best_score) {
|
||||
best_perm.clear ();
|
||||
best_perm.deep_copy (¤t_perm);
|
||||
best_perm.clear();
|
||||
best_perm.deep_copy(¤t_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';
|
||||
@ -503,7 +504,7 @@ void dump_words(WERD_RES_LIST &perm, inT16 score, inT16 mode, BOOL8 improved) {
|
||||
for (word_res_it.mark_cycle_pt ();
|
||||
!word_res_it.cycled_list (); word_res_it.forward ()) {
|
||||
if (!word_res_it.data ()->part_of_combo)
|
||||
tprintf ("%s/%1d ",
|
||||
tprintf("%s/%1d ",
|
||||
word_res_it.data ()->best_choice->string ().
|
||||
string (),
|
||||
(int) word_res_it.data ()->best_choice->permuter ());
|
||||
@ -708,8 +709,8 @@ void fix_noisy_space_list(WERD_RES_LIST &best_perm, ROW *row) {
|
||||
current_score = fp_eval_word_spacing (current_perm);
|
||||
dump_words (current_perm, current_score, 2, improved);
|
||||
if (current_score > best_score) {
|
||||
best_perm.clear ();
|
||||
best_perm.deep_copy (¤t_perm);
|
||||
best_perm.clear();
|
||||
best_perm.deep_copy(¤t_perm, &WERD_RES::deep_copy);
|
||||
best_score = current_score;
|
||||
improved = TRUE;
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
&&
|
||||
((dirdiff =
|
||||
step_dir (destindex - 1) - step_dir (destindex - 2)) ==
|
||||
-64 || dirdiff == 64))
|
||||
destindex -= 2; // Forget u turn
|
||||
prevpos += step(destindex - 1);
|
||||
}
|
||||
prevpos = destpos;
|
||||
while (destindex >= 2 &&
|
||||
((dirdiff =
|
||||
step_dir (destindex - 1) - step_dir (destindex - 2)) == -64 ||
|
||||
dirdiff == 64)) {
|
||||
prevpos -= step(destindex - 1);
|
||||
prevpos -= step(destindex - 2);
|
||||
destindex -= 2; // Forget u turn
|
||||
}
|
||||
//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];
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
@ -402,11 +431,11 @@ const OUTLINE & source //from this
|
||||
) {
|
||||
box = source.box;
|
||||
start = source.start;
|
||||
if (!outline.empty ())
|
||||
outline.clear ();
|
||||
outline.deep_copy (&source.outline);
|
||||
if (!children.empty ())
|
||||
children.clear ();
|
||||
children.deep_copy (&source.children);
|
||||
if (!outline.empty())
|
||||
outline.clear();
|
||||
outline.deep_copy(&source.outline, &POLYPT::deep_copy);
|
||||
if (!children.empty())
|
||||
children.clear();
|
||||
children.deep_copy(&source.children, &OUTLINE::deep_copy);
|
||||
return *this;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -140,8 +140,9 @@ const WERD_CHOICE & second //second word
|
||||
!second_word_blob_choices_it.cycled_list();
|
||||
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_CHOICE_LIST* blob_choices_copy = new BLOB_CHOICE_LIST();
|
||||
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);
|
||||
}
|
||||
@ -179,8 +180,9 @@ WERD_CHOICE& WERD_CHOICE::operator= (const WERD_CHOICE& source) {
|
||||
!source_word_blob_choices_it.cycled_list();
|
||||
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_CHOICE_LIST* blob_choices_copy = new BLOB_CHOICE_LIST();
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
if (!outlines.empty ())
|
||||
outlines.clear ();
|
||||
make_serialise(C_BLOB)
|
||||
|
||||
outlines.deep_copy (&source.outlines);
|
||||
C_BLOB& operator= (const C_BLOB & source) {
|
||||
if (!outlines.empty ())
|
||||
outlines.clear();
|
||||
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
|
||||
};
|
||||
|
@ -404,24 +404,15 @@ void WERD::copy_on( //copy blobs
|
||||
// blob iterator
|
||||
PBLOB_LIST blobs;
|
||||
|
||||
blobs.deep_copy ((PBLOB_LIST *) (&other->cblobs));
|
||||
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 {
|
||||
blobs.deep_copy(reinterpret_cast<PBLOB_LIST*>(&other->cblobs),
|
||||
&PBLOB::deep_copy);
|
||||
blob_it.move_to_last();
|
||||
blob_it.add_list_after(&blobs);
|
||||
} 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 ()) {
|
||||
@ -943,35 +924,24 @@ const WERD & source //from this
|
||||
dummy = source.dummy;
|
||||
correct = source.correct;
|
||||
if (flags.bit (W_POLYGON)) {
|
||||
if (!cblobs.empty ())
|
||||
((PBLOB_LIST *) (&cblobs))->clear ();
|
||||
((PBLOB_LIST *) (&cblobs))->deep_copy ((PBLOB_LIST *) (&source.cblobs));
|
||||
if (!cblobs.empty())
|
||||
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 {
|
||||
if (!rej_cblobs.empty())
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
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 =
|
||||
|
@ -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)
|
||||
|
100
ccutil/elst.cpp
100
ccutil/elst.cpp
@ -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;
|
||||
}
|
||||
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)
|
||||
|
255
ccutil/elst.h
255
ccutil/elst.h
@ -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
|
||||
@ -912,16 +917,12 @@ ELISTIZEH_C. ELISTIZEH is simply a concatenation of these parts.
|
||||
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 */
|
||||
#define ELISTIZEH_A(CLASSNAME) \
|
||||
\
|
||||
extern DLLSYM void CLASSNAME##_zapper(ELIST_LINK* link);
|
||||
|
||||
#define ELISTIZEH_B( CLASSNAME ) \
|
||||
\
|
||||
#define ELISTIZEH_B(CLASSNAME) \
|
||||
\
|
||||
/*********************************************************************** \
|
||||
* CLASS - CLASSNAME##_LIST \
|
||||
* \
|
||||
@ -945,11 +946,11 @@ 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&) \
|
||||
{ DONT_ASSIGN_LISTS.error( QUOTE_IT( CLASSNAME##_LIST ), \
|
||||
@ -1042,105 +1043,83 @@ ELISTIZEH_C( CLASSNAME )
|
||||
ELISTIZE_S is a simple extension to ELISTIZE
|
||||
***********************************************************************/
|
||||
|
||||
#define ELISTIZE( CLASSNAME ) \
|
||||
\
|
||||
/*********************************************************************** \
|
||||
* CLASSNAME##_zapper \
|
||||
* \
|
||||
* A function which can delete a CLASSNAME element. This is passed to the \
|
||||
* generic clear list member function so that when a list is cleared the \
|
||||
* elements on the list are properly destroyed from the base class, even \
|
||||
* though we dont use a virtual destructor function. \
|
||||
**********************************************************************/ \
|
||||
\
|
||||
DLLSYM void CLASSNAME##_zapper( /*delete a link*/ \
|
||||
ELIST_LINK* link) /*link to delete*/ \
|
||||
{ \
|
||||
delete (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. \
|
||||
**********************************************************************/ \
|
||||
\
|
||||
DLLSYM ELIST_LINK* CLASSNAME##_copier( /*deep copy a link*/ \
|
||||
ELIST_LINK* old_element) /*source link*/ \
|
||||
{ \
|
||||
CLASSNAME* new_element; \
|
||||
\
|
||||
new_element = new CLASSNAME; \
|
||||
*new_element = *reinterpret_cast<CLASSNAME*>(old_element); \
|
||||
return (ELIST_LINK*) new_element; \
|
||||
#define ELISTIZE(CLASSNAME) \
|
||||
\
|
||||
/*********************************************************************** \
|
||||
* CLASSNAME##_zapper \
|
||||
* \
|
||||
* A function which can delete a CLASSNAME element. This is passed to the \
|
||||
* generic clear list member function so that when a list is cleared the \
|
||||
* elements on the list are properly destroyed from the base class, even \
|
||||
* though we dont use a virtual destructor function. \
|
||||
**********************************************************************/ \
|
||||
\
|
||||
DLLSYM void CLASSNAME##_zapper(ELIST_LINK* link) { \
|
||||
delete reinterpret_cast<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); \
|
||||
\
|
||||
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) \
|
||||
{ \
|
||||
CLASSNAME##_IT it(this); \
|
||||
\
|
||||
serialise_INT32(f,length()); \
|
||||
for (it.mark_cycle_pt();!it.cycled_list();it.forward()) \
|
||||
it.data()->serialise_asc(f); /*serialise the list*/\
|
||||
} \
|
||||
\
|
||||
void CLASSNAME##_LIST::de_serialise_asc( \
|
||||
/*de-dump from ascii*/\
|
||||
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--) \
|
||||
{ \
|
||||
new_elt=new CLASSNAME; \
|
||||
new_elt->de_serialise_asc(f); \
|
||||
it.add_to_end(new_elt); /*put on the list*/ \
|
||||
} \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
/*********************************************************************** \
|
||||
* CLASSNAME##_serialiser \
|
||||
* \
|
||||
* A function which can serialise an element \
|
||||
#define ELISTIZE_S(CLASSNAME) \
|
||||
\
|
||||
ELISTIZE(CLASSNAME) \
|
||||
\
|
||||
void CLASSNAME##_LIST::serialise_asc(FILE* f) { \
|
||||
CLASSNAME##_IT it(this); \
|
||||
\
|
||||
serialise_INT32(f, length()); \
|
||||
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) \
|
||||
it.data()->serialise_asc(f); /*serialise the list*/ \
|
||||
} \
|
||||
\
|
||||
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--) { \
|
||||
new_elt = new CLASSNAME; \
|
||||
new_elt->de_serialise_asc(f); \
|
||||
it.add_to_end(new_elt); /*put on the list*/ \
|
||||
} \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
/*********************************************************************** \
|
||||
* CLASSNAME##_serialiser \
|
||||
* \
|
||||
* A function which can serialise an element \
|
||||
* This is passed to the generic dump member function so that when a list is \
|
||||
* serialised the elements on the list are properly serialised. \
|
||||
**********************************************************************/ \
|
||||
\
|
||||
DLLSYM void CLASSNAME##_serialiser( \
|
||||
FILE* f, \
|
||||
ELIST_LINK* element) \
|
||||
{ \
|
||||
((CLASSNAME*) element)->serialise( f ); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
\
|
||||
/*********************************************************************** \
|
||||
* CLASSNAME##_de_serialiser \
|
||||
* \
|
||||
* A function which can de-serialise an element \
|
||||
* serialised the elements on the list are properly serialised. \
|
||||
**********************************************************************/ \
|
||||
\
|
||||
DLLSYM void CLASSNAME##_serialiser(FILE* f, ELIST_LINK* element) { \
|
||||
reinterpret_cast<CLASSNAME*>(element)->serialise(f); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
\
|
||||
/*********************************************************************** \
|
||||
* CLASSNAME##_de_serialiser \
|
||||
* \
|
||||
* A function which can de-serialise an element \
|
||||
* This is passed to the generic de-dump member function so that when a list \
|
||||
* is de-serialised the elements on the list are properly de-serialised. \
|
||||
**********************************************************************/ \
|
||||
\
|
||||
DLLSYM ELIST_LINK* CLASSNAME##_de_serialiser( \
|
||||
FILE* f) \
|
||||
{ \
|
||||
return (ELIST_LINK*) CLASSNAME::de_serialise( f ); \
|
||||
* is de-serialised the elements on the list are properly de-serialised. \
|
||||
**********************************************************************/ \
|
||||
\
|
||||
DLLSYM ELIST_LINK* CLASSNAME##_de_serialiser(FILE* f) { \
|
||||
return (ELIST_LINK*) CLASSNAME::de_serialise(f); \
|
||||
}
|
||||
#endif
|
||||
|
112
ccutil/elst2.cpp
112
ccutil/elst2.cpp
@ -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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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)
|
||||
|
140
ccutil/elst2.h
140
ccutil/elst2.h
@ -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 ) \
|
||||
\
|
||||
@ -967,11 +968,11 @@ 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&) \
|
||||
{ DONT_ASSIGN_LISTS.error( QUOTE_IT( CLASSNAME##_LIST ), \
|
||||
@ -1078,32 +1079,22 @@ ELIST2_LINK* link) /*link to delete*/ \
|
||||
{ \
|
||||
delete (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. \
|
||||
**********************************************************************/ \
|
||||
\
|
||||
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; \
|
||||
\
|
||||
/* 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); \
|
||||
\
|
||||
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 ) \
|
||||
\
|
||||
ELIST2IZE( CLASSNAME ) \
|
||||
\
|
||||
#define ELIST2IZE_S(CLASSNAME) \
|
||||
\
|
||||
ELIST2IZE(CLASSNAME) \
|
||||
\
|
||||
/*********************************************************************** \
|
||||
* CLASSNAME##_serialiser \
|
||||
* \
|
||||
@ -1111,16 +1102,11 @@ ELIST2IZE( CLASSNAME ) \
|
||||
* This is passed to the generic dump member function so that when a list is \
|
||||
* 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 \
|
||||
* \
|
||||
@ -1128,10 +1114,8 @@ ELIST2_LINK* element) \
|
||||
* This is passed to the generic de-dump member function so that when a list \
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user