juce_Variant.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. ==============================================================================
  3. This file is part of the juce_core module of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. or without fee is hereby granted, provided that the above copyright notice and this
  7. permission notice appear in all copies.
  8. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  9. TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  10. NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  11. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  12. IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  13. CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. ------------------------------------------------------------------------------
  15. NOTE! This permissive ISC license applies ONLY to files within the juce_core module!
  16. All other JUCE modules are covered by a dual GPL/commercial license, so if you are
  17. using any other modules, be sure to check that you also comply with their license.
  18. For more details, visit www.juce.com
  19. ==============================================================================
  20. */
  21. #ifndef JUCE_VARIANT_H_INCLUDED
  22. #define JUCE_VARIANT_H_INCLUDED
  23. //==============================================================================
  24. /**
  25. A variant class, that can be used to hold a range of primitive values.
  26. A var object can hold a range of simple primitive values, strings, or
  27. any kind of ReferenceCountedObject. The var class is intended to act like
  28. the kind of values used in dynamic scripting languages.
  29. You can save/load var objects either in a small, proprietary binary format
  30. using writeToStream()/readFromStream(), or as JSON by using the JSON class.
  31. @see JSON, DynamicObject
  32. */
  33. class JUCE_API var
  34. {
  35. public:
  36. //==============================================================================
  37. /** This structure is passed to a NativeFunction callback, and contains invocation
  38. details about the function's arguments and context.
  39. */
  40. struct NativeFunctionArgs
  41. {
  42. NativeFunctionArgs (const var& thisObject, const var* args, int numArgs) noexcept;
  43. const var& thisObject;
  44. const var* arguments;
  45. int numArguments;
  46. JUCE_DECLARE_NON_COPYABLE (NativeFunctionArgs)
  47. };
  48. typedef var (*NativeFunction) (const NativeFunctionArgs&);
  49. typedef Identifier identifier;
  50. //==============================================================================
  51. /** Creates a void variant. */
  52. var() noexcept;
  53. /** Destructor. */
  54. ~var() noexcept;
  55. /** A static var object that can be used where you need an empty variant object. */
  56. static const var null;
  57. var (const var& valueToCopy);
  58. var (int value) noexcept;
  59. var (int64 value) noexcept;
  60. var (bool value) noexcept;
  61. var (double value) noexcept;
  62. var (const char* value);
  63. var (const wchar_t* value);
  64. var (const String& value);
  65. var (const Array<var>& value);
  66. var (ReferenceCountedObject* object);
  67. var (NativeFunction method) noexcept;
  68. var (const void* binaryData, size_t dataSize);
  69. var (const MemoryBlock& binaryData);
  70. var& operator= (const var& valueToCopy);
  71. var& operator= (int value);
  72. var& operator= (int64 value);
  73. var& operator= (bool value);
  74. var& operator= (double value);
  75. var& operator= (const char* value);
  76. var& operator= (const wchar_t* value);
  77. var& operator= (const String& value);
  78. var& operator= (const Array<var>& value);
  79. var& operator= (ReferenceCountedObject* object);
  80. var& operator= (NativeFunction method);
  81. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  82. var (var&& other) noexcept;
  83. var (String&& value);
  84. var (MemoryBlock&& binaryData);
  85. var (Array<var>&& value);
  86. var& operator= (var&& other) noexcept;
  87. var& operator= (String&& value);
  88. #endif
  89. void swapWith (var& other) noexcept;
  90. /** Returns a var object that can be used where you need the javascript "undefined" value. */
  91. static var undefined() noexcept;
  92. //==============================================================================
  93. operator int() const noexcept;
  94. operator int64() const noexcept;
  95. operator bool() const noexcept;
  96. operator float() const noexcept;
  97. operator double() const noexcept;
  98. operator String() const;
  99. String toString() const;
  100. /** If this variant holds an array, this provides access to it.
  101. NOTE: Beware when you use this - the array pointer is only valid for the lifetime
  102. of the variant that returned it, so be very careful not to call this method on temporary
  103. var objects that are the return-value of a function, and which may go out of scope before
  104. you use the array!
  105. */
  106. Array<var>* getArray() const noexcept;
  107. /** If this variant holds a memory block, this provides access to it.
  108. NOTE: Beware when you use this - the MemoryBlock pointer is only valid for the lifetime
  109. of the variant that returned it, so be very careful not to call this method on temporary
  110. var objects that are the return-value of a function, and which may go out of scope before
  111. you use the MemoryBlock!
  112. */
  113. MemoryBlock* getBinaryData() const noexcept;
  114. ReferenceCountedObject* getObject() const noexcept;
  115. DynamicObject* getDynamicObject() const noexcept;
  116. //==============================================================================
  117. bool isVoid() const noexcept;
  118. bool isUndefined() const noexcept;
  119. bool isInt() const noexcept;
  120. bool isInt64() const noexcept;
  121. bool isBool() const noexcept;
  122. bool isDouble() const noexcept;
  123. bool isString() const noexcept;
  124. bool isObject() const noexcept;
  125. bool isArray() const noexcept;
  126. bool isBinaryData() const noexcept;
  127. bool isMethod() const noexcept;
  128. /** Returns true if this var has the same value as the one supplied.
  129. Note that this ignores the type, so a string var "123" and an integer var with the
  130. value 123 are considered to be equal.
  131. @see equalsWithSameType
  132. */
  133. bool equals (const var& other) const noexcept;
  134. /** Returns true if this var has the same value and type as the one supplied.
  135. This differs from equals() because e.g. "123" and 123 will be considered different.
  136. @see equals
  137. */
  138. bool equalsWithSameType (const var& other) const noexcept;
  139. /** Returns true if this var has the same type as the one supplied. */
  140. bool hasSameTypeAs (const var& other) const noexcept;
  141. /** Returns a deep copy of this object.
  142. For simple types this just returns a copy, but if the object contains any arrays
  143. or DynamicObjects, they will be cloned (recursively).
  144. */
  145. var clone() const noexcept;
  146. //==============================================================================
  147. /** If the var is an array, this returns the number of elements.
  148. If the var isn't actually an array, this will return 0.
  149. */
  150. int size() const;
  151. /** If the var is an array, this can be used to return one of its elements.
  152. To call this method, you must make sure that the var is actually an array, and
  153. that the index is a valid number. If these conditions aren't met, behaviour is
  154. undefined.
  155. For more control over the array's contents, you can call getArray() and manipulate
  156. it directly as an Array\<var\>.
  157. */
  158. const var& operator[] (int arrayIndex) const;
  159. /** If the var is an array, this can be used to return one of its elements.
  160. To call this method, you must make sure that the var is actually an array, and
  161. that the index is a valid number. If these conditions aren't met, behaviour is
  162. undefined.
  163. For more control over the array's contents, you can call getArray() and manipulate
  164. it directly as an Array\<var\>.
  165. */
  166. var& operator[] (int arrayIndex);
  167. /** Appends an element to the var, converting it to an array if it isn't already one.
  168. If the var isn't an array, it will be converted to one, and if its value was non-void,
  169. this value will be kept as the first element of the new array. The parameter value
  170. will then be appended to it.
  171. For more control over the array's contents, you can call getArray() and manipulate
  172. it directly as an Array\<var\>.
  173. */
  174. void append (const var& valueToAppend);
  175. /** Inserts an element to the var, converting it to an array if it isn't already one.
  176. If the var isn't an array, it will be converted to one, and if its value was non-void,
  177. this value will be kept as the first element of the new array. The parameter value
  178. will then be inserted into it.
  179. For more control over the array's contents, you can call getArray() and manipulate
  180. it directly as an Array\<var\>.
  181. */
  182. void insert (int index, const var& value);
  183. /** If the var is an array, this removes one of its elements.
  184. If the index is out-of-range or the var isn't an array, nothing will be done.
  185. For more control over the array's contents, you can call getArray() and manipulate
  186. it directly as an Array\<var\>.
  187. */
  188. void remove (int index);
  189. /** Treating the var as an array, this resizes it to contain the specified number of elements.
  190. If the var isn't an array, it will be converted to one, and if its value was non-void,
  191. this value will be kept as the first element of the new array before resizing.
  192. For more control over the array's contents, you can call getArray() and manipulate
  193. it directly as an Array\<var\>.
  194. */
  195. void resize (int numArrayElementsWanted);
  196. /** If the var is an array, this searches it for the first occurrence of the specified value,
  197. and returns its index.
  198. If the var isn't an array, or if the value isn't found, this returns -1.
  199. */
  200. int indexOf (const var& value) const;
  201. //==============================================================================
  202. /** If this variant is an object, this returns one of its properties. */
  203. var operator[] (Identifier propertyName) const;
  204. /** If this variant is an object, this returns one of its properties. */
  205. var operator[] (const char* propertyName) const;
  206. /** If this variant is an object, this returns one of its properties, or a default
  207. fallback value if the property is not set. */
  208. var getProperty (Identifier propertyName, const var& defaultReturnValue) const;
  209. /** Invokes a named method call with no arguments. */
  210. var call (Identifier method) const;
  211. /** Invokes a named method call with one argument. */
  212. var call (Identifier method, const var& arg1) const;
  213. /** Invokes a named method call with 2 arguments. */
  214. var call (Identifier method, const var& arg1, const var& arg2) const;
  215. /** Invokes a named method call with 3 arguments. */
  216. var call (Identifier method, const var& arg1, const var& arg2, const var& arg3);
  217. /** Invokes a named method call with 4 arguments. */
  218. var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
  219. /** Invokes a named method call with 5 arguments. */
  220. var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
  221. /** Invokes a named method call with a list of arguments. */
  222. var invoke (Identifier method, const var* arguments, int numArguments) const;
  223. /** If this object is a method, this returns the function pointer. */
  224. NativeFunction getNativeFunction() const;
  225. //==============================================================================
  226. /** Writes a binary representation of this value to a stream.
  227. The data can be read back later using readFromStream().
  228. @see JSON
  229. */
  230. void writeToStream (OutputStream& output) const;
  231. /** Reads back a stored binary representation of a value.
  232. The data in the stream must have been written using writeToStream(), or this
  233. will have unpredictable results.
  234. @see JSON
  235. */
  236. static var readFromStream (InputStream& input);
  237. private:
  238. //==============================================================================
  239. class VariantType; friend class VariantType;
  240. class VariantType_Void; friend class VariantType_Void;
  241. class VariantType_Undefined; friend class VariantType_Undefined;
  242. class VariantType_Int; friend class VariantType_Int;
  243. class VariantType_Int64; friend class VariantType_Int64;
  244. class VariantType_Double; friend class VariantType_Double;
  245. class VariantType_Bool; friend class VariantType_Bool;
  246. class VariantType_String; friend class VariantType_String;
  247. class VariantType_Object; friend class VariantType_Object;
  248. class VariantType_Array; friend class VariantType_Array;
  249. class VariantType_Binary; friend class VariantType_Binary;
  250. class VariantType_Method; friend class VariantType_Method;
  251. union ValueUnion
  252. {
  253. int intValue;
  254. int64 int64Value;
  255. bool boolValue;
  256. double doubleValue;
  257. char stringValue [sizeof (String)];
  258. ReferenceCountedObject* objectValue;
  259. MemoryBlock* binaryValue;
  260. NativeFunction methodValue;
  261. };
  262. const VariantType* type;
  263. ValueUnion value;
  264. Array<var>* convertToArray();
  265. var (const VariantType&) noexcept;
  266. };
  267. /** Compares the values of two var objects, using the var::equals() comparison. */
  268. bool operator== (const var& v1, const var& v2) noexcept;
  269. /** Compares the values of two var objects, using the var::equals() comparison. */
  270. bool operator!= (const var& v1, const var& v2) noexcept;
  271. bool operator== (const var& v1, const String& v2);
  272. bool operator!= (const var& v1, const String& v2);
  273. bool operator== (const var& v1, const char* v2);
  274. bool operator!= (const var& v1, const char* v2);
  275. #endif // JUCE_VARIANT_H_INCLUDED