Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
16KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2016 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of the ISC license
  6. http://www.isc.org/downloads/software-support-policy/isc-license/
  7. Permission to use, copy, modify, and/or distribute this software for any
  8. purpose with or without fee is hereby granted, provided that the above
  9. copyright notice and this permission notice appear in all copies.
  10. THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
  11. TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  12. FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
  13. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  14. USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  16. OF THIS SOFTWARE.
  17. -----------------------------------------------------------------------------
  18. To release a closed-source product which uses other parts of JUCE not
  19. licensed under the ISC terms, commercial licenses are available: visit
  20. www.juce.com for more information.
  21. ==============================================================================
  22. */
  23. #include "Variant.h"
  24. namespace water {
  25. enum VariantStreamMarkers
  26. {
  27. varMarker_Int = 1,
  28. varMarker_BoolTrue = 2,
  29. varMarker_BoolFalse = 3,
  30. varMarker_Double = 4,
  31. varMarker_String = 5,
  32. varMarker_Int64 = 6,
  33. varMarker_Undefined = 9
  34. };
  35. //==============================================================================
  36. class var::VariantType
  37. {
  38. public:
  39. VariantType() noexcept {}
  40. virtual ~VariantType() noexcept {}
  41. virtual int toInt (const ValueUnion&) const noexcept { return 0; }
  42. virtual int64 toInt64 (const ValueUnion&) const noexcept { return 0; }
  43. virtual double toDouble (const ValueUnion&) const noexcept { return 0; }
  44. virtual String toString (const ValueUnion&) const { return String(); }
  45. virtual bool toBool (const ValueUnion&) const noexcept { return false; }
  46. virtual var clone (const var& original) const { return original; }
  47. virtual bool isVoid() const noexcept { return false; }
  48. virtual bool isUndefined() const noexcept { return false; }
  49. virtual bool isInt() const noexcept { return false; }
  50. virtual bool isInt64() const noexcept { return false; }
  51. virtual bool isBool() const noexcept { return false; }
  52. virtual bool isDouble() const noexcept { return false; }
  53. virtual bool isString() const noexcept { return false; }
  54. virtual void cleanUp (ValueUnion&) const noexcept {}
  55. virtual void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest = source; }
  56. virtual bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept = 0;
  57. };
  58. //==============================================================================
  59. class var::VariantType_Void : public var::VariantType
  60. {
  61. public:
  62. VariantType_Void() noexcept {}
  63. static const VariantType_Void instance;
  64. bool isVoid() const noexcept override { return true; }
  65. bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept override { return otherType.isVoid() || otherType.isUndefined(); }
  66. };
  67. //==============================================================================
  68. class var::VariantType_Undefined : public var::VariantType
  69. {
  70. public:
  71. VariantType_Undefined() noexcept {}
  72. static const VariantType_Undefined instance;
  73. bool isUndefined() const noexcept override { return true; }
  74. String toString (const ValueUnion&) const override { return "undefined"; }
  75. bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept override { return otherType.isVoid() || otherType.isUndefined(); }
  76. };
  77. //==============================================================================
  78. class var::VariantType_Int : public var::VariantType
  79. {
  80. public:
  81. VariantType_Int() noexcept {}
  82. static const VariantType_Int instance;
  83. int toInt (const ValueUnion& data) const noexcept override { return data.intValue; };
  84. int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.intValue; };
  85. double toDouble (const ValueUnion& data) const noexcept override { return (double) data.intValue; }
  86. String toString (const ValueUnion& data) const override { return String (data.intValue); }
  87. bool toBool (const ValueUnion& data) const noexcept override { return data.intValue != 0; }
  88. bool isInt() const noexcept override { return true; }
  89. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  90. {
  91. if (otherType.isDouble() || otherType.isInt64() || otherType.isString())
  92. return otherType.equals (otherData, data, *this);
  93. return otherType.toInt (otherData) == data.intValue;
  94. }
  95. };
  96. //==============================================================================
  97. class var::VariantType_Int64 : public var::VariantType
  98. {
  99. public:
  100. VariantType_Int64() noexcept {}
  101. static const VariantType_Int64 instance;
  102. int toInt (const ValueUnion& data) const noexcept override { return (int) data.int64Value; };
  103. int64 toInt64 (const ValueUnion& data) const noexcept override { return data.int64Value; };
  104. double toDouble (const ValueUnion& data) const noexcept override { return (double) data.int64Value; }
  105. String toString (const ValueUnion& data) const override { return String (data.int64Value); }
  106. bool toBool (const ValueUnion& data) const noexcept override { return data.int64Value != 0; }
  107. bool isInt64() const noexcept override { return true; }
  108. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  109. {
  110. if (otherType.isDouble() || otherType.isString())
  111. return otherType.equals (otherData, data, *this);
  112. return otherType.toInt64 (otherData) == data.int64Value;
  113. }
  114. };
  115. //==============================================================================
  116. class var::VariantType_Double : public var::VariantType
  117. {
  118. public:
  119. VariantType_Double() noexcept {}
  120. static const VariantType_Double instance;
  121. int toInt (const ValueUnion& data) const noexcept override { return (int) data.doubleValue; };
  122. int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.doubleValue; };
  123. double toDouble (const ValueUnion& data) const noexcept override { return data.doubleValue; }
  124. String toString (const ValueUnion& data) const override { return String (data.doubleValue, 20); }
  125. bool toBool (const ValueUnion& data) const noexcept override { return data.doubleValue != 0; }
  126. bool isDouble() const noexcept override { return true; }
  127. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  128. {
  129. return std::abs (otherType.toDouble (otherData) - data.doubleValue) < std::numeric_limits<double>::epsilon();
  130. }
  131. };
  132. //==============================================================================
  133. class var::VariantType_Bool : public var::VariantType
  134. {
  135. public:
  136. VariantType_Bool() noexcept {}
  137. static const VariantType_Bool instance;
  138. int toInt (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; };
  139. int64 toInt64 (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; };
  140. double toDouble (const ValueUnion& data) const noexcept override { return data.boolValue ? 1.0 : 0.0; }
  141. String toString (const ValueUnion& data) const override { return String::charToString (data.boolValue ? (juce_wchar) '1' : (juce_wchar) '0'); }
  142. bool toBool (const ValueUnion& data) const noexcept override { return data.boolValue; }
  143. bool isBool() const noexcept override { return true; }
  144. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  145. {
  146. return otherType.toBool (otherData) == data.boolValue;
  147. }
  148. };
  149. //==============================================================================
  150. class var::VariantType_String : public var::VariantType
  151. {
  152. public:
  153. VariantType_String() noexcept {}
  154. static const VariantType_String instance;
  155. void cleanUp (ValueUnion& data) const noexcept override { getString (data)-> ~String(); }
  156. void createCopy (ValueUnion& dest, const ValueUnion& source) const override { new (dest.stringValue) String (*getString (source)); }
  157. bool isString() const noexcept override { return true; }
  158. int toInt (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue(); };
  159. int64 toInt64 (const ValueUnion& data) const noexcept override { return getString (data)->getLargeIntValue(); };
  160. double toDouble (const ValueUnion& data) const noexcept override { return getString (data)->getDoubleValue(); }
  161. String toString (const ValueUnion& data) const override { return *getString (data); }
  162. bool toBool (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue() != 0
  163. || getString (data)->trim().equalsIgnoreCase ("true")
  164. || getString (data)->trim().equalsIgnoreCase ("yes"); }
  165. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  166. {
  167. return otherType.toString (otherData) == *getString (data);
  168. }
  169. private:
  170. static inline const String* getString (const ValueUnion& data) noexcept { return reinterpret_cast<const String*> (data.stringValue); }
  171. static inline String* getString (ValueUnion& data) noexcept { return reinterpret_cast<String*> (data.stringValue); }
  172. };
  173. //==============================================================================
  174. const var::VariantType_Void var::VariantType_Void::instance;
  175. const var::VariantType_Undefined var::VariantType_Undefined::instance;
  176. const var::VariantType_Int var::VariantType_Int::instance;
  177. const var::VariantType_Int64 var::VariantType_Int64::instance;
  178. const var::VariantType_Bool var::VariantType_Bool::instance;
  179. const var::VariantType_Double var::VariantType_Double::instance;
  180. const var::VariantType_String var::VariantType_String::instance;
  181. //==============================================================================
  182. var::var() noexcept : type (&VariantType_Void::instance) {}
  183. var::var (const VariantType& t) noexcept : type (&t) {}
  184. var::~var() noexcept { type->cleanUp (value); }
  185. //==============================================================================
  186. var::var (const var& valueToCopy) : type (valueToCopy.type)
  187. {
  188. type->createCopy (value, valueToCopy.value);
  189. }
  190. var::var (const int v) noexcept : type (&VariantType_Int::instance) { value.intValue = v; }
  191. var::var (const int64 v) noexcept : type (&VariantType_Int64::instance) { value.int64Value = v; }
  192. var::var (const bool v) noexcept : type (&VariantType_Bool::instance) { value.boolValue = v; }
  193. var::var (const double v) noexcept : type (&VariantType_Double::instance) { value.doubleValue = v; }
  194. var::var (const String& v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
  195. var::var (const char* const v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
  196. var var::undefined() noexcept { return var (VariantType_Undefined::instance); }
  197. //==============================================================================
  198. bool var::isVoid() const noexcept { return type->isVoid(); }
  199. bool var::isUndefined() const noexcept { return type->isUndefined(); }
  200. bool var::isInt() const noexcept { return type->isInt(); }
  201. bool var::isInt64() const noexcept { return type->isInt64(); }
  202. bool var::isBool() const noexcept { return type->isBool(); }
  203. bool var::isDouble() const noexcept { return type->isDouble(); }
  204. bool var::isString() const noexcept { return type->isString(); }
  205. var::operator int() const noexcept { return type->toInt (value); }
  206. var::operator int64() const noexcept { return type->toInt64 (value); }
  207. var::operator bool() const noexcept { return type->toBool (value); }
  208. var::operator float() const noexcept { return (float) type->toDouble (value); }
  209. var::operator double() const noexcept { return type->toDouble (value); }
  210. String var::toString() const { return type->toString (value); }
  211. var::operator String() const { return type->toString (value); }
  212. //==============================================================================
  213. void var::swapWith (var& other) noexcept
  214. {
  215. std::swap (type, other.type);
  216. std::swap (value, other.value);
  217. }
  218. var& var::operator= (const var& v) { type->cleanUp (value); type = v.type; type->createCopy (value, v.value); return *this; }
  219. var& var::operator= (const int v) { type->cleanUp (value); type = &VariantType_Int::instance; value.intValue = v; return *this; }
  220. var& var::operator= (const int64 v) { type->cleanUp (value); type = &VariantType_Int64::instance; value.int64Value = v; return *this; }
  221. var& var::operator= (const bool v) { type->cleanUp (value); type = &VariantType_Bool::instance; value.boolValue = v; return *this; }
  222. var& var::operator= (const double v) { type->cleanUp (value); type = &VariantType_Double::instance; value.doubleValue = v; return *this; }
  223. var& var::operator= (const char* const v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; }
  224. var& var::operator= (const String& v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; }
  225. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  226. var::var (var&& other) noexcept
  227. : type (other.type),
  228. value (other.value)
  229. {
  230. other.type = &VariantType_Void::instance;
  231. }
  232. var& var::operator= (var&& other) noexcept
  233. {
  234. swapWith (other);
  235. return *this;
  236. }
  237. var::var (String&& v) : type (&VariantType_String::instance)
  238. {
  239. new (value.stringValue) String (static_cast<String&&> (v));
  240. }
  241. var& var::operator= (String&& v)
  242. {
  243. type->cleanUp (value);
  244. type = &VariantType_String::instance;
  245. new (value.stringValue) String (static_cast<String&&> (v));
  246. return *this;
  247. }
  248. #endif
  249. //==============================================================================
  250. bool var::equals (const var& other) const noexcept
  251. {
  252. return type->equals (value, other.value, *other.type);
  253. }
  254. bool var::equalsWithSameType (const var& other) const noexcept
  255. {
  256. return type == other.type && equals (other);
  257. }
  258. bool var::hasSameTypeAs (const var& other) const noexcept
  259. {
  260. return type == other.type;
  261. }
  262. bool operator== (const var& v1, const var& v2) noexcept { return v1.equals (v2); }
  263. bool operator!= (const var& v1, const var& v2) noexcept { return ! v1.equals (v2); }
  264. bool operator== (const var& v1, const String& v2) { return v1.toString() == v2; }
  265. bool operator!= (const var& v1, const String& v2) { return v1.toString() != v2; }
  266. bool operator== (const var& v1, const char* const v2) { return v1.toString() == v2; }
  267. bool operator!= (const var& v1, const char* const v2) { return v1.toString() != v2; }
  268. //==============================================================================
  269. var var::clone() const noexcept
  270. {
  271. return type->clone (*this);
  272. }
  273. }