Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
VariantRef.hpp
00001 // ArduinoJson - arduinojson.org 00002 // Copyright Benoit Blanchon 2014-2021 00003 // MIT License 00004 00005 #pragma once 00006 00007 #include <stddef.h> 00008 #include <stdint.h> // for uint8_t 00009 00010 #include <ArduinoJson/Memory/MemoryPool.hpp> 00011 #include <ArduinoJson/Misc/Visitable.hpp> 00012 #include <ArduinoJson/Polyfills/type_traits.hpp> 00013 #include <ArduinoJson/Strings/StringAdapters.hpp> 00014 #include <ArduinoJson/Variant/VariantAs.hpp> 00015 #include <ArduinoJson/Variant/VariantFunctions.hpp> 00016 #include <ArduinoJson/Variant/VariantOperators.hpp> 00017 #include <ArduinoJson/Variant/VariantRef.hpp> 00018 #include <ArduinoJson/Variant/VariantShortcuts.hpp> 00019 #include <ArduinoJson/Variant/VariantTag.hpp> 00020 00021 namespace ARDUINOJSON_NAMESPACE { 00022 00023 // Forward declarations. 00024 class ArrayRef; 00025 class ObjectRef; 00026 00027 // Contains the methods shared by VariantRef and VariantConstRef 00028 template <typename TData> 00029 class VariantRefBase : public VariantTag { 00030 public: 00031 // Tells wether the variant has the specified type. 00032 // Returns true if the variant has type type T, false otherwise. 00033 // 00034 // bool is<char>() const; 00035 // bool is<signed char>() const; 00036 // bool is<signed short>() const; 00037 // bool is<signed int>() const; 00038 // bool is<signed long>() const; 00039 // bool is<unsigned char>() const; 00040 // bool is<unsigned short>() const; 00041 // bool is<unsigned int>() const; 00042 // bool is<unsigned long>() const; 00043 template <typename T> 00044 FORCE_INLINE 00045 typename enable_if<is_integral<T>::value && !is_same<bool, T>::value, 00046 bool>::type 00047 is() const { 00048 return variantIsInteger<T>(_data); 00049 } 00050 // 00051 // bool is<double>() const; 00052 // bool is<float>() const; 00053 template <typename T> 00054 FORCE_INLINE typename enable_if<is_floating_point<T>::value, bool>::type is() 00055 const { 00056 return variantIsFloat(_data); 00057 } 00058 // 00059 // bool is<bool>() const 00060 template <typename T> 00061 FORCE_INLINE typename enable_if<is_same<T, bool>::value, bool>::type is() 00062 const { 00063 return variantIsBoolean(_data); 00064 } 00065 // 00066 // bool is<const char*>() const; 00067 // bool is<char*>() const; 00068 // bool is<std::string>() const; 00069 // bool is<String>() const; 00070 template <typename T> 00071 FORCE_INLINE typename enable_if<is_same<T, const char *>::value || 00072 is_same<T, char *>::value || 00073 IsWriteableString<T>::value, 00074 bool>::type 00075 is() const { 00076 return variantIsString(_data); 00077 } 00078 // 00079 // bool is<ArrayRef> const; 00080 // bool is<const ArrayRef> const; 00081 template <typename T> 00082 FORCE_INLINE typename enable_if< 00083 is_same<typename remove_const<T>::type, ArrayRef>::value, bool>::type 00084 is() const { 00085 return variantIsArray(_data); 00086 } 00087 // 00088 // bool is<ObjectRef> const; 00089 // bool is<const ObjectRef> const; 00090 template <typename T> 00091 FORCE_INLINE typename enable_if< 00092 is_same<typename remove_const<T>::type, ObjectRef>::value, bool>::type 00093 is() const { 00094 return variantIsObject(_data); 00095 } 00096 #if ARDUINOJSON_HAS_NULLPTR 00097 // 00098 // bool is<nullptr_t> const; 00099 template <typename T> 00100 FORCE_INLINE 00101 typename enable_if<is_same<T, decltype(nullptr)>::value, bool>::type 00102 is() const { 00103 return variantIsNull(_data); 00104 } 00105 #endif 00106 // bool is<enum>() const; 00107 template <typename T> 00108 FORCE_INLINE typename enable_if<is_enum<T>::value, bool>::type is() const { 00109 return variantIsInteger<int>(_data); 00110 } 00111 00112 FORCE_INLINE bool isNull() const { 00113 return variantIsNull(_data); 00114 } 00115 00116 FORCE_INLINE bool isUndefined() const { 00117 return !_data; 00118 } 00119 00120 FORCE_INLINE size_t memoryUsage() const { 00121 return _data ? _data->memoryUsage() : 0; 00122 } 00123 00124 FORCE_INLINE size_t nesting() const { 00125 return _data ? _data->nesting() : 0; 00126 } 00127 00128 size_t size() const { 00129 return variantSize(_data); 00130 } 00131 00132 protected: 00133 VariantRefBase(TData *data) : _data(data) {} 00134 TData *_data; 00135 }; 00136 00137 // A variant that can be a any value serializable to a JSON value. 00138 // 00139 // It can be set to: 00140 // - a boolean 00141 // - a char, short, int or a long (signed or unsigned) 00142 // - a string (const char*) 00143 // - a reference to a ArrayRef or ObjectRef 00144 class VariantRef : public VariantRefBase<VariantData>, 00145 public VariantOperators<VariantRef>, 00146 public VariantShortcuts<VariantRef>, 00147 public Visitable { 00148 typedef VariantRefBase<VariantData> base_type; 00149 friend class VariantConstRef; 00150 00151 public: 00152 // Intenal use only 00153 FORCE_INLINE VariantRef(MemoryPool *pool, VariantData *data) 00154 : base_type(data), _pool(pool) {} 00155 00156 // Creates an uninitialized VariantRef 00157 FORCE_INLINE VariantRef() : base_type(0), _pool(0) {} 00158 00159 FORCE_INLINE void clear() const { 00160 return variantSetNull(_data); 00161 } 00162 00163 // set(bool value) 00164 template <typename T> 00165 FORCE_INLINE bool set( 00166 T value, typename enable_if<is_same<T, bool>::value>::type * = 0) const { 00167 return variantSetBoolean(_data, value); 00168 } 00169 00170 // set(double value); 00171 // set(float value); 00172 template <typename T> 00173 FORCE_INLINE bool set( 00174 T value, 00175 typename enable_if<is_floating_point<T>::value>::type * = 0) const { 00176 return variantSetFloat(_data, static_cast<Float>(value)); 00177 } 00178 00179 // set(char) 00180 // set(signed short) 00181 // set(signed int) 00182 // set(signed long) 00183 // set(signed char) 00184 // set(unsigned short) 00185 // set(unsigned int) 00186 // set(unsigned long) 00187 template <typename T> 00188 FORCE_INLINE bool set( 00189 T value, typename enable_if<is_integral<T>::value && 00190 !is_same<bool, T>::value>::type * = 0) const { 00191 return variantSetInteger<T>(_data, value); 00192 } 00193 00194 // set(SerializedValue<const char *>) 00195 FORCE_INLINE bool set(SerializedValue<const char *> value) const { 00196 return variantSetLinkedRaw(_data, value); 00197 } 00198 00199 // set(SerializedValue<std::string>) 00200 // set(SerializedValue<String>) 00201 // set(SerializedValue<const __FlashStringHelper*>) 00202 template <typename T> 00203 FORCE_INLINE bool set( 00204 SerializedValue<T> value, 00205 typename enable_if<!is_same<const char *, T>::value>::type * = 0) const { 00206 return variantSetOwnedRaw(_data, value, _pool); 00207 } 00208 00209 // set(const std::string&) 00210 // set(const String&) 00211 template <typename T> 00212 FORCE_INLINE bool set( 00213 const T &value, 00214 typename enable_if<IsString<T>::value>::type * = 0) const { 00215 return variantSetString(_data, adaptString(value), _pool); 00216 } 00217 // set(char*) 00218 // set(const __FlashStringHelper*) 00219 // set(const char*) 00220 template <typename T> 00221 FORCE_INLINE bool set( 00222 T *value, typename enable_if<IsString<T *>::value>::type * = 0) const { 00223 return variantSetString(_data, adaptString(value), _pool); 00224 } 00225 00226 // set(VariantRef) 00227 // set(VariantConstRef) 00228 // set(ArrayRef) 00229 // set(ArrayConstRef) 00230 // set(ObjectRef) 00231 // set(ObjecConstRef) 00232 // set(const JsonDocument&) 00233 template <typename TVariant> 00234 typename enable_if<IsVisitable<TVariant>::value, bool>::type set( 00235 const TVariant &value) const; 00236 00237 // set(enum value) 00238 template <typename T> 00239 FORCE_INLINE bool set( 00240 T value, typename enable_if<is_enum<T>::value>::type * = 0) const { 00241 return variantSetInteger(_data, static_cast<Integer>(value)); 00242 } 00243 00244 #if ARDUINOJSON_HAS_NULLPTR 00245 // set(nullptr_t) 00246 FORCE_INLINE bool set(decltype(nullptr)) const { 00247 variantSetNull(_data); 00248 return true; 00249 } 00250 #endif 00251 00252 template <typename T> 00253 FORCE_INLINE typename VariantAs<T>::type as() const { 00254 return variantAs<typename VariantAs<T>::type>(_data, _pool); 00255 } 00256 00257 template <typename T> 00258 FORCE_INLINE operator T() const { 00259 return variantAs<T>(_data, _pool); 00260 } 00261 00262 template <typename TVisitor> 00263 typename TVisitor::result_type accept(TVisitor &visitor) const { 00264 return variantAccept(_data, visitor); 00265 } 00266 00267 // Change the type of the variant 00268 // 00269 // ArrayRef to<ArrayRef>() 00270 template <typename T> 00271 typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type to() const; 00272 // 00273 // ObjectRef to<ObjectRef>() 00274 template <typename T> 00275 typename enable_if<is_same<T, ObjectRef>::value, ObjectRef>::type to() const; 00276 // 00277 // ObjectRef to<VariantRef>() 00278 template <typename T> 00279 typename enable_if<is_same<T, VariantRef>::value, VariantRef>::type to() 00280 const; 00281 00282 VariantRef addElement() const; 00283 00284 FORCE_INLINE VariantRef getElement(size_t) const; 00285 00286 FORCE_INLINE VariantRef getOrAddElement(size_t) const; 00287 00288 // getMember(const char*) const 00289 // getMember(const __FlashStringHelper*) const 00290 template <typename TChar> 00291 FORCE_INLINE VariantRef getMember(TChar *) const; 00292 00293 // getMember(const std::string&) const 00294 // getMember(const String&) const 00295 template <typename TString> 00296 FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type 00297 getMember(const TString &) const; 00298 00299 // getOrAddMember(char*) const 00300 // getOrAddMember(const char*) const 00301 // getOrAddMember(const __FlashStringHelper*) const 00302 template <typename TChar> 00303 FORCE_INLINE VariantRef getOrAddMember(TChar *) const; 00304 00305 // getOrAddMember(const std::string&) const 00306 // getOrAddMember(const String&) const 00307 template <typename TString> 00308 FORCE_INLINE VariantRef getOrAddMember(const TString &) const; 00309 00310 FORCE_INLINE void remove(size_t index) const { 00311 if (_data) 00312 _data->remove(index); 00313 } 00314 // remove(char*) const 00315 // remove(const char*) const 00316 // remove(const __FlashStringHelper*) const 00317 template <typename TChar> 00318 FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove( 00319 TChar *key) const { 00320 if (_data) 00321 _data->remove(adaptString(key)); 00322 } 00323 // remove(const std::string&) const 00324 // remove(const String&) const 00325 template <typename TString> 00326 FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove( 00327 const TString &key) const { 00328 if (_data) 00329 _data->remove(adaptString(key)); 00330 } 00331 00332 private: 00333 MemoryPool *_pool; 00334 }; // namespace ARDUINOJSON_NAMESPACE 00335 00336 class VariantConstRef : public VariantRefBase<const VariantData>, 00337 public VariantOperators<VariantConstRef>, 00338 public VariantShortcuts<VariantConstRef>, 00339 public Visitable { 00340 typedef VariantRefBase<const VariantData> base_type; 00341 friend class VariantRef; 00342 00343 public: 00344 VariantConstRef() : base_type(0) {} 00345 VariantConstRef(const VariantData *data) : base_type(data) {} 00346 VariantConstRef(VariantRef var) : base_type(var._data) {} 00347 00348 template <typename TVisitor> 00349 typename TVisitor::result_type accept(TVisitor &visitor) const { 00350 return variantAccept(_data, visitor); 00351 } 00352 00353 template <typename T> 00354 FORCE_INLINE typename VariantConstAs<T>::type as() const { 00355 return variantAs<typename VariantConstAs<T>::type>(_data); 00356 } 00357 00358 template <typename T> 00359 FORCE_INLINE operator T() const { 00360 return variantAs<T>(_data); 00361 } 00362 00363 FORCE_INLINE VariantConstRef getElement(size_t) const; 00364 00365 FORCE_INLINE VariantConstRef operator[](size_t index) const { 00366 return getElement(index); 00367 } 00368 00369 // getMember(const std::string&) const 00370 // getMember(const String&) const 00371 template <typename TString> 00372 FORCE_INLINE VariantConstRef getMember(const TString &key) const { 00373 return VariantConstRef( 00374 objectGetMember(variantAsObject(_data), adaptString(key))); 00375 } 00376 00377 // getMember(char*) const 00378 // getMember(const char*) const 00379 // getMember(const __FlashStringHelper*) const 00380 template <typename TChar> 00381 FORCE_INLINE VariantConstRef getMember(TChar *key) const { 00382 const CollectionData *obj = variantAsObject(_data); 00383 return VariantConstRef(obj ? obj->getMember(adaptString(key)) : 0); 00384 } 00385 00386 // operator[](const std::string&) const 00387 // operator[](const String&) const 00388 template <typename TString> 00389 FORCE_INLINE 00390 typename enable_if<IsString<TString>::value, VariantConstRef>::type 00391 operator[](const TString &key) const { 00392 return getMember(key); 00393 } 00394 00395 // operator[](char*) const 00396 // operator[](const char*) const 00397 // operator[](const __FlashStringHelper*) const 00398 template <typename TChar> 00399 FORCE_INLINE 00400 typename enable_if<IsString<TChar *>::value, VariantConstRef>::type 00401 operator[](TChar *key) const { 00402 return getMember(key); 00403 } 00404 }; 00405 } // namespace ARDUINOJSON_NAMESPACE
Generated on Wed Jul 13 2022 01:10:37 by
1.7.2