// Copyright 2005-2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the 'License'); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an 'AS IS' BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // 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 #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_; } 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_; } private: W weight_; }; // Filter state is a list of signed integer types T. Order matters // for equality. template class ListFilterState { public: ListFilterState() = default; 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_; } private: std::forward_list list_; }; // Filter state that is the combination of two filter states. template class PairFilterState { public: using FilterState1 = FS1; using FilterState2 = FS2; PairFilterState() : fs1_(FS1::NoState()), fs2_(FS2::NoState()) {} PairFilterState(const FilterState1 &fs1, const FilterState2 &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 FilterState1 &GetState1() const { return fs1_; } const FilterState2 &GetState2() const { return fs2_; } private: FilterState1 fs1_; FilterState2 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_