Minh Nguyen / ArduinoJson
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ArrayRef.hpp Source File

ArrayRef.hpp

00001 // ArduinoJson - arduinojson.org
00002 // Copyright Benoit Blanchon 2014-2021
00003 // MIT License
00004 
00005 #pragma once
00006 
00007 #include <ArduinoJson/Array/ArrayFunctions.hpp>
00008 #include <ArduinoJson/Array/ArrayIterator.hpp>
00009 #include <ArduinoJson/Variant/VariantData.hpp>
00010 
00011 // Returns the size (in bytes) of an array with n elements.
00012 // Can be very handy to determine the size of a StaticMemoryPool.
00013 #define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
00014   ((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
00015 
00016 namespace ARDUINOJSON_NAMESPACE {
00017 
00018 class ObjectRef;
00019 template <typename>
00020 class ElementProxy;
00021 
00022 template <typename TData>
00023 class ArrayRefBase {
00024  public:
00025   operator VariantConstRef() const {
00026     const void* data = _data;  // prevent warning cast-align
00027     return VariantConstRef(reinterpret_cast<const VariantData*>(data));
00028   }
00029 
00030   template <typename TVisitor>
00031   FORCE_INLINE typename TVisitor::result_type accept(TVisitor& visitor) const {
00032     return arrayAccept(_data, visitor);
00033   }
00034 
00035   FORCE_INLINE bool isNull() const {
00036     return _data == 0;
00037   }
00038 
00039   FORCE_INLINE operator bool() const {
00040     return _data != 0;
00041   }
00042 
00043   FORCE_INLINE size_t memoryUsage() const {
00044     return _data ? _data->memoryUsage() : 0;
00045   }
00046 
00047   FORCE_INLINE size_t nesting() const {
00048     return _data ? _data->nesting() : 0;
00049   }
00050 
00051   FORCE_INLINE size_t size() const {
00052     return _data ? _data->size() : 0;
00053   }
00054 
00055  protected:
00056   ArrayRefBase(TData* data) : _data(data) {}
00057   TData* _data;
00058 };
00059 
00060 class ArrayConstRef : public ArrayRefBase<const CollectionData>,
00061                       public Visitable {
00062   friend class ArrayRef;
00063   typedef ArrayRefBase<const CollectionData> base_type;
00064 
00065  public:
00066   typedef ArrayConstRefIterator iterator;
00067 
00068   FORCE_INLINE iterator begin() const {
00069     if (!_data)
00070       return iterator();
00071     return iterator(_data->head());
00072   }
00073 
00074   FORCE_INLINE iterator end() const {
00075     return iterator();
00076   }
00077 
00078   FORCE_INLINE ArrayConstRef() : base_type(0) {}
00079   FORCE_INLINE ArrayConstRef(const CollectionData* data) : base_type(data) {}
00080 
00081   FORCE_INLINE bool operator==(ArrayConstRef rhs) const {
00082     return arrayEquals(_data, rhs._data);
00083   }
00084 
00085   FORCE_INLINE VariantConstRef operator[](size_t index) const {
00086     return getElement(index);
00087   }
00088 
00089   FORCE_INLINE VariantConstRef getElement(size_t index) const {
00090     return VariantConstRef(_data ? _data->getElement(index) : 0);
00091   }
00092 };
00093 
00094 class ArrayRef : public ArrayRefBase<CollectionData>,
00095                  public ArrayShortcuts<ArrayRef>,
00096                  public Visitable {
00097   typedef ArrayRefBase<CollectionData> base_type;
00098 
00099  public:
00100   typedef ArrayIterator iterator;
00101 
00102   FORCE_INLINE ArrayRef() : base_type(0), _pool(0) {}
00103   FORCE_INLINE ArrayRef(MemoryPool* pool, CollectionData* data)
00104       : base_type(data), _pool(pool) {}
00105 
00106   operator VariantRef() {
00107     void* data = _data;  // prevent warning cast-align
00108     return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
00109   }
00110 
00111   operator ArrayConstRef() const {
00112     return ArrayConstRef(_data);
00113   }
00114 
00115   VariantRef addElement() const {
00116     return VariantRef(_pool, arrayAdd(_data, _pool));
00117   }
00118 
00119   FORCE_INLINE iterator begin() const {
00120     if (!_data)
00121       return iterator();
00122     return iterator(_pool, _data->head());
00123   }
00124 
00125   FORCE_INLINE iterator end() const {
00126     return iterator();
00127   }
00128 
00129   // Copy a ArrayRef
00130   FORCE_INLINE bool set(ArrayConstRef src) const {
00131     if (!_data || !src._data)
00132       return false;
00133     return _data->copyFrom(*src._data, _pool);
00134   }
00135 
00136   FORCE_INLINE bool operator==(ArrayRef rhs) const {
00137     return arrayEquals(_data, rhs._data);
00138   }
00139 
00140   // Internal use
00141   FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
00142     return VariantRef(_pool, _data ? _data->getOrAddElement(index, _pool) : 0);
00143   }
00144 
00145   // Gets the value at the specified index.
00146   FORCE_INLINE VariantRef getElement(size_t index) const {
00147     return VariantRef(_pool, _data ? _data->getElement(index) : 0);
00148   }
00149 
00150   // Removes element at specified position.
00151   FORCE_INLINE void remove(iterator it) const {
00152     if (!_data)
00153       return;
00154     _data->removeSlot(it.internal());
00155   }
00156 
00157   // Removes element at specified index.
00158   FORCE_INLINE void remove(size_t index) const {
00159     if (!_data)
00160       return;
00161     _data->removeElement(index);
00162   }
00163 
00164  private:
00165   MemoryPool* _pool;
00166 };
00167 }  // namespace ARDUINOJSON_NAMESPACE