// See www.openfst.org for extensive documentation on this weighted // finite-state transducer library. #ifndef FST_SCRIPT_ENCODEMAPPER_CLASS_H_ #define FST_SCRIPT_ENCODEMAPPER_CLASS_H_ #include #include #include #include #include #include // Scripting API support for EncodeMapper. namespace fst { namespace script { // Virtual interface implemented by each concrete EncodeMapperClassImpl. class EncodeMapperImplBase { public: // Returns an encoded ArcClass. virtual ArcClass operator()(const ArcClass &a) = 0; virtual const string &ArcType() const = 0; virtual uint32 Flags() const = 0; virtual uint64 Properties(uint64 inprops) = 0; virtual EncodeType Type() const = 0; virtual const SymbolTable *InputSymbols() const = 0; virtual const SymbolTable *OutputSymbols() const = 0; virtual void SetInputSymbols(const SymbolTable *syms) = 0; virtual void SetOutputSymbols(const SymbolTable *syms) = 0; virtual const string &WeightType() const = 0; virtual ~EncodeMapperImplBase() {} }; // Templated implementation. template class EncodeMapperClassImpl : public EncodeMapperImplBase { public: EncodeMapperClassImpl(uint32 flags, EncodeType type) : encoder_(flags, type) {} ArcClass operator()(const ArcClass &a) final; const string &ArcType() const final { return Arc::Type(); } uint32 Flags() const final { return encoder_.Flags(); } uint64 Properties(uint64 inprops) final { return encoder_.Properties(inprops); } EncodeType Type() const final { return encoder_.Type(); } const SymbolTable *InputSymbols() const final { return encoder_.InputSymbols(); } const SymbolTable *OutputSymbols() const final { return encoder_.OutputSymbols(); } void SetInputSymbols(const SymbolTable *syms) final { encoder_.SetInputSymbols(syms); } void SetOutputSymbols(const SymbolTable *syms) final { encoder_.SetOutputSymbols(syms); } const string &WeightType() const final { return Arc::Weight::Type(); } ~EncodeMapperClassImpl() override {} EncodeMapper *GetImpl() const { return &encoder_; } EncodeMapper *GetImpl() { return &encoder_; } private: EncodeMapper encoder_; }; // This is returned by value because it is very likely to undergo return-value // optimization. template inline ArcClass EncodeMapperClassImpl::operator()(const ArcClass &a) { Arc arc(a.ilabel, a.olabel, *(a.weight.GetWeight()), a.nextstate); return ArcClass(encoder_(arc)); } class EncodeMapperClass; using InitEncodeMapperClassArgs = std::tuple; class EncodeMapperClass { public: EncodeMapperClass(const string &arc_type, uint32 flags, EncodeType type); template EncodeMapperClass(uint32 flags, EncodeType type) : impl_(new EncodeMapperClassImpl(flags, type)) {} ArcClass operator()(const ArcClass &arc) { return (*impl_)(arc); } const string &ArcType() const { return impl_->ArcType(); } uint32 Flags() const { return impl_->Flags(); } uint64 Properties(uint64 inprops) { return impl_->Properties(inprops); } EncodeType Type() const { return impl_->Type(); } const SymbolTable *InputSymbols() const { return impl_->InputSymbols(); } const SymbolTable *OutputSymbols() const { return impl_->OutputSymbols(); } void SetInputSymbols(const SymbolTable *syms) { impl_->SetInputSymbols(syms); } void SetOutputSymbols(const SymbolTable *syms) { impl_->SetOutputSymbols(syms); } const string &WeightType() const { return impl_->WeightType(); } template friend void InitEncodeMapperClass(InitEncodeMapperClassArgs *args); // Naturally, this exists in non-const and const forms. Encoding arcs or FSTs // mutates the underlying encoder; decoding them does not. template EncodeMapper *GetEncodeMapper() { if (Arc::Type() != ArcType()) { return nullptr; } else { auto *typed_impl = static_cast *>(impl_.get()); return typed_impl->GetImpl(); } } template const EncodeMapper *GetEncodeMapper() const { if (Arc::Type() != ArcType()) { return nullptr; } else { auto *typed_impl = static_cast *>(impl_.get()); return typed_impl->GetImpl(); } } private: std::unique_ptr impl_; }; template void InitEncodeMapperClass(InitEncodeMapperClassArgs *args) { std::get<2>(*args)->impl_.reset( new EncodeMapperClassImpl(std::get<0>(*args), std::get<1>(*args))); } } // namespace script } // namespace fst #endif // FST_SCRIPT_ENCODEMAPPER_CLASS_H_