source: _old/app/src/lib/tft.h @ 1e121f4

Last change on this file since 1e121f4 was 1e121f4, checked in by Adam Kędziora <s301614@…>, 14 years ago

Replacing old implementation with working implementation

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