1d48814a6d829fa50c14914d28fa3d16f98cdd31
[platform/upstream/openfst.git] / src / include / fst / register.h
1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
3 //
4 // Classes for registering derived FST for generic reading.
5
6 #ifndef FST_LIB_REGISTER_H_
7 #define FST_LIB_REGISTER_H_
8
9 #include <string>
10
11
12 #include <fst/compat.h>
13 #include <fst/generic-register.h>
14 #include <fst/util.h>
15
16
17 #include <fst/types.h>
18 #include <fst/log.h>
19
20 namespace fst {
21
22 template <class Arc>
23 class Fst;
24
25 struct FstReadOptions;
26
27 // This class represents a single entry in a FstRegister
28 template <class Arc>
29 struct FstRegisterEntry {
30   using Reader = Fst<Arc> *(*)(std::istream &istrm, const FstReadOptions &opts);
31   using Converter = Fst<Arc> *(*)(const Fst<Arc> &fst);
32
33   Reader reader;
34   Converter converter;
35
36   explicit FstRegisterEntry(Reader reader = nullptr,
37                             Converter converter = nullptr)
38       : reader(reader), converter(converter) {}
39 };
40
41 // This class maintains the correspondence between a string describing
42 // an FST type, and its reader and converter.
43 template <class Arc>
44 class FstRegister
45     : public GenericRegister<string, FstRegisterEntry<Arc>, FstRegister<Arc>> {
46  public:
47   using Reader = typename FstRegisterEntry<Arc>::Reader;
48   using Converter = typename FstRegisterEntry<Arc>::Converter;
49
50   const Reader GetReader(const string &type) const {
51     return this->GetEntry(type).reader;
52   }
53
54   const Converter GetConverter(const string &type) const {
55     return this->GetEntry(type).converter;
56   }
57
58  protected:
59   string ConvertKeyToSoFilename(const string &key) const override {
60     string legal_type(key);
61     ConvertToLegalCSymbol(&legal_type);
62     return legal_type + "-fst.so";
63   }
64 };
65
66 // This class registers an FST type for generic reading and creating.
67 // The type must have a default constructor and a copy constructor from
68 // Fst<Arc>.
69 template <class FST>
70 class FstRegisterer : public GenericRegisterer<FstRegister<typename FST::Arc>> {
71  public:
72   using Arc = typename FST::Arc;
73   using Entry = typename FstRegister<Arc>::Entry;
74   using Reader = typename FstRegister<Arc>::Reader;
75
76   FstRegisterer()
77       : GenericRegisterer<FstRegister<typename FST::Arc>>(FST().Type(),
78                                                           BuildEntry()) {}
79
80  private:
81   static Entry BuildEntry() {
82     FST *(*reader)(std::istream & strm, const FstReadOptions &opts) =
83         &FST::Read;
84     return Entry(reinterpret_cast<Reader>(reader),
85                  &FstRegisterer<FST>::Convert);
86   }
87
88   static Fst<Arc> *Convert(const Fst<Arc> &fst) { return new FST(fst); }
89 };
90
91 // Convenience macro to generate static FstRegisterer instance.
92 #define REGISTER_FST(FST, Arc) \
93   static fst::FstRegisterer<FST<Arc>> FST##_##Arc##_registerer
94
95 // Converts an FST to the specified type.
96 template <class Arc>
97 Fst<Arc> *Convert(const Fst<Arc> &fst, const string &fst_type) {
98   auto *reg = FstRegister<Arc>::GetRegister();
99   const auto converter = reg->GetConverter(fst_type);
100   if (!converter) {
101     FSTERROR() << "Fst::Convert: Unknown FST type " << fst_type << " (arc type "
102                << Arc::Type() << ")";
103     return nullptr;
104   }
105   return converter(fst);
106 }
107
108 }  // namespace fst
109
110 #endif  // FST_LIB_REGISTER_H_