Add initial bits for Qt6 support
[carla.git] / source / includes / vst3sdk / pluginterfaces / base / fvariant.h
blob491c93fbf039505ccc01dd0ed69fecd20c4eb37f
1 //-----------------------------------------------------------------------------
2 // Project : SDK Core
3 //
4 // Category : SDK Core Interfaces
5 // Filename : pluginterfaces/base/fvariant.h
6 // Created by : Steinberg, 01/2004
7 // Description : Basic Interface
8 //
9 //-----------------------------------------------------------------------------
10 // This file is part of a Steinberg SDK. It is subject to the license terms
11 // in the LICENSE file found in the top-level directory of this distribution
12 // and at www.steinberg.net/sdklicenses.
13 // No part of the SDK, including this file, may be copied, modified, propagated,
14 // or distributed except according to the terms contained in the LICENSE file.
15 //-----------------------------------------------------------------------------
17 #pragma once
19 #include "pluginterfaces/base/fstrdefs.h"
20 #include "pluginterfaces/base/funknown.h"
22 //------------------------------------------------------------------------
23 namespace Steinberg {
25 class FUnknown;
27 //------------------------------------------------------------------------
28 // FVariant struct declaration
29 //------------------------------------------------------------------------
30 /** A Value of variable type.
31 \ingroup pluginBase
33 class FVariant
35 //------------------------------------------------------------------------
36 public:
37 enum
39 kEmpty = 0,
40 kInteger = 1 << 0,
41 kFloat = 1 << 1,
42 kString8 = 1 << 2,
43 kObject = 1 << 3,
44 kOwner = 1 << 4,
45 kString16 = 1 << 5
48 //------------------------------------------------------------------------
49 // ctors
50 inline FVariant () { memset (this, 0, sizeof (FVariant)); }
51 inline FVariant (const FVariant& variant);
53 inline FVariant (bool b) : type (kInteger), intValue (b) {}
54 inline FVariant (uint32 v) : type (kInteger), intValue (v) {}
55 inline FVariant (int64 v) : type (kInteger), intValue (v) {}
56 inline FVariant (double v) : type (kFloat), floatValue (v) {}
57 inline FVariant (const char8* str) : type (kString8), string8 (str) {}
58 inline FVariant (const char16* str) : type (kString16), string16 (str) {}
59 inline FVariant (FUnknown* obj, bool owner = false) : type (kObject), object (obj)
61 setOwner (owner);
63 inline ~FVariant () { empty (); }
65 //------------------------------------------------------------------------
66 inline FVariant& operator= (const FVariant& variant);
68 inline void set (bool b)
70 setInt (b);
73 inline void set (uint32 v)
75 setInt (v);
78 inline void set (int64 v)
80 setInt (v);
83 inline void set (double v)
85 setFloat (v);
88 inline void set (const char8* c)
90 setString8 (c);
93 inline void set (const char16* c)
95 setString16 (c);
98 inline void setInt (int64 v)
100 empty ();
101 type = kInteger;
102 intValue = v;
105 inline void setFloat (double v)
107 empty ();
108 type = kFloat;
109 floatValue = v;
111 inline void setString8 (const char8* v)
113 empty ();
114 type = kString8;
115 string8 = v;
117 inline void setString16 (const char16* v)
119 empty ();
120 type = kString16;
121 string16 = v;
124 inline void setObject (FUnknown* obj)
126 empty ();
127 type = kObject;
128 object = obj;
131 template <typename T>
132 inline T get () const;
134 inline int64 getInt () const { return (type & kInteger) ? intValue : 0; }
135 inline double getFloat () const { return (type & kFloat) ? floatValue : 0.; }
136 inline double getNumber () const
138 return (type & kInteger) ? static_cast<double> (intValue) : (type & kFloat) ? floatValue :
141 inline const char8* getString8 () const { return (type & kString8) ? string8 : nullptr; }
142 inline const char16* getString16 () const { return (type & kString16) ? string16 : nullptr; }
144 inline FUnknown* getObject () const { return (type & kObject) ? object : nullptr; }
146 inline uint16 getType () const { return static_cast<uint16> (type & ~(kOwner)); }
147 inline bool isEmpty () const { return getType () == kEmpty; }
148 inline bool isOwner () const { return (type & kOwner) != 0; }
149 inline bool isString () const { return (type & (kString8 | kString16)) != 0; }
150 inline void setOwner (bool state)
152 if (state)
153 type |= kOwner;
154 else
155 type &= ~kOwner;
158 void empty ();
159 //------------------------------------------------------------------------
160 uint16 type;
161 union
163 int64 intValue;
164 double floatValue;
165 const char8* string8;
166 const char16* string16;
167 FUnknown* object;
171 //------------------------------------------------------------------------
172 inline bool operator== (const FVariant& v1, const FVariant& v2)
174 #if SMTG_PLATFORM_64
175 return v1.type == v2.type && v1.intValue == v2.intValue;
176 #else
177 if (v1.type != v2.type)
178 return false;
179 if (v1.type & (FVariant::kString8 | FVariant::kString16 | FVariant::kObject))
180 return v1.string8 == v2.string8; // pointer type comparisons
181 return v1.intValue == v2.intValue; // intValue & double comparison
183 #endif
186 template <>
187 inline bool FVariant::get<bool> () const
189 return getInt () != 0;
192 template <>
193 inline uint32 FVariant::get<uint32> () const
195 return static_cast<uint32> (getInt ());
198 template <>
199 inline int32 FVariant::get<int32> () const
201 return static_cast<int32> (getInt ());
204 template <>
205 inline int64 FVariant::get<int64> () const
207 return static_cast<int64> (getInt ());
210 template <>
211 inline float FVariant::get<float> () const
213 return static_cast<float> (getFloat ());
216 template <>
217 inline double FVariant::get<double> () const
219 return getFloat ();
222 template <>
223 inline const char8* FVariant::get<const char8*> () const
225 return getString8 ();
228 template <>
229 inline const char16* FVariant::get<const char16*> () const
231 return getString16 ();
234 template <>
235 inline FUnknown* FVariant::get<FUnknown*> () const
237 return getObject ();
240 //------------------------------------------------------------------------
241 inline bool operator!= (const FVariant& v1, const FVariant& v2) { return !(v1 == v2); }
243 //------------------------------------------------------------------------
244 inline FVariant::FVariant (const FVariant& variant) : type (kEmpty) { *this = variant; }
246 //------------------------------------------------------------------------
247 inline void FVariant::empty ()
249 if (type & kOwner)
251 if ((type & kString8) && string8)
252 delete[] string8;
253 else if ((type & kString16) && string16)
254 delete[] string16;
256 else if ((type & kObject) && object)
257 object->release ();
259 memset (this, 0, sizeof (FVariant));
262 //------------------------------------------------------------------------
263 inline FVariant& FVariant::operator= (const FVariant& variant)
265 empty ();
267 type = variant.type;
269 if ((type & kString8) && variant.string8)
271 string8 = new char8[strlen (variant.string8) + 1];
272 strcpy (const_cast<char8*> (string8), variant.string8);
273 type |= kOwner;
275 else if ((type & kString16) && variant.string16)
277 auto len = static_cast<size_t> (strlen16 (variant.string16));
278 string16 = new char16[len + 1];
279 char16* tmp = const_cast<char16*> (string16);
280 memcpy (tmp, variant.string16, len * sizeof (char16));
281 tmp[len] = 0;
282 type |= kOwner;
284 else if ((type & kObject) && variant.object)
286 object = variant.object;
287 object->addRef ();
288 type |= kOwner;
290 else
291 intValue = variant.intValue; // copy memory
293 return *this;
296 //------------------------------------------------------------------------
297 } // namespace Steinberg