diff options
Diffstat (limited to 'kaldi_io/src/tools/openfst/include/fst/edit-fst.h')
-rw-r--r-- | kaldi_io/src/tools/openfst/include/fst/edit-fst.h | 779 |
1 files changed, 0 insertions, 779 deletions
diff --git a/kaldi_io/src/tools/openfst/include/fst/edit-fst.h b/kaldi_io/src/tools/openfst/include/fst/edit-fst.h deleted file mode 100644 index bd33b9d..0000000 --- a/kaldi_io/src/tools/openfst/include/fst/edit-fst.h +++ /dev/null @@ -1,779 +0,0 @@ - -// 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. -// -// Copyright 2005-2010 Google, Inc. -// Author: [email protected] (Dan Bikel) -// -// An \ref Fst implementation that allows non-destructive edit operations on an -// existing fst. - -#ifndef FST_LIB_EDIT_FST_H_ -#define FST_LIB_EDIT_FST_H_ - -#include <vector> -using std::vector; - -#include <fst/cache.h> - -#include <tr1/unordered_map> -using std::tr1::unordered_map; -using std::tr1::unordered_multimap; - -namespace fst { - -// The EditFst class enables non-destructive edit operations on a wrapped -// ExpandedFst. The implementation uses copy-on-write semantics at the node -// level: if a user has an underlying fst on which he or she wants to perform a -// relatively small number of edits (read: mutations), then this implementation -// will copy the edited node to an internal MutableFst and perform any edits in -// situ on that copied node. This class supports all the methods of MutableFst -// except for DeleteStates(const vector<StateId> &); thus, new nodes may also be -// added, and one may add transitions from existing nodes of the wrapped fst to -// new nodes. -// -// N.B.: The documentation for Fst::Copy(true) says that its behavior is -// undefined if invoked on an fst that has already been accessed. This class -// requires that the Fst implementation it wraps provides consistent, reliable -// behavior when its Copy(true) method is invoked, where consistent means -// the graph structure, graph properties and state numbering and do not change. -// VectorFst and CompactFst, for example, are both well-behaved in this regard. - -// The EditFstData class is a container for all mutable data for EditFstImpl; -// also, this class provides most of the actual implementation of what EditFst -// does (that is, most of EditFstImpl's methods delegate to methods in this, the -// EditFstData class). Instances of this class are reference-counted and can be -// shared between otherwise independent EditFstImpl instances. This scheme -// allows EditFstImpl to implement the thread-safe, copy-on-write semantics -// required by Fst::Copy(true). -// -// template parameters: -// A the type of arc to use -// WrappedFstT the type of fst wrapped by the EditFst instance that -// this EditFstData instance is backing -// MutableFstT the type of mutable fst to use internally for edited states; -// crucially, MutableFstT::Copy(false) *must* yield an fst that is -// thread-safe for reading (VectorFst, for example, has this property) -template <typename A, - typename WrappedFstT = ExpandedFst<A>, - typename MutableFstT = VectorFst<A> > -class EditFstData { - public: - typedef A Arc; - typedef typename A::Weight Weight; - typedef typename A::StateId StateId; - typedef typename unordered_map<StateId, StateId>::const_iterator - IdMapIterator; - typedef typename unordered_map<StateId, Weight>::const_iterator - FinalWeightIterator; - - - EditFstData() : num_new_states_(0) { - SetEmptyAndDeleteKeysForInternalMaps(); - } - - EditFstData(const EditFstData &other) : - edits_(other.edits_), - external_to_internal_ids_(other.external_to_internal_ids_), - edited_final_weights_(other.edited_final_weights_), - num_new_states_(other.num_new_states_) { - } - - ~EditFstData() { - } - - static EditFstData<A, WrappedFstT, MutableFstT> *Read(istream &strm, - const FstReadOptions &opts); - - bool Write(ostream &strm, const FstWriteOptions &opts) const { - // Serialize all private data members of this class. - FstWriteOptions edits_opts(opts); - edits_opts.write_header = true; // Force writing contained header. - edits_.Write(strm, edits_opts); - WriteType(strm, external_to_internal_ids_); - WriteType(strm, edited_final_weights_); - WriteType(strm, num_new_states_); - if (!strm) { - LOG(ERROR) << "EditFstData::Write: write failed: " << opts.source; - return false; - } - return true; - } - - int RefCount() const { return ref_count_.count(); } - int IncrRefCount() { return ref_count_.Incr(); } - int DecrRefCount() { return ref_count_.Decr(); } - - StateId NumNewStates() const { - return num_new_states_; - } - - // accessor methods for the fst holding edited states - StateId EditedStart() const { - return edits_.Start(); - } - - Weight Final(StateId s, const WrappedFstT *wrapped) const { - FinalWeightIterator final_weight_it = GetFinalWeightIterator(s); - if (final_weight_it == NotInFinalWeightMap()) { - IdMapIterator it = GetEditedIdMapIterator(s); - return it == NotInEditedMap() ? - wrapped->Final(s) : edits_.Final(it->second); - } - else { - return final_weight_it->second; - } - } - - size_t NumArcs(StateId s, const WrappedFstT *wrapped) const { - IdMapIterator it = GetEditedIdMapIterator(s); - return it == NotInEditedMap() ? - wrapped->NumArcs(s) : edits_.NumArcs(it->second); - } - - size_t NumInputEpsilons(StateId s, const WrappedFstT *wrapped) const { - IdMapIterator it = GetEditedIdMapIterator(s); - return it == NotInEditedMap() ? - wrapped->NumInputEpsilons(s) : - edits_.NumInputEpsilons(it->second); - } - - size_t NumOutputEpsilons(StateId s, const WrappedFstT *wrapped) const { - IdMapIterator it = GetEditedIdMapIterator(s); - return it == NotInEditedMap() ? - wrapped->NumOutputEpsilons(s) : - edits_.NumOutputEpsilons(it->second); - } - - void SetEditedProperties(uint64 props, uint64 mask) { - edits_.SetProperties(props, mask); - } - - // non-const MutableFst operations - - // Sets the start state for this fst. - void SetStart(StateId s) { - edits_.SetStart(s); - } - - // Sets the final state for this fst. - Weight SetFinal(StateId s, Weight w, const WrappedFstT *wrapped) { - Weight old_weight = Final(s, wrapped); - IdMapIterator it = GetEditedIdMapIterator(s); - // if we haven't already edited state s, don't add it to edited_ (which can - // be expensive if s has many transitions); just use the - // edited_final_weights_ map - if (it == NotInEditedMap()) { - edited_final_weights_[s] = w; - } - else { - edits_.SetFinal(GetEditableInternalId(s, wrapped), w); - } - return old_weight; - } - - // Adds a new state to this fst, initially with no arcs. - StateId AddState(StateId curr_num_states) { - StateId internal_state_id = edits_.AddState(); - StateId external_state_id = curr_num_states; - external_to_internal_ids_[external_state_id] = internal_state_id; - num_new_states_++; - return external_state_id; - } - - // Adds the specified arc to the specified state of this fst. - const A *AddArc(StateId s, const Arc &arc, const WrappedFstT *wrapped) { - StateId internal_id = GetEditableInternalId(s, wrapped); - - size_t num_arcs = edits_.NumArcs(internal_id); - ArcIterator<MutableFstT> arc_it(edits_, internal_id); - const A *prev_arc = NULL; - if (num_arcs > 0) { - // grab the final arc associated with this state in edits_ - arc_it.Seek(num_arcs - 1); - prev_arc = &(arc_it.Value()); - } - edits_.AddArc(internal_id, arc); - return prev_arc; - } - - void DeleteStates() { - edits_.DeleteStates(); - num_new_states_ = 0; - external_to_internal_ids_.clear(); - edited_final_weights_.clear(); - } - - // Removes all but the first n outgoing arcs of the specified state. - void DeleteArcs(StateId s, size_t n, const WrappedFstT *wrapped) { - edits_.DeleteArcs(GetEditableInternalId(s, wrapped), n); - } - - // Removes all outgoing arcs from the specified state. - void DeleteArcs(StateId s, const WrappedFstT *wrapped) { - edits_.DeleteArcs(GetEditableInternalId(s, wrapped)); - } - - // end methods for non-const MutableFst operations - - // Provides information for the generic arc iterator. - void InitArcIterator(StateId s, ArcIteratorData<Arc> *data, - const WrappedFstT *wrapped) const { - IdMapIterator id_map_it = GetEditedIdMapIterator(s); - if (id_map_it == NotInEditedMap()) { - VLOG(3) << "EditFstData::InitArcIterator: iterating on state " - << s << " of original fst"; - wrapped->InitArcIterator(s, data); - } else { - VLOG(2) << "EditFstData::InitArcIterator: iterating on edited state " - << s << " (internal state id: " << id_map_it->second << ")"; - edits_.InitArcIterator(id_map_it->second, data); - } - } - - // Provides information for the generic mutable arc iterator. - void InitMutableArcIterator(StateId s, MutableArcIteratorData<A> *data, - const WrappedFstT *wrapped) { - data->base = - new MutableArcIterator<MutableFstT>(&edits_, - GetEditableInternalId(s, wrapped)); - } - - // Prints out the map from external to internal state id's (for debugging - // purposes). - void PrintMap() { - for (IdMapIterator map_it = external_to_internal_ids_.begin(); - map_it != NotInEditedMap(); ++map_it) { - LOG(INFO) << "(external,internal)=(" - << map_it->first << "," << map_it->second << ")"; - } - } - - - private: - void SetEmptyAndDeleteKeysForInternalMaps() { - } - - // Returns the iterator of the map from external to internal state id's - // of edits_ for the specified external state id. - IdMapIterator GetEditedIdMapIterator(StateId s) const { - return external_to_internal_ids_.find(s); - } - IdMapIterator NotInEditedMap() const { - return external_to_internal_ids_.end(); - } - - FinalWeightIterator GetFinalWeightIterator(StateId s) const { - return edited_final_weights_.find(s); - } - FinalWeightIterator NotInFinalWeightMap() const { - return edited_final_weights_.end(); - } - - // Returns the internal state id of the specified external id if the state has - // already been made editable, or else copies the state from wrapped_ - // to edits_ and returns the state id of the newly editable state in edits_. - // - // \return makes the specified state editable if it isn't already and returns - // its state id in edits_ - StateId GetEditableInternalId(StateId s, const WrappedFstT *wrapped) { - IdMapIterator id_map_it = GetEditedIdMapIterator(s); - if (id_map_it == NotInEditedMap()) { - StateId new_internal_id = edits_.AddState(); - VLOG(2) << "EditFstData::GetEditableInternalId: editing state " << s - << " of original fst; new internal state id:" << new_internal_id; - external_to_internal_ids_[s] = new_internal_id; - for (ArcIterator< Fst<A> > arc_iterator(*wrapped, s); - !arc_iterator.Done(); - arc_iterator.Next()) { - edits_.AddArc(new_internal_id, arc_iterator.Value()); - } - // copy the final weight - FinalWeightIterator final_weight_it = GetFinalWeightIterator(s); - if (final_weight_it == NotInFinalWeightMap()) { - edits_.SetFinal(new_internal_id, wrapped->Final(s)); - } else { - edits_.SetFinal(new_internal_id, final_weight_it->second); - edited_final_weights_.erase(s); - } - return new_internal_id; - } else { - return id_map_it->second; - } - } - - // A mutable fst (by default, a VectorFst) to contain new states, and/or - // copies of states from a wrapped ExpandedFst that have been modified in - // some way. - MutableFstT edits_; - // A mapping from external state id's to the internal id's of states that - // appear in edits_. - unordered_map<StateId, StateId> external_to_internal_ids_; - // A mapping from external state id's to final state weights assigned to - // those states. The states in this map are *only* those whose final weight - // has been modified; if any other part of the state has been modified, - // the entire state is copied to edits_, and all modifications reside there. - unordered_map<StateId, Weight> edited_final_weights_; - // The number of new states added to this mutable fst impl, which is <= the - // number of states in edits_ (since edits_ contains both edited *and* new - // states). - StateId num_new_states_; - RefCounter ref_count_; -}; - -// EditFstData method implementations: just the Read method. -template <typename A, typename WrappedFstT, typename MutableFstT> -EditFstData<A, WrappedFstT, MutableFstT> * -EditFstData<A, WrappedFstT, MutableFstT>::Read(istream &strm, - const FstReadOptions &opts) { - EditFstData<A, WrappedFstT, MutableFstT> *data = - new EditFstData<A, WrappedFstT, MutableFstT>(); - // next read in MutabelFstT machine that stores edits - FstReadOptions edits_opts(opts); - edits_opts.header = 0; // Contained header was written out, so read it in. - - // Because our internal representation of edited states is a solid object - // of type MutableFstT (defaults to VectorFst<A>) and not a pointer, - // and because the static Read method allocates a new object on the heap, - // we need to call Read, check if there was a failure, use - // MutableFstT::operator= to assign the object (not the pointer) to the - // edits_ data member (which will increase the ref count by 1 on the impl) - // and, finally, delete the heap-allocated object. - MutableFstT *edits = MutableFstT::Read(strm, edits_opts); - if (!edits) { - return 0; - } - data->edits_ = *edits; - delete edits; - // finally, read in rest of private data members - ReadType(strm, &data->external_to_internal_ids_); - ReadType(strm, &data->edited_final_weights_); - ReadType(strm, &data->num_new_states_); - if (!strm) { - LOG(ERROR) << "EditFst::Read: read failed: " << opts.source; - return 0; - } - return data; -} - -// This class enables non-destructive edit operations on a wrapped ExpandedFst. -// The implementation uses copy-on-write semantics at the node level: if a user -// has an underlying fst on which he or she wants to perform a relatively small -// number of edits (read: mutations), then this implementation will copy the -// edited node to an internal MutableFst and perform any edits in situ on that -// copied node. This class supports all the methods of MutableFst except for -// DeleteStates(const vector<StateId> &); thus, new nodes may also be added, and -// one may add transitions from existing nodes of the wrapped fst to new nodes. -// -// template parameters: -// A the type of arc to use -// WrappedFstT the type of fst wrapped by the EditFst instance that -// this EditFstImpl instance is backing -// MutableFstT the type of mutable fst to use internally for edited states; -// crucially, MutableFstT::Copy(false) *must* yield an fst that is -// thread-safe for reading (VectorFst, for example, has this property) -template <typename A, - typename WrappedFstT = ExpandedFst<A>, - typename MutableFstT = VectorFst<A> > -class EditFstImpl : public FstImpl<A> { - public: - using FstImpl<A>::SetProperties; - using FstImpl<A>::SetInputSymbols; - using FstImpl<A>::SetOutputSymbols; - using FstImpl<A>::WriteHeader; - - typedef A Arc; - typedef typename Arc::Weight Weight; - typedef typename Arc::StateId StateId; - - // Constructs an editable fst implementation with no states. Effectively, - // this initially-empty fst will in every way mimic the behavior of - // a VectorFst--more precisely, a VectorFstImpl instance--but with slightly - // slower performance (by a constant factor), due to the fact that - // this class maintains a mapping between external state id's and - // their internal equivalents. - EditFstImpl() { - FstImpl<A>::SetType("edit"); - wrapped_ = new MutableFstT(); - InheritPropertiesFromWrapped(); - data_ = new EditFstData<A, WrappedFstT, MutableFstT>(); - } - - // Wraps the specified ExpandedFst. This constructor requires that the - // specified Fst is an ExpandedFst instance. This requirement is only enforced - // at runtime. (See below for the reason.) - // - // This library uses the pointer-to-implementation or "PIMPL" design pattern. - // In particular, to make it convenient to bind an implementation class to its - // interface, there are a pair of template "binder" classes, one for immutable - // and one for mutable fst's (ImplToFst and ImplToMutableFst, respectively). - // As it happens, the API for the ImplToMutableFst<I,F> class requires that - // the implementation class--the template parameter "I"--have a constructor - // taking a const Fst<A> reference. Accordingly, the constructor here must - // perform a static_cast to the WrappedFstT type required by EditFst and - // therefore EditFstImpl. - explicit EditFstImpl(const Fst<A> &wrapped) - : wrapped_(static_cast<WrappedFstT *>(wrapped.Copy())) { - FstImpl<A>::SetType("edit"); - - data_ = new EditFstData<A, WrappedFstT, MutableFstT>(); - // have edits_ inherit all properties from wrapped_ - data_->SetEditedProperties(wrapped_->Properties(kFstProperties, false), - kFstProperties); - InheritPropertiesFromWrapped(); - } - - // A copy constructor for this implementation class, used to implement - // the Copy() method of the Fst interface. - EditFstImpl(const EditFstImpl &impl) - : FstImpl<A>(), - wrapped_(static_cast<WrappedFstT *>(impl.wrapped_->Copy(true))), - data_(impl.data_) { - data_->IncrRefCount(); - SetProperties(impl.Properties()); - } - - ~EditFstImpl() { - delete wrapped_; - if (!data_->DecrRefCount()) { - delete data_; - } - } - - // const Fst/ExpandedFst operations, declared in the Fst and ExpandedFst - // interfaces - StateId Start() const { - StateId edited_start = data_->EditedStart(); - return edited_start == kNoStateId ? wrapped_->Start() : edited_start; - } - - Weight Final(StateId s) const { - return data_->Final(s, wrapped_); - } - - size_t NumArcs(StateId s) const { - return data_->NumArcs(s, wrapped_); - } - - size_t NumInputEpsilons(StateId s) const { - return data_->NumInputEpsilons(s, wrapped_); - } - - size_t NumOutputEpsilons(StateId s) const { - return data_->NumOutputEpsilons(s, wrapped_); - } - - StateId NumStates() const { - return wrapped_->NumStates() + data_->NumNewStates(); - } - - static EditFstImpl<A, WrappedFstT, MutableFstT> * - Read(istream &strm, - const FstReadOptions &opts); - - bool Write(ostream &strm, const FstWriteOptions &opts) const { - FstHeader hdr; - hdr.SetStart(Start()); - hdr.SetNumStates(NumStates()); - FstWriteOptions header_opts(opts); - header_opts.write_isymbols = false; // Let contained FST hold any symbols. - header_opts.write_osymbols = false; - WriteHeader(strm, header_opts, kFileVersion, &hdr); - - // First, serialize wrapped fst to stream. - FstWriteOptions wrapped_opts(opts); - wrapped_opts.write_header = true; // Force writing contained header. - wrapped_->Write(strm, wrapped_opts); - - data_->Write(strm, opts); - - strm.flush(); - if (!strm) { - LOG(ERROR) << "EditFst::Write: write failed: " << opts.source; - return false; - } - return true; - } - // end const Fst operations - - // non-const MutableFst operations - - // Sets the start state for this fst. - void SetStart(StateId s) { - MutateCheck(); - data_->SetStart(s); - SetProperties(SetStartProperties(FstImpl<A>::Properties())); - } - - // Sets the final state for this fst. - void SetFinal(StateId s, Weight w) { - MutateCheck(); - Weight old_weight = data_->SetFinal(s, w, wrapped_); - SetProperties(SetFinalProperties(FstImpl<A>::Properties(), old_weight, w)); - } - - // Adds a new state to this fst, initially with no arcs. - StateId AddState() { - MutateCheck(); - SetProperties(AddStateProperties(FstImpl<A>::Properties())); - return data_->AddState(NumStates()); - } - - // Adds the specified arc to the specified state of this fst. - void AddArc(StateId s, const Arc &arc) { - MutateCheck(); - const A *prev_arc = data_->AddArc(s, arc, wrapped_); - SetProperties(AddArcProperties(FstImpl<A>::Properties(), s, arc, prev_arc)); - } - - void DeleteStates(const vector<StateId>& dstates) { - FSTERROR() << ": EditFstImpl::DeleteStates(const std::vector<StateId>&): " - << " not implemented"; - SetProperties(kError, kError); - } - - // Deletes all states in this fst. - void DeleteStates(); - - // Removes all but the first n outgoing arcs of the specified state. - void DeleteArcs(StateId s, size_t n) { - MutateCheck(); - data_->DeleteArcs(s, n, wrapped_); - SetProperties(DeleteArcsProperties(FstImpl<A>::Properties())); - } - - // Removes all outgoing arcs from the specified state. - void DeleteArcs(StateId s) { - MutateCheck(); - data_->DeleteArcs(s, wrapped_); - SetProperties(DeleteArcsProperties(FstImpl<A>::Properties())); - } - - void ReserveStates(StateId s) { - } - - void ReserveArcs(StateId s, size_t n) { - } - - // end non-const MutableFst operations - - // Provides information for the generic state iterator. - void InitStateIterator(StateIteratorData<Arc> *data) const { - data->base = 0; - data->nstates = NumStates(); - } - - // Provides information for the generic arc iterator. - void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const { - data_->InitArcIterator(s, data, wrapped_); - } - - // Provides information for the generic mutable arc iterator. - void InitMutableArcIterator(StateId s, MutableArcIteratorData<A> *data) { - MutateCheck(); - data_->InitMutableArcIterator(s, data, wrapped_); - } - - private: - typedef typename unordered_map<StateId, StateId>::const_iterator - IdMapIterator; - typedef typename unordered_map<StateId, Weight>::const_iterator - FinalWeightIterator; - // Properties always true of this Fst class - static const uint64 kStaticProperties = kExpanded | kMutable; - // Current file format version - static const int kFileVersion = 2; - // Minimum file format version supported - static const int kMinFileVersion = 2; - - // Causes this fst to inherit all the properties from its wrapped fst, except - // for the two properties that always apply to EditFst instances: kExpanded - // and kMutable. - void InheritPropertiesFromWrapped() { - SetProperties(wrapped_->Properties(kCopyProperties, false) | - kStaticProperties); - SetInputSymbols(wrapped_->InputSymbols()); - SetOutputSymbols(wrapped_->OutputSymbols()); - } - - // This method ensures that any operations that alter the mutable data - // portion of this EditFstImpl cause the data_ member to be copied when its - // reference count is greater than 1. Note that this method is distinct from - // MutableFst::Mutate, which gets invoked whenever one of the basic mutation - // methods defined in MutableFst is invoked, such as SetInputSymbols. - // The MutateCheck here in EditFstImpl is invoked whenever one of the - // mutating methods specifically related to the types of edits provided - // by EditFst is performed, such as changing an arc of an existing state - // of the wrapped fst via a MutableArcIterator, or adding a new state via - // AddState(). - void MutateCheck() { - if (data_->RefCount() > 1) { - EditFstData<A, WrappedFstT, MutableFstT> *data_copy = - new EditFstData<A, WrappedFstT, MutableFstT>(*data_); - if (data_ && !data_->DecrRefCount()) { - delete data_; - } - data_ = data_copy; - } - } - - // The fst that this fst wraps. The purpose of this class is to enable - // non-destructive edits on this wrapped fst. - const WrappedFstT *wrapped_; - // The mutable data for this EditFst instance, with delegates for all the - // methods that can mutate data. - EditFstData<A, WrappedFstT, MutableFstT> *data_; -}; - -template <typename A, typename WrappedFstT, typename MutableFstT> -const uint64 EditFstImpl<A, WrappedFstT, MutableFstT>::kStaticProperties; - -// EditFstImpl IMPLEMENTATION STARTS HERE - -template<typename A, typename WrappedFstT, typename MutableFstT> -inline void EditFstImpl<A, WrappedFstT, MutableFstT>::DeleteStates() { - data_->DeleteStates(); - delete wrapped_; - // we are deleting all states, so just forget about pointer to wrapped_ - // and do what default constructor does: set wrapped_ to a new VectorFst - wrapped_ = new MutableFstT(); - uint64 newProps = DeleteAllStatesProperties(FstImpl<A>::Properties(), - kStaticProperties); - FstImpl<A>::SetProperties(newProps); -} - -template <typename A, typename WrappedFstT, typename MutableFstT> -EditFstImpl<A, WrappedFstT, MutableFstT> * -EditFstImpl<A, WrappedFstT, MutableFstT>::Read(istream &strm, - const FstReadOptions &opts) { - EditFstImpl<A, WrappedFstT, MutableFstT> *impl = new EditFstImpl(); - FstHeader hdr; - if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) { - return 0; - } - impl->SetStart(hdr.Start()); - - // first, read in wrapped fst - FstReadOptions wrapped_opts(opts); - wrapped_opts.header = 0; // Contained header was written out, so read it in. - Fst<A> *wrapped_fst = Fst<A>::Read(strm, wrapped_opts); - if (!wrapped_fst) { - return 0; - } - impl->wrapped_ = static_cast<WrappedFstT *>(wrapped_fst); - - impl->data_ = EditFstData<A, WrappedFstT, MutableFstT>::Read(strm, opts); - - if (!impl->data_) { - delete wrapped_fst; - return 0; - } - - return impl; -} - -// END EditFstImpl IMPLEMENTATION - -// Concrete, editable FST. This class attaches interface to implementation. -template <typename A, - typename WrappedFstT = ExpandedFst<A>, - typename MutableFstT = VectorFst<A> > -class EditFst : - public ImplToMutableFst< EditFstImpl<A, WrappedFstT, MutableFstT> > { - public: - friend class MutableArcIterator< EditFst<A, WrappedFstT, MutableFstT> >; - - typedef A Arc; - typedef typename A::StateId StateId; - typedef EditFstImpl<A, WrappedFstT, MutableFstT> Impl; - - EditFst() : ImplToMutableFst<Impl>(new Impl()) {} - - explicit EditFst(const Fst<A> &fst) : - ImplToMutableFst<Impl>(new Impl(fst)) {} - - explicit EditFst(const WrappedFstT &fst) : - ImplToMutableFst<Impl>(new Impl(fst)) {} - - // See Fst<>::Copy() for doc. - EditFst(const EditFst<A, WrappedFstT, MutableFstT> &fst, bool safe = false) : - ImplToMutableFst<Impl>(fst, safe) {} - - virtual ~EditFst() {} - - // Get a copy of this EditFst. See Fst<>::Copy() for further doc. - virtual EditFst<A, WrappedFstT, MutableFstT> *Copy(bool safe = false) const { - return new EditFst<A, WrappedFstT, MutableFstT>(*this, safe); - } - - EditFst<A, WrappedFstT, MutableFstT> & - operator=(const EditFst<A, WrappedFstT, MutableFstT> &fst) { - SetImpl(fst.GetImpl(), false); - return *this; - } - - virtual EditFst<A, WrappedFstT, MutableFstT> &operator=(const Fst<A> &fst) { - if (this != &fst) { - SetImpl(new Impl(fst)); - } - return *this; - } - - // Read an EditFst from an input stream; return NULL on error. - static EditFst<A, WrappedFstT, MutableFstT> * - Read(istream &strm, - const FstReadOptions &opts) { - Impl* impl = Impl::Read(strm, opts); - return impl ? new EditFst<A>(impl) : 0; - } - - // Read an EditFst from a file; return NULL on error. - // Empty filename reads from standard input. - static EditFst<A, WrappedFstT, MutableFstT> *Read(const string &filename) { - Impl* impl = ImplToExpandedFst<Impl, MutableFst<A> >::Read(filename); - return impl ? new EditFst<A, WrappedFstT, MutableFstT>(impl) : 0; - } - - virtual bool Write(ostream &strm, const FstWriteOptions &opts) const { - return GetImpl()->Write(strm, opts); - } - - virtual bool Write(const string &filename) const { - return Fst<A>::WriteFile(filename); - } - - virtual void InitStateIterator(StateIteratorData<Arc> *data) const { - GetImpl()->InitStateIterator(data); - } - - virtual void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const { - GetImpl()->InitArcIterator(s, data); - } - - virtual - void InitMutableArcIterator(StateId s, MutableArcIteratorData<A> *data) { - GetImpl()->InitMutableArcIterator(s, data); - } - private: - explicit EditFst(Impl *impl) : ImplToMutableFst<Impl>(impl) {} - - // Makes visible to friends. - Impl *GetImpl() const { return ImplToFst< Impl, MutableFst<A> >::GetImpl(); } - - void SetImpl(Impl *impl, bool own_impl = true) { - ImplToFst< Impl, MutableFst<A> >::SetImpl(impl, own_impl); - } -}; - -} // namespace fst - -#endif // FST_LIB_EDIT_FST_H_ |