You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
5.3 KiB

  1. // Copyright 2005-2024 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the 'License');
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an 'AS IS' BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. // See www.openfst.org for extensive documentation on this weighted
  16. // finite-state transducer library.
  17. //
  18. // Classes for storing filter state in various algorithms like composition.
  19. #ifndef FST_FILTER_STATE_H_
  20. #define FST_FILTER_STATE_H_
  21. #include <climits>
  22. #include <cstddef>
  23. #include <forward_list>
  24. #include <utility>
  25. #include <fst/fst-decl.h> // For optional argument declarations
  26. #include <fst/fst.h>
  27. #include <fst/matcher.h>
  28. namespace fst {
  29. // The filter state interface represents the state of a (e.g., composition)
  30. // filter.
  31. //
  32. // class FilterState {
  33. // public:
  34. // // Required constructors.
  35. //
  36. // FilterState();
  37. //
  38. // FilterState(const FilterState &fs);
  39. //
  40. // // An invalid filter state.
  41. // static const FilterState NoState();
  42. //
  43. // // Maps state to integer for hashing.
  44. // size_t Hash() const;
  45. //
  46. // // Equality of filter states.
  47. // bool operator==(const FilterState &fs) const;
  48. //
  49. // // Inequality of filter states.
  50. // bool operator!=(const FilterState &fs) const;
  51. //
  52. // // Assignment to filter states.
  53. // FilterState &operator=(const FilterState& fs);
  54. // };
  55. // Filter state that is a signed integral type.
  56. template <typename T>
  57. class IntegerFilterState {
  58. public:
  59. IntegerFilterState() : state_(kNoStateId) {}
  60. explicit IntegerFilterState(T s) : state_(s) {}
  61. static const IntegerFilterState NoState() { return IntegerFilterState(); }
  62. size_t Hash() const { return static_cast<size_t>(state_); }
  63. bool operator==(const IntegerFilterState &fs) const {
  64. return state_ == fs.state_;
  65. }
  66. bool operator!=(const IntegerFilterState &fs) const {
  67. return state_ != fs.state_;
  68. }
  69. T GetState() const { return state_; }
  70. private:
  71. T state_;
  72. };
  73. using CharFilterState = IntegerFilterState<signed char>;
  74. using ShortFilterState = IntegerFilterState<short>; // NOLINT
  75. using IntFilterState = IntegerFilterState<int>;
  76. // Filter state that is a weight (class).
  77. template <class W>
  78. class WeightFilterState {
  79. public:
  80. WeightFilterState() : weight_(W::Zero()) {}
  81. explicit WeightFilterState(W weight) : weight_(std::move(weight)) {}
  82. static const WeightFilterState NoState() { return WeightFilterState(); }
  83. size_t Hash() const { return weight_.Hash(); }
  84. bool operator==(const WeightFilterState &fs) const {
  85. return weight_ == fs.weight_;
  86. }
  87. bool operator!=(const WeightFilterState &fs) const {
  88. return weight_ != fs.weight_;
  89. }
  90. W GetWeight() const { return weight_; }
  91. private:
  92. W weight_;
  93. };
  94. // Filter state is a list of signed integer types T. Order matters
  95. // for equality.
  96. template <typename T>
  97. class ListFilterState {
  98. public:
  99. ListFilterState() = default;
  100. explicit ListFilterState(T s) { list_.push_front(s); }
  101. static const ListFilterState NoState() { return ListFilterState(kNoStateId); }
  102. size_t Hash() const {
  103. size_t h = 0;
  104. for (const auto &elem : list_) h ^= h << 1 ^ elem;
  105. return h;
  106. }
  107. bool operator==(const ListFilterState &fs) const { return list_ == fs.list_; }
  108. bool operator!=(const ListFilterState &fs) const { return list_ != fs.list_; }
  109. const std::forward_list<T> &GetState() const { return list_; }
  110. std::forward_list<T> *GetMutableState() { return &list_; }
  111. private:
  112. std::forward_list<T> list_;
  113. };
  114. // Filter state that is the combination of two filter states.
  115. template <class FS1, class FS2>
  116. class PairFilterState {
  117. public:
  118. using FilterState1 = FS1;
  119. using FilterState2 = FS2;
  120. PairFilterState() : fs1_(FS1::NoState()), fs2_(FS2::NoState()) {}
  121. PairFilterState(const FilterState1 &fs1, const FilterState2 &fs2)
  122. : fs1_(fs1), fs2_(fs2) {}
  123. static const PairFilterState NoState() { return PairFilterState(); }
  124. size_t Hash() const {
  125. const auto h1 = fs1_.Hash();
  126. static constexpr auto lshift = 5;
  127. static constexpr auto rshift = CHAR_BIT * sizeof(size_t) - 5;
  128. return h1 << lshift ^ h1 >> rshift ^ fs2_.Hash();
  129. }
  130. bool operator==(const PairFilterState &fs) const {
  131. return fs1_ == fs.fs1_ && fs2_ == fs.fs2_;
  132. }
  133. bool operator!=(const PairFilterState &fs) const {
  134. return fs1_ != fs.fs1_ || fs2_ != fs.fs2_;
  135. }
  136. const FilterState1 &GetState1() const { return fs1_; }
  137. const FilterState2 &GetState2() const { return fs2_; }
  138. private:
  139. FilterState1 fs1_;
  140. FilterState2 fs2_;
  141. };
  142. // Single non-blocking filter state.
  143. class TrivialFilterState {
  144. public:
  145. explicit TrivialFilterState(bool state = false) : state_(state) {}
  146. static const TrivialFilterState NoState() { return TrivialFilterState(); }
  147. size_t Hash() const { return 0; }
  148. bool operator==(const TrivialFilterState &fs) const {
  149. return state_ == fs.state_;
  150. }
  151. bool operator!=(const TrivialFilterState &fs) const {
  152. return state_ != fs.state_;
  153. }
  154. private:
  155. bool state_;
  156. };
  157. } // namespace fst
  158. #endif // FST_FILTER_STATE_H_