source: app/src/lib/tft.h @ 2f8d6d8

Last change on this file since 2f8d6d8 was 2f8d6d8, checked in by to <to@…>, 15 years ago

Poprawki kodu w C++ (nazwy plikow naglowkowych, using ...).

modified: compiledic/aut2fsa.cc
modified: dgp/grammar.hh
modified: dgp/mgraph.hh
modified: dgp/sgraph.hh
modified: dgp/thesymbols.hh
modified: gue/guess.cc
modified: kor/corlist.cc
modified: lem/lem.cc
modified: lib/symtab.cc
modified: lib/tft.h
modified: lib/tfti.h
modified: lib/ttrans.h
modified: lib/word.cc
modified: lib/word.h

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