// 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 <climits>
|
|
#include <cstddef>
|
|
#include <forward_list>
|
|
#include <utility>
|
|
|
|
#include <fst/fst-decl.h> // For optional argument declarations
|
|
#include <fst/fst.h>
|
|
#include <fst/matcher.h>
|
|
|
|
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 <typename T>
|
|
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<size_t>(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<signed char>;
|
|
using ShortFilterState = IntegerFilterState<short>; // NOLINT
|
|
using IntFilterState = IntegerFilterState<int>;
|
|
|
|
// Filter state that is a weight (class).
|
|
template <class W>
|
|
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 <typename T>
|
|
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<T> &GetState() const { return list_; }
|
|
|
|
std::forward_list<T> *GetMutableState() { return &list_; }
|
|
|
|
private:
|
|
std::forward_list<T> list_;
|
|
};
|
|
|
|
// Filter state that is the combination of two filter states.
|
|
template <class FS1, class FS2>
|
|
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_
|