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 (at) 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> 27 using std::vector; 28 29 #include <fst/mutable-fst.h> 30 #include <fst/test-properties.h> 31 32 33 namespace fst { 34 35 template <class A> class VectorFst; 36 template <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. 41 template <class State> 42 class 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. 165 template <class A> 166 struct 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. 181 template <class A> 182 class 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 private: 277 // Properties always true of this Fst class 278 static const uint64 kStaticProperties = kExpanded | kMutable; 279 // Current file format version 280 static const int kFileVersion = 2; 281 // Minimum file format version supported 282 static const int kMinFileVersion = 1; 283 284 DISALLOW_COPY_AND_ASSIGN(VectorFstImpl); 285 }; 286 287 template <class A> const uint64 VectorFstImpl<A>::kStaticProperties; 288 template <class A> const int VectorFstImpl<A>::kFileVersion; 289 template <class A> const int VectorFstImpl<A>::kMinFileVersion; 290 291 292 template <class A> 293 VectorFstImpl<A>::VectorFstImpl(const Fst<A> &fst) { 294 SetType("vector"); 295 SetInputSymbols(fst.InputSymbols()); 296 SetOutputSymbols(fst.OutputSymbols()); 297 BaseImpl::SetStart(fst.Start()); 298 if (fst.Properties(kExpanded, false)) 299 BaseImpl::ReserveStates(CountStates(fst)); 300 301 for (StateIterator< Fst<A> > siter(fst); 302 !siter.Done(); 303 siter.Next()) { 304 StateId s = siter.Value(); 305 BaseImpl::AddState(); 306 BaseImpl::SetFinal(s, fst.Final(s)); 307 ReserveArcs(s, fst.NumArcs(s)); 308 for (ArcIterator< Fst<A> > aiter(fst, s); 309 !aiter.Done(); 310 aiter.Next()) { 311 const A &arc = aiter.Value(); 312 BaseImpl::AddArc(s, arc); 313 if (arc.ilabel == 0) 314 ++GetState(s)->niepsilons; 315 if (arc.olabel == 0) 316 ++GetState(s)->noepsilons; 317 } 318 } 319 SetProperties(fst.Properties(kCopyProperties, false) | kStaticProperties); 320 } 321 322 template <class A> 323 VectorFstImpl<A> *VectorFstImpl<A>::Read(istream &strm, 324 const FstReadOptions &opts) { 325 VectorFstImpl<A> *impl = new VectorFstImpl; 326 FstHeader hdr; 327 if (!impl->ReadHeader(strm, opts, kMinFileVersion, &hdr)) { 328 delete impl; 329 return 0; 330 } 331 impl->BaseImpl::SetStart(hdr.Start()); 332 if (hdr.NumStates() != kNoStateId) { 333 impl->ReserveStates(hdr.NumStates()); 334 } 335 336 StateId s = 0; 337 for (;hdr.NumStates() == kNoStateId || s < hdr.NumStates(); ++s) { 338 typename A::Weight final; 339 if (!final.Read(strm)) break; 340 impl->BaseImpl::AddState(); 341 VectorState<A> *state = impl->GetState(s); 342 state->final = final; 343 int64 narcs; 344 ReadType(strm, &narcs); 345 if (!strm) { 346 LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source; 347 delete impl; 348 return 0; 349 } 350 impl->ReserveArcs(s, narcs); 351 for (size_t j = 0; j < narcs; ++j) { 352 A arc; 353 ReadType(strm, &arc.ilabel); 354 ReadType(strm, &arc.olabel); 355 arc.weight.Read(strm); 356 ReadType(strm, &arc.nextstate); 357 if (!strm) { 358 LOG(ERROR) << "VectorFst::Read: read failed: " << opts.source; 359 delete impl; 360 return 0; 361 } 362 impl->BaseImpl::AddArc(s, arc); 363 if (arc.ilabel == 0) 364 ++state->niepsilons; 365 if (arc.olabel == 0) 366 ++state->noepsilons; 367 } 368 } 369 if (hdr.NumStates() != kNoStateId && s != hdr.NumStates()) { 370 LOG(ERROR) << "VectorFst::Read: unexpected end of file: " << opts.source; 371 delete impl; 372 return 0; 373 } 374 return impl; 375 } 376 377 // Converts a string into a weight. 378 template <class W> class WeightFromString { 379 public: 380 W operator()(const string &s); 381 }; 382 383 // Generic case fails. 384 template <class W> inline 385 W WeightFromString<W>::operator()(const string &s) { 386 FSTERROR() << "VectorFst::Read: Obsolete file format"; 387 return W::NoWeight(); 388 } 389 390 // TropicalWeight version. 391 template <> inline 392 TropicalWeight WeightFromString<TropicalWeight>::operator()(const string &s) { 393 float f; 394 memcpy(&f, s.data(), sizeof(f)); 395 return TropicalWeight(f); 396 } 397 398 // LogWeight version. 399 template <> inline 400 LogWeight WeightFromString<LogWeight>::operator()(const string &s) { 401 float f; 402 memcpy(&f, s.data(), sizeof(f)); 403 return LogWeight(f); 404 } 405 406 // Simple concrete, mutable FST. This class attaches interface to 407 // implementation and handles reference counting, delegating most 408 // methods to ImplToMutableFst. Supports additional operations: 409 // ReserveStates and ReserveArcs (cf. STL vectors). 410 template <class A> 411 class VectorFst : public ImplToMutableFst< VectorFstImpl<A> > { 412 public: 413 friend class StateIterator< VectorFst<A> >; 414 friend class ArcIterator< VectorFst<A> >; 415 friend class MutableArcIterator< VectorFst<A> >; 416 template <class F, class G> friend void Cast(const F &, G *); 417 418 typedef A Arc; 419 typedef typename A::StateId StateId; 420 typedef VectorFstImpl<A> Impl; 421 422 VectorFst() : ImplToMutableFst<Impl>(new Impl) {} 423 424 explicit VectorFst(const Fst<A> &fst) 425 : ImplToMutableFst<Impl>(new Impl(fst)) {} 426 427 VectorFst(const VectorFst<A> &fst) : ImplToMutableFst<Impl>(fst) {} 428 429 // Get a copy of this VectorFst. See Fst<>::Copy() for further doc. 430 virtual VectorFst<A> *Copy(bool safe = false) const { 431 return new VectorFst<A>(*this); 432 } 433 434 VectorFst<A> &operator=(const VectorFst<A> &fst) { 435 SetImpl(fst.GetImpl(), false); 436 return *this; 437 } 438 439 virtual VectorFst<A> &operator=(const Fst<A> &fst) { 440 if (this != &fst) SetImpl(new Impl(fst)); 441 return *this; 442 } 443 444 // Read a VectorFst from an input stream; return NULL on error 445 static VectorFst<A> *Read(istream &strm, const FstReadOptions &opts) { 446 Impl* impl = Impl::Read(strm, opts); 447 return impl ? new VectorFst<A>(impl) : 0; 448 } 449 450 // Read a VectorFst from a file; return NULL on error 451 // Empty filename reads from standard input 452 static VectorFst<A> *Read(const string &filename) { 453 Impl* impl = ImplToExpandedFst<Impl, MutableFst<A> >::Read(filename); 454 return impl ? new VectorFst<A>(impl) : 0; 455 } 456 457 virtual bool Write(ostream &strm, const FstWriteOptions &opts) const { 458 return WriteFst(*this, strm, opts); 459 } 460 461 virtual bool Write(const string &filename) const { 462 return Fst<A>::WriteFile(filename); 463 } 464 465 template <class F> 466 static bool WriteFst(const F &fst, ostream &strm, 467 const FstWriteOptions &opts); 468 469 void ReserveStates(StateId n) { 470 MutateCheck(); 471 GetImpl()->ReserveStates(n); 472 } 473 474 void ReserveArcs(StateId s, size_t n) { 475 MutateCheck(); 476 GetImpl()->ReserveArcs(s, n); 477 } 478 479 virtual void InitStateIterator(StateIteratorData<Arc> *data) const { 480 GetImpl()->InitStateIterator(data); 481 } 482 483 virtual void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const { 484 GetImpl()->InitArcIterator(s, data); 485 } 486 487 virtual inline 488 void InitMutableArcIterator(StateId s, MutableArcIteratorData<A> *); 489 490 private: 491 explicit VectorFst(Impl *impl) : ImplToMutableFst<Impl>(impl) {} 492 493 // Makes visible to friends. 494 Impl *GetImpl() const { return ImplToFst< Impl, MutableFst<A> >::GetImpl(); } 495 496 void SetImpl(Impl *impl, bool own_impl = true) { 497 ImplToFst< Impl, MutableFst<A> >::SetImpl(impl, own_impl); 498 } 499 500 void MutateCheck() { return ImplToMutableFst<Impl>::MutateCheck(); } 501 }; 502 503 // Specialization for VectorFst; see generic version in fst.h 504 // for sample usage (but use the VectorFst type!). This version 505 // should inline. 506 template <class A> 507 class StateIterator< VectorFst<A> > { 508 public: 509 typedef typename A::StateId StateId; 510 511 explicit StateIterator(const VectorFst<A> &fst) 512 : nstates_(fst.GetImpl()->NumStates()), s_(0) {} 513 514 bool Done() const { return s_ >= nstates_; } 515 516 StateId Value() const { return s_; } 517 518 void Next() { ++s_; } 519 520 void Reset() { s_ = 0; } 521 522 private: 523 StateId nstates_; 524 StateId s_; 525 526 DISALLOW_COPY_AND_ASSIGN(StateIterator); 527 }; 528 529 // Writes Fst to file, will call CountStates so may involve two passes if 530 // called from an Fst that is not derived from Expanded. 531 template <class A> 532 template <class F> 533 bool VectorFst<A>::WriteFst(const F &fst, ostream &strm, 534 const FstWriteOptions &opts) { 535 static const int kFileVersion = 2; 536 bool update_header = true; 537 FstHeader hdr; 538 hdr.SetStart(fst.Start()); 539 hdr.SetNumStates(kNoStateId); 540 size_t start_offset = 0; 541 if (fst.Properties(kExpanded, false) || (start_offset = strm.tellp()) != -1) { 542 hdr.SetNumStates(CountStates(fst)); 543 update_header = false; 544 } 545 FstImpl<A>::WriteFstHeader(fst, strm, opts, kFileVersion, "vector", &hdr); 546 StateId num_states = 0; 547 for (StateIterator<F> siter(fst); !siter.Done(); siter.Next()) { 548 typename A::StateId s = siter.Value(); 549 fst.Final(s).Write(strm); 550 int64 narcs = fst.NumArcs(s); 551 WriteType(strm, narcs); 552 for (ArcIterator<F> aiter(fst, s); !aiter.Done(); aiter.Next()) { 553 const A &arc = aiter.Value(); 554 WriteType(strm, arc.ilabel); 555 WriteType(strm, arc.olabel); 556 arc.weight.Write(strm); 557 WriteType(strm, arc.nextstate); 558 } 559 num_states++; 560 } 561 strm.flush(); 562 if (!strm) { 563 LOG(ERROR) << "VectorFst::Write: write failed: " << opts.source; 564 return false; 565 } 566 if (update_header) { 567 hdr.SetNumStates(num_states); 568 return FstImpl<A>::UpdateFstHeader(fst, strm, opts, kFileVersion, "vector", 569 &hdr, start_offset); 570 } else { 571 if (num_states != hdr.NumStates()) { 572 LOG(ERROR) << "Inconsistent number of states observed during write"; 573 return false; 574 } 575 } 576 return true; 577 } 578 579 // Specialization for VectorFst; see generic version in fst.h 580 // for sample usage (but use the VectorFst type!). This version 581 // should inline. 582 template <class A> 583 class ArcIterator< VectorFst<A> > { 584 public: 585 typedef typename A::StateId StateId; 586 587 ArcIterator(const VectorFst<A> &fst, StateId s) 588 : arcs_(fst.GetImpl()->GetState(s)->arcs), i_(0) {} 589 590 bool Done() const { return i_ >= arcs_.size(); } 591 592 const A& Value() const { return arcs_[i_]; } 593 594 void Next() { ++i_; } 595 596 void Reset() { i_ = 0; } 597 598 void Seek(size_t a) { i_ = a; } 599 600 size_t Position() const { return i_; } 601 602 uint32 Flags() const { 603 return kArcValueFlags; 604 } 605 606 void SetFlags(uint32 f, uint32 m) {} 607 608 private: 609 const vector<A>& arcs_; 610 size_t i_; 611 612 DISALLOW_COPY_AND_ASSIGN(ArcIterator); 613 }; 614 615 // Specialization for VectorFst; see generic version in fst.h 616 // for sample usage (but use the VectorFst type!). This version 617 // should inline. 618 template <class A> 619 class MutableArcIterator< VectorFst<A> > 620 : public MutableArcIteratorBase<A> { 621 public: 622 typedef typename A::StateId StateId; 623 typedef typename A::Weight Weight; 624 625 MutableArcIterator(VectorFst<A> *fst, StateId s) : i_(0) { 626 fst->MutateCheck(); 627 state_ = fst->GetImpl()->GetState(s); 628 properties_ = &fst->GetImpl()->properties_; 629 } 630 631 bool Done() const { return i_ >= state_->arcs.size(); } 632 633 const A& Value() const { return state_->arcs[i_]; } 634 635 void Next() { ++i_; } 636 637 size_t Position() const { return i_; } 638 639 void Reset() { i_ = 0; } 640 641 void Seek(size_t a) { i_ = a; } 642 643 void SetValue(const A &arc) { 644 A& oarc = state_->arcs[i_]; 645 if (oarc.ilabel != oarc.olabel) 646 *properties_ &= ~kNotAcceptor; 647 if (oarc.ilabel == 0) { 648 --state_->niepsilons; 649 *properties_ &= ~kIEpsilons; 650 if (oarc.olabel == 0) 651 *properties_ &= ~kEpsilons; 652 } 653 if (oarc.olabel == 0) { 654 --state_->noepsilons; 655 *properties_ &= ~kOEpsilons; 656 } 657 if (oarc.weight != Weight::Zero() && oarc.weight != Weight::One()) 658 *properties_ &= ~kWeighted; 659 oarc = arc; 660 if (arc.ilabel != arc.olabel) { 661 *properties_ |= kNotAcceptor; 662 *properties_ &= ~kAcceptor; 663 } 664 if (arc.ilabel == 0) { 665 ++state_->niepsilons; 666 *properties_ |= kIEpsilons; 667 *properties_ &= ~kNoIEpsilons; 668 if (arc.olabel == 0) { 669 *properties_ |= kEpsilons; 670 *properties_ &= ~kNoEpsilons; 671 } 672 } 673 if (arc.olabel == 0) { 674 ++state_->noepsilons; 675 *properties_ |= kOEpsilons; 676 *properties_ &= ~kNoOEpsilons; 677 } 678 if (arc.weight != Weight::Zero() && arc.weight != Weight::One()) { 679 *properties_ |= kWeighted; 680 *properties_ &= ~kUnweighted; 681 } 682 *properties_ &= kSetArcProperties | kAcceptor | kNotAcceptor | 683 kEpsilons | kNoEpsilons | kIEpsilons | kNoIEpsilons | 684 kOEpsilons | kNoOEpsilons | kWeighted | kUnweighted; 685 } 686 687 uint32 Flags() const { 688 return kArcValueFlags; 689 } 690 691 void SetFlags(uint32 f, uint32 m) {} 692 693 694 private: 695 // This allows base-class virtual access to non-virtual derived- 696 // class members of the same name. It makes the derived class more 697 // efficient to use but unsafe to further derive. 698 virtual bool Done_() const { return Done(); } 699 virtual const A& Value_() const { return Value(); } 700 virtual void Next_() { Next(); } 701 virtual size_t Position_() const { return Position(); } 702 virtual void Reset_() { Reset(); } 703 virtual void Seek_(size_t a) { Seek(a); } 704 virtual void SetValue_(const A &a) { SetValue(a); } 705 uint32 Flags_() const { return Flags(); } 706 void SetFlags_(uint32 f, uint32 m) { SetFlags(f, m); } 707 708 struct VectorState<A> *state_; 709 uint64 *properties_; 710 size_t i_; 711 712 DISALLOW_COPY_AND_ASSIGN(MutableArcIterator); 713 }; 714 715 // Provide information needed for the generic mutable arc iterator 716 template <class A> inline 717 void VectorFst<A>::InitMutableArcIterator( 718 StateId s, MutableArcIteratorData<A> *data) { 719 data->base = new MutableArcIterator< VectorFst<A> >(this, s); 720 } 721 722 // A useful alias when using StdArc. 723 typedef VectorFst<StdArc> StdVectorFst; 724 725 } // namespace fst 726 727 #endif // FST_LIB_VECTOR_FST_H__ 728