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