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