ThingsBoard Client SDK 0.16.0
Client SDK to connect with ThingsBoard IoT Platform from IoT devices (Arduino, Espressif, etc.)
Loading...
Searching...
No Matches
Container.h
Go to the documentation of this file.
1#ifndef Container_h
2#define Container_h
3
4// Local include.
5#include "Helper.h"
6
7// Library includes.
8#include <assert.h>
9
10
22#if THINGSBOARD_ENABLE_DYNAMIC
23template <typename T>
24#else
27template <typename T, size_t Capacity>
28#endif // THINGSBOARD_ENABLE_DYNAMIC
29class Container {
30 public:
31 using value_type = T;
33 using reference = T &;
34 using const_reference = T const &;
35 using pointer = T *;
36 using const_pointer = T const *;
39
40#if THINGSBOARD_ENABLE_DYNAMIC
42 Container() = default;
43
45 ~Container() {
46 delete[] m_elements;
47 }
48
53 Container(Container const & other)
54 : m_elements{}
55 , m_capacity{other.m_capacity}
56 , m_size{0U} {
57 m_elements = new T[m_capacity]{};
58 assign(other);
59 }
60
65 Container & operator=(Container const & other) {
66 if (&other != this) {
67 delete[] m_elements;
68 m_elements = new T[other.m_capacity]{};
69 m_capacity = other.m_capacity;
70 m_size = 0U;
71 assign(other);
72 }
73 return *this;
74 }
75#else
79 : m_elements()
80 , m_size(0U)
81 {
82 static_assert(Capacity > 0);
83 }
84#endif // THINGSBOARD_ENABLE_DYNAMIC
85
92 : Container()
93 {
94 for (; count > 0; --count) {
95 push_back(value);
96 }
97 }
98
107 template<typename InputIterator>
108 Container(InputIterator const & first, InputIterator const & last)
109 : Container()
110 {
111 assign(first, last);
112 }
113
120 template<typename Iterable_Container>
121 Container(Iterable_Container const & container)
122 : Container(container.cbegin(), container.cend())
123 {
124 // Nothing to do
125 }
126
128 template<typename InputIterator>
129 void assign(InputIterator const & first, InputIterator const & last) {
130 insert(end(), first, last);
131 }
132
134 template<typename Container>
135 void assign(Container const & container) {
136 assign(container.cbegin(), container.cend());
137 }
138
141 bool empty() const {
142 return m_size == 0U;
143 }
144
147 size_type size() const {
148 return m_size;
149 }
150
153#if THINGSBOARD_ENABLE_DYNAMIC
154 size_type capacity() const {
155 return m_capacity;
156#else
157 size_type constexpr capacity() const {
158 return Capacity;
159#endif // THINGSBOARD_ENABLE_DYNAMIC
160 }
161
166 return m_elements;
167 }
168
171 return m_elements;
172 }
173
176 return begin();
177 }
178
183 assert(m_size != 0U);
184 return m_elements[0U];
185 }
186
189 assert(m_size != 0U);
190 return m_elements[0U];
191 }
192
197 assert(m_size != 0U);
198 return m_elements[m_size - 1U];
199 }
200
203 assert(m_size != 0U);
204 return m_elements[m_size - 1U];
205 }
206
210 return m_elements + m_size;
211 }
212
215 return m_elements + m_size;
216 }
217
220 return end();
221 }
222
231#if THINGSBOARD_ENABLE_DYNAMIC
232 increase_capacity();
233#else
234 assert(m_size < Capacity);
235#endif // THINGSBOARD_ENABLE_DYNAMIC
236 if (is_destructible()) {
237 m_elements[m_size].~T();
238 }
239 m_elements[m_size] = element;
240 m_size++;
241 }
242
256 template<typename InputIterator>
257 void insert(iterator position, InputIterator const & first, InputIterator const & last) {
258 (void)--position;
259 assert_iterator_in_range(position);
260#if !THINGSBOARD_ENABLE_DYNAMIC
261 assert((m_size + Helper::distance(first, last)) < Capacity);
262#endif // !THINGSBOARD_ENABLE_DYNAMIC
263 for (auto it = first; it != last; ++it, ++position) {
264#if THINGSBOARD_ENABLE_DYNAMIC
265 increase_capacity();
266#endif // THINGSBOARD_ENABLE_DYNAMIC
267 if (is_destructible()) {
268 (*position).~T();
269 }
270 *position = *it;
271 (void)++m_size;
272 }
273 }
274
284 void erase(const_iterator position) {
285 assert_iterator_in_range(position);
286 size_type const index = Helper::distance(cbegin(), position);
287 // Move all elements after the index one position to the left
288 for (size_type i = index; i <= m_size; ++i) {
289 if (is_destructible()) {
290 m_elements[i].~T();
291 m_elements[i] = m_elements[i + 1];
292 }
293 }
294 if (is_destructible()) {
295 m_elements[m_size].~T();
296 }
297 // Decrease the size of the array to remove the last element, because either it was moved one index to the left or was the element we wanted to delete anyway
298 (void)--m_size;
299 }
300
304 reference at(size_type const & index) {
305 assert(index < m_size);
306 return m_elements[index];
307 }
308
310 const_reference at(size_type const & index) const {
311 assert(index < m_size);
312 return m_elements[index];
313 }
314
319 return m_elements[index];
320 }
321
324 return m_elements[index];
325 }
326
330 void clear() {
331 m_size = 0;
332 }
333
334 private:
338 bool is_destructible() const {
339#if THINGSBOARD_ENABLE_STL
340 return std::is_destructible<T>::value;
341#else
342 // Workaround for ArduinoJson version after 6.21.0, to still be able to access internal enable_if and is_floating_point declarations, previously accessible with ARDUINOJSON_NAMESPACE
343 return ArduinoJson::ARDUINOJSON_VERSION_NAMESPACE::detail::is_class<T>::value;
344#endif // THINGSBOARD_ENABLE_CXX20
345 }
346
347 void assert_iterator_in_range(const_iterator position) {
348 assert(cbegin() >= position);
349 assert(position < cend());
350 }
351
352#if THINGSBOARD_ENABLE_DYNAMIC
354 void increase_capacity() {
355 if (m_size == m_capacity) {
356 m_capacity = (m_capacity == 0) ? 1 : 2 * m_capacity;
357 T* new_elements = new T[m_capacity]();
358 if (m_elements != nullptr) {
359 memcpy(new_elements, m_elements, m_size * sizeof(T));
360 delete[] m_elements;
361 }
362 m_elements = new_elements;
363 }
364 }
365#endif // THINGSBOARD_ENABLE_DYNAMIC
366
367#if THINGSBOARD_ENABLE_DYNAMIC
368 value_type *m_elements = {}; // Pointer to the start of our elements
369 size_t m_capacity = {}; // Allocated capacity that shows how many elements we could hold
370#else
371 value_type m_elements[Capacity] = {}; // Underlying c-array holding our data
372#endif // THINGSBOARD_ENABLE_DYNAMIC
373 size_type m_size = {}; // Used size that shows how many elements we entered
374};
375
376#endif // Container_h
Custom std::array or std::vector implementation that contains a partial vector-like interface impleme...
Definition: Container.h:29
T value_type
Definition: Container.h:31
size_type size() const
Gets the current amount of elements in the underlying data container.
Definition: Container.h:147
reference back()
Returns a reference to the last element of the array. If the array is empty this method will assert a...
Definition: Container.h:196
iterator begin()
Returns an iterator to the first element of the underlying data container. If the array is empty,...
Definition: Container.h:165
reference front()
Returns a reference to the first element of the array. If the array is empty this method will assert ...
Definition: Container.h:182
reference at(size_type const &index)
Returns a reference to the element at specified location index, with bounds checking.
Definition: Container.h:304
Container(Iterable_Container const &container)
Accesses the begin and end iterator of the given data container and forwards the call to the iterator...
Definition: Container.h:121
void erase(const_iterator position)
Removes the element at the given position, has to move all element one to the left if the iterator do...
Definition: Container.h:284
Container()
Default constructor, simply initalizes the underlying c-style array with the necessary capacity....
Definition: Container.h:78
void insert(iterator position, InputIterator const &first, InputIterator const &last)
Copies all elements from the given start to exclusively the given end iterator into the underlying da...
Definition: Container.h:257
const_iterator cbegin() const
Returns an iterator to the first element of the underlying data container. If the array is empty,...
Definition: Container.h:175
size_type constexpr capacity() const
Gets the maximum amount of elements that can be stored in the underlying data container.
Definition: Container.h:157
void push_back(const_reference element)
Appends the given element at the end of the underlying data container.
Definition: Container.h:230
const_reference at(size_type const &index) const
Returns a reference to the element at specified location index, with bounds checking.
Definition: Container.h:310
const_pointer const_iterator
Definition: Container.h:38
const_iterator begin() const
Returns an iterator to the first element of the underlying data container. If the array is empty,...
Definition: Container.h:170
bool empty() const
Returns whether there are any elements in the underlying data container.
Definition: Container.h:141
const_iterator cend() const
Returns a iterator to one-past-the-last element of the underlying data container.
Definition: Container.h:219
T & reference
Definition: Container.h:33
reference operator[](size_type index)
Returns a reference to the element at specified location index. No bounds checking is performed.
Definition: Container.h:318
T const & const_reference
Definition: Container.h:34
void clear()
Erases all elements from the container. After this call, size() returns zero.
Definition: Container.h:330
pointer iterator
Definition: Container.h:37
void assign(InputIterator const &first, InputIterator const &last)
Copies all elements from the given start to exclusively the given end iterator into the underlying da...
Definition: Container.h:129
iterator end()
Returns a iterator to one-past-the-last element of the underlying data container.
Definition: Container.h:209
const_reference front() const
Returns a reference to the first element of the array. If the array is empty this method will assert ...
Definition: Container.h:188
const_reference back() const
Returns a reference to the last element of the array. If the array is empty this method will assert a...
Definition: Container.h:202
size_t size_type
Definition: Container.h:32
const_reference operator[](size_type index) const
Returns a reference to the element at specified location index. No bounds checking is performed.
Definition: Container.h:323
const_iterator end() const
Returns a iterator to one-past-the-last element of the underlying data container.
Definition: Container.h:214
Container(InputIterator const &first, InputIterator const &last)
Copies all elements from the given start to exclusively the given end iterator into the underlying da...
Definition: Container.h:108
Container(size_type count, const_reference value=T{})
Creates the constructor with the given amount of elements, either x copies of the passed value or x d...
Definition: Container.h:91
T * pointer
Definition: Container.h:35
void assign(Container const &container)
Definition: Container.h:135
T const * const_pointer
Definition: Container.h:36
static size_t distance(InputIterator const &first, InputIterator const &last)
Calculates the distance between two iterators.
Definition: Helper.h:85