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

// 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_