00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef ASTL_DEBUG_H
00023 #define ASTL_DEBUG_H
00024
00025 #include <astl.h>
00026 #include <iostream>
00027 #include <utility>
00028
00029 using namespace std;
00030
00031 namespace astl {
00032
00033
00034
00035 template <class DFA>
00036 class cursor_debug : public cursor_concept
00037 {
00038 public:
00039 typedef cursor_debug self;
00040 typedef typename DFA::state_type state_type;
00041 typedef typename DFA::tag_type tag_type;
00042 typedef typename DFA::char_type char_type;
00043 typedef typename DFA::char_traits char_traits;
00044
00045
00046 typedef state_type State;
00047 typedef tag_type Tag;
00048 typedef char_type Alphabet;
00049 typedef char_traits Sigma;
00050
00051 protected:
00052 const DFA *dfa;
00053 state_type q;
00054 bool singular;
00055 ostream &out;
00056
00057 public:
00058 cursor_debug(ostream &o = cerr)
00059 : dfa(NULL), singular(true), out(o)
00060 { }
00061
00062 cursor_debug(const DFA &a, ostream &o = cerr)
00063 : dfa(&a), singular(true), out(o)
00064 { }
00065
00066 cursor_debug(const DFA &a, state_type p, ostream &o = cerr)
00067 : dfa(&a), q(p), out(o)
00068 {
00069 if (q == dfa->null_state) {
00070 out << "cursor::cursor(DFA, state_type) : WARNING" << endl;
00071 out << "\t cursor set on the sink state" << endl;
00072 }
00073 }
00074
00075 state_type sink_state() const {
00076 if (singular) {
00077 out << "cursor::sink_state(): CRITICAL" << endl;
00078 out << "\t accessing sink state through a singular cursor" << endl;
00079 }
00080 return dfa->null_state;
00081 }
00082
00083 state_type src() const {
00084 if (singular) {
00085 out << "cursor::src(): CRITICAL" << endl;
00086 out << "\t trying to access state through a singular cursor" << endl;
00087 }
00088 return q;
00089 }
00090
00091 self& operator= (state_type p) {
00092 q = p;
00093 if (q == dfa->null_state) {
00094 out << "cursor::operator=(state_type) : WARNING" << endl;
00095 out << "\t assigning sink state to the cursor" << endl;
00096 }
00097 singular = false;
00098 return *this;
00099 }
00100
00101 self& operator=(const self &x) {
00102 if (this == &x) {
00103 out << "cursor::operator=(cursor &x) : WARNING" << endl;
00104 out << "\t assigning cursor to itself (this == &x)" << endl;
00105 }
00106 q = x.q;
00107 dfa = x.dfa;
00108 singular = x.singular;
00109 if (singular) {
00110 out << "cursor::operator=(cursor &x): CRITICAL" << endl;
00111 out << "\t x has a singular value" << endl;
00112 }
00113 return *this;
00114 }
00115
00116 bool operator==(const self &x) const {
00117 if (this == &x) {
00118 out << "cursor::operator==(cursor &x) : WARNING" << endl;
00119 out << "\t comparing cursor to itself (this == &x)" << endl;
00120 }
00121 if (singular) {
00122 out << "cursor::operator==(cursor &x): CRITICAL" << endl;
00123 out << "\t comparing a singular cursor" << endl;
00124 }
00125 return q == x.q;
00126 }
00127
00128 bool sink() const {
00129 if (singular) {
00130 out << "cursor::sink(): CRITICAL" << endl;
00131 out << "\t testing a singular cursor" << endl;
00132 }
00133 return q == dfa->null_state;
00134 }
00135
00136 bool forward(const char_type &letter) {
00137 if (singular) {
00138 out << "cursor::forward(letter): CRITICAL" << endl;
00139 out << "\t trying to move along a transition through"
00140 "a singular cursor" << endl;
00141 }
00142 else
00143 if (q == dfa->null_state) {
00144 out << "cursor::forward(letter): CRITICAL" << endl;
00145 out << "\t source state is the sink state" << endl;
00146 }
00147 q = dfa->delta1(q, letter);
00148 return q != dfa->null_state;
00149 }
00150
00151 bool src_final() const {
00152 if (singular) {
00153 out << "cursor::src_final(): CRITICAL" << endl;
00154 out << "\t trying to access source state of a singular cursor" << endl;
00155 }
00156 else
00157 if (q == dfa->null_state) {
00158 out << "cursor::src_final(): CRITICAL" << endl;
00159 out << "\t trying to access sink state" << endl;
00160 }
00161 return dfa->final(q);
00162 }
00163
00164 const tag_type& src_tag() const {
00165 if (singular) {
00166 out << "cursor::src_tag(): CRITICAL" << endl;
00167 out << "\t testing a singular cursor" << endl;
00168 }
00169 else
00170 if (q == dfa->null_state) {
00171 out << "cursor::src_tag(): CRITICAL" << endl;
00172 out << "\t trying to access tag of sink state" << endl;
00173 }
00174 return dfa->tag(q);
00175 }
00176
00177 bool exists(const char_type &letter) const {
00178 if (singular) {
00179 out << "cursor::exists(): CRITICAL" << endl;
00180 out << "\t testing for a transition through a singular cursor" << endl;
00181 }
00182 else
00183 if (q == dfa->null_state) {
00184 out << "cursor::exists(): CRITICAL" << endl;
00185 out << "\t testing for an outgoing transition of sink state" << endl;
00186 }
00187 return dfa->delta1(q, letter) != dfa->null_state;
00188 }
00189 };
00190
00191
00192
00193 template <class DFA>
00194 class forward_cursor_debug : public forward_cursor_concept
00195 {
00196 public:
00197 typedef forward_cursor_debug self;
00198 typedef typename DFA::state_type state_type;
00199 typedef typename DFA::tag_type tag_type;
00200 typedef typename DFA::char_type char_type;
00201 typedef typename DFA::char_traits char_traits;
00202
00203
00204 typedef state_type State;
00205 typedef tag_type Tag;
00206 typedef char_type Alphabet;
00207 typedef char_traits Sigma;
00208
00209 protected:
00210 typedef typename DFA::edges_type::const_iterator edges_iterator;
00211 const DFA *dfa;
00212 state_type q;
00213 edges_iterator transition;
00214 bool dereferenceable, singular;
00215
00216
00217
00218 ostream &out;
00219
00220 public:
00221 forward_cursor_debug(const DFA &a, state_type p,
00222 const char_type& Letter, ostream &o = cerr)
00223 : dfa(&a), q(p), dereferenceable(false), singular(false), out(o)
00224 {
00225 if (q == dfa->null_state)
00226 out << "forward_cursor::forward_cursor(DFA, state_type, letter): warning" << endl
00227 << "\t cursor initialized with null state" << endl;
00228 else
00229 if ((transition = dfa->delta2(q).find(Letter)) == dfa->delta2(q).end()) {
00230 out << "forward_cursor::forward_cursor(DFA, state_type, letter): warning" << endl;
00231 out << "\t cursor set on a sink transition" << endl;
00232 }
00233 else
00234 dereferenceable = true;
00235 }
00236
00237 forward_cursor_debug(const DFA &a, state_type p,
00238 edges_iterator t, ostream &o = cerr)
00239 : dfa(&a), q(p), transition(t), dereferenceable(false), singular(false), out(o)
00240 {
00241 if (q == dfa->null_state) {
00242 out << "forward_cursor::forward_cursor(DFA, state_type, edges_iterator):";
00243 out << " warning" << endl << "\t cursor initialized with null state" << endl;
00244 }
00245 else
00246 dereferenceable = t != dfa->delta2(q).end();
00247 }
00248
00249 forward_cursor_debug(const DFA &a, state_type p, ostream &o = cerr)
00250 : dfa(&a), q(p), dereferenceable(false), singular(false), out(o)
00251 {
00252 if (q == dfa->null_state) {
00253 out << "forward_cursor::forward_cursor(DFA, state_type): warning" << endl;
00254 out << "\t cursor initialized with null state" << endl;
00255 }
00256 }
00257
00258 forward_cursor_debug(const DFA &a, ostream &o = cerr)
00259 : dfa(&a), q(a.initial()), dereferenceable(false), singular(true), out(o)
00260 {
00261 if (q == dfa->null_state) {
00262 out << "forward_cursor::forward_cursor(DFA): warning" << endl;
00263 out << "\t cursor initialized with initial state which is null" << endl;
00264 }
00265 }
00266
00267 forward_cursor_debug(ostream &o = cerr)
00268 : dfa(NULL), dereferenceable(false), singular(true), out(o)
00269 { }
00270
00271 self& operator= (state_type p) {
00272
00273 q = p;
00274 dereferenceable = false;
00275 if (q == dfa->null_state) {
00276 out << "forward_cursor::operator= (state_type): warning" << endl;
00277 out << "\t assigning null state" << endl;
00278 }
00279 singular = false;
00280 return *this;
00281 }
00282
00283 self& operator= (const self &x) {
00284
00285 if (this == &x) {
00286 out << "forward_cursor::operator= (forward_cursor x): warning" << endl;
00287 out << "\t assigning cursor to itself (this == &x)" << endl;
00288 }
00289 q = x.q;
00290 transition = x.transition;
00291 dereferenceable = x.dereferenceable;
00292 singular = x.singular;
00293 dfa = x.dfa;
00294 if (singular) {
00295 out << "forward_cursor::operator= (forward_cursor x): warning" << endl;
00296 out << "\t x has a singular value" << endl;
00297 }
00298 if (dfa == NULL) {
00299 out << "forward_cursor::operator= (forward_cursor x): WARNING" << endl;
00300 out << "\t assigning a non-initialized cursor x (dfa == NULL)" << endl;
00301 }
00302
00303 return *this;
00304 }
00305
00306 bool operator== (const self &x) const {
00307 if (this == &x) {
00308 out << "forward_cursor::operator== : warning" << endl;
00309 out << "\t comparing cursor with itself" << endl;
00310 }
00311 return (q == x.q && transition == x.transition);
00312 }
00313
00314 char_type letter() const {
00315 if (singular) {
00316 out << "forward_cursor::letter() : CRITICAL" << endl;
00317 out << "\t trying to access transition through a singular cursor" << endl;
00318 }
00319 else
00320 if (!dereferenceable) {
00321 out << "forward_cursor::letter() : CRITICAL" << endl;
00322 out << "\t trying to access transition through a non dereferenceable cursor" << endl;
00323 out << "\t state = " << q << endl;
00324 }
00325 return (*transition).first;
00326 }
00327
00328 bool sink() const {
00329 if (singular) {
00330 out << "forward_cursor::sink(): CRITICAL" << endl;
00331 out << "\t testing for sink state on a singular cursor" << endl;
00332 }
00333 return q == dfa->null_state;
00334 }
00335
00336 state_type sink_state() const {
00337
00338 if (singular) {
00339 out << "forward_cursor::sink_state(): CRITICAL" << endl;
00340 out << "\t requesting the sink state value from a singular cursor" << endl;
00341 }
00342 return dfa->null_state;
00343 }
00344
00345
00346 void to_sink() {
00347 if (singular) {
00348 out << "forward_cursor::to_sink(): CRITICAL" << endl;
00349 out << "\t moving a singular cursor to the sink state" << endl;
00350 }
00351 if (dfa == NULL) {
00352 out << "forward_cursor::to_sink() : CRITICAL" << endl;
00353 out << "\t trying to move to the sink state with a non-initialized cursor (dfa == NULL)" << endl;
00354 }
00355 q = dfa->null_state;
00356 }
00357
00358
00359 bool first() {
00360 if (singular) {
00361 out << "forward_cursor::first() : CRITICAL" << endl;
00362 out << "\t seeking first outgoing transition of a singular cursor" << endl;
00363 }
00364 else
00365 if (q == dfa->null_state) {
00366 out << "forward_cursor::first() : CRITICAL" << endl;
00367 out << "\t trying to access first transition of sink source state" << endl;
00368 }
00369 return dereferenceable = (transition = dfa->delta2(q).begin()) != dfa->delta2(q).end();
00370 }
00371
00372 bool next() {
00373 if (singular) {
00374 out << "forward_cursor::next() : CRITICAL" << endl;
00375 out << "\t seeking next transition of a singular cursor" << endl;
00376 }
00377 else
00378 if (q == dfa->null_state) {
00379 out << "forward_cursor::next() : CRITICAL" << endl;
00380 out << "\t seeking next transition of sink source state" << endl;
00381 }
00382 else
00383 if (!dereferenceable) {
00384 out << "forward_cursor::next(): CRITICAL" << endl;
00385 out << "\t seeking next transition of a non dereferenceable cursor" << endl;
00386 }
00387 return dereferenceable = (++transition != dfa->delta2(q).end());
00388 }
00389
00390 void forward() {
00391 if (singular) {
00392 out << "forward_cursor::forward() : CRITICAL" << endl;
00393 out << "\t trying to move along transition of a singular cursor" << endl;
00394 }
00395 else
00396 if (q == dfa->null_state) {
00397 out << "forward_cursor::forward() : CRITICAL" << endl;
00398 out << "\t trying to move along transition of sink source state" << endl;
00399 }
00400 else
00401 if (!dereferenceable) {
00402 out << "forward_cursor::forward() : CRITICAL" << endl;
00403 out << "\t trying to move along transition of a non dereferenceable cursor" << endl;
00404 }
00405 q = (*transition).second;
00406 dereferenceable = false;
00407 }
00408
00409 bool find(const char_type &letter) {
00410 if (singular) {
00411 out << "forward_cursor::find() : CRITICAL" << endl;
00412 out << "\t trying to find an outgoing transition through a singular cursor" << endl;
00413 }
00414 else
00415 if (q == dfa->null_state) {
00416 out << "forward_cursor::find() : CRITICAL" << endl;
00417 out << "\t trying to find an outgoing transition of sink source state" << endl;
00418 }
00419 edges_iterator tmp = dfa->delta2(q).find(letter);
00420 if (tmp != dfa->delta2(q).end()) {
00421 transition = tmp;
00422 dereferenceable = true;
00423 return true;
00424 }
00425
00426 return false;
00427 }
00428
00429 bool forward(const char_type &letter) {
00430 if (singular) {
00431 out << "forward_cursor::forward(letter) : CRITICAL" << endl;
00432 out << "\t trying to move along transition through a singular cursor" << endl;
00433 }
00434 else
00435 if (q == dfa->null_state) {
00436 out << "forward_cursor::forward(letter) : CRITICAL" << endl;
00437 out << "\t trying to move along outgoing transition of sink state" << endl;
00438 }
00439 dereferenceable = false;
00440 q = dfa->delta1(q, letter);
00441 return q != dfa->null_state;
00442 }
00443
00444 state_type src() const {
00445 if (singular) {
00446 out << "forward_cursor::src(): CRITICAL" << endl;
00447 out << "\t trying to access source state of a singular cursor" << endl;
00448 }
00449 return q;
00450 }
00451
00452 state_type aim() const {
00453 if (singular) {
00454 out << "forward_cursor::aim() : CRITICAL" << endl;
00455 out << "\t trying to access aim state of a singular cursor" << endl;
00456 }
00457 else
00458 if (!dereferenceable) {
00459 out << "forward_cursor::aim() : CRITICAL" << endl;
00460 out << "\t trying to access aim state of a non dereferenceable cursor" << endl;
00461 }
00462 return (*transition).second;
00463 }
00464
00465 bool src_final() const {
00466 if (singular) {
00467 out << "forward_cursor::src_final(): CRITICAL" << endl;
00468 out << "\t trying to access source state of a singular cursor" << endl;
00469 }
00470 else
00471 if (q == dfa->null_state) {
00472 out << "forward_cursor::src_final(): CRITICAL" << endl;
00473 out << "\t trying to access sink state" << endl;
00474 }
00475 return dfa->final(q);
00476 }
00477
00478 bool aim_final() const {
00479 if (singular) {
00480 out << "forward_cursor::aim_final() : CRITICAL" << endl;
00481 out << "\t trying to access aim state of a singular cursor" << endl;
00482 }
00483 else
00484 if (!dereferenceable) {
00485 out << "forward_cursor::aim_final() : CRITICAL" << endl;
00486 out << "\t trying to access aim state of a non dereferenceable cursor" << endl;
00487 }
00488 return dfa->final((*transition).second);
00489 }
00490
00491 bool exists(const char_type &letter) const {
00492
00493 if (singular) {
00494 out << "forward_cursor::exist() : CRITICAL" << endl;
00495 out << "\t testing for a transition through a singular cursor" << endl;
00496 }
00497 else if (!dereferenceable) {
00498 out << "forward_cursor::exist() : CRITICAL" << endl;
00499 out << "\t testing for a transition through a non dereferenceable cursor" << endl;
00500 }
00501 else
00502 if (q == dfa->null_state) {
00503 out << "forward_cursor::exist() : CRITICAL" << endl;
00504 out << "\t testing for a transition from sink state" << endl;
00505 }
00506 return dfa->delta1(q, letter) != dfa->null_state;
00507 }
00508
00509 const tag_type& src_tag() const {
00510 if (singular) {
00511 out << "forward_cursor::src_tag() : CRITICAL" << endl;
00512 out << "\t trying to access source tag of a singular cursor" << endl;
00513 }
00514 else
00515 if (q == dfa->null_state) {
00516 out << "forward_cursor::src_tag(): CRITICAL" << endl;
00517 out << "\t trying to access tag of sink state" << endl;
00518 }
00519 return dfa->tag(q);
00520 }
00521
00522 const tag_type& aim_tag() const {
00523 if (singular) {
00524 out << "forward_cursor::aim_tag() : CRITICAL" << endl;
00525 out << "\t trying to access aim tag of a singular cursor" << endl;
00526 }
00527 else
00528 if (!dereferenceable) {
00529 out << "forward_cursor::aim_tag() : CRITICAL" << endl;
00530 out << "\t trying to access aim tag of a non dereferenceable cursor";
00531 }
00532 return dfa->tag((*transition).second);
00533 }
00534
00535
00536 friend ostream& operator << (ostream &out, const self &x) {
00537 out << x.q << " , '";
00538 if (x.singular) out << "singular'";
00539 else
00540 if (!x.dereferenceable) {
00541 if (x.transition == x.dfa->delta2(x.q).end()) out << "end of range'";
00542 else
00543 out << "not dereferenceable'";
00544 }
00545 else
00546 out << (*(x.transition)).first << "', " << (*(x.transition)).second;
00547 return out;
00548 }
00549
00550
00551 bool operator < (const self &x) const {
00552
00553
00554 if (singular)
00555 out << "forward_cursor::operator< (forward_cursor) : caution" << endl
00556 << "\t comparing singular left cursor with"
00557 << (x.singular ? " singular " : " ") << "right cursor" << endl;
00558 else
00559 if (x.singular)
00560 out << "forward_cursor::operator< (forward_cursor) : caution" << endl
00561 << "\t comparing left cursor with singular right cursor" << endl;
00562 return q < x.q || (q == x.q && transition < x.transition);
00563 }
00564 };
00565
00566
00567
00568 template <class DFA>
00569 cursor_debug<DFA> debugplainc(const DFA &a, ostream &out = cerr) {
00570 return cursor_debug<DFA>(a, a.initial(), out);
00571 }
00572
00573
00574 template <class DFA>
00575 forward_cursor_debug<DFA> debugc(const DFA &a, ostream &out = cerr) {
00576 return forward_cursor_debug<DFA>(a, a.initial(), out);
00577 }
00578
00579 template <class Cursor>
00580 class cursor_trace : public cursor_concept
00581 {
00582 public:
00583 typedef cursor_trace self;
00584 typedef typename Cursor::state_type state_type;
00585 typedef typename Cursor::tag_type tag_type;
00586 typedef typename Cursor::char_type char_type;
00587 typedef typename Cursor::char_traits char_traits;
00588 static int id;
00589
00590
00591 typedef state_type State;
00592 typedef tag_type Tag;
00593 typedef char_type Alphabet;
00594 typedef char_traits Sigma;
00595
00596 protected:
00597 Cursor c;
00598 int ID;
00599 ostream &out;
00600
00601 public:
00602 cursor_trace(ostream &o = cerr)
00603 : c(), ID(++id), out(o) {
00604 out << "cursor[" << ID << "]::cursor()" << endl;
00605 }
00606
00607 cursor_trace(const Cursor &x, ostream &o = cerr)
00608 : c(x), ID(++id), out(o) {
00609 out << "cursor[" << ID << "]::cursor(Cursor " << &x << ")" << endl;
00610 }
00611
00612 cursor_trace(const self &x)
00613 : c(x.c), ID(x.ID), out(x.out) {
00614 out << "cursor[" << ID << "]::cursor(self)" << endl;
00615 }
00616
00617 ~cursor_trace() {
00618 out << "cursor[" << ID << "]::~cursor()" << endl;
00619 }
00620
00621 state_type src() const {
00622 out << "cursor[" << ID << "]::src() == " << c.src() << endl;
00623 return c.src();
00624 }
00625
00626 state_type sink_state() const {
00627 out << "cursor[" << ID << "]::sink_state() == " << c.sink_state() << endl;
00628 return c.sink_state();
00629 }
00630
00631 self& operator= (state_type p) {
00632 out << "cursor[" << ID << "]::operator=(state_type " << p << ")" << endl;
00633 c = p;
00634 return *this;
00635 }
00636
00637 self& operator= (const self &x) {
00638 out << "cursor[" << ID << "]::operator=(self [" << x.ID << "])" << endl;
00639 c = x.c;
00640 return *this;
00641 }
00642
00643 bool operator== (const self &x) const {
00644 out << "cursor[" << ID << "]::operator==(self [" << x.ID << "]) == " << (c == x.c) << endl;
00645 return c == x.c;
00646 }
00647
00648 bool sink() const {
00649 out << "cursor[" << ID << "]::sink() == " << c.sink() << endl;
00650 return c.sink();
00651 }
00652
00653 bool forward(const char_type &letter) {
00654 out << "cursor[" << ID << "]::forward('" << letter << "') == ";
00655 out << c.forward(letter) << endl;
00656 return !c.sink();
00657 }
00658
00659 bool src_final() const {
00660 out << "cursor[" << ID << "]::src_final() == " << c.src_final() << endl;
00661 return c.src_final();
00662 }
00663
00664 const tag_type& src_tag() const {
00665 out << "cursor[" << ID << "]::src_tag()" << endl;
00666 return c.src_tag();
00667 }
00668
00669 bool exists(const char_type &letter) const {
00670 out << "cursor[" << ID << "]::exists(int " << letter << ") == " << c.exists(letter) << endl;
00671 return c.exists(letter);
00672 }
00673 };
00674
00675 template <class Cursor> int cursor_trace<Cursor>::id = 0;
00676
00677 template <class ForwardCursor>
00678 class forward_cursor_trace : public forward_cursor_concept
00679 {
00680 public:
00681 typedef forward_cursor_trace self;
00682 typedef typename ForwardCursor::state_type state_type;
00683 typedef typename ForwardCursor::tag_type tag_type;
00684 typedef typename ForwardCursor::char_type char_type;
00685 typedef typename ForwardCursor::char_traits char_traits;
00686
00687
00688 typedef state_type State;
00689 typedef tag_type Tag;
00690 typedef char_type Alphabet;
00691 typedef char_traits Sigma;
00692
00693 protected:
00694 ForwardCursor c;
00695 static int id;
00696 int ID;
00697 ostream &out;
00698
00699 public:
00700 forward_cursor_trace(const ForwardCursor &x, ostream &o = cerr)
00701 : c(x), ID(++id), out(o) {
00702 out << "fcursor[" << ID << "]::fcursor(forward_cursor " << &x << ")" << endl;
00703 }
00704
00705 forward_cursor_trace(ostream &o = cerr)
00706 : c(), ID(++id), out(o) {
00707 out << "fcursor[" << ID << "]::fcursor()";
00708 }
00709
00710 const ForwardCursor& cursor() const { return c; }
00711
00712 forward_cursor_trace(const self &x)
00713 : c(x.c), ID(++id), out(x.out) {
00714 out << "fcursor[" << ID << "](self[" << x.ID << "])" << endl;
00715 }
00716
00717 ~forward_cursor_trace() {
00718 out << "fcursor[" << ID << "]::~fcursor()" << endl;
00719 }
00720
00721 self& operator= (state_type p) {
00722 out << "fcursor[" << ID << "]::operator=(state_type " << p << ")" << endl;
00723 c = p;
00724 return *this;
00725 }
00726
00727 self& operator= (const self &x) {
00728 out << "fcursor[" << ID << "]::operator=(self [" << x.ID << "])" << endl;
00729 c = x.c;
00730 return *this;
00731 }
00732
00733 bool operator== (const self &x) const {
00734 out << "fcursor[" << ID << "]::operator==(self [" << x.ID << "]) == " << (c == x.c) << endl;
00735 return (c == x.c);
00736 }
00737
00738 char_type letter() const {
00739 out << "fcursor[" << ID << "]::letter() == '" << c.letter() << "'" << endl;
00740 return c.letter();
00741 }
00742
00743 bool first() {
00744 out << "fcursor[" << ID << "]::first() == ";
00745 if (c.first())
00746 out << "(" << c.src() << ", '" << c.letter() << "', " << c.aim() << ")" << endl;
00747 else
00748 out << "0" << endl;
00749 return c.first();
00750 }
00751
00752 bool next() {
00753 bool r = c.next();
00754 out << "fcursor[" << ID << "]::next() == ";
00755 if (r)
00756 out << "(" << c.src() << ", '" << c.letter() << "', " << c.aim() << ")" << endl;
00757 else
00758 out << "0" << endl;
00759 return r;
00760 }
00761
00762 bool forward(const char_type &letter) {
00763 out << "fcursor[" << ID << "]::forward('" << letter << "') == ";
00764 if (c.forward(letter))
00765 out << c.src() << endl;
00766 else {
00767 out << "0 && sink() == " << c.sink() << endl;
00768 }
00769 return !c.sink();
00770 }
00771
00772 void forward() {
00773 c.forward();
00774 out << "fcursor[" << ID << "]::forward() == " << c.src() << endl;
00775 }
00776
00777 bool find(const char_type &letter) {
00778 out << "fcursor[" << ID << "]::find('" << letter << "') == ";
00779 if (c.find(letter))
00780 out << "(" << c.src() << ", '" << c.letter() << "', " << c.aim() << ")" << endl;
00781 else
00782 out << "0" << endl;
00783 return c.find(letter);
00784 }
00785
00786 state_type src() const {
00787 out << "fcursor[" << ID << "]::src() == " << c.src() << endl;
00788 return c.src();
00789 }
00790
00791 bool src_final() const {
00792 out << "fcursor[" << ID << "]::src_final() == " << c.src_final() << endl;
00793 return c.src_final();
00794 }
00795
00796 state_type aim() const {
00797
00798 out << "fcursor[" << ID << "]::aim() == " << c.aim() << endl;
00799 return c.aim();
00800 }
00801
00802 bool aim_final() const {
00803 out << "fcursor[" << ID << "]::aim_final() == " << c.aim_final() << endl;
00804 return c.aim_final();
00805 }
00806
00807 tag_type aim_tag() const {
00808 out << "fcursor[" << ID << "]::aim_tag() == " << c.aim_tag() << endl;
00809 return c.aim_tag();
00810 }
00811
00812 tag_type src_tag() const {
00813 out << "fcursor[" << ID << "]::src_tag() == " << c.src_tag() << endl;
00814 return c.src_tag();
00815 }
00816
00817 bool sink() const {
00818 out << "fcursor[" << ID << "]::sink() == " << c.sink() << endl;
00819 return c.sink();
00820 }
00821
00822 state_type sink_state() const {
00823 out << "fcursor[" << ID << "]::sink_state() == " << c.sink_state() << endl;
00824 return c.sink_state();
00825 }
00826
00827 bool exists(const char_type &letter) const {
00828 out << "fcursor[" << ID << "]::exists(" << letter << ") == " << c.exists(letter) << endl;
00829 return c.exists(letter);
00830 }
00831 };
00832
00833 template <class ForwardCursor> int forward_cursor_trace<ForwardCursor>::id = 0;
00834
00835 template <class ForwardCursor>
00836 forward_cursor_trace<ForwardCursor>
00837 tracec(const ForwardCursor &x, ostream &out = cerr) {
00838 return forward_cursor_trace<ForwardCursor>(x, out);
00839 }
00840
00841 }
00842
00843 #endif // ASTL_CURSOR_DEBUG