FST  openfst-1.7.2
OpenFst Library
weight-class.h
Go to the documentation of this file.
1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
3 //
4 // Represents a generic weight in an FST; that is, represents a specific type
5 // of weight underneath while hiding that type from a client.
6 
7 #ifndef FST_SCRIPT_WEIGHT_CLASS_H_
8 #define FST_SCRIPT_WEIGHT_CLASS_H_
9 
10 #include <memory>
11 #include <ostream>
12 #include <string>
13 
14 #include <fst/arc.h>
15 #include <fst/generic-register.h>
16 #include <fst/util.h>
17 #include <fst/weight.h>
18 
19 namespace fst {
20 namespace script {
21 
23  public:
24  virtual WeightImplBase *Copy() const = 0;
25  virtual void Print(std::ostream *o) const = 0;
26  virtual const string &Type() const = 0;
27  virtual string ToString() const = 0;
28  virtual bool Member() const = 0;
29  virtual bool operator==(const WeightImplBase &other) const = 0;
30  virtual bool operator!=(const WeightImplBase &other) const = 0;
31  virtual WeightImplBase &PlusEq(const WeightImplBase &other) = 0;
32  virtual WeightImplBase &TimesEq(const WeightImplBase &other) = 0;
33  virtual WeightImplBase &DivideEq(const WeightImplBase &other) = 0;
34  virtual WeightImplBase &PowerEq(size_t n) = 0;
35  virtual ~WeightImplBase() {}
36 };
37 
38 template <class W>
40  public:
41  explicit WeightClassImpl(const W &weight) : weight_(weight) {}
42 
43  WeightClassImpl<W> *Copy() const final {
44  return new WeightClassImpl<W>(weight_);
45  }
46 
47  const string &Type() const final { return W::Type(); }
48 
49  void Print(std::ostream *ostrm) const final { *ostrm << weight_; }
50 
51  string ToString() const final {
52  string str;
53  WeightToStr(weight_, &str);
54  return str;
55  }
56 
57  bool Member() const final { return weight_.Member(); }
58 
59  bool operator==(const WeightImplBase &other) const final {
60  const auto *typed_other = static_cast<const WeightClassImpl<W> *>(&other);
61  return weight_ == typed_other->weight_;
62  }
63 
64  bool operator!=(const WeightImplBase &other) const final {
65  return !(*this == other);
66  }
67 
68  WeightClassImpl<W> &PlusEq(const WeightImplBase &other) final {
69  const auto *typed_other = static_cast<const WeightClassImpl<W> *>(&other);
70  weight_ = Plus(weight_, typed_other->weight_);
71  return *this;
72  }
73 
74  WeightClassImpl<W> &TimesEq(const WeightImplBase &other) final {
75  const auto *typed_other = static_cast<const WeightClassImpl<W> *>(&other);
76  weight_ = Times(weight_, typed_other->weight_);
77  return *this;
78  }
79 
81  const auto *typed_other = static_cast<const WeightClassImpl<W> *>(&other);
82  weight_ = Divide(weight_, typed_other->weight_);
83  return *this;
84  }
85 
86  WeightClassImpl<W> &PowerEq(size_t n) final {
87  weight_ = Power<W>(weight_, n);
88  return *this;
89  }
90 
91  W *GetImpl() { return &weight_; }
92 
93  private:
94  W weight_;
95 };
96 
97 
98 class WeightClass {
99  public:
100  WeightClass() = default;
101 
102  template <class W>
103  explicit WeightClass(const W &weight)
104  : impl_(new WeightClassImpl<W>(weight)) {}
105 
106  template <class W>
107  explicit WeightClass(const WeightClassImpl<W> &impl)
108  : impl_(new WeightClassImpl<W>(impl)) {}
109 
110  WeightClass(const string &weight_type, const string &weight_str);
111 
112  WeightClass(const WeightClass &other)
113  : impl_(other.impl_ ? other.impl_->Copy() : nullptr) {}
114 
116  impl_.reset(other.impl_ ? other.impl_->Copy() : nullptr);
117  return *this;
118  }
119 
120  static constexpr const char *__ZERO__ = "__ZERO__"; // NOLINT
121 
122  static WeightClass Zero(const string &weight_type);
123 
124  static constexpr const char *__ONE__ = "__ONE__"; // NOLINT
125 
126  static WeightClass One(const string &weight_type);
127 
128  static constexpr const char *__NOWEIGHT__ = "__NOWEIGHT__"; // NOLINT
129 
130  static WeightClass NoWeight(const string &weight_type);
131 
132  template <class W>
133  const W *GetWeight() const {
134  if (W::Type() != impl_->Type()) {
135  return nullptr;
136  } else {
137  auto *typed_impl = static_cast<WeightClassImpl<W> *>(impl_.get());
138  return typed_impl->GetImpl();
139  }
140  }
141 
142  string ToString() const { return (impl_) ? impl_->ToString() : "none"; }
143 
144  const string &Type() const {
145  if (impl_) return impl_->Type();
146  static const string *const no_type = new string("none");
147  return *no_type;
148  }
149 
150  bool Member() const { return impl_ && impl_->Member(); }
151 
152  bool WeightTypesMatch(const WeightClass &other, const string &op_name) const;
153 
154  friend bool operator==(const WeightClass &lhs, const WeightClass &rhs);
155 
156  friend WeightClass Plus(const WeightClass &lhs, const WeightClass &rhs);
157 
158  friend WeightClass Times(const WeightClass &lhs, const WeightClass &rhs);
159 
160  friend WeightClass Divide(const WeightClass &lhs, const WeightClass &rhs);
161 
162  friend WeightClass Power(const WeightClass &w, size_t n);
163 
164  private:
165  const WeightImplBase *GetImpl() const { return impl_.get(); }
166 
167  WeightImplBase *GetImpl() { return impl_.get(); }
168 
169  std::unique_ptr<WeightImplBase> impl_;
170 
171  friend std::ostream &operator<<(std::ostream &o, const WeightClass &c);
172 };
173 
174 bool operator==(const WeightClass &lhs, const WeightClass &rhs);
175 
176 bool operator!=(const WeightClass &lhs, const WeightClass &rhs);
177 
178 WeightClass Plus(const WeightClass &lhs, const WeightClass &rhs);
179 
180 WeightClass Times(const WeightClass &lhs, const WeightClass &rhs);
181 
182 WeightClass Divide(const WeightClass &lhs, const WeightClass &rhs);
183 
184 WeightClass Power(const WeightClass &w, size_t n);
185 
186 std::ostream &operator<<(std::ostream &o, const WeightClass &c);
187 
188 // Registration for generic weight types.
189 
190 using StrToWeightImplBaseT = WeightImplBase *(*)(const string &str,
191  const string &src,
192  size_t nline);
193 
194 template <class W>
195 WeightImplBase *StrToWeightImplBase(const string &str, const string &src,
196  size_t nline) {
197  if (str == WeightClass::__ZERO__)
198  return new WeightClassImpl<W>(W::Zero());
199  else if (str == WeightClass::__ONE__)
200  return new WeightClassImpl<W>(W::One());
201  else if (str == WeightClass::__NOWEIGHT__)
202  return new WeightClassImpl<W>(W::NoWeight());
203  return new WeightClassImpl<W>(StrToWeight<W>(str, src, nline));
204 }
205 
206 class WeightClassRegister : public GenericRegister<string, StrToWeightImplBaseT,
207  WeightClassRegister> {
208  protected:
209  string ConvertKeyToSoFilename(const string &key) const final {
210  string legal_type(key);
211  ConvertToLegalCSymbol(&legal_type);
212  return legal_type + ".so";
213  }
214 };
215 
217 
218 // Internal version; needs to be called by wrapper in order for macro args to
219 // expand.
220 #define REGISTER_FST_WEIGHT__(Weight, line) \
221  static WeightClassRegisterer weight_registerer##_##line( \
222  Weight::Type(), StrToWeightImplBase<Weight>)
223 
224 // This layer is where __FILE__ and __LINE__ are expanded.
225 #define REGISTER_FST_WEIGHT_EXPANDER(Weight, line) \
226  REGISTER_FST_WEIGHT__(Weight, line)
227 
228 // Macro for registering new weight types; clients call this.
229 #define REGISTER_FST_WEIGHT(Weight) \
230  REGISTER_FST_WEIGHT_EXPANDER(Weight, __LINE__)
231 
232 } // namespace script
233 } // namespace fst
234 
235 #endif // FST_SCRIPT_WEIGHT_CLASS_H_
void ConvertToLegalCSymbol(string *s)
Definition: util.cc:50
WeightClass Divide(const WeightClass &lhs, const WeightClass &rhs)
Definition: weight-class.cc:79
WeightClassImpl< W > * Copy() const final
Definition: weight-class.h:43
virtual bool operator!=(const WeightImplBase &other) const =0
static constexpr const char * __ZERO__
Definition: weight-class.h:120
WeightClassImpl< W > & DivideEq(const WeightImplBase &other) final
Definition: weight-class.h:80
WeightClass(const WeightClass &other)
Definition: weight-class.h:112
bool operator!=(const WeightImplBase &other) const final
Definition: weight-class.h:64
WeightImplBase * StrToWeightImplBase(const string &str, const string &src, size_t nline)
Definition: weight-class.h:195
WeightClass Plus(const WeightClass &lhs, const WeightClass &rhs)
Definition: weight-class.cc:59
virtual WeightImplBase & PowerEq(size_t n)=0
virtual const string & Type() const =0
WeightClass & operator=(const WeightClass &other)
Definition: weight-class.h:115
virtual bool Member() const =0
virtual WeightImplBase * Copy() const =0
WeightClass(const W &weight)
Definition: weight-class.h:103
static constexpr const char * __ONE__
Definition: weight-class.h:124
static constexpr const char * __NOWEIGHT__
Definition: weight-class.h:128
string ToString() const
Definition: weight-class.h:142
string ConvertKeyToSoFilename(const string &key) const final
Definition: weight-class.h:209
virtual WeightImplBase & DivideEq(const WeightImplBase &other)=0
WeightClassImpl< W > & TimesEq(const WeightImplBase &other) final
Definition: weight-class.h:74
std::ostream & operator<<(std::ostream &o, const WeightClass &c)
Definition: weight-class.cc:96
string ToString() const final
Definition: weight-class.h:51
virtual void Print(std::ostream *o) const =0
virtual WeightImplBase & PlusEq(const WeightImplBase &other)=0
WeightImplBase *(*)(const string &str, const string &src, size_t nline) StrToWeightImplBaseT
Definition: weight-class.h:192
const string & Type() const final
Definition: weight-class.h:47
const W * GetWeight() const
Definition: weight-class.h:133
bool Member() const final
Definition: weight-class.h:57
WeightClassImpl< W > & PlusEq(const WeightImplBase &other) final
Definition: weight-class.h:68
void WeightToStr(Weight w, string *s)
Definition: util.h:259
virtual string ToString() const =0
WeightClassImpl(const W &weight)
Definition: weight-class.h:41
virtual WeightImplBase & TimesEq(const WeightImplBase &other)=0
virtual bool operator==(const WeightImplBase &other) const =0
const string & Type() const
Definition: weight-class.h:144
WeightClass(const WeightClassImpl< W > &impl)
Definition: weight-class.h:107
void Print(std::ostream *ostrm) const final
Definition: weight-class.h:49
WeightClassImpl< W > & PowerEq(size_t n) final
Definition: weight-class.h:86
WeightClass Times(const WeightClass &lhs, const WeightClass &rhs)
Definition: weight-class.cc:69
bool operator==(const WeightImplBase &other) const final
Definition: weight-class.h:59
WeightClass Power(const WeightClass &w, size_t n)
Definition: weight-class.cc:89