1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
4 // Classes for registering derived FST for generic reading.
6 #ifndef FST_LIB_REGISTER_H_
7 #define FST_LIB_REGISTER_H_
10 #include <type_traits>
13 #include <fst/compat.h>
14 #include <fst/generic-register.h>
18 #include <fst/types.h>
26 struct FstReadOptions;
28 // This class represents a single entry in a FstRegister
30 struct FstRegisterEntry {
31 using Reader = Fst<Arc> *(*)(std::istream &istrm, const FstReadOptions &opts);
32 using Converter = Fst<Arc> *(*)(const Fst<Arc> &fst);
37 explicit FstRegisterEntry(Reader reader = nullptr,
38 Converter converter = nullptr)
39 : reader(reader), converter(converter) {}
42 // This class maintains the correspondence between a string describing
43 // an FST type, and its reader and converter.
46 : public GenericRegister<string, FstRegisterEntry<Arc>, FstRegister<Arc>> {
48 using Reader = typename FstRegisterEntry<Arc>::Reader;
49 using Converter = typename FstRegisterEntry<Arc>::Converter;
51 const Reader GetReader(const string &type) const {
52 return this->GetEntry(type).reader;
55 const Converter GetConverter(const string &type) const {
56 return this->GetEntry(type).converter;
60 string ConvertKeyToSoFilename(const string &key) const override {
61 string legal_type(key);
62 ConvertToLegalCSymbol(&legal_type);
63 return legal_type + "-fst.so";
67 // This class registers an FST type for generic reading and creating.
68 // The type must have a default constructor and a copy constructor from
71 class FstRegisterer : public GenericRegisterer<FstRegister<typename FST::Arc>> {
73 using Arc = typename FST::Arc;
74 using Entry = typename FstRegister<Arc>::Entry;
75 using Reader = typename FstRegister<Arc>::Reader;
78 : GenericRegisterer<FstRegister<typename FST::Arc>>(FST().Type(),
82 static Fst<Arc> *ReadGeneric(
83 std::istream &strm, const FstReadOptions &opts) {
84 static_assert(std::is_base_of<Fst<Arc>, FST>::value,
85 "FST class does not inherit from Fst<Arc>");
86 return FST::Read(strm, opts);
89 static Entry BuildEntry() {
90 return Entry(&ReadGeneric, &FstRegisterer<FST>::Convert);
93 static Fst<Arc> *Convert(const Fst<Arc> &fst) { return new FST(fst); }
96 // Convenience macro to generate static FstRegisterer instance.
97 #define REGISTER_FST(FST, Arc) \
98 static fst::FstRegisterer<FST<Arc>> FST##_##Arc##_registerer
100 // Converts an FST to the specified type.
102 Fst<Arc> *Convert(const Fst<Arc> &fst, const string &fst_type) {
103 auto *reg = FstRegister<Arc>::GetRegister();
104 const auto converter = reg->GetConverter(fst_type);
106 FSTERROR() << "Fst::Convert: Unknown FST type " << fst_type << " (arc type "
107 << Arc::Type() << ")";
110 return converter(fst);
115 #endif // FST_LIB_REGISTER_H_