d38aab2c4b15d2d6c4f3e46dd4dab8135af4d923
[ardour.git] / libs / ardour / ardour / port_set.h
1 /*
2     Copyright (C) 2006 Paul Davis 
3     
4     This program is free software; you can redistribute it and/or modify it
5     under the terms of the GNU General Public License as published by the Free
6     Software Foundation; either version 2 of the License, or (at your option)
7     any later version.
8     
9     This program is distributed in the hope that it will be useful, but WITHOUT
10     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12     for more details.
13     
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #ifndef __ardour_port_set_h__
20 #define __ardour_port_set_h__
21
22 #include <vector>
23 #include <ardour/port.h>
24 #include <ardour/audio_port.h>
25 #include <ardour/midi_port.h>
26 #include <ardour/chan_count.h>
27
28 namespace ARDOUR {
29
30
31 /** An ordered list of Ports, possibly of various types.
32  *
33  * This allows access to all the ports as a list, ignoring type, or accessing
34  * the nth port of a given type.  Note that port(n) and nth_audio_port(n) may
35  * NOT return the same port.
36  */
37 class PortSet {
38 public:
39         PortSet();
40
41         size_t num_ports() const;
42         size_t num_ports(DataType type) const { return _ports[type.to_index()].size(); }
43
44         void add_port(Port* port);
45
46         Port* port(size_t index) const;
47
48         Port* nth_port_of_type(DataType type, size_t n) const;
49
50         AudioPort* nth_audio_port(size_t n) const;
51         
52         MidiPort* nth_midi_port(size_t n) const;
53
54         bool contains(const Port* port) const;
55         
56         /** Remove all ports from the PortSet.  Ports are not deregistered with
57          * the engine, it's the caller's responsibility to not leak here!
58          */
59         void clear() { _ports.clear(); }
60
61         const ChanCount& chan_count() const { return _chan_count; }
62
63         bool empty() const { return (_chan_count.get_total() == 0); }
64
65         // ITERATORS
66         
67         // obviously these iterators will need to get more clever
68         // experimental phase, it's the interface that counts right now
69         
70         class iterator {
71         public:
72
73                 Port* operator*()  { return _list.port(_index); }
74                 iterator& operator++() { ++_index; return *this; } // yes, prefix only
75                 bool operator==(const iterator& other) { return (_index == other._index); }
76                 bool operator!=(const iterator& other) { return (_index != other._index); }
77
78         private:
79                 friend class PortSet;
80
81                 iterator(PortSet& list, size_t index) : _list(list), _index(index) {}
82
83                 PortSet& _list;
84                 size_t    _index;
85         };
86
87         iterator begin() { return iterator(*this, 0); }
88         iterator end()   { return iterator(*this, _chan_count.get_total()); }
89         
90         class const_iterator {
91         public:
92
93                 const Port* operator*()  { return _list.port(_index); }
94                 const_iterator& operator++() { ++_index; return *this; } // yes, prefix only
95                 bool operator==(const const_iterator& other) { return (_index == other._index); }
96                 bool operator!=(const const_iterator& other) { return (_index != other._index); }
97
98         private:
99                 friend class PortSet;
100
101                 const_iterator(const PortSet& list, size_t index) : _list(list), _index(index) {}
102
103                 const PortSet& _list;
104                 size_t          _index;
105         };
106
107         const_iterator begin() const { return const_iterator(*this, 0); }
108         const_iterator end()   const { return const_iterator(*this, _chan_count.get_total()); }
109
110         
111
112         class audio_iterator {
113         public:
114
115                 AudioPort* operator*()  { return _list.nth_audio_port(_index); }
116                 audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only
117                 bool operator==(const audio_iterator& other) { return (_index == other._index); }
118                 bool operator!=(const audio_iterator& other) { return (_index != other._index); }
119
120         private:
121                 friend class PortSet;
122
123                 audio_iterator(PortSet& list, size_t index) : _list(list), _index(index) {}
124
125                 PortSet& _list;
126                 size_t    _index;
127         };
128
129         audio_iterator audio_begin() { return audio_iterator(*this, 0); }
130         audio_iterator audio_end()   { return audio_iterator(*this, _chan_count.get(DataType::AUDIO)); }
131
132
133
134
135 private:        
136         // Prevent copies (undefined)
137         PortSet(const PortSet& copy);
138         void operator=(const PortSet& other);
139
140         typedef std::vector<Port*> PortVec;
141         
142         // Vector of vectors, indexed by DataType::to_index()
143         std::vector<PortVec> _ports;
144
145         ChanCount _chan_count;
146 };
147
148
149 } // namespace ARDOUR
150
151 #endif // __ardour_port_set_h__