source: src/lib/tft.h @ d2f119e

Last change on this file since d2f119e was 5f4d9c3, checked in by Maciej Prill <mprill@…>, 13 years ago

Rewritten the build system, added lem UTF-8 version.

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