// See www.openfst.org for extensive documentation on this weighted // finite-state transducer library. // // Classes for storing filter state in various algorithms like composition. #ifndef FST_FILTER_STATE_H_ #define FST_FILTER_STATE_H_ #include #include #include // For optional argument declarations #include #include namespace fst { // The filter state interface represents the state of a (e.g., composition) // filter. // // class FilterState { // public: // // Required constructors. // // FilterState(); // // FilterState(const FilterState &fs); // // // An invalid filter state. // static const FilterState NoState(); // // // Maps state to integer for hashing. // size_t Hash() const; // // // Equality of filter states. // bool operator==(const FilterState &fs) const; // // // Inequality of filter states. // bool operator!=(const FilterState &fs) const; // // // Assignment to filter states. // FilterState &operator=(const FilterState& fs); // }; // Filter state that is a signed integral type. template class IntegerFilterState { public: IntegerFilterState() : state_(kNoStateId) {} explicit IntegerFilterState(T s) : state_(s) {} static const IntegerFilterState NoState() { return IntegerFilterState(); } size_t Hash() const { return static_cast(state_); } bool operator==(const IntegerFilterState &fs) const { return state_ == fs.state_; } bool operator!=(const IntegerFilterState &fs) const { return state_ != fs.state_; } T GetState() const { return state_; } void SetState(T state) { state_ = state; } private: T state_; }; using CharFilterState = IntegerFilterState; using ShortFilterState = IntegerFilterState; // NOLINT using IntFilterState = IntegerFilterState; // Filter state that is a weight (class). template class WeightFilterState { public: WeightFilterState() : weight_(W::Zero()) {} explicit WeightFilterState(W weight) : weight_(std::move(weight)) {} static const WeightFilterState NoState() { return WeightFilterState(); } size_t Hash() const { return weight_.Hash(); } bool operator==(const WeightFilterState &fs) const { return weight_ == fs.weight_; } bool operator!=(const WeightFilterState &fs) const { return weight_ != fs.weight_; } W GetWeight() const { return weight_; } void SetWeight(W weight) { weight_ = std::move(weight); } private: W weight_; }; // Filter state is a list of signed integer types T. Order matters // for equality. template class ListFilterState { public: ListFilterState() {} explicit ListFilterState(T s) { list_.push_front(s); } static const ListFilterState NoState() { return ListFilterState(kNoStateId); } size_t Hash() const { size_t h = 0; for (const auto &elem : list_) h ^= h << 1 ^ elem; return h; } bool operator==(const ListFilterState &fs) const { return list_ == fs.list_; } bool operator!=(const ListFilterState &fs) const { return list_ != fs.list_; } const std::forward_list &GetState() const { return list_; } std::forward_list *GetMutableState() { return &list_; } void SetState(const std::forward_list &state) { list_ = state; } private: std::forward_list list_; }; // Filter state that is the combination of two filter states. template class PairFilterState { public: PairFilterState() : fs1_(FS1::NoState()), fs2_(FS2::NoState()) {} PairFilterState(const FS1 &fs1, const FS2 &fs2) : fs1_(fs1), fs2_(fs2) {} static const PairFilterState NoState() { return PairFilterState(); } size_t Hash() const { const auto h1 = fs1_.Hash(); static constexpr auto lshift = 5; static constexpr auto rshift = CHAR_BIT * sizeof(size_t) - 5; return h1 << lshift ^ h1 >> rshift ^ fs2_.Hash(); } bool operator==(const PairFilterState &fs) const { return fs1_ == fs.fs1_ && fs2_ == fs.fs2_; } bool operator!=(const PairFilterState &fs) const { return fs1_ != fs.fs1_ || fs2_ != fs.fs2_; } const FS1 &GetState1() const { return fs1_; } const FS2 &GetState2() const { return fs2_; } void SetState(const FS1 &fs1, const FS2 &fs2) { fs1_ = fs1; fs2_ = fs2; } private: FS1 fs1_; FS2 fs2_; }; // Single non-blocking filter state. class TrivialFilterState { public: explicit TrivialFilterState(bool state = false) : state_(state) {} static const TrivialFilterState NoState() { return TrivialFilterState(); } size_t Hash() const { return 0; } bool operator==(const TrivialFilterState &fs) const { return state_ == fs.state_; } bool operator!=(const TrivialFilterState &fs) const { return state_ != fs.state_; } private: bool state_; }; } // namespace fst #endif // FST_FILTER_STATE_H_