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 // 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 288 template <class A> const uint64 VectorFstImpl<A>::kStaticProperties; 289 template <class A> const int VectorFstImpl<A>::kFileVersion; 290 template <class A> const int VectorFstImpl<A>::kMinFileVersion; 291 292 293 template <class A> 294 VectorFstImpl<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 323 template <class A> 324 VectorFstImpl<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. 379 template <class W> class WeightFromString { 380 public: 381 W operator()(const string &s); 382 }; 383 384 // Generic case fails. 385 template <class W> inline 386 W WeightFromString<W>::operator()(const string &s) { 387 FSTERROR() << "VectorFst::Read: Obsolete file format"; 388 return W::NoWeight(); 389 } 390 391 // TropicalWeight version. 392 template <> inline 393 TropicalWeight 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. 400 template <> inline 401 LogWeight 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). 411 template <class A> 412 class 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. 507 template <class A> 508 class 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. 532 template <class A> 533 template <class F> 534 bool 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. 586 template <class A> 587 class 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. 622 template <class A> 623 class 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 720 template <class A> inline 721 void 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. 727 typedef VectorFst<StdArc> StdVectorFst; 728 729 } // namespace fst 730 731 #endif // FST_LIB_VECTOR_FST_H__ 732