1// vector-fst.h
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// Copyright 2005-2010 Google, Inc.
16// Author: riley@google.com (Michael Riley)
17//
18// \file
19// Simple concrete, mutable FST whose states and arcs are stored in STL
20// vectors.
21
22#ifndef FST_LIB_VECTOR_FST_H__
23#define FST_LIB_VECTOR_FST_H__
24
25#include <string>
26#include <vector>
27using std::vector;
28
29#include <fst/mutable-fst.h>
30#include <fst/test-properties.h>
31
32
33namespace fst {
34
35template <class A> class VectorFst;
36template <class F, class G> void Cast(const F &, G *);
37
38
39// States and arcs implemented by STL vectors, templated on the
40// State definition. This does not manage the Fst properties.
41template <class State>
42class VectorFstBaseImpl : public FstImpl<typename State::Arc> {
43 public:
44  typedef typename State::Arc Arc;
45  typedef typename Arc::Weight Weight;
46  typedef typename Arc::StateId StateId;
47
48  VectorFstBaseImpl() : start_(kNoStateId) {}
49
50  ~VectorFstBaseImpl() {
51    for (StateId s = 0; s < states_.size(); ++s)
52      delete states_[s];
53  }
54
55  StateId Start() const { return start_; }
56
57  Weight Final(StateId s) const { return states_[s]->final; }
58
59  StateId NumStates() const { return states_.size(); }
60
61  size_t NumArcs(StateId s) const { return states_[s]->arcs.size(); }
62
63  void SetStart(StateId s) { start_ = s; }
64
65  void SetFinal(StateId s, Weight w) { states_[s]->final = w; }
66
67  StateId AddState() {
68    states_.push_back(new State);
69    return states_.size() - 1;
70  }
71
72  StateId AddState(State *state) {
73    states_.push_back(state);
74    return states_.size() - 1;
75  }
76
77  void AddArc(StateId s, const Arc &arc) {
78    states_[s]->arcs.push_back(arc);
79  }
80
81  void DeleteStates(const vector<StateId>& dstates) {
82    vector<StateId> newid(states_.size(), 0);
83    for (size_t i = 0; i < dstates.size(); ++i)
84      newid[dstates[i]] = kNoStateId;
85    StateId nstates = 0;
86    for (StateId s = 0; s < states_.size(); ++s) {
87      if (newid[s] != kNoStateId) {
88        newid[s] = nstates;
89        if (s != nstates)
90          states_[nstates] = states_[s];
91        ++nstates;
92      } else {
93        delete states_[s];
94      }
95    }
96    states_.resize(nstates);
97    for (StateId s = 0; s < states_.size(); ++s) {
98      vector<Arc> &arcs = states_[s]->arcs;
99      size_t narcs = 0;
100      for (size_t i = 0; i < arcs.size(); ++i) {
101        StateId t = newid[arcs[i].nextstate];
102        if (t != kNoStateId) {
103          arcs[i].nextstate = t;
104          if (i != narcs)
105            arcs[narcs] = arcs[i];
106          ++narcs;
107        } else {
108          if (arcs[i].ilabel == 0)
109            --states_[s]->niepsilons;
110          if (arcs[i].olabel == 0)
111            --states_[s]->noepsilons;
112        }
113      }
114      arcs.resize(narcs);
115    }
116    if (Start() != kNoStateId)
117      SetStart(newid[Start()]);
118  }
119
120  void DeleteStates() {
121    for (StateId s = 0; s < states_.size(); ++s)
122      delete states_[s];
123    states_.clear();
124    SetStart(kNoStateId);
125  }
126
127  void DeleteArcs(StateId s, size_t n) {
128    states_[s]->arcs.resize(states_[s]->arcs.size() - n);
129  }
130
131  void DeleteArcs(StateId s) { states_[s]->arcs.clear(); }
132
133  State *GetState(StateId s) { return states_[s]; }
134
135  const State *GetState(StateId s) const { return states_[s]; }
136
137  void SetState(StateId s, State *state) { states_[s] = state; }
138
139  void ReserveStates(StateId n) { states_.reserve(n); }
140
141  void ReserveArcs(StateId s, size_t n) { states_[s]->arcs.reserve(n); }
142
143  // Provide information needed for generic state iterator
144  void InitStateIterator(StateIteratorData<Arc> *data) const {
145    data->base = 0;
146    data->nstates = states_.size();
147  }
148
149  // Provide information needed for generic arc iterator
150  void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const {
151    data->base = 0;
152    data->narcs = states_[s]->arcs.size();
153    data->arcs = data->narcs > 0 ? &states_[s]->arcs[0] : 0;
154    data->ref_count = 0;
155  }
156
157 private:
158  vector<State *> states_;      // States represenation.
159  StateId start_;               // initial state
160
161  DISALLOW_COPY_AND_ASSIGN(VectorFstBaseImpl);
162};
163
164// Arcs implemented by an STL vector per state.
165template <class A>
166struct VectorState {
167  typedef A Arc;
168  typedef typename A::Weight Weight;
169  typedef typename A::StateId StateId;
170
171  VectorState() : final(Weight::Zero()), niepsilons(0), noepsilons(0) {}
172
173  Weight final;              // Final weight
174  vector<A> arcs;            // Arcs represenation
175  size_t niepsilons;         // # of input epsilons
176  size_t noepsilons;         // # of output epsilons
177};
178
179// This is a VectorFstBaseImpl container that holds VectorState's.  It
180// manages Fst properties and the # of input and output epsilons.
181template <class A>
182class VectorFstImpl : public VectorFstBaseImpl< VectorState<A> > {
183 public:
184  using FstImpl<A>::SetInputSymbols;
185  using FstImpl<A>::SetOutputSymbols;
186  using FstImpl<A>::SetType;
187  using FstImpl<A>::SetProperties;
188  using FstImpl<A>::Properties;
189
190  using VectorFstBaseImpl<VectorState<A> >::Start;
191  using VectorFstBaseImpl<VectorState<A> >::NumStates;
192  using VectorFstBaseImpl<VectorState<A> >::GetState;
193  using VectorFstBaseImpl<VectorState<A> >::ReserveArcs;
194
195  friend class MutableArcIterator< VectorFst<A> >;
196
197  typedef VectorFstBaseImpl< VectorState<A> > BaseImpl;
198  typedef typename A::Weight Weight;
199  typedef typename A::StateId StateId;
200
201  VectorFstImpl() {
202    SetType("vector");
203    SetProperties(kNullProperties | kStaticProperties);
204  }
205  explicit VectorFstImpl(const Fst<A> &fst);
206
207  static VectorFstImpl<A> *Read(istream &strm, const FstReadOptions &opts);
208
209  size_t NumInputEpsilons(StateId s) const { return GetState(s)->niepsilons; }
210
211  size_t NumOutputEpsilons(StateId s) const { return GetState(s)->noepsilons; }
212
213  void SetStart(StateId s) {
214    BaseImpl::SetStart(s);
215    SetProperties(SetStartProperties(Properties()));
216  }
217
218  void SetFinal(StateId s, Weight w) {
219    Weight ow = BaseImpl::Final(s);
220    BaseImpl::SetFinal(s, w);
221    SetProperties(SetFinalProperties(Properties(), ow, w));
222  }
223
224  StateId AddState() {
225    StateId s = BaseImpl::AddState();
226    SetProperties(AddStateProperties(Properties()));
227    return s;
228  }
229
230  void AddArc(StateId s, const A &arc) {
231    VectorState<A> *state = GetState(s);
232    if (arc.ilabel == 0) {
233      ++state->niepsilons;
234    }
235    if (arc.olabel == 0) {
236      ++state->noepsilons;
237    }
238
239    const A *parc = state->arcs.empty() ? 0 : &(state->arcs.back());
240    SetProperties(AddArcProperties(Properties(), s, arc, parc));
241
242    BaseImpl::AddArc(s, arc);
243  }
244
245  void DeleteStates(const vector<StateId> &dstates) {
246    BaseImpl::DeleteStates(dstates);
247    SetProperties(DeleteStatesProperties(Properties()));
248  }
249
250  void DeleteStates() {
251    BaseImpl::DeleteStates();
252    SetProperties(DeleteAllStatesProperties(Properties(),
253                                            kStaticProperties));
254  }
255
256  void DeleteArcs(StateId s, size_t n) {
257    const vector<A> &arcs = GetState(s)->arcs;
258    for (size_t i = 0; i < n; ++i) {
259      size_t j = arcs.size() - i - 1;
260      if (arcs[j].ilabel == 0)
261        --GetState(s)->niepsilons;
262      if (arcs[j].olabel == 0)
263        --GetState(s)->noepsilons;
264    }
265    BaseImpl::DeleteArcs(s, n);
266    SetProperties(DeleteArcsProperties(Properties()));
267  }
268
269  void DeleteArcs(StateId s) {
270    GetState(s)->niepsilons = 0;
271    GetState(s)->noepsilons = 0;
272    BaseImpl::DeleteArcs(s);
273    SetProperties(DeleteArcsProperties(Properties()));
274  }
275
276  // Properties always true of this Fst class
277  static const uint64 kStaticProperties = kExpanded | kMutable;
278
279 private:
280  // Current file format version
281  static const int kFileVersion = 2;
282  // Minimum file format version supported
283  static const int kMinFileVersion = 1;
284
285  DISALLOW_COPY_AND_ASSIGN(VectorFstImpl);
286};
287
288template <class A> const uint64 VectorFstImpl<A>::kStaticProperties;
289template <class A> const int VectorFstImpl<A>::kFileVersion;
290template <class A> const int VectorFstImpl<A>::kMinFileVersion;
291
292
293template <class A>
294VectorFstImpl<A>::VectorFstImpl(const Fst<A> &fst) {
295  SetType("vector");
296  SetInputSymbols(fst.InputSymbols());
297  SetOutputSymbols(fst.OutputSymbols());
298  BaseImpl::SetStart(fst.Start());
299  if (fst.Properties(kExpanded, false))
300    BaseImpl::ReserveStates(CountStates(fst));
301
302  for (StateIterator< Fst<A> > siter(fst);
303       !siter.Done();
304       siter.Next()) {
305    StateId s = siter.Value();
306    BaseImpl::AddState();
307    BaseImpl::SetFinal(s, fst.Final(s));
308    ReserveArcs(s, fst.NumArcs(s));
309    for (ArcIterator< Fst<A> > aiter(fst, s);
310         !aiter.Done();
311         aiter.Next()) {
312      const A &arc = aiter.Value();
313      BaseImpl::AddArc(s, arc);
314      if (arc.ilabel == 0)
315        ++GetState(s)->niepsilons;
316      if (arc.olabel == 0)
317        ++GetState(s)->noepsilons;
318    }
319  }
320  SetProperties(fst.Properties(kCopyProperties, false) | kStaticProperties);
321}
322
323template <class A>
324VectorFstImpl<A> *VectorFstImpl<A>::Read(istream &strm,
325                                         const FstReadOptions &opts) {
326  VectorFstImpl<A> *impl = new VectorFstImpl;
327  FstHeader hdr;
328  if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) {
329    delete impl;
330    return 0;
331  }
332  impl->BaseImpl::SetStart(hdr.Start());
333  if (hdr.NumStates() != kNoStateId) {
334    impl->ReserveStates(hdr.NumStates());
335  }
336
337  StateId s = 0;
338  for (;hdr.NumStates() == kNoStateId || s < hdr.NumStates(); ++s) {
339    typename A::Weight final;
340    if (!final.Read(strm)) break;
341    impl->BaseImpl::AddState();
342    VectorState<A> *state = impl->GetState(s);
343    state->final = final;
344    int64 narcs;
345    ReadType(strm, &narcs);
346    if (!strm) {
347      LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source;
348      delete impl;
349      return 0;
350    }
351    impl->ReserveArcs(s, narcs);
352    for (size_t j = 0; j < narcs; ++j) {
353      A arc;
354      ReadType(strm, &arc.ilabel);
355      ReadType(strm, &arc.olabel);
356      arc.weight.Read(strm);
357       ReadType(strm, &arc.nextstate);
358       if (!strm) {
359        LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source;
360        delete impl;
361        return 0;
362      }
363      impl->BaseImpl::AddArc(s, arc);
364      if (arc.ilabel == 0)
365        ++state->niepsilons;
366      if (arc.olabel == 0)
367        ++state->noepsilons;
368    }
369  }
370  if (hdr.NumStates() != kNoStateId && s != hdr.NumStates()) {
371    LOG(ERROR) << "VectorFst::Read: unexpected end of file: " << opts.source;
372    delete impl;
373    return 0;
374  }
375  return impl;
376}
377
378// Converts a string into a weight.
379template <class W> class WeightFromString {
380 public:
381  W operator()(const string &s);
382};
383
384// Generic case fails.
385template <class W> inline
386W WeightFromString<W>::operator()(const string &s) {
387  FSTERROR() << "VectorFst::Read: Obsolete file format";
388  return W::NoWeight();
389}
390
391// TropicalWeight version.
392template <> inline
393TropicalWeight WeightFromString<TropicalWeight>::operator()(const string &s) {
394  float f;
395  memcpy(&f, s.data(), sizeof(f));
396  return TropicalWeight(f);
397}
398
399// LogWeight version.
400template <> inline
401LogWeight WeightFromString<LogWeight>::operator()(const string &s) {
402  float f;
403  memcpy(&f, s.data(), sizeof(f));
404  return LogWeight(f);
405}
406
407// Simple concrete, mutable FST. This class attaches interface to
408// implementation and handles reference counting, delegating most
409// methods to ImplToMutableFst. Supports additional operations:
410// ReserveStates and ReserveArcs (cf. STL vectors).
411template <class A>
412class VectorFst : public ImplToMutableFst< VectorFstImpl<A> > {
413 public:
414  friend class StateIterator< VectorFst<A> >;
415  friend class ArcIterator< VectorFst<A> >;
416  friend class MutableArcIterator< VectorFst<A> >;
417  template <class F, class G> friend void Cast(const F &, G *);
418
419  typedef A Arc;
420  typedef typename A::StateId StateId;
421  typedef VectorFstImpl<A> Impl;
422
423  VectorFst() : ImplToMutableFst<Impl>(new Impl) {}
424
425  explicit VectorFst(const Fst<A> &fst)
426      : ImplToMutableFst<Impl>(new Impl(fst)) {}
427
428  VectorFst(const VectorFst<A> &fst) : ImplToMutableFst<Impl>(fst) {}
429
430  // Get a copy of this VectorFst. See Fst<>::Copy() for further doc.
431  virtual VectorFst<A> *Copy(bool safe = false) const {
432    return new VectorFst<A>(*this);
433  }
434
435  VectorFst<A> &operator=(const VectorFst<A> &fst) {
436    SetImpl(fst.GetImpl(), false);
437    return *this;
438  }
439
440  virtual VectorFst<A> &operator=(const Fst<A> &fst) {
441    if (this != &fst) SetImpl(new Impl(fst));
442    return *this;
443  }
444
445  // Read a VectorFst from an input stream; return NULL on error
446  static VectorFst<A> *Read(istream &strm, const FstReadOptions &opts) {
447    Impl* impl = Impl::Read(strm, opts);
448    return impl ? new VectorFst<A>(impl) : 0;
449  }
450
451  // Read a VectorFst from a file; return NULL on error
452  // Empty filename reads from standard input
453  static VectorFst<A> *Read(const string &filename) {
454    Impl* impl = ImplToExpandedFst<Impl, MutableFst<A> >::Read(filename);
455    return impl ? new VectorFst<A>(impl) : 0;
456  }
457
458  virtual bool Write(ostream &strm, const FstWriteOptions &opts) const {
459    return WriteFst(*this, strm, opts);
460  }
461
462  virtual bool Write(const string &filename) const {
463    return Fst<A>::WriteFile(filename);
464  }
465
466  template <class F>
467  static bool WriteFst(const F &fst, ostream &strm,
468                       const FstWriteOptions &opts);
469
470  void ReserveStates(StateId n) {
471    MutateCheck();
472    GetImpl()->ReserveStates(n);
473  }
474
475  void ReserveArcs(StateId s, size_t n) {
476    MutateCheck();
477    GetImpl()->ReserveArcs(s, n);
478  }
479
480  virtual void InitStateIterator(StateIteratorData<Arc> *data) const {
481    GetImpl()->InitStateIterator(data);
482  }
483
484  virtual void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const {
485    GetImpl()->InitArcIterator(s, data);
486  }
487
488  virtual inline
489  void InitMutableArcIterator(StateId s, MutableArcIteratorData<A> *);
490
491 private:
492  explicit VectorFst(Impl *impl) : ImplToMutableFst<Impl>(impl) {}
493
494  // Makes visible to friends.
495  Impl *GetImpl() const { return ImplToFst< Impl, MutableFst<A> >::GetImpl(); }
496
497  void SetImpl(Impl *impl, bool own_impl = true) {
498    ImplToFst< Impl, MutableFst<A> >::SetImpl(impl, own_impl);
499  }
500
501  void MutateCheck() { return ImplToMutableFst<Impl>::MutateCheck(); }
502};
503
504// Specialization for VectorFst; see generic version in fst.h
505// for sample usage (but use the VectorFst type!). This version
506// should inline.
507template <class A>
508class StateIterator< VectorFst<A> > {
509 public:
510  typedef typename A::StateId StateId;
511
512  explicit StateIterator(const VectorFst<A> &fst)
513      : nstates_(fst.GetImpl()->NumStates()), s_(0) {}
514
515  bool Done() const { return s_ >= nstates_; }
516
517  StateId Value() const { return s_; }
518
519  void Next() { ++s_; }
520
521  void Reset() { s_ = 0; }
522
523 private:
524  StateId nstates_;
525  StateId s_;
526
527  DISALLOW_COPY_AND_ASSIGN(StateIterator);
528};
529
530// Writes Fst to file, will call CountStates so may involve two passes if
531// called from an Fst that is not derived from Expanded.
532template <class A>
533template <class F>
534bool VectorFst<A>::WriteFst(const F &fst, ostream &strm,
535                            const FstWriteOptions &opts) {
536  static const int kFileVersion = 2;
537  bool update_header = true;
538  FstHeader hdr;
539  hdr.SetStart(fst.Start());
540  hdr.SetNumStates(kNoStateId);
541  size_t start_offset = 0;
542  if (fst.Properties(kExpanded, false) || (start_offset = strm.tellp()) != -1) {
543    hdr.SetNumStates(CountStates(fst));
544    update_header = false;
545  }
546  uint64 properties = fst.Properties(kCopyProperties, false) |
547      VectorFstImpl<A>::kStaticProperties;
548  FstImpl<A>::WriteFstHeader(fst, strm, opts, kFileVersion, "vector",
549                             properties, &hdr);
550  StateId num_states = 0;
551  for (StateIterator<F> siter(fst); !siter.Done(); siter.Next()) {
552    typename A::StateId s = siter.Value();
553    fst.Final(s).Write(strm);
554    int64 narcs = fst.NumArcs(s);
555    WriteType(strm, narcs);
556    for (ArcIterator<F> aiter(fst, s); !aiter.Done(); aiter.Next()) {
557      const A &arc = aiter.Value();
558      WriteType(strm, arc.ilabel);
559      WriteType(strm, arc.olabel);
560      arc.weight.Write(strm);
561      WriteType(strm, arc.nextstate);
562    }
563    num_states++;
564  }
565  strm.flush();
566  if (!strm) {
567    LOG(ERROR) << "VectorFst::Write: write failed: " << opts.source;
568    return false;
569  }
570  if (update_header) {
571    hdr.SetNumStates(num_states);
572    return FstImpl<A>::UpdateFstHeader(fst, strm, opts, kFileVersion, "vector",
573                                       properties, &hdr, start_offset);
574  } else {
575    if (num_states != hdr.NumStates()) {
576      LOG(ERROR) << "Inconsistent number of states observed during write";
577      return false;
578    }
579  }
580  return true;
581}
582
583// Specialization for VectorFst; see generic version in fst.h
584// for sample usage (but use the VectorFst type!). This version
585// should inline.
586template <class A>
587class ArcIterator< VectorFst<A> > {
588 public:
589  typedef typename A::StateId StateId;
590
591  ArcIterator(const VectorFst<A> &fst, StateId s)
592      : arcs_(fst.GetImpl()->GetState(s)->arcs), i_(0) {}
593
594  bool Done() const { return i_ >= arcs_.size(); }
595
596  const A& Value() const { return arcs_[i_]; }
597
598  void Next() { ++i_; }
599
600  void Reset() { i_ = 0; }
601
602  void Seek(size_t a) { i_ = a; }
603
604  size_t Position() const { return i_; }
605
606  uint32 Flags() const {
607    return kArcValueFlags;
608  }
609
610  void SetFlags(uint32 f, uint32 m) {}
611
612 private:
613  const vector<A>& arcs_;
614  size_t i_;
615
616  DISALLOW_COPY_AND_ASSIGN(ArcIterator);
617};
618
619// Specialization for VectorFst; see generic version in fst.h
620// for sample usage (but use the VectorFst type!). This version
621// should inline.
622template <class A>
623class MutableArcIterator< VectorFst<A> >
624  : public MutableArcIteratorBase<A> {
625 public:
626  typedef typename A::StateId StateId;
627  typedef typename A::Weight Weight;
628
629  MutableArcIterator(VectorFst<A> *fst, StateId s) : i_(0) {
630    fst->MutateCheck();
631    state_ = fst->GetImpl()->GetState(s);
632    properties_ = &fst->GetImpl()->properties_;
633  }
634
635  bool Done() const { return i_ >= state_->arcs.size(); }
636
637  const A& Value() const { return state_->arcs[i_]; }
638
639  void Next() { ++i_; }
640
641  size_t Position() const { return i_; }
642
643  void Reset() { i_ = 0; }
644
645  void Seek(size_t a) { i_ = a; }
646
647  void SetValue(const A &arc) {
648    A& oarc = state_->arcs[i_];
649    if (oarc.ilabel != oarc.olabel)
650      *properties_ &= ~kNotAcceptor;
651    if (oarc.ilabel == 0) {
652      --state_->niepsilons;
653      *properties_ &= ~kIEpsilons;
654      if (oarc.olabel == 0)
655        *properties_ &= ~kEpsilons;
656    }
657    if (oarc.olabel == 0) {
658      --state_->noepsilons;
659      *properties_ &= ~kOEpsilons;
660    }
661    if (oarc.weight != Weight::Zero() && oarc.weight != Weight::One())
662      *properties_ &= ~kWeighted;
663    oarc = arc;
664    if (arc.ilabel != arc.olabel) {
665      *properties_ |= kNotAcceptor;
666      *properties_ &= ~kAcceptor;
667    }
668    if (arc.ilabel == 0) {
669      ++state_->niepsilons;
670      *properties_ |= kIEpsilons;
671      *properties_ &= ~kNoIEpsilons;
672      if (arc.olabel == 0) {
673        *properties_ |= kEpsilons;
674        *properties_ &= ~kNoEpsilons;
675      }
676    }
677    if (arc.olabel == 0) {
678      ++state_->noepsilons;
679      *properties_ |= kOEpsilons;
680      *properties_ &= ~kNoOEpsilons;
681    }
682    if (arc.weight != Weight::Zero() && arc.weight != Weight::One()) {
683      *properties_ |= kWeighted;
684      *properties_ &= ~kUnweighted;
685    }
686    *properties_ &= kSetArcProperties | kAcceptor | kNotAcceptor |
687        kEpsilons | kNoEpsilons | kIEpsilons | kNoIEpsilons |
688        kOEpsilons | kNoOEpsilons | kWeighted | kUnweighted;
689  }
690
691  uint32 Flags() const {
692    return kArcValueFlags;
693  }
694
695  void SetFlags(uint32 f, uint32 m) {}
696
697
698 private:
699  // This allows base-class virtual access to non-virtual derived-
700  // class members of the same name. It makes the derived class more
701  // efficient to use but unsafe to further derive.
702  virtual bool Done_() const { return Done(); }
703  virtual const A& Value_() const { return Value(); }
704  virtual void Next_() { Next(); }
705  virtual size_t Position_() const { return Position(); }
706  virtual void Reset_() { Reset(); }
707  virtual void Seek_(size_t a) { Seek(a); }
708  virtual void SetValue_(const A &a) { SetValue(a); }
709  uint32 Flags_() const { return Flags(); }
710  void SetFlags_(uint32 f, uint32 m) { SetFlags(f, m); }
711
712  struct VectorState<A> *state_;
713  uint64 *properties_;
714  size_t i_;
715
716  DISALLOW_COPY_AND_ASSIGN(MutableArcIterator);
717};
718
719// Provide information needed for the generic mutable arc iterator
720template <class A> inline
721void VectorFst<A>::InitMutableArcIterator(
722    StateId s, MutableArcIteratorData<A> *data) {
723  data->base = new MutableArcIterator< VectorFst<A> >(this, s);
724}
725
726// A useful alias when using StdArc.
727typedef VectorFst<StdArc> StdVectorFst;
728
729}  // namespace fst
730
731#endif  // FST_LIB_VECTOR_FST_H__
732