Strip trailing whitespace and fix other whitespace errors (e.g. space/tab mixing...
[ardour.git] / libs / evoral / evoral / Parameter.hpp
1
2 /* This file is part of Evoral.
3  * Copyright (C) 2008 Dave Robillard <http://drobilla.net>
4  * Copyright (C) 2000-2008 Paul Davis
5  *
6  * Evoral is free software; you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation; either version 2 of the License, or (at your option) any later
9  * version.
10  *
11  * Evoral is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19
20 #ifndef EVORAL_PARAMETER_HPP
21 #define EVORAL_PARAMETER_HPP
22
23 #include <string>
24 #include <map>
25 #include <stdint.h>
26 #include <boost/shared_ptr.hpp>
27 #include <boost/format.hpp>
28 #include <iostream>
29
30 namespace Evoral {
31
32
33 /** ID of a [play|record|automate]able parameter.
34  *
35  * A parameter is defined by (type, id, channel).  Type is an integer which
36  * can be used in any way by the application (e.g. cast to a custom enum,
37  * map to/from a URI, etc).  ID is type specific (e.g. MIDI controller #).
38  *
39  * This class defines a < operator which is a strict weak ordering, so
40  * Parameter may be stored in a std::set, used as a std::map key, etc.
41  */
42 class Parameter
43 {
44 public:
45         Parameter(uint32_t type, uint8_t channel=0, uint32_t id=0)
46                 : _type(type), _id(id), _channel(channel)
47         {}
48
49         virtual ~Parameter() {}
50
51         inline uint32_t type()    const { return _type; }
52         inline uint8_t  channel() const { return _channel; }
53         inline uint32_t id()      const { return _id; }
54
55         /** Equivalence operator
56          * It is obvious from the definition that this operator
57          * is transitive, as required by stict weak ordering
58          * (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html)
59          */
60         inline bool operator==(const Parameter& id) const {
61                 return (_type == id._type && _channel == id._channel && _id == id._id );
62         }
63
64         /** Strict weak ordering
65          * See: http://www.sgi.com/tech/stl/StrictWeakOrdering.html
66          * Sort Parameters first according to type then to id and lastly to channel.
67          *
68          * Proof:
69          * <ol>
70          * <li>Irreflexivity: f(x, x) is false because of the irreflexivity of \c < in each branch.</li>
71          * <li>Antisymmetry: given x != y, f(x, y) implies !f(y, x) because of the same
72          *     property of \c < in each branch and the symmetry of operator==. </li>
73          * <li>Transitivity: let f(x, y) and f(y, z) => f(x, z) be true.
74          *    We prove by contradiction, assuming the contrary:
75          *    f(x, y) and f(x, z) hold => !f(x, z)
76          *
77          *    That implies one of the following:
78          *        <ol>
79          *      <li> x == z which contradicts the assumption f(x, y) and f(y, x)
80          *                 because of antisymmetry.
81          *      </li>
82          *      <li> f(z, x) is true. That would imply that one of the ivars (we call it i)
83          *           of x is greater than the same ivar in z while all "previous" ivars
84          *           are equal. That would imply that also in y all those "previous"
85          *           ivars are equal and because if x.i > z.i it is impossible
86          *           that there is an y that satisfies x.i < y.i < z.i at the same
87          *           time which contradicts the assumption.
88          *      </li>
89          *      Therefore f(x, z) is true (transitivity)
90          *    </ol>
91          * </li>
92          * </ol>
93          */
94         inline bool operator<(const Parameter& other) const {
95                 if (_type < other._type) {
96                         return true;
97                 } else if (_type == other._type && _channel < other._channel) {
98                         return true;
99                 } else if (_type == other._type && _channel == other._channel && _id < other._id ) {
100                         return true;
101                 }
102
103                 return false;
104         }
105
106         inline operator bool() const { return (_type != 0); }
107
108         /** Not used in indentity/comparison */
109         struct Metadata {
110                 Metadata(double low=0.0, double high=1.0, double mid=0.0)
111                         : min(low), max(high), normal(mid)
112                 {}
113                 double min;
114                 double max;
115                 double normal;
116         };
117
118         inline static void set_range(uint32_t type, double min, double max, double normal) {
119                 _type_metadata[type] = Metadata(min, max, normal);
120         }
121
122         inline void set_range(double min, double max, double normal) {
123                 _metadata = boost::shared_ptr<Metadata>(new Metadata(min, max, normal));
124         }
125
126         inline Metadata& metadata() const {
127                 if (_metadata)
128                         return *_metadata.get();
129                 else
130                         return _type_metadata[_type];
131         }
132
133         inline double min()    const { return metadata().min; }
134         inline double max()    const { return metadata().max; }
135         inline double normal() const { return metadata().normal; }
136
137 protected:
138         // Default copy constructor is ok
139
140         // ID (used in comparison)
141         uint32_t _type;
142         uint32_t _id;
143         uint8_t  _channel;
144
145         boost::shared_ptr<Metadata> _metadata;
146
147         typedef std::map<uint32_t, Metadata> TypeMetadata;
148         static TypeMetadata _type_metadata;
149 };
150
151
152 } // namespace Evoral
153
154 #endif // EVORAL_PARAMETER_HPP
155