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 // See if this track matches an endpoint in the block
34 for(unsigned i=0; i<beps.size(); ++i)
35 if(beps[i].track==_track && beps[i].track_ep==_entry)
36 return BlockIter(&block, i);
38 if(!_track->get_type().is_turnout())
40 /* Since there was no endpoint match, the preceding track can't be in a
42 TrackIter rev = flip();
44 while(rev && &rev.track()->get_block()==&block)
50 // If we ran out of tracks, return an empty iterator
54 TrackIter fwd = last.reverse();
55 for(unsigned i=0; i<beps.size(); ++i)
56 if(beps[i].track==fwd.track() && beps[i].track_ep==fwd.entry())
57 return BlockIter(&block, i);
60 throw logic_error("internal error (didn't find block entry endpoint)");
63 const TrackType::Endpoint &TrackIter::endpoint() const
66 throw logic_error("null track");
68 return _track->get_type().get_endpoint(_entry);
71 int TrackIter::get_exit(unsigned path) const
73 path = _track->get_type().coerce_path(_entry, path);
74 const vector<TrackType::Endpoint> &eps = _track->get_type().get_endpoints();
76 // Find an endpoint that's connected to the entry and has the requested path
77 for(unsigned i=0; i<eps.size(); ++i)
78 if(i!=_entry && eps[i].has_path(path) && eps[i].has_common_paths(eps[_entry]))
84 TrackIter TrackIter::next() const
89 return next(_track->get_active_path());
92 TrackIter TrackIter::next(unsigned path) const
97 int exit = get_exit(path);
102 result._track = _track->get_link(exit);
103 result._entry = (result._track ? result._track->get_link_slot(*_track) : 0);
108 TrackIter TrackIter::reverse() const
113 return reverse(_track->get_active_path());
116 TrackIter TrackIter::reverse(unsigned path) const
121 int exit = get_exit(path);
125 return TrackIter(_track, exit);
128 TrackIter TrackIter::flip() const
134 result._track = _track->get_link(_entry);
135 result._entry = (result._track ? result._track->get_link_slot(*_track) : 0);
140 Track &TrackIter::operator*() const
143 throw logic_error("null track");
148 bool TrackIter::operator==(const TrackIter &other) const
150 return _track==other._track && _entry==other._entry;
154 TrackLoopIter::TrackLoopIter():
158 TrackLoopIter::TrackLoopIter(Track *t, unsigned e):
160 _visited(new TrackList()),
161 _last(_visited->insert(_visited->end(), track())),
165 TrackLoopIter::TrackLoopIter(const TrackIter &i):
167 _visited(new TrackList()),
168 _last(_visited->insert(_visited->end(), track())),
172 TrackLoopIter::TrackLoopIter(const TrackIter &i, RefPtr<TrackList> v, const TrackList::iterator &l):
180 _looped = (_visited && find(_visited->begin(), _last, track())!=_last);
183 if(_last!=_visited->end())
185 _visited = new TrackList(_visited->begin(), _last);
186 _last = _visited->end();
188 _visited->push_back(track());
193 TrackLoopIter TrackLoopIter::next() const
195 return TrackLoopIter(TrackIter::next(), _visited, _last);
198 TrackLoopIter TrackLoopIter::next(unsigned path) const
200 return TrackLoopIter(TrackIter::next(path), _visited, _last);