VCV Rack API v2
common.hpp
Go to the documentation of this file.
1#pragma once
2// Include most of the C stdlib for convenience
3#include <cstddef>
4#include <cstdlib>
5#include <cstdio>
6#include <cstdint>
7#include <cinttypes>
8#include <cstdarg>
9#include <climits>
10#include <cmath>
11#include <cstring>
12#include <cassert>
13
14// Include some of the C++ stdlib for convenience
15#include <string>
16#include <stdexcept>
17
18
24#define DEPRECATED __attribute__((deprecated))
25
29#ifndef PRIVATE
30#define PRIVATE
31#endif
32
33
44#define CONCAT_LITERAL(x, y) x ## y
45#define CONCAT(x, y) CONCAT_LITERAL(x, y)
46
47
60#define TOSTRING_LITERAL(x) #x
61#define TOSTRING(x) TOSTRING_LITERAL(x)
62
63
65#define LENGTHOF(arr) (sizeof(arr) / sizeof((arr)[0]))
66
67
78#define ENUMS(name, count) name, name ## _LAST = name + (count) - 1
79
80
101#if defined ARCH_MAC
102 // Use output from `xxd -i`
103 #define BINARY(sym) extern unsigned char sym[]; extern unsigned int sym##_len
104 #define BINARY_START(sym) ((const void*) sym)
105 #define BINARY_END(sym) ((const void*) sym + sym##_len)
106 #define BINARY_SIZE(sym) (sym##_len)
107#else
108 #define BINARY(sym) extern char _binary_##sym##_start, _binary_##sym##_end, _binary_##sym##_size
109 #define BINARY_START(sym) ((const void*) &_binary_##sym##_start)
110 #define BINARY_END(sym) ((const void*) &_binary_##sym##_end)
111 // The symbol "_binary_##sym##_size" doesn't seem to be valid after a plugin is dynamically loaded, so simply take the difference between the two addresses.
112 #define BINARY_SIZE(sym) ((size_t) (&_binary_##sym##_end - &_binary_##sym##_start))
113#endif
114
115
125inline int8_t operator"" _i8(unsigned long long x) {return x;}
126inline int16_t operator"" _i16(unsigned long long x) {return x;}
127inline int32_t operator"" _i32(unsigned long long x) {return x;}
128inline int64_t operator"" _i64(unsigned long long x) {return x;}
129inline uint8_t operator"" _u8(unsigned long long x) {return x;}
130inline uint16_t operator"" _u16(unsigned long long x) {return x;}
131inline uint32_t operator"" _u32(unsigned long long x) {return x;}
132inline uint64_t operator"" _u64(unsigned long long x) {return x;}
133inline float operator"" _f32(long double x) {return x;}
134inline float operator"" _f32(unsigned long long x) {return x;}
135inline double operator"" _f64(long double x) {return x;}
136inline double operator"" _f64(unsigned long long x) {return x;}
137
138
139#if defined ARCH_WIN
140// wchar_t on Windows should be 2 bytes
141static_assert(sizeof(wchar_t) == 2);
142
143// Windows C standard functions are ASCII-8 instead of UTF-8, so redirect these functions to wrappers which convert to UTF-8
144#define fopen fopen_u8
145
146extern "C" {
147FILE* fopen_u8(const char* filename, const char* mode);
148}
149
150namespace std {
151 using ::fopen_u8;
152}
153#endif
154
155
157namespace rack {
158
159
161template <typename To, typename From>
162To bitCast(From from) {
163 static_assert(sizeof(From) == sizeof(To), "Types must be the same size");
164 To to;
165 // This is optimized out
166 std::memcpy(&to, &from, sizeof(From));
167 return to;
168}
169
170
176template <typename T>
178 return new T;
179}
180
181template <typename T, typename F, typename V, typename... Args>
182T* construct(F f, V v, Args... args) {
183 T* o = construct<T>(args...);
184 o->*f = v;
185 return o;
186}
187
188
199template <typename F>
201 F f;
202 DeferWrapper(F f) : f(f) {}
204 f();
205 }
206};
207
208template <typename F>
210 return DeferWrapper<F>(f);
211}
212
213#define DEFER(code) auto CONCAT(_defer_, __COUNTER__) = rack::deferWrapper([&]() code)
214
215
219struct Exception : std::exception {
220 std::string msg;
221
222 // Attribute index 1 refers to `Exception*` argument so use 2.
223 __attribute__((format(printf, 2, 3)))
224 Exception(const char* format, ...);
225 Exception(const std::string& msg) : msg(msg) {}
226 const char* what() const noexcept override {
227 return msg.c_str();
228 }
229};
230
231
245template <typename C>
246typename C::mapped_type get(const C& m, const typename C::key_type& key, const typename C::mapped_type& def = typename C::mapped_type()) {
247 typename C::const_iterator it = m.find(key);
248 if (it == m.end())
249 return def;
250 return it->second;
251}
252
253
254// config
255
256extern const std::string APP_NAME;
257extern const std::string APP_EDITION;
258extern const std::string APP_EDITION_NAME;
259extern const std::string APP_VERSION_MAJOR;
260extern const std::string APP_VERSION;
261extern const std::string APP_OS;
262extern const std::string API_URL;
263
264
265} // namespace rack
266
267
268// Logger depends on common.hpp, but it is handy to include it along with common.hpp.
269#include <logger.hpp>
const char * filename
Definition: logger.hpp:40
const char int const char const char * format
Definition: logger.hpp:40
Root namespace for the Rack API.
Definition: AudioDisplay.hpp:9
T * construct()
C#-style property constructor Example:
Definition: common.hpp:177
const std::string APP_NAME
To bitCast(From from)
Casts a primitive, preserving its bits instead of converting.
Definition: common.hpp:162
const std::string API_URL
const std::string APP_VERSION_MAJOR
const std::string APP_VERSION
C::mapped_type get(const C &m, const typename C::key_type &key, const typename C::mapped_type &def=typename C::mapped_type())
Given a std::map, returns the value of the given key, or returns def if the key doesn't exist.
Definition: common.hpp:246
const std::string APP_EDITION
const std::string APP_OS
const std::string APP_EDITION_NAME
DeferWrapper< F > deferWrapper(F f)
Definition: common.hpp:209
Defers running code until the scope is destructed.
Definition: common.hpp:200
~DeferWrapper()
Definition: common.hpp:203
DeferWrapper(F f)
Definition: common.hpp:202
F f
Definition: common.hpp:201
An exception explicitly thrown by Rack or a Rack plugin.
Definition: common.hpp:219
__attribute__((format(printf, 2, 3))) Exception(const char *format
std::string msg
Definition: common.hpp:220
const char * what() const noexcept override
Definition: common.hpp:226