12 TrackIter::TrackIter():
17 TrackIter::TrackIter(Track *t, unsigned e):
21 if(_track && _entry>_track->get_type().get_endpoints().size())
22 throw out_of_range("TrackIter::TrackIter");
25 BlockIter TrackIter::block_iter() const
30 Block &block = _track->get_block();
31 const vector<Block::Endpoint> &beps = block.get_endpoints();
33 if(_track->get_type().is_turnout())
35 /* A turnouts is the only track in its block. Go ahead and find the
36 matching endpoint in the block. */
37 for(unsigned i=0; i<beps.size(); ++i)
38 if(beps[i].track==_track && beps[i].track_ep==_entry)
39 return BlockIter(&block, i);
43 TrackIter rev = reverse();
44 while(rev && &rev.track()->get_block()==&block)
46 TrackIter fwd = rev.reverse();
48 for(unsigned i=0; i<beps.size(); ++i)
49 if(beps[i].track==fwd.track() && beps[i].track_ep==fwd.entry())
50 return BlockIter(&block, i);
56 throw logic_error("internal error (didn't find block entry endpoint)");
59 const TrackType::Endpoint &TrackIter::endpoint() const
62 throw logic_error("null track");
64 return _track->get_type().get_endpoint(_entry);
67 int TrackIter::get_exit(unsigned path) const
69 const vector<TrackType::Endpoint> &eps = _track->get_type().get_endpoints();
71 // Find an endpoint that's connected to the entry and has the requested path
72 for(unsigned i=0; i<eps.size(); ++i)
73 if(i!=_entry && (eps[i].paths&(1<<path)) && (eps[i].paths&eps[_entry].paths))
79 TrackIter TrackIter::next() const
84 return next(_track->get_active_path());
87 TrackIter TrackIter::next(unsigned path) const
92 int exit = get_exit(path);
97 result._track = _track->get_link(exit);
98 result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
103 TrackIter TrackIter::reverse() const
108 return reverse(_track->get_active_path());
111 TrackIter TrackIter::reverse(unsigned path) const
116 int exit = get_exit(path);
120 return TrackIter(_track, exit);
123 TrackIter TrackIter::flip() const
129 result._track = _track->get_link(_entry);
130 result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
135 Track &TrackIter::operator*() const
138 throw logic_error("null track");
143 bool TrackIter::operator==(const TrackIter &other) const
145 return _track==other._track && _entry==other._entry;
149 TrackLoopIter::TrackLoopIter():
153 TrackLoopIter::TrackLoopIter(Track *t, unsigned e):
155 _visited(new TrackList()),
156 _last(_visited->insert(_visited->end(), track())),
160 TrackLoopIter::TrackLoopIter(const TrackIter &i):
162 _visited(new TrackList()),
163 _last(_visited->insert(_visited->end(), track())),
167 TrackLoopIter::TrackLoopIter(const TrackIter &i, RefPtr<TrackList> v, const TrackList::iterator &l):
175 _looped = (_visited && find(_visited->begin(), _last, track())!=_last);
178 if(_last!=_visited->end())
180 _visited = new TrackList(_visited->begin(), _last);
181 _last = _visited->end();
183 _visited->push_back(track());
188 TrackLoopIter TrackLoopIter::next() const
190 return TrackLoopIter(TrackIter::next(), _visited, _last);
193 TrackLoopIter TrackLoopIter::next(unsigned path) const
195 return TrackLoopIter(TrackIter::next(path), _visited, _last);