The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

281 lines
12KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #ifndef __JUCE_VARIANT_JUCEHEADER__
  19. #define __JUCE_VARIANT_JUCEHEADER__
  20. #include "../text/juce_Identifier.h"
  21. #include "../streams/juce_OutputStream.h"
  22. #include "../streams/juce_InputStream.h"
  23. #include "../containers/juce_Array.h"
  24. #ifndef DOXYGEN
  25. class ReferenceCountedObject;
  26. class DynamicObject;
  27. #endif
  28. //==============================================================================
  29. /**
  30. A variant class, that can be used to hold a range of primitive values.
  31. A var object can hold a range of simple primitive values, strings, or
  32. any kind of ReferenceCountedObject. The var class is intended to act like
  33. the kind of values used in dynamic scripting languages.
  34. You can save/load var objects either in a small, proprietary binary format
  35. using writeToStream()/readFromStream(), or as JSON by using the JSON class.
  36. @see JSON, DynamicObject
  37. */
  38. class JUCE_API var
  39. {
  40. public:
  41. //==============================================================================
  42. typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments);
  43. typedef Identifier identifier;
  44. //==============================================================================
  45. /** Creates a void variant. */
  46. var() noexcept;
  47. /** Destructor. */
  48. ~var() noexcept;
  49. /** A static var object that can be used where you need an empty variant object. */
  50. static const var null;
  51. var (const var& valueToCopy);
  52. var (int value) noexcept;
  53. var (int64 value) noexcept;
  54. var (bool value) noexcept;
  55. var (double value) noexcept;
  56. var (const char* value);
  57. var (const wchar_t* value);
  58. var (const String& value);
  59. var (const Array<var>& value);
  60. var (ReferenceCountedObject* object);
  61. var (MethodFunction method) noexcept;
  62. var& operator= (const var& valueToCopy);
  63. var& operator= (int value);
  64. var& operator= (int64 value);
  65. var& operator= (bool value);
  66. var& operator= (double value);
  67. var& operator= (const char* value);
  68. var& operator= (const wchar_t* value);
  69. var& operator= (const String& value);
  70. var& operator= (const Array<var>& value);
  71. var& operator= (ReferenceCountedObject* object);
  72. var& operator= (MethodFunction method);
  73. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  74. var (var&& other) noexcept;
  75. var (String&& value);
  76. var& operator= (var&& other) noexcept;
  77. var& operator= (String&& value);
  78. #endif
  79. void swapWith (var& other) noexcept;
  80. operator int() const noexcept;
  81. operator int64() const noexcept;
  82. operator bool() const noexcept;
  83. operator float() const noexcept;
  84. operator double() const noexcept;
  85. operator String() const;
  86. String toString() const;
  87. Array<var>* getArray() const noexcept;
  88. ReferenceCountedObject* getObject() const noexcept;
  89. DynamicObject* getDynamicObject() const noexcept;
  90. bool isVoid() const noexcept;
  91. bool isInt() const noexcept;
  92. bool isInt64() const noexcept;
  93. bool isBool() const noexcept;
  94. bool isDouble() const noexcept;
  95. bool isString() const noexcept;
  96. bool isObject() const noexcept;
  97. bool isArray() const noexcept;
  98. bool isMethod() const noexcept;
  99. /** Returns true if this var has the same value as the one supplied.
  100. Note that this ignores the type, so a string var "123" and an integer var with the
  101. value 123 are considered to be equal.
  102. @see equalsWithSameType
  103. */
  104. bool equals (const var& other) const noexcept;
  105. /** Returns true if this var has the same value and type as the one supplied.
  106. This differs from equals() because e.g. "123" and 123 will be considered different.
  107. @see equals
  108. */
  109. bool equalsWithSameType (const var& other) const noexcept;
  110. //==============================================================================
  111. /** If the var is an array, this returns the number of elements.
  112. If the var isn't actually an array, this will return 0.
  113. */
  114. int size() const;
  115. /** If the var is an array, this can be used to return one of its elements.
  116. To call this method, you must make sure that the var is actually an array, and
  117. that the index is a valid number. If these conditions aren't met, behaviour is
  118. undefined.
  119. For more control over the array's contents, you can call getArray() and manipulate
  120. it directly as an Array\<var\>.
  121. */
  122. const var& operator[] (int arrayIndex) const;
  123. /** If the var is an array, this can be used to return one of its elements.
  124. To call this method, you must make sure that the var is actually an array, and
  125. that the index is a valid number. If these conditions aren't met, behaviour is
  126. undefined.
  127. For more control over the array's contents, you can call getArray() and manipulate
  128. it directly as an Array\<var\>.
  129. */
  130. var& operator[] (int arrayIndex);
  131. /** Appends an element to the var, converting it to an array if it isn't already one.
  132. If the var isn't an array, it will be converted to one, and if its value was non-void,
  133. this value will be kept as the first element of the new array. The parameter value
  134. will then be appended to it.
  135. For more control over the array's contents, you can call getArray() and manipulate
  136. it directly as an Array\<var\>.
  137. */
  138. void append (const var& valueToAppend);
  139. /** Inserts an element to the var, converting it to an array if it isn't already one.
  140. If the var isn't an array, it will be converted to one, and if its value was non-void,
  141. this value will be kept as the first element of the new array. The parameter value
  142. will then be inserted into it.
  143. For more control over the array's contents, you can call getArray() and manipulate
  144. it directly as an Array\<var\>.
  145. */
  146. void insert (int index, const var& value);
  147. /** If the var is an array, this removes one of its elements.
  148. If the index is out-of-range or the var isn't an array, nothing will be done.
  149. For more control over the array's contents, you can call getArray() and manipulate
  150. it directly as an Array\<var\>.
  151. */
  152. void remove (int index);
  153. /** Treating the var as an array, this resizes it to contain the specified number of elements.
  154. If the var isn't an array, it will be converted to one, and if its value was non-void,
  155. this value will be kept as the first element of the new array before resizing.
  156. For more control over the array's contents, you can call getArray() and manipulate
  157. it directly as an Array\<var\>.
  158. */
  159. void resize (int numArrayElementsWanted);
  160. /** If the var is an array, this searches it for the first occurrence of the specified value,
  161. and returns its index.
  162. If the var isn't an array, or if the value isn't found, this returns -1.
  163. */
  164. int indexOf (const var& value) const;
  165. //==============================================================================
  166. /** If this variant is an object, this returns one of its properties. */
  167. var operator[] (const Identifier& propertyName) const;
  168. /** If this variant is an object, this returns one of its properties. */
  169. var operator[] (const char* propertyName) const;
  170. /** If this variant is an object, this returns one of its properties, or a default
  171. fallback value if the property is not set. */
  172. var getProperty (const Identifier& propertyName, const var& defaultReturnValue) const;
  173. /** If this variant is an object, this invokes one of its methods with no arguments. */
  174. var call (const Identifier& method) const;
  175. /** If this variant is an object, this invokes one of its methods with one argument. */
  176. var call (const Identifier& method, const var& arg1) const;
  177. /** If this variant is an object, this invokes one of its methods with 2 arguments. */
  178. var call (const Identifier& method, const var& arg1, const var& arg2) const;
  179. /** If this variant is an object, this invokes one of its methods with 3 arguments. */
  180. var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3);
  181. /** If this variant is an object, this invokes one of its methods with 4 arguments. */
  182. var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
  183. /** If this variant is an object, this invokes one of its methods with 5 arguments. */
  184. var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
  185. /** If this variant is an object, this invokes one of its methods with a list of arguments. */
  186. var invoke (const Identifier& method, const var* arguments, int numArguments) const;
  187. //==============================================================================
  188. /** Writes a binary representation of this value to a stream.
  189. The data can be read back later using readFromStream().
  190. @see JSON
  191. */
  192. void writeToStream (OutputStream& output) const;
  193. /** Reads back a stored binary representation of a value.
  194. The data in the stream must have been written using writeToStream(), or this
  195. will have unpredictable results.
  196. @see JSON
  197. */
  198. static var readFromStream (InputStream& input);
  199. private:
  200. //==============================================================================
  201. class VariantType; friend class VariantType;
  202. class VariantType_Void; friend class VariantType_Void;
  203. class VariantType_Int; friend class VariantType_Int;
  204. class VariantType_Int64; friend class VariantType_Int64;
  205. class VariantType_Double; friend class VariantType_Double;
  206. class VariantType_Bool; friend class VariantType_Bool;
  207. class VariantType_String; friend class VariantType_String;
  208. class VariantType_Object; friend class VariantType_Object;
  209. class VariantType_Array; friend class VariantType_Array;
  210. class VariantType_Method; friend class VariantType_Method;
  211. union ValueUnion
  212. {
  213. int intValue;
  214. int64 int64Value;
  215. bool boolValue;
  216. double doubleValue;
  217. char stringValue [sizeof (String)];
  218. ReferenceCountedObject* objectValue;
  219. Array<var>* arrayValue;
  220. MethodFunction methodValue;
  221. };
  222. const VariantType* type;
  223. ValueUnion value;
  224. Array<var>* convertToArray();
  225. friend class DynamicObject;
  226. var invokeMethod (DynamicObject*, const var*, int) const;
  227. };
  228. /** Compares the values of two var objects, using the var::equals() comparison. */
  229. bool operator== (const var& v1, const var& v2) noexcept;
  230. /** Compares the values of two var objects, using the var::equals() comparison. */
  231. bool operator!= (const var& v1, const var& v2) noexcept;
  232. bool operator== (const var& v1, const String& v2);
  233. bool operator!= (const var& v1, const String& v2);
  234. bool operator== (const var& v1, const char* v2);
  235. bool operator!= (const var& v1, const char* v2);
  236. #endif // __JUCE_VARIANT_JUCEHEADER__