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()13SubstTable<T>::SubstTable() 14 : pairsValid_(1) 15 { 16 } 17 18 template<class T> addSubst(T from,T to)19void 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) const40String<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) const66void 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) const88void 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