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.
 
 
 

143 lines
4.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.
//
// Helper class template useful for attaching an FST interface to its
// implementation, handling reference counting.
#ifndef FST_IMPL_TO_FST_H_
#define FST_IMPL_TO_FST_H_
#include <cstdint>
#include <memory>
#include <string>
#include <fst/fst.h>
#include <fst/impl-to-fst.h>
#include <fst/symbol-table.h>
#include <fst/test-properties.h>
namespace fst {
// This is a helper class template useful for attaching an FST interface to
// its implementation, handling reference counting.
// Thread-unsafe due to Properties (a const function) calling
// Impl::SetProperties. TODO(jrosenstock): Make thread-compatible.
// Impl's copy constructor must produce a thread-safe copy.
template <class Impl, class FST = Fst<typename Impl::Arc>>
class ImplToFst : public FST {
public:
using Arc = typename Impl::Arc;
using StateId = typename Arc::StateId;
using Weight = typename Arc::Weight;
StateId Start() const override { return impl_->Start(); }
Weight Final(StateId s) const override { return impl_->Final(s); }
size_t NumArcs(StateId s) const override { return impl_->NumArcs(s); }
size_t NumInputEpsilons(StateId s) const override {
return impl_->NumInputEpsilons(s);
}
size_t NumOutputEpsilons(StateId s) const override {
return impl_->NumOutputEpsilons(s);
}
// Note that this is a const function, but can set the Impl's properties
// when test is true.
uint64_t Properties(uint64_t mask, bool test) const override {
if (test) {
uint64_t knownprops,
testprops = internal::TestProperties(*this, mask, &knownprops);
// Properties is a const member function, but can set the cached
// properties. UpdateProperties does this thread-safely via atomics.
impl_->UpdateProperties(testprops, knownprops);
return testprops & mask;
} else {
return impl_->Properties(mask);
}
}
const std::string &Type() const override { return impl_->Type(); }
const SymbolTable *InputSymbols() const override {
return impl_->InputSymbols();
}
const SymbolTable *OutputSymbols() const override {
return impl_->OutputSymbols();
}
protected:
explicit ImplToFst(std::shared_ptr<Impl> impl) : impl_(std::move(impl)) {}
// The object is thread-compatible if constructed with safe=true,
// otherwise thread-unsafe.
// This constructor presumes there is a copy constructor for the
// implementation that produces a thread-safe copy.
ImplToFst(const ImplToFst &fst, bool safe) {
if (safe) {
impl_ = std::make_shared<Impl>(*(fst.impl_));
} else {
impl_ = fst.impl_;
}
}
ImplToFst() = delete;
ImplToFst(const ImplToFst &fst) : impl_(fst.impl_) {}
ImplToFst(ImplToFst &&fst) noexcept : impl_(std::move(fst.impl_)) {
fst.impl_ = std::make_shared<Impl>();
}
ImplToFst &operator=(const ImplToFst &fst) {
impl_ = fst.impl_;
return *this;
}
ImplToFst &operator=(ImplToFst &&fst) noexcept {
if (this != &fst) {
impl_ = std::move(fst.impl_);
fst.impl_ = std::make_shared<Impl>();
}
return *this;
}
// Returns raw pointers to the shared object.
const Impl *GetImpl() const { return impl_.get(); }
Impl *GetMutableImpl() const { return impl_.get(); }
// Returns a ref-counted smart poiner to the implementation.
std::shared_ptr<Impl> GetSharedImpl() const { return impl_; }
bool Unique() const { return impl_.unique(); }
void SetImpl(std::shared_ptr<Impl> impl) { impl_ = std::move(impl); }
private:
template <class IFST, class OFST>
friend void Cast(const IFST &ifst, OFST *ofst);
std::shared_ptr<Impl> impl_;
};
} // namespace fst
#endif // FST_IMPL_TO_FST_H_