]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/trackiter.cpp
Fix remaining exception class names
[r2c2.git] / source / libr2c2 / trackiter.cpp
1 #include <algorithm>
2 #include "track.h"
3 #include "trackiter.h"
4 #include "tracktype.h"
5
6 using namespace std;
7 using namespace Msp;
8
9 namespace R2C2 {
10
11 TrackIter::TrackIter():
12         _track(0),
13         _entry(0)
14 { }
15
16 TrackIter::TrackIter(Track *t, unsigned e):
17         _track(t),
18         _entry(t ? e : 0)
19 {
20         if(_track && _entry>_track->get_type().get_endpoints().size())
21                 throw out_of_range("TrackIter::TrackIter");
22 }
23
24 const TrackType::Endpoint &TrackIter::endpoint() const
25 {
26         if(!_track)
27                 throw logic_error("null track");
28
29         return _track->get_type().get_endpoint(_entry);
30 }
31
32 int TrackIter::get_exit(unsigned path) const
33 {
34         const vector<TrackType::Endpoint> &eps = _track->get_type().get_endpoints();
35         
36         // Find an endpoint that's connected to the entry and has the requested path
37         for(unsigned i=0; i<eps.size(); ++i)
38                 if(i!=_entry && (eps[i].paths&(1<<path)) && (eps[i].paths&eps[_entry].paths))
39                         return i;
40
41         return -1;
42 }
43
44 TrackIter TrackIter::next() const
45 {
46         if(!_track)
47                 return TrackIter();
48
49         return next(_track->get_active_path());
50 }
51
52 TrackIter TrackIter::next(unsigned path) const
53 {
54         if(!_track)
55                 return TrackIter();
56
57         int exit = get_exit(path);
58         if(exit<0)
59                 return TrackIter();
60
61         TrackIter result;
62         result._track = _track->get_link(exit);
63         result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
64
65         return result;
66 }
67
68 TrackIter TrackIter::reverse() const
69 {
70         if(!_track)
71                 return TrackIter();
72
73         return reverse(_track->get_active_path());
74 }
75
76 TrackIter TrackIter::reverse(unsigned path) const
77 {
78         if(!_track)
79                 return TrackIter();
80
81         int exit = get_exit(path);
82         if(exit<0)
83                 return TrackIter();
84
85         return TrackIter(_track, exit);
86 }
87
88 TrackIter TrackIter::flip() const
89 {
90         if(!_track)
91                 return TrackIter();
92
93         TrackIter result;
94         result._track = _track->get_link(_entry);
95         result._entry = (result._track ? result._track->get_endpoint_by_link(*_track) : 0);
96
97         return result;
98 }
99
100 Track &TrackIter::operator*() const
101 {
102         if(!_track)
103                 throw logic_error("null track");
104
105         return *_track;
106 }
107
108 bool TrackIter::operator==(const TrackIter &other) const
109 {
110         return _track==other._track && _entry==other._entry;
111 }
112
113
114 TrackLoopIter::TrackLoopIter():
115         _looped(false)
116 { }
117
118 TrackLoopIter::TrackLoopIter(Track *t, unsigned e):
119         TrackIter(t, e),
120         _visited(new TrackList()),
121         _last(_visited->insert(_visited->end(), track())),
122         _looped(false)
123 { }
124
125 TrackLoopIter::TrackLoopIter(const TrackIter &i):
126         TrackIter(i),
127         _visited(new TrackList()),
128         _last(_visited->insert(_visited->end(), track())),
129         _looped(false)
130 { }
131
132 TrackLoopIter::TrackLoopIter(const TrackIter &i, RefPtr<TrackList> v, const TrackList::iterator &l):
133         TrackIter(i),
134         _looped(false)
135 {
136         if(track())
137         {
138                 _visited = v;
139                 _last = l;
140                 _looped = (_visited && find(_visited->begin(), _last, track())!=_last);
141
142                 ++_last;
143                 if(_last!=_visited->end())
144                 {
145                         _visited = new TrackList(_visited->begin(), _last);
146                         _last = _visited->end();
147                 }
148                 _visited->push_back(track());
149                 --_last;
150         }
151 }
152
153 TrackLoopIter TrackLoopIter::next() const
154 {
155         return TrackLoopIter(TrackIter::next(), _visited, _last);
156 }
157
158 TrackLoopIter TrackLoopIter::next(unsigned path) const
159 {
160         return TrackLoopIter(TrackIter::next(path), _visited, _last);
161 }
162
163 } // namespace R2C2