1 // Copyright (c) 1994 James Clark
2 // See the file COPYING for copying permission.
3 #pragma ident	"%Z%%M%	%I%	%E% SMI"
4 
5 #ifndef SubstTable_DEF_INCLUDED
6 #define SubstTable_DEF_INCLUDED 1
7 
8 #ifdef SP_NAMESPACE
9 namespace SP_NAMESPACE {
10 #endif
11 
12 template<class T>
SubstTable()13 SubstTable<T>::SubstTable()
14 : pairsValid_(1)
15 {
16 }
17 
18 template<class T>
addSubst(T from,T to)19 void SubstTable<T>::addSubst(T from, T to)
20 {
21   if (table_.size() == 0) {
22     table_.resize(T(-1) + 1);
23 #if _MSC_VER == 1100
24     // Workaround for Visual C++ 5.0 bug.
25     T n = 0;
26     int i = 0;
27     while (i < T(-1) + 1)
28       table_[i++] = n++;
29 #else
30     for (int i = 0; i < T(-1) + 1; i++)
31       table_[i] = i;
32 #endif
33   }
34   if (table_[from] != to)
35     pairsValid_ = 0;
36   table_[from] = to;
37 }
38 
39 template<class T>
inverse(T ch) const40 String<T> SubstTable<T>::inverse(T ch) const
41 {
42   if (!pairsValid_) {
43     const T *p = table_.data();
44     size_t length = table_.size();
45     for (size_t i = 0; i < length; i++)
46       if (p[i] != i) {
47 	// FIXME use mutable if available
48 	((SubstTable<T> *)this)->pairs_ += T(i);
49 	((SubstTable<T> *)this)->pairs_ += p[i];
50       }
51     ((SubstTable<T> *)this)->pairsValid_ = 1;
52   }
53   const T *p = pairs_.data();
54   if (!p)
55     return String<T>(&ch, 1);
56   String<T> result;
57   if (table_[ch] == ch)
58     result += ch;
59   for (size_t n = pairs_.size(); n > 0; n -= 2, p += 2)
60     if (p[1] == ch)
61       result += p[0];
62   return result;
63 }
64 
65 template<class T>
inverseTable(SubstTable<T> & inv) const66 void SubstTable<T>::inverseTable(SubstTable<T> &inv) const
67 {
68   if (table_.size() == 0) {
69     inv.table_.resize(0);
70     inv.pairs_.resize(0);
71     inv.pairsValid_ = 1;
72   }
73   else {
74     if (inv.table_.size() == 0)
75       inv.table_.resize(T(-1) + 1);
76     int i;
77     for (i = 0; i < T(-1) + 1; i++)
78       inv.table_[i] = i;
79     inv.pairs_.resize(0);
80     inv.pairsValid_ = 0;
81     for (i = 0; i < T(-1) + 1; i++)
82       if (table_[i] != i)
83 	inv.table_[table_[i]] = i;
84   }
85 }
86 
87 template<class T>
subst(String<T> & str) const88 void SubstTable<T>::subst(String<T> &str) const
89 {
90   for (size_t i = 0; i < str.size(); i++)
91     subst(str[i]);
92 }
93 
94 #ifdef SP_NAMESPACE
95 }
96 #endif
97 
98 #endif /* not SubstTable_DEF_INCLUDED */
99