source: app/src/lib/tft.h @ 25b4022

Last change on this file since 25b4022 was 25ae32e, checked in by obrebski <obrebski@…>, 16 years ago

git-svn-id: svn://atos.wmid.amu.edu.pl/utt@4 e293616e-ec6a-49c2-aa92-f4a8b91c5d16

  • Property mode set to 100755
File size: 21.0 KB
Line 
1#ifndef _TFT_h
2#define _TFT_h
3//---------------------------------------------------------------------------
4#include <stddef.h>
5#include <iostream.h>
6#include <typeinfo>
7#include <string.h>
8
9#include <stdio.h>
10
11//#include "top.h"
12#include "ttrans.h"
13//---------------------------------------------------------------------------
14
15/// Klasa bazowa przetwornika skoñczonego.
16/**
17    \remark Po co ta klasa? Co dotyczy samych przej¶æ, przenie¶æ do TTrans,
18    resztê wcieliæ do TFT.
19*/
20class FT
21{
22public:
23  FT() : copy_default(false), print_mode(OO), ttn(0) {};
24
25//print mode
26  enum OUTPUT { II,                         ///< tylko symbole wej¶ciowe
27                OO,                         ///< tylko symbole wyj¶ciowe
28                IOIO,                       ///< symbol wyj¶ciowy po wej¶ciowym
29                OIOI,                       ///< symbol wyj¶ciowy przed wej¶ciowym
30                IIOO,                       ///< ca³e wej¶cie, potem ca³e wyj¶cie
31                OOII                        ///< ca³e wyj¶cie, potem ca³e wej¶cie
32
33              };
34
35/// maks d³ugo¶æ ¶cie¿ki
36  static const unsigned int ftMAXPATH=500;
37
38/// maks d³ugo¶æ opisu typu symbolu we/wy
39/**
40    \remark Przenie¶æ do TTrans
41*/
42  static const unsigned int ftTYPELEN=32;
43
44/// specjalny symbol dla warto¶ci 'epsilon'
45/**
46    \remark Przenie¶æ do TTrans
47*/
48  static const char ftEPSILON='~';
49
50/// specialny symbol dla warto¶ci 'default'
51/**
52    \remark Przenie¶æ do TTrans
53*/
54  static const char ftDEFAULT='@';
55
56/// domy¶lny symbol wyj¶ciowy (true-'@', flase-'~')
57/**
58    \remark Przenie¶æ do TTrans(???)
59*/
60  bool copy_default;
61
62/// tryb wyj¶cia
63  OUTPUT print_mode;
64
65/// false, je¶li automat nie ma przej¶æ
66  operator bool() { return (bool)ttn; };
67
68  virtual const char* intype() { return itype; };
69  virtual const char* outtype() { return otype; };
70
71protected:
72
73/// liczba elementów tablicy tt
74  unsigned long ttn;
75
76/// liczba stanów
77  unsigned long states;
78
79/// liczba przej¶æ
80  unsigned long transitions;
81
82/// typ symboli wej¶ciowych (napis)
83/**
84    \remark Przenie¶æ do TTrans(???)
85*/
86  char itype[ftTYPELEN];
87
88/// typ symboli wyj¶ciowych (napis)
89/**
90    \remark Przenie¶æ do TTrans(???)
91*/
92  char otype[ftTYPELEN];
93};
94
95//---------------------------------------------------------------------------
96
97/// Szablon przetwornika skoñczonego
98/**
99    \param I - typ symbolu wej¶ciowego
100    \param Ipass - typ, jaki ma byæ u¿yty przy przekazywaniu symbolu we jako parametru
101                   do funkcji (metody), równy \a I lub \a I&
102    \param O - typ symbolu wyj¶ciowego
103    \param Opass - typ, jaki ma byæ u¿yty przy przekazywaniu symbolu wy jako parametru
104                   do funkcji (metody), równy \a O lub \a O&
105    \param - typ przej¶cia, musi byæ podklas± TTrans
106*/
107template<class I, class Ipass, class O, class Opass, class TT>
108class TFT : public FT
109{
110
111
112public:
113
114  TFT() : FT(), tt(NULL) { setiotypes(); };
115
116/**
117\name Metody poziomu 1
118Poziom przej¶æ.
119*/
120
121//@{
122
123/// Test, czy przej¶cie \a t akceptuje symbol \a in.
124  bool accepts(long t, Ipass in) const;
125
126/// Test, czy lista przej¶æ dla aktualnego stanu jest kontynuowana po \a t.
127  bool continued(long t) const;
128
129/// Stan, do którego prowadzi przej¶cie \a t.
130/**
131    \pre !empty(t)
132*/
133  long next(long t) const;
134
135/// Symbol wej¶ciowy przej¶cia \a t.
136  Ipass input(long t) const;
137
138/// Symbol wyj¶ciowy przej¶cia \a t.
139  Opass output(long t) const;
140
141/// Zwraca \c true, je¶li symbolem we przej¶cia \a t jest epsilon.
142  bool epsi(long t) const;
143
144/// Zwraca \c true, je¶li symbolem we przej¶cia \a t jest symbol domy¶lny.
145  bool defi(long t) const;
146
147/// Zwraca \c true, je¶li symbolem wy przej¶cia \a t jest epsilon.
148  bool epso(long t) const;
149
150/// Zwraca \c true, je¶li symbolem wy przej¶cia \a t jest symbol domy¶lny.
151  bool defo(long t) const;
152
153/// Indeks przej¶cia przez \a in.
154  long tra(long t, Ipass in) const;
155
156/// Indeks przej¶cia przez \a in - non-deterministic.
157  long tra_nd(long t, Ipass in, long nth) const;
158
159//@}
160
161/**
162\name Poziom 2
163Poziom stanów. Stan (indeks stanu) = indeks jego pierwszego przej¶cia
164*/
165//@{
166/// Zwraca \c true je¶li stan \a s jest pusty (nie ma z niego przej¶æ).
167  bool empty(long s) const { return tt[s].empty(); }
168
169/// Zwraca \c true je¶li stan \a s jest stanem koñcowym.
170  bool final(long s) const { return tt[s].final(); }
171
172  long next(long t, Ipass in) const;
173
174//long trans(const I* si, I* so, long& olen) const;
175
176  long gtra(long s, const I* w, long maxpath=ftMAXPATH) const;
177
178//@}
179
180/**
181\name Poziom 3
182Poziom ...
183*/
184//@{
185  long cont(long s=-1, I* c=NULL) const;
186
187  long match(const I* w=NULL, long* p=NULL) const;
188
189  long match_nd(const I* w=NULL, long* p=NULL) const;
190
191  long lgstmatch(const I* w, long* p, long& plen, long maxpath=ftMAXPATH) const;
192
193  /*NOWE*/
194
195  long lgstpath(I*& buf, long*& path, long start=0) const;
196
197  long pref(I*& buf, I sep, long start=0) const;
198
199//@}
200
201protected:
202
203  TT* tt;                // tablica przej¶æ
204
205  long prn(const I* si, long* p, O* so) const;
206
207  void prntt(ostream& os);
208
209  void sort();
210
211  void setiotypes();     // NIE DZIA£A (dlaczego???)
212
213//  friend ostream& operator<<(ostream&,const CDFA&);
214//  friend istream& operator>>(istream&,CDFA&);
215
216private:
217  long prn_oo(const I* si, long* p, O* so) const;
218  long prn_ioio(const I* si, long* p, O* so) const;
219  long prn_oioi(const I* si, long* p, O* so) const;
220  long prn_iioo(const I* si, long* p, O* so) const;
221  long prn_ooii(const I* si, long* p, O* so) const;
222};
223
224
225//---------------------------------------------------------------------------
226//---------------------------------------------------------------------------
227
228/**
229    stan = indeks pierwszego przej¶cia
230
231    state(t) = stan, do którego nale¿y t
232
233    symbol zerowy = symbol s, dla którego (bool)s zwraca \c false,
234    w przypadku znaków - '\0'
235*/
236
237//---------------------------------------------------------------------------
238//---------------------------------------------------------------------------
239
240
241template <class I, class Ipass, class O, class Opass, class TT>
242inline
243bool TFT<I,Ipass,O,Opass,TT>::accepts(long t, Ipass in) const
244{ return tt[t].accepts(in); }
245
246/// Test whether the transition list continues after \a t.
247template <class I, class Ipass, class O, class Opass, class TT>
248inline
249bool TFT<I,Ipass,O,Opass,TT>::continued(long t) const
250{ return tt[t].continued(); }
251
252/**
253    \pre !empty(t)
254*/
255template <class I, class Ipass, class O, class Opass, class TT>
256inline
257long TFT<I,Ipass,O,Opass,TT>::next(long t) const
258{ return tt[t].next(); }
259
260template <class I, class Ipass, class O, class Opass, class TT>
261inline
262Ipass TFT<I,Ipass,O,Opass,TT>::input(long t) const
263{ return tt[t].in(); }
264
265template <class I, class Ipass, class O, class Opass, class TT>
266inline
267Opass TFT<I,Ipass,O,Opass,TT>::output(long t) const
268{ return tt[t].out(); }
269
270template <class I, class Ipass, class O, class Opass, class TT>
271inline
272bool TFT<I,Ipass,O,Opass,TT>::epsi(long t) const
273{ return tt[t].epsi(); }
274
275template <class I, class Ipass, class O, class Opass, class TT>
276inline
277bool TFT<I,Ipass,O,Opass,TT>::defi(long t) const
278{ return tt[t].defi(); }
279
280template <class I, class Ipass, class O, class Opass, class TT>
281inline
282bool TFT<I,Ipass,O,Opass,TT>::epso(long t) const
283{ return tt[t].epso(); }
284
285template <class I, class Ipass, class O, class Opass, class TT>
286inline
287bool TFT<I,Ipass,O,Opass,TT>::defo(long t) const
288{ return tt[t].defo(); }
289
290/**
291    \param +t - indeks przej¶cia
292    \param +in - symbol we
293    \return Indeks przj¶cia (>=\a t) dla bie¿±cego stanu, które
294    akceptuje symbol we \a in lub -1, je¶li nie ma takiego przej¶cia
295*/
296template <class I, class Ipass, class O, class Opass, class TT>
297long TFT<I,Ipass,O,Opass,TT>::tra(long t, Ipass in) const
298{
299  if(t<0 || t>=ttn)
300    return -1;
301
302  if(empty(t)) return -1;
303  while(!accepts(t,in))
304    if(continued(t))
305      t++;
306    else
307      return -1;
308  return t;
309}
310
311//---------------------------------------------------------------------------
312/// Indeks przej¶cia - wersja dla automatu niedeterministycznego.
313/**
314    \param +t  - indeks przej¶cia
315    \param +in - symbol we
316    \return Indeks przj¶cia (>=\a t) dla bie¿±cego stanu, które
317    akceptuje symbol we \a in lub -1, je¶li nie ma takiego przej¶cia
318    Je¶li nth==0, t1>=t, w przeciwnym razie t1>t.
319*/
320template <class I, class Ipass, class O, class Opass, class TT>
321long TFT<I,Ipass,O,Opass,TT>::tra_nd(long t, Ipass in, long nth) const
322{
323  if(t<0 || t>=ttn)
324    return -1;
325
326  if(nth)
327    if(continued(t))
328      t++;
329    else
330      return -1;
331  else
332  { if(empty(t)) return -1; }
333
334  while(!accepts(t,in))
335    if(continued(t))
336      t++;
337    else
338      return -1;
339
340  return t;
341}
342
343//}
344
345//---------------------------------------------------------------------------
346//----------------------------------------------------------------------------
347
348
349/// Funkcja przej¶cia.
350/**
351    \param t - stan
352    \param in - symbol we
353    \return Stan, do którego mo¿na przej¶æ z \a t po wp³ywem symbolu \a in
354    lub -1, je¶li nie ma przej¶cia przez \a in
355
356*/
357template <class I, class Ipass, class O, class Opass, class TT>
358long TFT<I,Ipass,O,Opass,TT>::next(long t, Ipass in) const
359{
360  if(t<0 || (unsigned long)t>=ttn)
361    return -1;
362
363  if(empty(t)) return -1;
364  while(!accepts(t,in))
365    if(continued(t))
366      t++;
367    else {
368      return -1;
369    }
370
371  return next(t);
372}
373
374//---------------------------------------------------------------------------
375
376//----------------------------------------------------------------------------
377/// Uogólniona funkcja przejscia.
378/**
379    \param +s - stan
380    \param +w - wskaŒnik pierwszego elementu ci±gu symboli we, zakoñczonego symbolem zerowym
381    \param maxpath maksymalna d³ugo¶æ ¶cie¿ki, domy¶lnie ftMAXPATH
382    \return stan osi±galny z \a s pod wp³ywem \a w (na ¶cie¿ce mog± siê pojawiæ
383    epsilon-przej¶cia
384*/
385template <class I, class Ipass, class O, class Opass, class TT>
386long TFT<I,Ipass,O,Opass,TT>::gtra(long s, const I* w, long maxpath) const
387{
388  if(s<0 || (unsigned long)s>=ttn)
389    return -1;
390
391  long i=0;
392  while(*w)
393  {
394    if(i>maxpath || empty(s)) return -1;
395    while(!accepts(s,*w))
396      if(continued(s))
397        s++;
398      else
399        return -1;
400    if(!epsi(s)) w++;
401    s=next(s);
402    i++;
403  }
404  return s;
405}
406
407//----------------------------------------------------------------------------
408
409/// Kontynuacja.
410/**
411...
412\param +s stan, je¶li -1 - poszukiwane jest nastêpne rozwi±zanie
413\param -c ci±g symboli we ze ¶cie¿ki prowadz±cej z \a s do
414       stanu koñcowego
415\return d³ugo¶æ ci±gu \a c (= d³ugo¶æ ¶cie¿ki)
416\remark DZIA£A TYLKO DLA ZNAKÓW!!!
417        EPSILON-PRZEJŠCIA NIEDOZWOLONE!!!
418*/
419template <class I, class Ipass, class O, class Opass, class TT>
420long TFT<I,Ipass,O,Opass,TT>::cont(long s, I* c) const
421{
422  static unsigned long path[ftMAXPATH]={0};
423  static unsigned long  i=0;
424  static bool more=false;
425
426  bool found=false;
427
428  if(s!=-1)
429  {
430    if(s<0 || (unsigned long)s>=ttn)
431      more=false;
432    else
433    {
434      i=0;
435      c[0]=0;
436      path[0]=s;
437      more=true;
438      if(final(s))
439        found=true;
440    }
441  }
442
443  while(more && !found)
444  {
445    if(!empty(path[i]) && i<ftMAXPATH)
446    {
447      path[i+1]=next(path[i]);
448      c[i]=input(path[i]);
449      i++;
450    }
451    else
452    {
453      do
454      {
455        if(i>0)
456          c[--i]=0;
457        else
458          more=false;
459      }while(more && !continued(path[i]));
460      path[i]=path[i]+1;
461    }
462    if(final(path[i]))
463    {
464      found=true;
465      c[i]=0;
466    }
467  }
468  return i;
469}
470
471//----------------------------------------------------------------------------
472/// Dopasowannie.
473/**
474    \remark Nie zaimplementowane.
475*/
476template <class I, class Ipass, class O, class Opass, class TT>
477long TFT<I,Ipass,O,Opass,TT>::match(const I* w, long* p) const
478{}
479
480//----------------------------------------------------------------------------
481/// Dopasowanie niedeterministyczne.
482/**
483    \param +w - wskaŒnik pierwszego elementu ci±gu symboli we, zakoñczonego symbolem zerowym,
484    je¶li NULL - poszukiwane jest nastêpne rozwi±zanie
485    \param -p ci±g przej¶æ zakoñczony -1
486    \return d³ugo¶æ dopasowania (PO CO?)
487*/
488template <class I, class Ipass, class O, class Opass, class TT>
489long TFT<I,Ipass,O,Opass,TT>::match_nd(const I* w, long* p) const
490{
491  static bool more=false;
492  static I *w0, *wc;
493  static long s=0, *p0, *pc, *pc_bound;
494
495  bool found=false;
496
497  if(w)
498  {
499    wc=w0=w;
500    pc=p0=p;
501    more=true;
502    pc_bound=pc+ftMAXPATH;
503    if(final(s=0))
504    {
505      *pc=-1; return 0;
506    }
507  }
508
509  while(more)
510  {
511    if(*wc && pc<pc_bound && (*pc=trand(s,*wc,0))>=0)
512    { if(!epsi(*pc)) wc++; s=next(*pc); pc++; }
513    else
514      while(true)
515      {
516        if(pc==p0) { more=false; return -1; }
517        if(!epsi(*(--pc))) wc--;
518        if((*pc=trand(*pc,*wc,1))>=0)
519        { if(!epsi(*pc)) wc++; s=next(*pc); pc++; break; }
520      }
521    if(final(s)) { *pc=-1; return wc-w0; }
522  }
523  return -1;
524}
525
526//----------------------------------------------------------------------------
527/// Najd³u¿sze dopasowanie.
528/**
529    \param +w wskaŒnik pierwszego elementu ci±gu symboli wej¶ciowych
530    \param -p ¶cie¿ka
531    \param -plen d³ugo¶æ ¶cie¿ki
532    \param +maxpath maks dd³ugo¶æ ¶cie¿ki, domy¶lnie FT::ftMAXPATH
533    \return d³ugo¶æ skonsumowanego wej¶cia
534*/
535template <class I, class Ipass, class O, class Opass, class TT>
536long TFT<I,Ipass,O,Opass,TT>
537        ::lgstmatch(const I* w, long* p, long& plen, long maxpath) const
538{
539  long s=0;
540  long t;
541  long i=0;
542  const char* w0=w;
543  long ilen=0;
544  while(*w && i<maxpath && (t=tra(s,*w))>=0)
545  {
546    if(!epsi(t)) w++;
547    s=next(t);
548    i++;
549    *(p++)=t;
550    if(final(s)) { plen=i; ilen=w-w0; }
551  }
552  *p=-1;
553  return ilen;
554}
555
556//----------------------------------------------------------------------------
557/// Najd³u¿sza ¶cie¿ka.
558/**
559    \param +buf  wskaŒnik pierwszego elementu ci±gu symboli wej¶ciowych
560    \param -buf  pozycja jeden za skonsumowanym prefiksem
561    \param +path wskaŒnik pierwszego elementu wektora przej¶æ
562    \param -path wskaŒnik jeden za ostatnim przej¶ciem
563    \return d³ugo¶æ skonsumowanego prefiksu (PO CO? LEPIEJ D£ ŠCIE¯KI)
564*/
565template <class I, class Ipass, class O, class Opass, class TT>
566long TFT<I,Ipass,O,Opass,TT>
567        ::lgstpath(I*& buf, long*& path, long start) const
568{
569  long s=start;
570  long t;
571  const char* buf0=buf;
572  const long* pathlimit=path+FT::ftMAXPATH;
573  while(*buf && path<pathlimit && (t=tra(s,*buf))>=0)
574  {
575    if(!epsi(t)) buf++;
576    s=next(t);
577    *(path++)=t;
578  }
579  return buf-buf0;
580}
581
582//----------------------------------------------------------------------------
583/// Najd³u¿szy prefiks.
584/**
585    \param +buf  wskaŒnik pierwszego elementu ci±gu symboli wej¶ciowych
586    \param -buf  pozycja jeden za skonsumowanym prefiksem
587    \param +sep  separator
588    \return stan po przej¶ciu przez \a sep
589    \remark Dzia³a tylko dla automatów deterministycznych, minimalnych, eps-wolnych,
590              gdzie d³. ¶cie¿ki == d³. dopasowania.
591*/
592template <class I, class Ipass, class O, class Opass, class TT>
593long TFT<I,Ipass,O,Opass,TT>
594        ::pref(I*& buf, I sep, long start) const
595{
596  static long pathtab[ftMAXPATH];
597  //  static long* path=pathtab;       
598  long* path=pathtab;
599  static bool more;
600
601  long s;
602  if(*buf)                     // pierwsze wywo³anie
603  {
604    if(!lgstpath(buf,path,start))
605      return -1;
606    --path;
607    more=true;
608  }
609  else                         // kolejne  wywo³anie
610    --buf,--path;
611  while(more)
612    if(path>=pathtab)
613      if((s=next(next(*path),sep))>=0) {
614        return s;
615      }
616      else
617        --buf, --path;
618    else
619    {
620      more=false;
621      return -1;
622    }
623  return -1;
624}
625
626//----------------------------------------------------------------------------
627
628/*
629template <class I, class Ipass, class O, class Opass, class TT>
630long TFT<I,Ipass,O,Opass,TT>::trans(const I* si, O* so, long& olen) const
631{
632  long p[ftMAXPATH];
633  long ilen;
634  long plen;
635  if((ilen=lgstmatch(si,p,plen))>0)
636    olen=prn(si,p,so);
637  else
638    ilen=olen=0;
639  return ilen;
640}
641*/
642//----------------------------------------------------------------------------
643
644template <class I, class Ipass, class O, class Opass, class TT>
645long TFT<I,Ipass,O,Opass,TT>::prn(const I* si, long* p, O* so) const
646{
647  switch(print_mode)
648  {
649    case OO: return prn_oo(si,p,so);
650    case IOIO: return prn_ioio(si,p,so);
651    case OIOI: return prn_oioi(si,p,so);
652    case IIOO: return prn_iioo(si,p,so);
653    case OOII: return prn_ooii(si,p,so);
654  }
655}
656
657//----------------------------------------------------------------------------
658
659template <class I, class Ipass, class O, class Opass, class TT>
660long TFT<I,Ipass,O,Opass,TT>::prn_oo(const I* si, long* p, O* so) const
661{
662  char* so0=so;
663  while(*p>=0)
664  {
665    long t=*p;
666    if(!epso(t))
667    {
668      if(defo(t))
669        *(so++)=*si;
670      else
671        *(so++)=output(t);
672    }
673    if(!epsi(t)) si++;
674    p++;
675
676  }
677  return so-so0;
678}
679
680//----------------------------------------------------------------------------
681
682
683template <class I, class Ipass, class O, class Opass, class TT>
684long TFT<I,Ipass,O,Opass,TT>::prn_ioio(const I* si, long* p, O* so) const
685{
686  char* so0=so;
687  while(*p>=0)
688  {
689    long t=*p;
690    if(!epsi(t))
691      *(so++)=*si;
692    if(!epso(t))
693      if(defo(t))
694        *(so++)=*si;
695      else
696        *(so++)=output(t);
697    if(!epsi(t)) si++;
698    p++;
699  }
700  return so-so0;
701}
702
703
704//----------------------------------------------------------------------------
705
706template <class I, class Ipass, class O, class Opass, class TT>
707long TFT<I,Ipass,O,Opass,TT>::prn_oioi(const I* si, long* p, O* so) const
708{
709  char* so0=so;
710  while(*p>=0)
711  {
712    long t=*p;
713    if(!epso(t))
714    {
715      if(defo(t))
716        *(so++)=*si;
717      else
718        *(so++)=output(t);
719    }
720    if(!epsi(t))
721      *(so++)=*(si++);
722    p++;
723  }
724  return so-so0;
725}
726
727//----------------------------------------------------------------------------
728
729template <class I, class Ipass, class O, class Opass, class TT>
730long TFT<I,Ipass,O,Opass,TT>::prn_iioo(const I* si, long* p, O* so) const
731{
732  const char* si0=si;
733  long* p0=p;
734  char* so0=so;
735  while(*p>=0)
736  {
737    long t=*p;
738    if(!epsi(t))
739    {
740      *(so++)=*si;
741      si++;
742    }
743    p++;
744  }
745  si=si0;
746  p=p0;
747  while(*p>=0)
748  {
749    long t=*p;
750    if(!epso(t))
751      if(defo(t))
752        *(so++)=*si;
753      else
754        *(so++)=output(t);
755    if(!epsi(t)) si++;
756    p++;
757  }
758  return so-so0;
759}
760
761//----------------------------------------------------------------------------
762
763template <class I, class Ipass, class O, class Opass, class TT>
764long TFT<I,Ipass,O,Opass,TT>::prn_ooii(const I* si, long* p, O* so) const
765{
766
767  const char* si0=si;
768  long* p0=p;
769  char* so0=so;
770  while(*p>=0)
771  {
772    long t=*p;
773    if(!epso(t))
774    {
775      if(defo(t))
776        *(so++)=*si;
777      else
778        *(so++)=output(t);
779    }
780    if(!epsi(t)) si++;
781    p++;
782  }
783  si=si0;
784  p=p0;
785  while(*p>=0)
786  {
787    long t=*p;
788    if(!epsi(t))
789      *(so++)=*(si++);
790    p++;
791  }
792  return so-so0;
793}
794
795//---------------------------------------------------------------------------
796
797template<class I, class Ipass, class O, class Opass, class TT>
798void TFT<I,Ipass,O,Opass,TT>::sort()
799{
800  long t=0;
801  while(t<ttn)
802  {
803    long t0=t;
804    long tn=1;
805    while(continued(t++)) tn++;
806    if(tn>1)
807    {
808      long eps=-1;
809      long def=-1;
810      for(int i=0; i<tn; i++)
811      {
812        if(defi(t0+i))
813          if(epsi(t0+i)) eps=i; else def=i;
814      }
815      if(eps>=0 && eps<tn-1)
816      {
817        TT temp=tt[t0+eps];
818        memmove(tt+t0+eps+1,tt+t0+eps,tn-eps-1);
819        tt[t-1]=temp;
820      }
821      if(def>eps) def--;
822      if(def>=0 && def<tn-1)
823      {
824        TT temp=tt[t0+def];
825        if(eps>=0)
826        {
827          memmove(tt+t0+def+1,tt+t0+def,tn-eps-2);
828          tt[t-2]=temp;
829        }
830        else
831        {
832          memmove(tt+t0+def+1,tt+t0+def,tn-eps-2);
833          tt[t-1]=temp;
834        }
835      }
836      while(t0<t-1)
837        tt[t0++].continued(true);
838      tt[t-1].continued(false);
839    }
840  }
841}
842
843//---------------------------------------------------------------------------
844
845template <class I, class Ipass, class O, class Opass, class TT>
846void TFT<I,Ipass,O,Opass,TT>::setiotypes()
847{
848  int i=0;
849  const char* it=typeid(I).name();
850  while(*it)
851    if(*it==' ')
852    { it++; continue; }
853    else
854      itype[i++]=*(it++);
855  itype[i]='\0';
856
857  i=0;
858  const char* ot=typeid(O).name();
859  while(*ot)
860    if(*ot==' ')
861    { ot++; continue; }
862    else
863      otype[i++]=*(ot++);
864  otype[i]='\0';
865};
866
867//---------------------------------------------------------------------------
868
869template <class I, class Ipass, class O, class Opass, class TT>
870void TFT<I,Ipass,O,Opass,TT>::prntt(ostream& os)
871{
872  for(long i=0; i<ttn; ++i)
873  {
874    os << i << ':';
875    os << tt[i];
876  }
877}
878
879#endif
Note: See TracBrowser for help on using the repository browser.