Ardour  8.12
variant.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014-2015 David Robillard <d@drobilla.net>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License 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  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef __ardour_variant_h__
20 #define __ardour_variant_h__
21 
22 #include <stdint.h>
23 #include <limits.h>
24 
25 #include <algorithm>
26 #include <stdexcept>
27 
29 #include "temporal/beats.h"
30 #include "pbd/compose.h"
31 
32 namespace ARDOUR {
33 
36 {
37 public:
38  enum Type {
41  BOOL,
44  INT,
45  LONG,
46  PATH,
48  URI
49  };
50 
51  Variant() : _type(NOTHING) { _long = 0; }
52 
53  explicit Variant(bool value) : _type(BOOL) { _bool = value; }
54  explicit Variant(double value) : _type(DOUBLE) { _double = value; }
55  explicit Variant(float value) : _type(FLOAT) { _float = value; }
56  explicit Variant(int32_t value) : _type(INT) { _int = value; }
57  explicit Variant(int64_t value) : _type(LONG) { _long = value; }
58 
59  explicit Variant(const Temporal::Beats& beats)
60  : _type(BEATS)
61  , _beats(beats)
62  {}
63 
65  Variant(Type type, const std::string& value)
66  : _type(type)
67  , _string(value)
68  {}
69 
74  Variant(Type type, double value)
75  : _type(type)
76  {
77  switch (type) {
78  case BOOL:
79  _bool = value != 0.0;
80  break;
81  case DOUBLE:
82  _double = (double)value;
83  break;
84  case FLOAT:
85  _float = (float)value;
86  break;
87  case INT:
88  _int = (int32_t)lrint(std::max((double)INT32_MIN,
89  std::min(value, (double)INT32_MAX)));
90  break;
91  case LONG:
92  _long = (int64_t)lrint(std::max((double)INT64_MIN,
93  std::min(value, (double)INT64_MAX)));
94  break;
95  case BEATS:
96  _beats = Temporal::Beats::from_double (value);
97  break;
98  default:
99  _type = NOTHING;
100  _long = 0;
101  }
102  }
103 
105  double to_double() const {
106  switch (_type) {
107  case BOOL: return _bool;
108  case DOUBLE: return _double;
109  case FLOAT: return _float;
110  case INT: return _int;
111  case LONG: return _long;
112  case BEATS: return Temporal::DoubleableBeats (_beats).to_double();
113  default: return 0.0;
114  }
115  }
116 
117  bool get_bool() const { ensure_type(BOOL); return _bool; }
118  double get_double() const { ensure_type(DOUBLE); return _double; }
119  float get_float() const { ensure_type(FLOAT); return _float; }
120  int get_int() const { ensure_type(INT); return _int; }
121  long get_long() const { ensure_type(LONG); return _long; }
122 
123  bool operator==(bool v) const { return _type == BOOL && _bool == v; }
124  double operator==(double v) const { return _type == DOUBLE && _double == v; }
125  float operator==(float v) const { return _type == FLOAT && _float == v; }
126  int operator==(int v) const { return _type == INT && _int == v; }
127  long operator==(long v) const { return _type == LONG && _long == v; }
128 
129  Variant& operator=(bool v) { _type = BOOL; _bool = v; return *this; }
130  Variant& operator=(double v) { _type = DOUBLE; _double = v; return *this; }
131  Variant& operator=(float v) { _type = FLOAT; _float = v; return *this; }
132  Variant& operator=(int v) { _type = INT; _int = v; return *this; }
133  Variant& operator=(long v) { _type = LONG; _long = v; return *this; }
134 
135  const std::string& get_path() const { ensure_type(PATH); return _string; }
136  const std::string& get_string() const { ensure_type(STRING); return _string; }
137  const std::string& get_uri() const { ensure_type(URI); return _string; }
138 
139  bool operator==(const Variant& v) const {
140  if (_type != v._type) {
141  return false;
142  }
143 
144  switch (_type) {
145  case NOTHING: return true;
146  case BEATS: return _beats == v._beats;
147  case BOOL: return _bool == v._bool;
148  case DOUBLE: return _double == v._double;
149  case FLOAT: return _float == v._float;
150  case INT: return _int == v._int;
151  case LONG: return _long == v._long;
152  case PATH:
153  case STRING:
154  case URI: return _string == v._string;
155  }
156 
157  return false;
158  }
159 
160  bool operator==(const Temporal::Beats& v) const {
161  return _type == BEATS && _beats == v;
162  }
163 
164  bool operator!() const { return _type == NOTHING; }
165 
167  _type = BEATS;
168  _beats = v;
169  return *this;
170  }
171 
172  const Temporal::Beats& get_beats() const {
173  ensure_type(BEATS); return _beats;
174  }
175 
176  Type type() const { return _type; }
177 
178  static bool type_is_numeric(Type type) {
179  switch (type) {
180  case BOOL: case DOUBLE: case FLOAT: case INT: case LONG: case BEATS:
181  return true;
182  default:
183  return false;
184  }
185  }
186 
187 private:
188  static const char* type_name(const Type type) {
189  static const char* names[] = {
190  "bool", "double", "float", "int", "long", "path", "string", "uri"
191  };
192 
193  return names[type];
194  }
195 
196  void ensure_type(const Type type) const {
197  if (_type != type) {
198  throw std::domain_error(
199  string_compose("get_%1 called on %2 variant",
200  type_name(type), type_name(_type)));
201  }
202  }
203 
205  std::string _string;
207 
208  // Union of all primitive numeric types
209  union {
210  bool _bool;
211  double _double;
212  float _float;
213  int32_t _int;
214  int64_t _long;
215  };
216 };
217 
218 } // namespace ARDOUR
219 
220 #endif // __ardour_variant_h__
long operator==(long v) const
Definition: variant.h:127
double operator==(double v) const
Definition: variant.h:124
bool get_bool() const
Definition: variant.h:117
int get_int() const
Definition: variant.h:120
const std::string & get_path() const
Definition: variant.h:135
Variant(double value)
Definition: variant.h:54
bool operator!() const
Definition: variant.h:164
Variant & operator=(Temporal::Beats v)
Definition: variant.h:166
int32_t _int
Definition: variant.h:213
double _double
Definition: variant.h:211
int operator==(int v) const
Definition: variant.h:126
std::string _string
PATH, STRING, URI.
Definition: variant.h:205
Variant & operator=(bool v)
Definition: variant.h:129
Variant(Type type, const std::string &value)
Definition: variant.h:65
Variant & operator=(int v)
Definition: variant.h:132
const Temporal::Beats & get_beats() const
Definition: variant.h:172
bool operator==(const Variant &v) const
Definition: variant.h:139
const std::string & get_string() const
Definition: variant.h:136
const std::string & get_uri() const
Definition: variant.h:137
float get_float() const
Definition: variant.h:119
Variant(int64_t value)
Definition: variant.h:57
Type _type
Type tag.
Definition: variant.h:204
Variant & operator=(float v)
Definition: variant.h:131
Variant & operator=(long v)
Definition: variant.h:133
Variant(bool value)
Definition: variant.h:53
Variant(Type type, double value)
Definition: variant.h:74
Variant & operator=(double v)
Definition: variant.h:130
Type type() const
Definition: variant.h:176
Variant(int32_t value)
Definition: variant.h:56
Temporal::Beats _beats
BEATS.
Definition: variant.h:206
static bool type_is_numeric(Type type)
Definition: variant.h:178
int64_t _long
Definition: variant.h:214
float operator==(float v) const
Definition: variant.h:125
Variant(const Temporal::Beats &beats)
Definition: variant.h:59
double get_double() const
Definition: variant.h:118
@ BOOL
Boolean.
Definition: variant.h:41
@ LONG
Signed 64-bit int.
Definition: variant.h:45
@ STRING
Raw string (no semantics)
Definition: variant.h:47
@ FLOAT
C float (32-bit IEEE-754)
Definition: variant.h:43
@ INT
Signed 32-bit int.
Definition: variant.h:44
@ NOTHING
Nothing (void)
Definition: variant.h:39
@ DOUBLE
C double (64-bit IEEE-754)
Definition: variant.h:42
@ PATH
File path string.
Definition: variant.h:46
@ BEATS
Beats+ticks.
Definition: variant.h:40
double to_double() const
Definition: variant.h:105
bool operator==(bool v) const
Definition: variant.h:123
long get_long() const
Definition: variant.h:121
static const char * type_name(const Type type)
Definition: variant.h:188
void ensure_type(const Type type) const
Definition: variant.h:196
float _float
Definition: variant.h:212
bool operator==(const Temporal::Beats &v) const
Definition: variant.h:160
Variant(float value)
Definition: variant.h:55
static Beats from_double(double beats)
Definition: beats.h:76
double to_double() const
Definition: beats.h:260
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:246
@ NOTHING
Definition: event.h:57
#define LIBARDOUR_API