FST  openfst-1.8.2
OpenFst Library
fst.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 // FST abstract base class definition, state and arc iterator interface, and
19 // suggested base implementation.
20 
21 #ifndef FST_FST_H_
22 #define FST_FST_H_
23 
24 #include <sys/types.h>
25 
26 #include <atomic>
27 #include <cmath>
28 #include <cstddef>
29 #include <cstdint>
30 #include <iostream>
31 #include <memory>
32 #include <sstream>
33 #include <string>
34 #include <utility>
35 
36 #include <fst/compat.h>
37 #include <fst/flags.h>
38 #include <fst/log.h>
39 #include <fstream>
40 
41 #include <fst/arc.h>
42 #include <fst/memory.h>
43 #include <fst/properties.h>
44 #include <fst/register.h>
45 #include <fst/symbol-table.h>
46 #include <fst/util.h>
47 #include <string_view>
48 
49 
50 DECLARE_bool(fst_align);
51 
52 namespace fst {
53 
54 // Identifies stream data as an FST (and its endianity).
55 inline constexpr int32_t kFstMagicNumber = 2125659606;
56 
57 class FstHeader;
58 
59 template <class Arc>
61 
62 template <class Arc>
64 
65 template <class Arc>
67 
69  // FileReadMode(s) are advisory, there are many conditions than prevent a
70  // file from being mapped, READ mode will be selected in these cases with
71  // a warning indicating why it was chosen.
72  enum FileReadMode { READ, MAP };
73 
74  std::string source; // Where you're reading from.
75  const FstHeader *header; // Pointer to FST header; if non-zero, use
76  // this info (don't read a stream header).
77  const SymbolTable *isymbols; // Pointer to input symbols; if non-zero, use
78  // this info (read and skip stream isymbols)
79  const SymbolTable *osymbols; // Pointer to output symbols; if non-zero, use
80  // this info (read and skip stream osymbols)
81  FileReadMode mode; // Read or map files (advisory, if possible)
82  bool read_isymbols; // Read isymbols, if any (default: true).
83  bool read_osymbols; // Read osymbols, if any (default: true).
84 
85  explicit FstReadOptions(const std::string_view source = "<unspecified>",
86  const FstHeader *header = nullptr,
87  const SymbolTable *isymbols = nullptr,
88  const SymbolTable *osymbols = nullptr);
89 
90  explicit FstReadOptions(const std::string_view source,
91  const SymbolTable *isymbols,
92  const SymbolTable *osymbols = nullptr);
93 
94  // Helper function to convert strings FileReadModes into their enum value.
95  static FileReadMode ReadMode(std::string_view mode);
96 
97  // Outputs a debug string for the FstReadOptions object.
98  std::string DebugString() const;
99 };
100 
102  std::string source; // Where you're writing to.
103  bool write_header; // Write the header?
104  bool write_isymbols; // Write input symbols?
105  bool write_osymbols; // Write output symbols?
106  bool align; // Write data aligned (may fail on pipes)?
107  bool stream_write; // Avoid seek operations in writing.
108 
109  explicit FstWriteOptions(std::string_view source = "<unspecified>",
110  bool write_header = true, bool write_isymbols = true,
111  bool write_osymbols = true,
112  bool align = FST_FLAGS_fst_align,
113  bool stream_write = false)
114  : source(source),
115  write_header(write_header),
116  write_isymbols(write_isymbols),
117  write_osymbols(write_osymbols),
118  align(align),
119  stream_write(stream_write) {}
120 };
121 
122 // Header class.
123 //
124 // This is the recommended file header representation.
125 
126 class FstHeader {
127  public:
128  enum Flags {
129  HAS_ISYMBOLS = 0x1, // Has input symbol table.
130  HAS_OSYMBOLS = 0x2, // Has output symbol table.
131  IS_ALIGNED = 0x4, // Memory-aligned (where appropriate).
132  };
133 
135  : version_(0),
136  flags_(0),
137  properties_(0),
138  start_(-1),
139  numstates_(0),
140  numarcs_(0) {}
141 
142  const std::string &FstType() const { return fsttype_; }
143 
144  const std::string &ArcType() const { return arctype_; }
145 
146  int32_t Version() const { return version_; }
147 
148  uint32_t GetFlags() const { return flags_; }
149 
150  uint64_t Properties() const { return properties_; }
151 
152  int64_t Start() const { return start_; }
153 
154  int64_t NumStates() const { return numstates_; }
155 
156  int64_t NumArcs() const { return numarcs_; }
157 
158  void SetFstType(std::string_view type) { fsttype_ = std::string(type); }
159 
160  void SetArcType(std::string_view type) { arctype_ = std::string(type); }
161 
162  void SetVersion(int32_t version) { version_ = version; }
163 
164  void SetFlags(uint32_t flags) { flags_ = flags; }
165 
166  void SetProperties(uint64_t properties) { properties_ = properties; }
167 
168  void SetStart(int64_t start) { start_ = start; }
169 
170  void SetNumStates(int64_t numstates) { numstates_ = numstates; }
171 
172  void SetNumArcs(int64_t numarcs) { numarcs_ = numarcs; }
173 
174  bool Read(std::istream &strm, const std::string &source, bool rewind = false);
175 
176  bool Write(std::ostream &strm, const std::string &source) const;
177 
178  // Outputs a debug string for the FstHeader object.
179  std::string DebugString() const;
180 
181  private:
182  std::string fsttype_; // E.g. "vector".
183  std::string arctype_; // E.g. "standard".
184  int32_t version_; // Type version number.
185  uint32_t flags_; // File format bits.
186  uint64_t properties_; // FST property bits.
187  int64_t start_; // Start state.
188  int64_t numstates_; // # of states.
189  int64_t numarcs_; // # of arcs.
190 };
191 
192 // Specifies matcher action.
193 enum MatchType {
194  MATCH_INPUT = 1, // Match input label.
195  MATCH_OUTPUT = 2, // Match output label.
196  MATCH_BOTH = 3, // Match input or output label.
197  MATCH_NONE = 4, // Match nothing.
199 }; // Otherwise, match type unknown.
200 
201 inline constexpr int kNoLabel = -1; // Not a valid label.
202 inline constexpr int kNoStateId = -1; // Not a valid state ID.
203 
204 // A generic FST, templated on the arc definition, with common-demoninator
205 // methods (use StateIterator and ArcIterator to iterate over its states and
206 // arcs). Derived classes should be assumed to be thread-unsafe unless
207 // otherwise specified.
208 template <class A>
209 class Fst {
210  public:
211  using Arc = A;
212  using StateId = typename Arc::StateId;
213  using Weight = typename Arc::Weight;
214 
215  virtual ~Fst() {}
216 
217  // Initial state.
218  virtual StateId Start() const = 0;
219 
220  // State's final weight.
221  virtual Weight Final(StateId) const = 0;
222 
223  // State's arc count.
224  virtual size_t NumArcs(StateId) const = 0;
225 
226  // State's input epsilon count.
227  virtual size_t NumInputEpsilons(StateId) const = 0;
228 
229  // State's output epsilon count.
230  virtual size_t NumOutputEpsilons(StateId) const = 0;
231 
232  // Property bits. If test = false, return stored properties bits for mask
233  // (some possibly unknown); if test = true, return property bits for mask
234  // (computing o.w. unknown).
235  virtual uint64_t Properties(uint64_t mask, bool test) const = 0;
236 
237  // FST type name.
238  virtual const std::string &Type() const = 0;
239 
240  // Gets a copy of this Fst. The copying behaves as follows:
241  //
242  // (1) The copying is constant time if safe = false or if safe = true
243  // and is on an otherwise unaccessed FST.
244  //
245  // (2) If safe = true, the copy is thread-safe in that the original
246  // and copy can be safely accessed (but not necessarily mutated) by
247  // separate threads. For some FST types, 'Copy(true)' should only be
248  // called on an FST that has not otherwise been accessed. Behavior is
249  // otherwise undefined.
250  //
251  // (3) If a MutableFst is copied and then mutated, then the original is
252  // unmodified and vice versa (often by a copy-on-write on the initial
253  // mutation, which may not be constant time).
254  virtual Fst *Copy(bool safe = false) const = 0;
255 
256  // Reads an FST from an input stream; returns nullptr on error.
257  static Fst *Read(std::istream &strm, const FstReadOptions &opts) {
258  FstReadOptions ropts(opts);
259  FstHeader hdr;
260  if (ropts.header) {
261  hdr = *opts.header;
262  } else {
263  if (!hdr.Read(strm, opts.source)) return nullptr;
264  ropts.header = &hdr;
265  }
266  const auto &fst_type = hdr.FstType();
267  const auto reader = FstRegister<Arc>::GetRegister()->GetReader(fst_type);
268  if (!reader) {
269  LOG(ERROR) << "Fst::Read: Unknown FST type " << fst_type
270  << " (arc type = " << Arc::Type() << "): " << ropts.source;
271  return nullptr;
272  }
273  return reader(strm, ropts);
274  }
275 
276  // Reads an FST from a file; returns nullptr on error. An empty source
277  // results in reading from standard input.
278  static Fst *Read(const std::string &source) {
279  if (!source.empty()) {
280  std::ifstream strm(source,
281  std::ios_base::in | std::ios_base::binary);
282  if (!strm) {
283  LOG(ERROR) << "Fst::Read: Can't open file: " << source;
284  return nullptr;
285  }
286  return Read(strm, FstReadOptions(source));
287  } else {
288  return Read(std::cin, FstReadOptions("standard input"));
289  }
290  }
291 
292  // Writes an FST to an output stream; returns false on error.
293  virtual bool Write(std::ostream &strm, const FstWriteOptions &opts) const {
294  LOG(ERROR) << "Fst::Write: No write stream method for " << Type()
295  << " FST type";
296  return false;
297  }
298 
299  // Writes an FST to a file; returns false on error; an empty source
300  // results in writing to standard output.
301  virtual bool Write(const std::string &source) const {
302  LOG(ERROR) << "Fst::Write: No write source method for " << Type()
303  << " FST type";
304  return false;
305  }
306 
307  // Some Fst implementations support
308  // template <class Fst2>
309  // static bool Fst1::WriteFst(const Fst2 &fst2, ...);
310  // which is equivalent to Fst1(fst2).Write(...), but uses less memory.
311  // WriteFst is not part of the general Fst interface.
312 
313  // Returns input label symbol table; return nullptr if not specified.
314  virtual const SymbolTable *InputSymbols() const = 0;
315 
316  // Return output label symbol table; return nullptr if not specified.
317  virtual const SymbolTable *OutputSymbols() const = 0;
318 
319  // For generic state iterator construction (not normally called directly by
320  // users). Does not copy the FST.
321  virtual void InitStateIterator(StateIteratorData<Arc> *data) const = 0;
322 
323  // For generic arc iterator construction (not normally called directly by
324  // users). Does not copy the FST.
325  virtual void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const = 0;
326 
327  // For generic matcher construction (not normally called directly by users).
328  // Does not copy the FST.
329  virtual MatcherBase<Arc> *InitMatcher(MatchType match_type) const;
330 
331  protected:
332  bool WriteFile(const std::string &source) const {
333  if (!source.empty()) {
334  std::ofstream strm(source,
335  std::ios_base::out | std::ios_base::binary);
336  if (!strm) {
337  LOG(ERROR) << "Fst::WriteFile: Can't open file: " << source;
338  return false;
339  }
340  if (!Write(strm, FstWriteOptions(source))) {
341  LOG(ERROR) << "Fst::WriteFile: Write failed: " << source;
342  return false;
343  }
344  return true;
345  } else {
346  return Write(std::cout, FstWriteOptions("standard output"));
347  }
348  }
349 };
350 
351 // A useful alias when using StdArc.
352 using StdFst = Fst<StdArc>;
353 
354 // State and arc iterator definitions.
355 //
356 // State iterator interface templated on the Arc definition; used for
357 // StateIterator specializations returned by the InitStateIterator FST method.
358 template <class Arc>
360  public:
361  using StateId = typename Arc::StateId;
362 
363  virtual ~StateIteratorBase() {}
364 
365  // End of iterator?
366  virtual bool Done() const = 0;
367  // Returns current state (when !Done()).
368  virtual StateId Value() const = 0;
369  // Advances to next state (when !Done()).
370  virtual void Next() = 0;
371  // Resets to initial condition.
372  virtual void Reset() = 0;
373 };
374 
375 // StateIterator initialization data.
376 
377 template <class Arc>
378 struct StateIteratorData {
379  using StateId = typename Arc::StateId;
380 
381  // Specialized iterator if non-null.
382  std::unique_ptr<StateIteratorBase<Arc>> base;
383  // Otherwise, the total number of states.
385 
386  StateIteratorData() : base(nullptr), nstates(0) {}
387 
388  StateIteratorData(const StateIteratorData &) = delete;
389  StateIteratorData &operator=(const StateIteratorData &) = delete;
390 };
391 
392 // Generic state iterator, templated on the FST definition (a wrapper
393 // around a pointer to a specific one). Here is a typical use:
394 //
395 // for (StateIterator<StdFst> siter(fst);
396 // !siter.Done();
397 // siter.Next()) {
398 // StateId s = siter.Value();
399 // ...
400 // }
401 // There is no copying of the FST.
402 //
403 // Specializations may exist for some FST types.
404 // StateIterators are thread-unsafe unless otherwise specified.
405 template <class FST>
407  public:
408  using Arc = typename FST::Arc;
409  using StateId = typename Arc::StateId;
410 
411  explicit StateIterator(const FST &fst) : s_(0) {
412  fst.InitStateIterator(&data_);
413  }
414 
415  bool Done() const {
416  return data_.base ? data_.base->Done() : s_ >= data_.nstates;
417  }
418 
419  StateId Value() const { return data_.base ? data_.base->Value() : s_; }
420 
421  void Next() {
422  if (data_.base) {
423  data_.base->Next();
424  } else {
425  ++s_;
426  }
427  }
428 
429  void Reset() {
430  if (data_.base) {
431  data_.base->Reset();
432  } else {
433  s_ = 0;
434  }
435  }
436 
437  private:
439  StateId s_;
440 };
441 
442 // Flags to control the behavior on an arc iterator via SetFlags().
443 // Value() gives valid ilabel.
444 inline constexpr uint8_t kArcILabelValue = 0x01;
445 // Value() call gives valid olabel.
446 inline constexpr uint8_t kArcOLabelValue = 0x02;
447 // Value() call gives valid weight.
448 inline constexpr uint8_t kArcWeightValue = 0x04;
449 // Value() call gives valid nextstate.
450 inline constexpr uint8_t kArcNextStateValue = 0x08;
451 // Arcs need not be cached.
452 inline constexpr uint8_t kArcNoCache = 0x10;
453 inline constexpr uint8_t kArcValueFlags =
454  kArcILabelValue | kArcOLabelValue | kArcWeightValue | kArcNextStateValue;
455 inline constexpr uint8_t kArcFlags = kArcValueFlags | kArcNoCache;
456 
457 // Arc iterator interface, templated on the arc definition; used for arc
458 // iterator specializations that are returned by the InitArcIterator FST method.
459 template <class Arc>
461  public:
462  using StateId = typename Arc::StateId;
463 
464  virtual ~ArcIteratorBase() {}
465 
466  // End of iterator?
467  virtual bool Done() const = 0;
468  // Returns current arc (when !Done()).
469  virtual const Arc &Value() const = 0;
470  // Advances to next arc (when !Done()).
471  virtual void Next() = 0;
472  // Returns current position.
473  virtual size_t Position() const = 0;
474  // Returns to initial condition.
475  virtual void Reset() = 0;
476  // Advances to arbitrary arc by position.
477  virtual void Seek(size_t) = 0;
478  // Returns current behavorial flags, a bitmask of kArcFlags.
479  virtual uint8_t Flags() const = 0;
480  // Sets behavorial flags, a bitmask of kArcFlags.
481  virtual void SetFlags(uint8_t, uint8_t) = 0;
482 };
483 
484 // ArcIterator initialization data.
485 template <class Arc>
486 struct ArcIteratorData {
488  : base(nullptr), arcs(nullptr), narcs(0), ref_count(nullptr) {}
489 
490  ArcIteratorData(const ArcIteratorData &) = delete;
491 
492  ArcIteratorData &operator=(const ArcIteratorData &) = delete;
493 
494  std::unique_ptr<ArcIteratorBase<Arc>>
495  base; // Specialized iterator if non-null.
496  const Arc *arcs; // O.w. arcs pointer
497  size_t narcs; // ... and arc count.
498  int *ref_count; // ... and a reference count of the `narcs`-length `arcs`
499  // array if non-null.
500 };
501 
502 // Generic arc iterator, templated on the FST definition (a wrapper around a
503 // pointer to a specific one). Here is a typical use:
504 //
505 // for (ArcIterator<StdFst> aiter(fst, s);
506 // !aiter.Done();
507 // aiter.Next()) {
508 // StdArc &arc = aiter.Value();
509 // ...
510 // }
511 // There is no copying of the FST.
512 //
513 // Specializations may exist for some FST types.
514 // ArcIterators are thread-unsafe unless otherwise specified.
515 template <class FST>
516 class ArcIterator {
517  public:
518  using Arc = typename FST::Arc;
519  using StateId = typename Arc::StateId;
520 
521  ArcIterator(const FST &fst, StateId s) : i_(0) {
522  fst.InitArcIterator(s, &data_);
523  }
524 
525  explicit ArcIterator(const ArcIteratorData<Arc> &data) = delete;
526 
528  if (data_.ref_count) {
529  --(*data_.ref_count);
530  }
531  }
532 
533  bool Done() const {
534  return data_.base ? data_.base->Done() : i_ >= data_.narcs;
535  }
536 
537  const Arc &Value() const {
538  return data_.base ? data_.base->Value() : data_.arcs[i_];
539  }
540 
541  void Next() {
542  if (data_.base) {
543  data_.base->Next();
544  } else {
545  ++i_;
546  }
547  }
548 
549  void Reset() {
550  if (data_.base) {
551  data_.base->Reset();
552  } else {
553  i_ = 0;
554  }
555  }
556 
557  void Seek(size_t a) {
558  if (data_.base) {
559  data_.base->Seek(a);
560  } else {
561  i_ = a;
562  }
563  }
564 
565  size_t Position() const { return data_.base ? data_.base->Position() : i_; }
566 
567  uint8_t Flags() const {
568  return data_.base ? data_.base->Flags() : kArcValueFlags;
569  }
570 
571  void SetFlags(uint8_t flags, uint8_t mask) {
572  if (data_.base) data_.base->SetFlags(flags, mask);
573  }
574 
575  private:
576  ArcIteratorData<Arc> data_;
577  size_t i_;
578 };
579 
580 } // namespace fst
581 
582 // ArcIterator placement operator new and destroy function; new needs to be in
583 // the global namespace.
584 
585 template <class FST>
586 void *operator new(size_t size,
588  return pool->Allocate();
589 }
590 
591 namespace fst {
592 
593 template <class FST>
595  if (aiter) {
596  aiter->~ArcIterator<FST>();
597  pool->Free(aiter);
598  }
599 }
600 
601 // Matcher definitions.
602 
603 template <class Arc>
605  return nullptr; // One should just use the default matcher.
606 }
607 
608 // FST accessors, useful in high-performance applications.
609 
610 namespace internal {
611 
612 // General case, requires non-abstract, 'final' methods. Use for inlining.
613 
614 template <class F>
615 inline typename F::Arc::Weight Final(const F &fst, typename F::Arc::StateId s) {
616  return fst.F::Final(s);
617 }
618 
619 template <class F>
620 inline ssize_t NumArcs(const F &fst, typename F::Arc::StateId s) {
621  return fst.F::NumArcs(s);
622 }
623 
624 template <class F>
625 inline ssize_t NumInputEpsilons(const F &fst, typename F::Arc::StateId s) {
626  return fst.F::NumInputEpsilons(s);
627 }
628 
629 template <class F>
630 inline ssize_t NumOutputEpsilons(const F &fst, typename F::Arc::StateId s) {
631  return fst.F::NumOutputEpsilons(s);
632 }
633 
634 // Fst<Arc> case, abstract methods.
635 
636 template <class Arc>
637 inline typename Arc::Weight Final(const Fst<Arc> &fst,
638  typename Arc::StateId s) {
639  return fst.Final(s);
640 }
641 
642 template <class Arc>
643 inline size_t NumArcs(const Fst<Arc> &fst, typename Arc::StateId s) {
644  return fst.NumArcs(s);
645 }
646 
647 template <class Arc>
648 inline size_t NumInputEpsilons(const Fst<Arc> &fst, typename Arc::StateId s) {
649  return fst.NumInputEpsilons(s);
650 }
651 
652 template <class Arc>
653 inline size_t NumOutputEpsilons(const Fst<Arc> &fst, typename Arc::StateId s) {
654  return fst.NumOutputEpsilons(s);
655 }
656 
657 // FST implementation base.
658 //
659 // This is the recommended FST implementation base class. It will handle
660 // reference counts, property bits, type information and symbols.
661 //
662 // Users are discouraged, but not prohibited, from subclassing this outside the
663 // FST library.
664 //
665 // This class is thread-compatible except for the const SetProperties
666 // overload. Derived classes should be assumed to be thread-unsafe unless
667 // otherwise specified. Derived-class copy constructors must produce a
668 // thread-safe copy.
669 template <class Arc>
670 class FstImpl {
671  public:
672  using StateId = typename Arc::StateId;
673  using Weight = typename Arc::Weight;
674 
675  FstImpl() : properties_(0), type_("null") {}
676 
677  FstImpl(const FstImpl<Arc> &impl)
678  : properties_(impl.properties_.load(std::memory_order_relaxed)),
679  type_(impl.type_),
680  isymbols_(impl.isymbols_ ? impl.isymbols_->Copy() : nullptr),
681  osymbols_(impl.osymbols_ ? impl.osymbols_->Copy() : nullptr) {}
682 
683  FstImpl(FstImpl<Arc> &&impl) noexcept;
684 
685  virtual ~FstImpl() {}
686 
687  FstImpl &operator=(const FstImpl &impl) {
688  properties_.store(impl.properties_.load(std::memory_order_relaxed),
689  std::memory_order_relaxed);
690  type_ = impl.type_;
691  isymbols_ = impl.isymbols_ ? impl.isymbols_->Copy() : nullptr;
692  osymbols_ = impl.osymbols_ ? impl.osymbols_->Copy() : nullptr;
693  return *this;
694  }
695 
696  FstImpl &operator=(FstImpl &&impl) noexcept;
697 
698  const std::string &Type() const { return type_; }
699 
700  void SetType(std::string_view type) { type_ = std::string(type); }
701 
702  virtual uint64_t Properties() const {
703  return properties_.load(std::memory_order_relaxed);
704  }
705 
706  virtual uint64_t Properties(uint64_t mask) const {
707  return properties_.load(std::memory_order_relaxed) & mask;
708  }
709 
710  void SetProperties(uint64_t props) {
711  uint64_t properties = properties_.load(std::memory_order_relaxed);
712  properties &= kError; // kError can't be cleared.
713  properties |= props;
714  properties_.store(properties, std::memory_order_relaxed);
715  }
716 
717  void SetProperties(uint64_t props, uint64_t mask) {
718  // Unlike UpdateProperties, does not require compatibility between props
719  // and properties_, since it may be used to update properties after
720  // a mutation.
721  uint64_t properties = properties_.load(std::memory_order_relaxed);
722  properties &= ~mask | kError; // kError can't be cleared.
723  properties |= props & mask;
724  properties_.store(properties, std::memory_order_relaxed);
725  }
726 
727  // Allows (only) setting error bit on const FST implementations.
728  void SetProperties(uint64_t props, uint64_t mask) const {
729  if (mask != kError) {
730  FSTERROR() << "FstImpl::SetProperties() const: Can only set kError";
731  }
732  properties_.fetch_or(kError, std::memory_order_relaxed);
733  }
734 
735  // Sets the subset of the properties that have changed, in a thread-safe
736  // manner via atomic bitwise-or..
737  void UpdateProperties(uint64_t props, uint64_t mask) {
738  // If properties_ and props are compatible (for example kAcceptor and
739  // kNoAcceptor cannot both be set), the props can be or-ed in.
740  // Compatibility is ensured if props comes from ComputeProperties
741  // and properties_ is set correctly initially. However
742  // relying on properties to be set correctly is too large an
743  // assumption, as many places set them incorrectly.
744  // Therefore, we or in only the newly discovered properties.
745  // These cannot become inconsistent, but this means that
746  // incorrectly set properties will remain incorrect.
747  const uint64_t properties = properties_.load(std::memory_order_relaxed);
748  DCHECK(internal::CompatProperties(properties, props));
749  const uint64_t old_props = properties & mask;
750  const uint64_t old_mask = internal::KnownProperties(old_props);
751  const uint64_t discovered_mask = mask & ~old_mask;
752  const uint64_t discovered_props = props & discovered_mask;
753  // It is always correct to or these bits in, but do this only when
754  // necessary to avoid extra stores and possible cache flushes.
755  if (discovered_props != 0) {
756  properties_.fetch_or(discovered_props, std::memory_order_relaxed);
757  }
758  }
759 
760  const SymbolTable *InputSymbols() const { return isymbols_.get(); }
761 
762  const SymbolTable *OutputSymbols() const { return osymbols_.get(); }
763 
764  SymbolTable *InputSymbols() { return isymbols_.get(); }
765 
766  SymbolTable *OutputSymbols() { return osymbols_.get(); }
767 
768  void SetInputSymbols(const SymbolTable *isyms) {
769  isymbols_.reset(isyms ? isyms->Copy() : nullptr);
770  }
771 
772  void SetOutputSymbols(const SymbolTable *osyms) {
773  osymbols_.reset(osyms ? osyms->Copy() : nullptr);
774  }
775 
776  // Reads header and symbols from input stream, initializes FST, and returns
777  // the header. If opts.header is non-null, skips reading and uses the option
778  // value instead. If opts.[io]symbols is non-null, reads in (if present), but
779  // uses the option value.
780  bool ReadHeader(std::istream &strm, const FstReadOptions &opts,
781  int min_version, FstHeader *hdr);
782 
783  // Writes header and symbols to output stream. If opts.header is false, skips
784  // writing header. If opts.[io]symbols is false, skips writing those symbols.
785  // This method is needed for implementations that implement Write methods.
786  void WriteHeader(std::ostream &strm, const FstWriteOptions &opts, int version,
787  FstHeader *hdr) const {
788  if (opts.write_header) {
789  hdr->SetFstType(type_);
790  hdr->SetArcType(Arc::Type());
791  hdr->SetVersion(version);
792  hdr->SetProperties(properties_.load(std::memory_order_relaxed));
793  int32_t file_flags = 0;
794  if (isymbols_ && opts.write_isymbols) {
795  file_flags |= FstHeader::HAS_ISYMBOLS;
796  }
797  if (osymbols_ && opts.write_osymbols) {
798  file_flags |= FstHeader::HAS_OSYMBOLS;
799  }
800  if (opts.align) file_flags |= FstHeader::IS_ALIGNED;
801  hdr->SetFlags(file_flags);
802  hdr->Write(strm, opts.source);
803  }
804  if (isymbols_ && opts.write_isymbols) isymbols_->Write(strm);
805  if (osymbols_ && opts.write_osymbols) osymbols_->Write(strm);
806  }
807 
808  // Writes out header and symbols to output stream. If opts.header is false,
809  // skips writing header. If opts.[io]symbols is false, skips writing those
810  // symbols. `type` is the FST type being written. This method is used in the
811  // cross-type serialization methods Fst::WriteFst.
812  static void WriteFstHeader(const Fst<Arc> &fst, std::ostream &strm,
813  const FstWriteOptions &opts, int version,
814  std::string_view type, uint64_t properties,
815  FstHeader *hdr) {
816  if (opts.write_header) {
817  hdr->SetFstType(type);
818  hdr->SetArcType(Arc::Type());
819  hdr->SetVersion(version);
820  hdr->SetProperties(properties);
821  int32_t file_flags = 0;
822  if (fst.InputSymbols() && opts.write_isymbols) {
823  file_flags |= FstHeader::HAS_ISYMBOLS;
824  }
825  if (fst.OutputSymbols() && opts.write_osymbols) {
826  file_flags |= FstHeader::HAS_OSYMBOLS;
827  }
828  if (opts.align) file_flags |= FstHeader::IS_ALIGNED;
829  hdr->SetFlags(file_flags);
830  hdr->Write(strm, opts.source);
831  }
832  if (fst.InputSymbols() && opts.write_isymbols) {
833  fst.InputSymbols()->Write(strm);
834  }
835  if (fst.OutputSymbols() && opts.write_osymbols) {
836  fst.OutputSymbols()->Write(strm);
837  }
838  }
839 
840  // In serialization routines where the header cannot be written until after
841  // the machine has been serialized, this routine can be called to seek to the
842  // beginning of the file an rewrite the header with updated fields. It
843  // repositions the file pointer back at the end of the file. Returns true on
844  // success, false on failure.
845  static bool UpdateFstHeader(const Fst<Arc> &fst, std::ostream &strm,
846  const FstWriteOptions &opts, int version,
847  std::string_view type, uint64_t properties,
848  FstHeader *hdr, size_t header_offset) {
849  strm.seekp(header_offset);
850  if (!strm) {
851  LOG(ERROR) << "Fst::UpdateFstHeader: Write failed: " << opts.source;
852  return false;
853  }
854  WriteFstHeader(fst, strm, opts, version, type, properties, hdr);
855  if (!strm) {
856  LOG(ERROR) << "Fst::UpdateFstHeader: Write failed: " << opts.source;
857  return false;
858  }
859  strm.seekp(0, std::ios_base::end);
860  if (!strm) {
861  LOG(ERROR) << "Fst::UpdateFstHeader: Write failed: " << opts.source;
862  return false;
863  }
864  return true;
865  }
866 
867  protected:
868  // Use atomic so that UpdateProperties() can be thread-safe.
869  // This is always used with memory_order_relaxed because it's only used
870  // as a cache and not used to synchronize other operations.
871  mutable std::atomic<uint64_t> properties_; // Property bits.
872 
873  private:
874  std::string type_; // Unique name of FST class.
875  std::unique_ptr<SymbolTable> isymbols_;
876  std::unique_ptr<SymbolTable> osymbols_;
877 };
878 
879 template <class Arc>
880 inline FstImpl<Arc>::FstImpl(FstImpl<Arc> &&) noexcept = default;
881 
882 template <class Arc>
883 inline FstImpl<Arc> &FstImpl<Arc>::operator=(FstImpl<Arc> &&) noexcept =
884  default;
885 
886 template <class Arc>
887 bool FstImpl<Arc>::ReadHeader(std::istream &strm, const FstReadOptions &opts,
888  int min_version, FstHeader *hdr) {
889  if (opts.header) {
890  *hdr = *opts.header;
891  } else if (!hdr->Read(strm, opts.source)) {
892  return false;
893  }
894  VLOG(2) << "FstImpl::ReadHeader: source: " << opts.source
895  << ", fst_type: " << hdr->FstType() << ", arc_type: " << Arc::Type()
896  << ", version: " << hdr->Version() << ", flags: " << hdr->GetFlags();
897  if (hdr->FstType() != type_) {
898  LOG(ERROR) << "FstImpl::ReadHeader: FST not of type " << type_ << ", found "
899  << hdr->FstType() << ": " << opts.source;
900  return false;
901  }
902  if (hdr->ArcType() != Arc::Type()) {
903  LOG(ERROR) << "FstImpl::ReadHeader: Arc not of type " << Arc::Type()
904  << ", found " << hdr->ArcType() << ": " << opts.source;
905  return false;
906  }
907  if (hdr->Version() < min_version) {
908  LOG(ERROR) << "FstImpl::ReadHeader: Obsolete " << type_ << " FST version "
909  << hdr->Version() << ", min_version=" << min_version << ": "
910  << opts.source;
911  return false;
912  }
913  properties_.store(hdr->Properties(), std::memory_order_relaxed);
914  if (hdr->GetFlags() & FstHeader::HAS_ISYMBOLS) {
915  isymbols_.reset(SymbolTable::Read(strm, opts.source));
916  }
917  // Deletes input symbol table.
918  if (!opts.read_isymbols) SetInputSymbols(nullptr);
919  if (hdr->GetFlags() & FstHeader::HAS_OSYMBOLS) {
920  osymbols_.reset(SymbolTable::Read(strm, opts.source));
921  }
922  // Deletes output symbol table.
923  if (!opts.read_osymbols) SetOutputSymbols(nullptr);
924  if (opts.isymbols) {
925  isymbols_.reset(opts.isymbols->Copy());
926  }
927  if (opts.osymbols) {
928  osymbols_.reset(opts.osymbols->Copy());
929  }
930  return true;
931 }
932 
933 template <class Arc>
934 uint64_t TestProperties(const Fst<Arc> &fst, uint64_t mask, uint64_t *known);
935 
936 } // namespace internal
937 
938 // This is a helper class template useful for attaching an FST interface to
939 // its implementation, handling reference counting.
940 // Thread-unsafe due to Properties (a const function) calling
941 // Impl::SetProperties. TODO(jrosenstock): Make thread-compatible.
942 // Impl's copy constructor must produce a thread-safe copy.
943 template <class Impl, class FST = Fst<typename Impl::Arc>>
944 class ImplToFst : public FST {
945  public:
946  using Arc = typename Impl::Arc;
947  using StateId = typename Arc::StateId;
948  using Weight = typename Arc::Weight;
949 
950  StateId Start() const override { return impl_->Start(); }
951 
952  Weight Final(StateId s) const override { return impl_->Final(s); }
953 
954  size_t NumArcs(StateId s) const override { return impl_->NumArcs(s); }
955 
956  size_t NumInputEpsilons(StateId s) const override {
957  return impl_->NumInputEpsilons(s);
958  }
959 
960  size_t NumOutputEpsilons(StateId s) const override {
961  return impl_->NumOutputEpsilons(s);
962  }
963 
964  // Note that this is a const function, but can set the Impl's properties
965  // when test is true.
966  uint64_t Properties(uint64_t mask, bool test) const override {
967  if (test) {
968  uint64_t knownprops,
969  testprops = internal::TestProperties(*this, mask, &knownprops);
970  // Properties is a const member function, but can set the cached
971  // properties. UpdateProperties does this thread-safely via atomics.
972  impl_->UpdateProperties(testprops, knownprops);
973  return testprops & mask;
974  } else {
975  return impl_->Properties(mask);
976  }
977  }
978 
979  const std::string &Type() const override { return impl_->Type(); }
980 
981  const SymbolTable *InputSymbols() const override {
982  return impl_->InputSymbols();
983  }
984 
985  const SymbolTable *OutputSymbols() const override {
986  return impl_->OutputSymbols();
987  }
988 
989  protected:
990  explicit ImplToFst(std::shared_ptr<Impl> impl) : impl_(std::move(impl)) {}
991 
992  // The object is thread-compatible if constructed with safe=true,
993  // otherwise thread-unsafe.
994  // This constructor presumes there is a copy constructor for the
995  // implementation that produces a thread-safe copy.
996  ImplToFst(const ImplToFst &fst, bool safe) {
997  if (safe) {
998  impl_ = std::make_shared<Impl>(*(fst.impl_));
999  } else {
1000  impl_ = fst.impl_;
1001  }
1002  }
1003 
1004  ImplToFst() = delete;
1005 
1006  ImplToFst(const ImplToFst &fst) : impl_(fst.impl_) {}
1007 
1008  ImplToFst(ImplToFst &&fst) noexcept : impl_(std::move(fst.impl_)) {
1009  fst.impl_ = std::make_shared<Impl>();
1010  }
1011 
1013  impl_ = fst.impl_;
1014  return *this;
1015  }
1016 
1018  if (this != &fst) {
1019  impl_ = std::move(fst.impl_);
1020  fst.impl_ = std::make_shared<Impl>();
1021  }
1022  return *this;
1023  }
1024 
1025  // Returns raw pointers to the shared object.
1026  const Impl *GetImpl() const { return impl_.get(); }
1027 
1028  Impl *GetMutableImpl() const { return impl_.get(); }
1029 
1030  // Returns a ref-counted smart poiner to the implementation.
1031  std::shared_ptr<Impl> GetSharedImpl() const { return impl_; }
1032 
1033  bool Unique() const { return impl_.unique(); }
1034 
1035  void SetImpl(std::shared_ptr<Impl> impl) { impl_ = std::move(impl); }
1036 
1037  private:
1038  template <class IFST, class OFST>
1039  friend void Cast(const IFST &ifst, OFST *ofst);
1040 
1041  std::shared_ptr<Impl> impl_;
1042 };
1043 
1044 // Converts FSTs by casting their implementations, where this makes sense
1045 // (which excludes implementations with weight-dependent virtual methods).
1046 // Must be a friend of the FST classes involved (currently the concrete FSTs:
1047 // ConstFst, CompactFst, and VectorFst). This can only be safely used for arc
1048 // types that have identical storage characteristics. As with an FST
1049 // copy constructor and Copy() method, this is a constant time operation
1050 // (but subject to copy-on-write if it is a MutableFst and modified).
1051 template <class IFST, class OFST>
1052 void Cast(const IFST &ifst, OFST *ofst) {
1053  using OImpl = typename OFST::Impl;
1054  ofst->impl_ = std::shared_ptr<OImpl>(
1055  ifst.impl_, reinterpret_cast<OImpl *>(ifst.impl_.get()));
1056 }
1057 
1058 // FST serialization.
1059 
1060 template <class Arc>
1061 std::string FstToString(
1062  const Fst<Arc> &fst,
1063  const FstWriteOptions &options = FstWriteOptions("FstToString")) {
1064  std::ostringstream ostrm;
1065  fst.Write(ostrm, options);
1066  return ostrm.str();
1067 }
1068 
1069 template <class Arc>
1070 void FstToString(const Fst<Arc> &fst, std::string *result) {
1071  *result = FstToString(fst);
1072 }
1073 
1074 template <class Arc>
1075 void FstToString(const Fst<Arc> &fst, std::string *result,
1076  const FstWriteOptions &options) {
1077  *result = FstToString(fst, options);
1078 }
1079 
1080 template <class Arc>
1081 Fst<Arc> *StringToFst(const std::string &s) {
1082  std::istringstream istrm(s);
1083  return Fst<Arc>::Read(istrm, FstReadOptions("StringToFst"));
1084 }
1085 
1086 } // namespace fst
1087 
1088 #endif // FST_FST_H_
size_t Position() const
Definition: fst.h:565
bool Write(std::ostream &strm) const
Definition: symbol-table.h:479
bool Read(std::istream &strm, const std::string &source, bool rewind=false)
Definition: fst.cc:50
void SetProperties(uint64_t props, uint64_t mask) const
Definition: fst.h:728
void SetProperties(uint64_t props)
Definition: fst.h:710
uint64_t TestProperties(const Fst< Arc > &fst, uint64_t mask, uint64_t *known)
constexpr int32_t kFstMagicNumber
Definition: fst.h:55
void SetArcType(std::string_view type)
Definition: fst.h:160
const SymbolTable * OutputSymbols() const override
Definition: fst.h:985
constexpr uint8_t kArcValueFlags
Definition: fst.h:453
typename ArcMapFst< Arc, Arc, EncodeMapper< Arc > >::Arc Arc
Definition: fst.h:518
constexpr int kNoLabel
Definition: fst.h:201
const FstHeader * header
Definition: fst.h:75
void Cast(const F &, G *)
constexpr uint8_t kArcNoCache
Definition: fst.h:452
void Reset()
Definition: fst.h:549
static Fst * Read(std::istream &strm, const FstReadOptions &opts)
Definition: fst.h:257
ImplToFst & operator=(const ImplToFst &fst)
Definition: fst.h:1012
std::shared_ptr< Impl > GetSharedImpl() const
Definition: fst.h:1031
virtual size_t NumArcs(StateId) const =0
FstHeader()
Definition: fst.h:134
bool CompatProperties(uint64_t props1, uint64_t props2)
Definition: properties.h:506
std::string source
Definition: fst.h:74
const SymbolTable * OutputSymbols() const
Definition: fst.h:762
MatchType
Definition: fst.h:193
void SetFlags(const char *usage, int *argc, char ***argv, bool remove_flags, const char *src="")
Definition: flags.cc:56
virtual SymbolTable * Copy() const
Definition: symbol-table.h:407
constexpr uint8_t kArcFlags
Definition: fst.h:455
constexpr uint64_t kError
Definition: properties.h:51
virtual bool Write(std::ostream &strm, const FstWriteOptions &opts) const
Definition: fst.h:293
size_t NumArcs(const Fst< Arc > &fst, typename Arc::StateId s)
Definition: fst.h:643
#define LOG(type)
Definition: log.h:49
StateId Start() const override
Definition: fst.h:950
virtual Weight Final(StateId) const =0
void SetOutputSymbols(const SymbolTable *osyms)
Definition: fst.h:772
void SetNumArcs(int64_t numarcs)
Definition: fst.h:172
typename RandGenFst< FromArc, ToArc, Sampler >::Arc::StateId StateId
Definition: fst.h:361
ImplToFst(const ImplToFst &fst)
Definition: fst.h:1006
static Fst * Read(const std::string &source)
Definition: fst.h:278
typename ArcMapFst< Arc, Arc, EncodeMapper< Arc > >::Arc Arc
Definition: fst.h:408
typename FST::Arc::StateId StateId
Definition: fst.h:462
void SetProperties(uint64_t properties)
Definition: fst.h:166
constexpr uint8_t kArcILabelValue
Definition: fst.h:444
bool read_isymbols
Definition: fst.h:82
DECLARE_bool(fst_align)
~ArcIterator()
Definition: fst.h:527
size_t NumArcs(StateId s) const override
Definition: fst.h:954
bool stream_write
Definition: fst.h:107
ImplToFst(const ImplToFst &fst, bool safe)
Definition: fst.h:996
const SymbolTable * osymbols
Definition: fst.h:79
FstReadOptions(const std::string_view source="<unspecified>", const FstHeader *header=nullptr, const SymbolTable *isymbols=nullptr, const SymbolTable *osymbols=nullptr)
Definition: fst.cc:102
constexpr int kNoStateId
Definition: fst.h:202
SymbolTable * InputSymbols()
Definition: fst.h:764
const Arc & Value() const
Definition: fst.h:537
uint32_t GetFlags() const
Definition: fst.h:148
virtual size_t NumInputEpsilons(StateId) const =0
size_t NumInputEpsilons(StateId s) const override
Definition: fst.h:956
ArcIterator(const FST &fst, StateId s)
Definition: fst.h:521
std::string source
Definition: fst.h:102
#define FSTERROR()
Definition: util.h:53
const std::string & FstType() const
Definition: fst.h:142
static void WriteFstHeader(const Fst< Arc > &fst, std::ostream &strm, const FstWriteOptions &opts, int version, std::string_view type, uint64_t properties, FstHeader *hdr)
Definition: fst.h:812
void SetFlags(uint8_t flags, uint8_t mask)
Definition: fst.h:571
size_t NumOutputEpsilons(const Fst< Arc > &fst, typename Arc::StateId s)
Definition: fst.h:653
SymbolTable * OutputSymbols()
Definition: fst.h:766
bool write_osymbols
Definition: fst.h:105
const std::string & Type() const override
Definition: fst.h:979
ImplToFst & operator=(ImplToFst &&fst) noexcept
Definition: fst.h:1017
virtual ~FstImpl()
Definition: fst.h:685
virtual ~StateIteratorBase()
Definition: fst.h:363
typename Arc::StateId StateId
Definition: fst.h:379
virtual uint64_t Properties() const
Definition: fst.h:702
void Seek(size_t a)
Definition: fst.h:557
bool write_isymbols
Definition: fst.h:104
uint8_t Flags() const
Definition: fst.h:567
static bool UpdateFstHeader(const Fst< Arc > &fst, std::ostream &strm, const FstWriteOptions &opts, int version, std::string_view type, uint64_t properties, FstHeader *hdr, size_t header_offset)
Definition: fst.h:845
std::string DebugString() const
Definition: fst.cc:127
uint64_t KnownProperties(uint64_t props)
Definition: properties.h:499
StateId nstates
Definition: fst.h:384
size_t NumOutputEpsilons(StateId s) const override
Definition: fst.h:960
constexpr uint8_t kArcOLabelValue
Definition: fst.h:446
#define VLOG(level)
Definition: log.h:50
void WriteHeader(std::ostream &strm, const FstWriteOptions &opts, int version, FstHeader *hdr) const
Definition: fst.h:786
StateId Value() const
Definition: fst.h:419
bool Done() const
Definition: fst.h:533
typename S::Arc::Weight Weight
Definition: fst.h:673
std::unique_ptr< StateIteratorBase< Arc > > base
Definition: fst.h:382
static SymbolTable * Read(std::istream &strm, const std::string &source)
Definition: symbol-table.h:391
const SymbolTable * InputSymbols() const override
Definition: fst.h:981
std::unique_ptr< ArcIteratorBase< Arc > > base
Definition: fst.h:495
void SetInputSymbols(const SymbolTable *isyms)
Definition: fst.h:768
void SetImpl(std::shared_ptr< Impl > impl)
Definition: fst.h:1035
bool write_header
Definition: fst.h:103
FstWriteOptions(std::string_view source="<unspecified>", bool write_header=true, bool write_isymbols=true, bool write_osymbols=true, bool align=FST_FLAGS_fst_align, bool stream_write=false)
Definition: fst.h:109
virtual ~ArcIteratorBase()
Definition: fst.h:464
const std::string & Type() const
Definition: fst.h:698
bool WriteFile(const std::string &source) const
Definition: fst.h:332
static FileReadMode ReadMode(std::string_view mode)
Definition: fst.cc:120
constexpr uint8_t kArcWeightValue
Definition: fst.h:448
FstImpl(const FstImpl< Arc > &impl)
Definition: fst.h:677
int64_t NumArcs() const
Definition: fst.h:156
virtual ~Fst()
Definition: fst.h:215
ImplToFst(ImplToFst &&fst) noexcept
Definition: fst.h:1008
void SetNumStates(int64_t numstates)
Definition: fst.h:170
Arc::Weight Final(const Fst< Arc > &fst, typename Arc::StateId s)
Definition: fst.h:637
typename internal::SynchronizeFstImpl< A >::Arc Arc
Definition: fst.h:211
virtual bool Write(const std::string &source) const
Definition: fst.h:301
virtual const SymbolTable * InputSymbols() const =0
const SymbolTable * InputSymbols() const
Definition: fst.h:760
void Next()
Definition: fst.h:421
constexpr uint8_t kArcNextStateValue
Definition: fst.h:450
int64_t NumStates() const
Definition: fst.h:154
Weight Final(StateId s) const override
Definition: fst.h:952
void SetType(std::string_view type)
Definition: fst.h:700
bool Done() const
Definition: fst.h:415
void SetFstType(std::string_view type)
Definition: fst.h:158
void SetStart(int64_t start)
Definition: fst.h:168
const Arc * arcs
Definition: fst.h:496
bool Write(std::ostream &strm, const std::string &source) const
Definition: fst.cc:79
ImplToFst(std::shared_ptr< Impl > impl)
Definition: fst.h:990
virtual MatcherBase< Arc > * InitMatcher(MatchType match_type) const
Definition: fst.h:604
FileReadMode mode
Definition: fst.h:81
int64_t Start() const
Definition: fst.h:152
#define DCHECK(x)
Definition: log.h:70
const SymbolTable * isymbols
Definition: fst.h:77
int32_t Version() const
Definition: fst.h:146
Fst< Arc > * StringToFst(const std::string &s)
Definition: fst.h:1081
Impl * GetMutableImpl() const
Definition: fst.h:1028
void Reset()
Definition: fst.h:429
size_t NumInputEpsilons(const Fst< Arc > &fst, typename Arc::StateId s)
Definition: fst.h:648
void SetVersion(int32_t version)
Definition: fst.h:162
bool Unique() const
Definition: fst.h:1033
virtual size_t NumOutputEpsilons(StateId) const =0
void SetFlags(uint32_t flags)
Definition: fst.h:164
bool read_osymbols
Definition: fst.h:83
std::string FstToString(const Fst< Arc > &fst, const FstWriteOptions &options=FstWriteOptions("FstToString"))
Definition: fst.h:1061
const std::string & ArcType() const
Definition: fst.h:144
int * ref_count
Definition: fst.h:498
virtual uint64_t Properties(uint64_t mask) const
Definition: fst.h:706
void Destroy(ArcIterator< FST > *aiter, MemoryPool< ArcIterator< FST >> *pool)
Definition: fst.h:594
size_t narcs
Definition: fst.h:497
FstImpl & operator=(const FstImpl &impl)
Definition: fst.h:687
void UpdateProperties(uint64_t props, uint64_t mask)
Definition: fst.h:737
typename S::Arc::StateId StateId
Definition: fst.h:672
void SetProperties(uint64_t props, uint64_t mask)
Definition: fst.h:717
uint64_t Properties(uint64_t mask, bool test) const override
Definition: fst.h:966
const Impl * GetImpl() const
Definition: fst.h:1026
uint64_t Properties() const
Definition: fst.h:150
std::atomic< uint64_t > properties_
Definition: fst.h:871
virtual const SymbolTable * OutputSymbols() const =0
void Next()
Definition: fst.h:541
StateIterator(const FST &fst)
Definition: fst.h:411