Branch data Line data Source code
1 : : ///\file
2 : :
3 : : /******************************************************************************
4 : : The MIT License(MIT)
5 : :
6 : : Embedded Template Library.
7 : : https://github.com/ETLCPP/etl
8 : : https://www.etlcpp.com
9 : :
10 : : Copyright(c) 2016 John Wellbelove
11 : :
12 : : Permission is hereby granted, free of charge, to any person obtaining a copy
13 : : of this software and associated documentation files(the "Software"), to deal
14 : : in the Software without restriction, including without limitation the rights
15 : : to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 : : copies of the Software, and to permit persons to whom the Software is
17 : : furnished to do so, subject to the following conditions :
18 : :
19 : : The above copyright notice and this permission notice shall be included in all
20 : : copies or substantial portions of the Software.
21 : :
22 : : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 : : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 : : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 : : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 : : SOFTWARE.
29 : : ******************************************************************************/
30 : :
31 : : #ifndef ETL_PVOIDVECTOR_INCLUDED
32 : : #define ETL_PVOIDVECTOR_INCLUDED
33 : :
34 : : #define ETL_IN_PVOIDVECTOR
35 : :
36 : : #include "../platform.h"
37 : : #include "../algorithm.h"
38 : : #include "../error_handler.h"
39 : : #include "../functional.h"
40 : : #include "../iterator.h"
41 : : #include "../type_traits.h"
42 : : #include "vector_base.h"
43 : :
44 : : #include <stddef.h>
45 : :
46 : : #include "minmax_push.h"
47 : :
48 : : namespace etl
49 : : {
50 : : //***************************************************************************
51 : : /// The base class for void* vectors.
52 : : ///\ingroup vector
53 : : //***************************************************************************
54 : 16272 : class pvoidvector : public vector_base
55 : : {
56 : : public:
57 : :
58 : : typedef void* value_type;
59 : : typedef value_type& reference;
60 : : typedef const value_type& const_reference;
61 : : typedef value_type* pointer;
62 : : typedef const value_type* const_pointer;
63 : : typedef value_type* iterator;
64 : : typedef const value_type* const_iterator;
65 : : typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
66 : : typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
67 : : typedef size_t size_type;
68 : : typedef etl::iterator_traits<iterator>::difference_type difference_type;
69 : :
70 : : public:
71 : :
72 : : //*********************************************************************
73 : : /// Returns an iterator to the beginning of the vector.
74 : : ///\return An iterator to the beginning of the vector.
75 : : //*********************************************************************
76 : 94724 : iterator begin()
77 : : {
78 : 94724 : return p_buffer;
79 : : }
80 : :
81 : : //*********************************************************************
82 : : /// Returns a const_iterator to the beginning of the vector.
83 : : ///\return A const iterator to the beginning of the vector.
84 : : //*********************************************************************
85 : 2560 : const_iterator begin() const
86 : : {
87 : 2560 : return const_iterator(p_buffer);
88 : : }
89 : :
90 : : //*********************************************************************
91 : : /// Returns an iterator to the end of the vector.
92 : : ///\return An iterator to the end of the vector.
93 : : //*********************************************************************
94 : 371392 : iterator end()
95 : : {
96 : 371392 : return p_end;
97 : : }
98 : :
99 : : //*********************************************************************
100 : : /// Returns a const_iterator to the end of the vector.
101 : : ///\return A const iterator to the end of the vector.
102 : : //*********************************************************************
103 : 2216 : const_iterator end() const
104 : : {
105 : 2216 : return const_iterator(p_end);
106 : : }
107 : :
108 : : //*********************************************************************
109 : : /// Returns a const_iterator to the beginning of the vector.
110 : : ///\return A const iterator to the beginning of the vector.
111 : : //*********************************************************************
112 : 7764 : const_iterator cbegin() const
113 : : {
114 : 7764 : return const_iterator(p_buffer);
115 : : }
116 : :
117 : : //*********************************************************************
118 : : /// Returns a const_iterator to the end of the vector.
119 : : ///\return A const iterator to the end of the vector.
120 : : //*********************************************************************
121 : 10284 : const_iterator cend() const
122 : : {
123 : 10284 : return const_iterator(p_end);
124 : : }
125 : :
126 : : //*********************************************************************
127 : : /// Returns an reverse iterator to the reverse beginning of the vector.
128 : : ///\return Iterator to the reverse beginning of the vector.
129 : : //*********************************************************************
130 : : reverse_iterator rbegin()
131 : : {
132 : : return reverse_iterator(end());
133 : : }
134 : :
135 : : //*********************************************************************
136 : : /// Returns a const reverse iterator to the reverse beginning of the vector.
137 : : ///\return Const iterator to the reverse beginning of the vector.
138 : : //*********************************************************************
139 : : const_reverse_iterator rbegin() const
140 : : {
141 : : return const_reverse_iterator(end());
142 : : }
143 : :
144 : : //*********************************************************************
145 : : /// Returns a reverse iterator to the end + 1 of the vector.
146 : : ///\return Reverse iterator to the end + 1 of the vector.
147 : : //*********************************************************************
148 : : reverse_iterator rend()
149 : : {
150 : : return reverse_iterator(begin());
151 : : }
152 : :
153 : : //*********************************************************************
154 : : /// Returns a const reverse iterator to the end + 1 of the vector.
155 : : ///\return Const reverse iterator to the end + 1 of the vector.
156 : : //*********************************************************************
157 : : const_reverse_iterator rend() const
158 : : {
159 : : return const_reverse_iterator(begin());
160 : : }
161 : :
162 : : //*********************************************************************
163 : : /// Returns a const reverse iterator to the reverse beginning of the vector.
164 : : ///\return Const reverse iterator to the reverse beginning of the vector.
165 : : //*********************************************************************
166 : : const_reverse_iterator crbegin() const
167 : : {
168 : : return const_reverse_iterator(cend());
169 : : }
170 : :
171 : : //*********************************************************************
172 : : /// Returns a const reverse iterator to the end + 1 of the vector.
173 : : ///\return Const reverse iterator to the end + 1 of the vector.
174 : : //*********************************************************************
175 : : const_reverse_iterator crend() const
176 : : {
177 : : return const_reverse_iterator(cbegin());
178 : : }
179 : :
180 : : //*********************************************************************
181 : : /// Resizes the vector.
182 : : /// If asserts or exceptions are enabled and the new size is larger than the
183 : : /// maximum then a vector_full is thrown.
184 : : ///\param new_size The new size.
185 : : //*********************************************************************
186 : 864 : void resize(size_t new_size)
187 : : {
188 [ + + + - ]: 864 : ETL_ASSERT_OR_RETURN(new_size <= CAPACITY, ETL_ERROR(vector_full));
189 : :
190 : 768 : p_end = p_buffer + new_size;
191 : 768 : }
192 : :
193 : : //*********************************************************************
194 : : /// Resizes the vector.
195 : : /// If asserts or exceptions are enabled and the new size is larger than the
196 : : /// maximum then a vector_full is thrown.
197 : : ///\param new_size The new size.
198 : : ///\param value The value to fill new elements with. Default = default
199 : : /// constructed value.
200 : : //*********************************************************************
201 : 400 : void resize(size_t new_size, value_type value)
202 : : {
203 [ + - # # ]: 400 : ETL_ASSERT_OR_RETURN(new_size <= CAPACITY, ETL_ERROR(vector_full));
204 : :
205 : 400 : pointer p_new_end = p_buffer + new_size;
206 : :
207 : : // Size up if necessary.
208 [ + + ]: 400 : if (p_end < p_new_end)
209 : : {
210 : 352 : etl::fill(p_end, p_new_end, value);
211 : 352 : }
212 : :
213 : 400 : p_end = p_new_end;
214 : 400 : }
215 : :
216 : : //*********************************************************************
217 : : /// Resizes the vector, but does not initialise new entries.
218 : : ///\param new_size The new size.
219 : : //*********************************************************************
220 : : void uninitialized_resize(size_t new_size)
221 : : {
222 : : ETL_ASSERT_OR_RETURN(new_size <= CAPACITY, ETL_ERROR(vector_full));
223 : :
224 : : p_end = p_buffer + new_size;
225 : : }
226 : :
227 : : //*********************************************************************
228 : : /// Returns a reference to the value at index 'i'
229 : : ///\param i The index.
230 : : ///\return A reference to the value at index 'i'
231 : : //*********************************************************************
232 : 3240 : reference operator[](size_t i)
233 : : {
234 [ + + + - ]: 3240 : ETL_ASSERT_CHECK_INDEX_OPERATOR(i < size(), ETL_ERROR(vector_out_of_bounds));
235 : 3144 : return p_buffer[i];
236 : 0 : }
237 : :
238 : : //*********************************************************************
239 : : /// Returns a const reference to the value at index 'i'
240 : : ///\param i The index.
241 : : ///\return A const reference to the value at index 'i'
242 : : //*********************************************************************
243 : 624 : const_reference operator[](size_t i) const
244 : : {
245 [ + + + - ]: 624 : ETL_ASSERT_CHECK_INDEX_OPERATOR(i < size(), ETL_ERROR(vector_out_of_bounds));
246 : 576 : return p_buffer[i];
247 : 0 : }
248 : :
249 : : //*********************************************************************
250 : : /// Returns a reference to the value at index 'i'
251 : : /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds
252 : : /// if the index is out of range.
253 : : ///\param i The index.
254 : : ///\return A reference to the value at index 'i'
255 : : //*********************************************************************
256 : 1152 : reference at(size_t i)
257 : : {
258 [ + + + - ]: 1152 : ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds));
259 : 1056 : return p_buffer[i];
260 : 0 : }
261 : :
262 : : //*********************************************************************
263 : : /// Returns a const reference to the value at index 'i'
264 : : /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds
265 : : /// if the index is out of range.
266 : : ///\param i The index.
267 : : ///\return A const reference to the value at index 'i'
268 : : //*********************************************************************
269 : 528 : const_reference at(size_t i) const
270 : : {
271 [ + + + - ]: 528 : ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds));
272 : 480 : return p_buffer[i];
273 : 0 : }
274 : :
275 : : //*********************************************************************
276 : : /// Returns a reference to the first element.
277 : : ///\return A reference to the first element.
278 : : //*********************************************************************
279 : 192 : reference front()
280 : : {
281 [ + + + - ]: 192 : ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(vector_out_of_bounds));
282 : 96 : return p_buffer[0];
283 : 0 : }
284 : :
285 : : //*********************************************************************
286 : : /// Returns a const reference to the first element.
287 : : ///\return A const reference to the first element.
288 : : //*********************************************************************
289 : 96 : const_reference front() const
290 : : {
291 [ + + + - ]: 96 : ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(vector_out_of_bounds));
292 : 48 : return p_buffer[0];
293 : 0 : }
294 : :
295 : : //*********************************************************************
296 : : /// Returns a reference to the last element.
297 : : ///\return A reference to the last element.
298 : : //*********************************************************************
299 : 2316 : reference back()
300 : : {
301 [ + + + - ]: 2316 : ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(vector_out_of_bounds));
302 : 2220 : return *(p_end - 1);
303 : 0 : }
304 : :
305 : : //*********************************************************************
306 : : /// Returns a const reference to the last element.
307 : : ///\return A const reference to the last element.
308 : : //*********************************************************************
309 : 96 : const_reference back() const
310 : : {
311 [ + + + - ]: 96 : ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(vector_out_of_bounds));
312 : 48 : return *(p_end - 1);
313 : 0 : }
314 : :
315 : : //*********************************************************************
316 : : /// Returns a pointer to the beginning of the vector data.
317 : : ///\return A pointer to the beginning of the vector data.
318 : : //*********************************************************************
319 : 292 : pointer data()
320 : : {
321 : 292 : return p_buffer;
322 : : }
323 : :
324 : : //*********************************************************************
325 : : /// Returns a const pointer to the beginning of the vector data.
326 : : ///\return A const pointer to the beginning of the vector data.
327 : : //*********************************************************************
328 : 208 : const_pointer data() const
329 : : {
330 : 208 : return p_buffer;
331 : : }
332 : :
333 : : //*********************************************************************
334 : : /// Assigns values to the vector. Non-pointer
335 : : /// If asserts or exceptions are enabled, emits vector_full if the vector
336 : : /// does not have enough free space. If asserts or exceptions are enabled,
337 : : /// emits vector_iterator if the iterators are reversed.
338 : : ///\param first The iterator to the first element.
339 : : ///\param last The iterator to the last element + 1.
340 : : //*********************************************************************
341 : : template <typename TIterator>
342 : 4080 : typename etl::enable_if<!etl::is_pointer<TIterator>::value, void>::type assign(TIterator first, TIterator last)
343 : : {
344 : : #if ETL_IS_DEBUG_BUILD
345 : 4080 : difference_type d = etl::distance(first, last);
346 [ + - # # : 4080 : ETL_ASSERT_OR_RETURN(static_cast<size_t>(d) <= CAPACITY, ETL_ERROR(vector_full));
+ - # # +
- # # + -
# # # # #
# ]
347 : : #endif
348 : :
349 : 4080 : initialise();
350 : :
351 [ + + + + : 37752 : while (first != last)
+ + + + #
# ]
352 : : {
353 : 33672 : *p_end++ = (void*)(*first);
354 : 33672 : ++first;
355 : : }
356 : 4080 : }
357 : :
358 : : //*********************************************************************
359 : : /// Assigns values to the vector. Pointer
360 : : /// If asserts or exceptions are enabled, emits vector_full if the vector
361 : : /// does not have enough free space. If asserts or exceptions are enabled,
362 : : /// emits vector_iterator if the iterators are reversed.
363 : : ///\param first The iterator to the first element.
364 : : ///\param last The iterator to the last element + 1.
365 : : //*********************************************************************
366 : : template <typename TIterator>
367 : 340 : typename etl::enable_if<etl::is_pointer<TIterator>::value, void>::type assign(TIterator first, TIterator last)
368 : : {
369 : : #if ETL_IS_DEBUG_BUILD
370 : 340 : difference_type d = etl::distance(first, last);
371 [ + - # # : 340 : ETL_ASSERT_OR_RETURN(static_cast<size_t>(d) <= CAPACITY, ETL_ERROR(vector_full));
+ - # # +
- # # ]
372 : : #endif
373 : :
374 : 340 : initialise();
375 : :
376 : 340 : void** p_first = (void**)(first);
377 : 340 : void** p_last = (void**)(last);
378 : :
379 : 340 : p_end = etl::mem_move(p_first, p_last, p_buffer) + (p_last - p_first);
380 : 340 : }
381 : :
382 : : //*********************************************************************
383 : : /// Assigns values to the vector.
384 : : /// If asserts or exceptions are enabled, emits vector_full if the vector
385 : : /// does not have enough free space.
386 : : ///\param n The number of elements to add.
387 : : ///\param value The value to insert for each element.
388 : : //*********************************************************************
389 : 96 : void assign(size_t n, value_type value)
390 : : {
391 [ + + + - ]: 96 : ETL_ASSERT_OR_RETURN(n <= CAPACITY, ETL_ERROR(vector_full));
392 : :
393 : 48 : initialise();
394 : :
395 : 48 : p_end = etl::fill_n(p_buffer, n, value);
396 : 48 : }
397 : :
398 : : //*************************************************************************
399 : : /// Clears the vector.
400 : : //*************************************************************************
401 : 33896 : void clear()
402 : : {
403 : 33896 : initialise();
404 : 33896 : }
405 : :
406 : : //*********************************************************************
407 : : /// Inserts a value at the end of the vector.
408 : : /// If asserts or exceptions are enabled, emits vector_full if the vector is
409 : : /// already full.
410 : : ///\param value The value to add.
411 : : //*********************************************************************
412 : 86484 : void push_back(value_type value)
413 : : {
414 [ + + + - ]: 86484 : ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full));
415 : :
416 : 86436 : *p_end++ = value;
417 : 86436 : }
418 : :
419 : : //*********************************************************************
420 : : /// Emplaces a value at the end of the vector.
421 : : /// If asserts or exceptions are enabled, emits vector_full if the vector is
422 : : /// already full.
423 : : ///\param value The value to add.
424 : : //*********************************************************************
425 : 408 : void emplace_back(value_type value)
426 : : {
427 [ + - # # ]: 408 : ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full));
428 : :
429 : 408 : *p_end++ = value;
430 : 408 : }
431 : :
432 : : //*************************************************************************
433 : : /// Removes an element from the end of the vector.
434 : : /// Does nothing if the vector is empty.
435 : : //*************************************************************************
436 : 480 : void pop_back()
437 : : {
438 [ + + + - ]: 480 : ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() > 0, ETL_ERROR(vector_empty));
439 : :
440 : 432 : --p_end;
441 : 432 : }
442 : :
443 : : //*********************************************************************
444 : : /// Inserts a value to the vector.
445 : : /// If asserts or exceptions are enabled, emits vector_full if the vector is
446 : : /// already full.
447 : : ///\param position The position to insert before.
448 : : ///\param value The value to insert.
449 : : //*********************************************************************
450 : : #if defined(ETL_COMPILER_GCC) && defined(ETL_IN_UNIT_TEST)
451 : : #include "diagnostic_array_bounds_push.h"
452 : : #endif
453 : 2724 : iterator insert(const_iterator position, value_type value)
454 : : {
455 [ + + + - ]: 2724 : ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
456 [ + + + - ]: 2652 : ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
457 : :
458 : 2604 : iterator position_ = to_iterator(position);
459 : :
460 [ - + ]: 2604 : if (size() != CAPACITY)
461 : : {
462 [ + + ]: 2604 : if (position_ != end())
463 : : {
464 : 1908 : ++p_end;
465 : 1908 : etl::mem_move(position_, end() - 1, position_ + 1);
466 : 1908 : *position_ = value;
467 : 1908 : }
468 : : else
469 : : {
470 : 696 : *p_end++ = value;
471 : : }
472 : 2604 : }
473 : :
474 : 2604 : return position_;
475 : 0 : }
476 : : #if defined(ETL_COMPILER_GCC) && defined(ETL_IN_UNIT_TEST)
477 : : #include "diagnostic_pop.h"
478 : : #endif
479 : :
480 : : //*************************************************************************
481 : : /// Emplaces a value to the vector at the specified position.
482 : : /// If asserts or exceptions are enabled, emits vector_full if the vector is
483 : : /// already full.
484 : : //*************************************************************************
485 : : #if defined(ETL_COMPILER_GCC) && defined(ETL_IN_UNIT_TEST)
486 : : #include "diagnostic_array_bounds_push.h"
487 : : #endif
488 : : iterator emplace(const_iterator position)
489 : : {
490 : : ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
491 : : ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
492 : :
493 : : iterator position_ = to_iterator(position);
494 : :
495 : : if (position_ != end())
496 : : {
497 : : ++p_end;
498 : : etl::mem_move(position_, end() - 1, position_ + 1);
499 : : *position_ = ETL_NULLPTR;
500 : : }
501 : : else
502 : : {
503 : : *p_end++ = ETL_NULLPTR;
504 : : }
505 : :
506 : : return position_;
507 : : }
508 : : #if defined(ETL_COMPILER_GCC) && defined(ETL_IN_UNIT_TEST)
509 : : #include "diagnostic_pop.h"
510 : : #endif
511 : :
512 : : //*************************************************************************
513 : : /// Emplaces a value to the vector at the specified position.
514 : : /// If asserts or exceptions are enabled, emits vector_full if the vector is
515 : : /// already full.
516 : : //*************************************************************************
517 : : #if defined(ETL_COMPILER_GCC) && defined(ETL_IN_UNIT_TEST)
518 : : #include "diagnostic_array_bounds_push.h"
519 : : #endif
520 : 288 : iterator emplace(const_iterator position, value_type value)
521 : : {
522 [ + - # # ]: 288 : ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
523 [ + + + - ]: 288 : ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
524 : :
525 : 264 : iterator position_ = to_iterator(position);
526 : :
527 [ + + ]: 264 : if (position_ != end())
528 : : {
529 : 228 : ++p_end;
530 : 228 : etl::mem_move(position_, end() - 1, position_ + 1);
531 : 228 : *position_ = value;
532 : 228 : }
533 : : else
534 : : {
535 : 36 : *p_end++ = value;
536 : : }
537 : :
538 : 264 : return position_;
539 : 0 : }
540 : : #if defined(ETL_COMPILER_GCC) && defined(ETL_IN_UNIT_TEST)
541 : : #include "diagnostic_pop.h"
542 : : #endif
543 : :
544 : : //*********************************************************************
545 : : /// Inserts 'n' values to the vector.
546 : : /// If asserts or exceptions are enabled, emits vector_full if the vector
547 : : /// does not have enough free space.
548 : : ///\param position The position to insert before.
549 : : ///\param n The number of elements to add.
550 : : ///\param value The value to insert.
551 : : //*********************************************************************
552 : : #if defined(ETL_COMPILER_GCC) && defined(ETL_IN_UNIT_TEST)
553 : : #include "diagnostic_array_bounds_push.h"
554 : : #endif
555 : 816 : void insert(const_iterator position, size_t n, value_type value)
556 : : {
557 [ + + + - ]: 816 : ETL_ASSERT_OR_RETURN((size() + n) <= CAPACITY, ETL_ERROR(vector_full));
558 [ + + + - ]: 624 : ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
559 : :
560 : 576 : iterator position_ = to_iterator(position);
561 : :
562 : 576 : etl::mem_move(position_, p_end, position_ + n);
563 : 576 : etl::fill_n(position_, n, value);
564 : :
565 : 576 : p_end += n;
566 : 576 : }
567 : : #if defined(ETL_COMPILER_GCC) && defined(ETL_IN_UNIT_TEST)
568 : : #include "diagnostic_pop.h"
569 : : #endif
570 : :
571 : : //*********************************************************************
572 : : /// Inserts a range of values to the vector.
573 : : /// If asserts or exceptions are enabled, emits vector_full if the vector
574 : : /// does not have enough free space. For non-pointer iterators.
575 : : ///\param position The position to insert before.
576 : : ///\param first The first element to add.
577 : : ///\param last The last + 1 element to add.
578 : : //*********************************************************************
579 : : template <typename TIterator>
580 : 528 : typename etl::enable_if<!etl::is_pointer<TIterator>::value, void>::type insert(const_iterator position, TIterator first, TIterator last)
581 : : {
582 : 528 : size_t count = static_cast<size_t>(etl::distance(first, last));
583 : :
584 : 528 : iterator position_ = to_iterator(position);
585 : :
586 [ + + + - : 528 : ETL_ASSERT_OR_RETURN((size() + count) <= CAPACITY, ETL_ERROR(vector_full));
+ - # # ]
587 [ + - # # : 336 : ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
- + + - ]
588 : :
589 : 288 : etl::mem_move(position_, p_end, position_ + count);
590 : 288 : etl::copy(first, last, position_);
591 : 288 : p_end += count;
592 : 288 : }
593 : :
594 : : //*********************************************************************
595 : : /// Inserts a range of values to the vector.
596 : : /// If asserts or exceptions are enabled, emits vector_full if the vector
597 : : /// does not have enough free space. For pointer iterators.
598 : : ///\param position The position to insert before.
599 : : ///\param first The first element to add.
600 : : ///\param last The last + 1 element to add.
601 : : //*********************************************************************
602 : : template <typename TIterator>
603 : 84 : typename etl::enable_if<etl::is_pointer<TIterator>::value, void>::type insert(const_iterator position, TIterator first, TIterator last)
604 : : {
605 : 84 : size_t count = static_cast<size_t>(etl::distance(first, last));
606 : :
607 : 84 : iterator position_ = to_iterator(position);
608 : :
609 [ + - # # ]: 84 : ETL_ASSERT_OR_RETURN((size() + count) <= CAPACITY, ETL_ERROR(vector_full));
610 [ + + + - ]: 84 : ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
611 : :
612 : 72 : etl::mem_move(position_, p_end, position_ + count);
613 : 72 : etl::mem_move((void**)first, (void**)last, position_);
614 : 72 : p_end += count;
615 : 72 : }
616 : :
617 : : //*********************************************************************
618 : : /// Erases an element.
619 : : ///\param i_element Iterator to the element.
620 : : ///\return An iterator pointing to the element that followed the erased
621 : : /// element.
622 : : //*********************************************************************
623 : 312 : iterator erase(iterator i_element)
624 : : {
625 [ + + + - ]: 312 : ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(vector_out_of_bounds));
626 : :
627 : 264 : etl::mem_move(i_element + 1, end(), i_element);
628 : 264 : --p_end;
629 : :
630 : 264 : return i_element;
631 : 0 : }
632 : :
633 : : //*********************************************************************
634 : : /// Erases an element.
635 : : ///\param i_element Iterator to the element.
636 : : ///\return An iterator pointing to the element that followed the erased
637 : : /// element.
638 : : //*********************************************************************
639 : 144 : iterator erase(const_iterator i_element)
640 : : {
641 [ + + + - ]: 144 : ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(vector_out_of_bounds));
642 : :
643 : 132 : iterator i_element_ = to_iterator(i_element);
644 : :
645 : 132 : etl::mem_move(i_element_ + 1, end(), i_element_);
646 : 132 : --p_end;
647 : :
648 : 132 : return i_element_;
649 : 0 : }
650 : :
651 : : //*********************************************************************
652 : : /// Erases a range of elements.
653 : : /// The range includes all the elements between first and last, including
654 : : /// the element pointed by first, but not the one pointed by last.
655 : : ///\param first Iterator to the first element.
656 : : ///\param last Iterator to the last element.
657 : : ///\return An iterator pointing to the element that followed the erased
658 : : /// element.
659 : : //*********************************************************************
660 : 636 : iterator erase(const_iterator first, const_iterator last)
661 : : {
662 [ + + + - ]: 636 : ETL_ASSERT_CHECK_EXTRA(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(vector_out_of_bounds));
663 : :
664 : 588 : iterator first_ = to_iterator(first);
665 : 588 : iterator last_ = to_iterator(last);
666 : :
667 : 588 : etl::mem_move(last_, end(), first_);
668 : 588 : size_t n_delete = static_cast<size_t>(etl::distance(first, last));
669 : :
670 : : // Just adjust the count.
671 : 588 : p_end -= n_delete;
672 : :
673 : 588 : return first_;
674 : 0 : }
675 : :
676 : : //*************************************************************************
677 : : /// Assignment operator.
678 : : //*************************************************************************
679 : 48 : etl::pvoidvector& operator=(const etl::pvoidvector& rhs)
680 : : {
681 [ - + ]: 48 : if (&rhs != this)
682 : : {
683 : 48 : this->initialise();
684 : 48 : this->resize(rhs.size());
685 : 48 : etl::mem_copy(rhs.data(), rhs.size(), this->data());
686 : 48 : }
687 : :
688 : 48 : return *this;
689 : : }
690 : :
691 : : #if ETL_USING_CPP11
692 : : //*************************************************************************
693 : : /// Move assignment operator.
694 : : //*************************************************************************
695 : : etl::pvoidvector& operator=(etl::pvoidvector&& rhs)
696 : : {
697 : : if (&rhs != this)
698 : : {
699 : : this->initialise();
700 : : this->resize(rhs.size());
701 : : etl::mem_copy(rhs.data(), rhs.size(), this->data());
702 : : rhs.initialise();
703 : : }
704 : :
705 : : return *this;
706 : : }
707 : : #endif
708 : :
709 : : //*************************************************************************
710 : : /// Gets the current size of the vector.
711 : : ///\return The current size of the vector.
712 : : //*************************************************************************
713 : 205080 : size_type size() const
714 : : {
715 : 205080 : return size_t(p_end - p_buffer);
716 : : }
717 : :
718 : : //*************************************************************************
719 : : /// Checks the 'empty' state of the vector.
720 : : ///\return <b>true</b> if empty.
721 : : //*************************************************************************
722 : 1284 : bool empty() const
723 : : {
724 : 1284 : return (p_end == p_buffer);
725 : : }
726 : :
727 : : //*************************************************************************
728 : : /// Checks the 'full' state of the vector.
729 : : ///\return <b>true</b> if full.
730 : : //*************************************************************************
731 : 85756 : bool full() const
732 : : {
733 : 85756 : return size() == CAPACITY;
734 : : }
735 : :
736 : : //*************************************************************************
737 : : /// Returns the remaining capacity.
738 : : ///\return The remaining capacity.
739 : : //*************************************************************************
740 : 132 : size_t available() const
741 : : {
742 : 132 : return max_size() - size();
743 : : }
744 : :
745 : : protected:
746 : :
747 : : //*********************************************************************
748 : : /// Constructor.
749 : : //*********************************************************************
750 : 16272 : pvoidvector(void** p_buffer_, size_t MAX_SIZE)
751 : 16272 : : vector_base(MAX_SIZE)
752 : 16272 : , p_buffer(p_buffer_)
753 : 16272 : , p_end(p_buffer_)
754 : 16272 : {
755 : 16272 : }
756 : :
757 : : //*********************************************************************
758 : : /// Initialise the vector.
759 : : //*********************************************************************
760 : 51596 : void initialise()
761 : : {
762 : 51596 : p_end = p_buffer;
763 : 51596 : }
764 : :
765 : : //*************************************************************************
766 : : /// Fix the internal pointers after a low level memory copy.
767 : : //*************************************************************************
768 : 24 : void repair_buffer(void** p_buffer_)
769 : : {
770 : 24 : uintptr_t length = static_cast<uintptr_t>(p_end - p_buffer);
771 : :
772 : 24 : p_buffer = p_buffer_;
773 : 24 : p_end = p_buffer_ + length;
774 : 24 : }
775 : :
776 : : void** p_buffer;
777 : : void** p_end;
778 : :
779 : : private:
780 : :
781 : : //*************************************************************************
782 : : /// Convert from const_iterator to iterator
783 : : //*************************************************************************
784 : 5364 : iterator to_iterator(const_iterator itr) const
785 : : {
786 : 5364 : return const_cast<iterator>(itr);
787 : : }
788 : :
789 : : // Disable copy construction.
790 : : pvoidvector(const pvoidvector&);
791 : : };
792 : :
793 : : //***************************************************************************
794 : : /// Equal operator.
795 : : ///\param lhs Reference to the first vector.
796 : : ///\param rhs Reference to the second vector.
797 : : ///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
798 : : ///\ingroup vector
799 : : //***************************************************************************
800 : : inline bool operator==(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs)
801 : : {
802 : : return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
803 : : }
804 : :
805 : : //***************************************************************************
806 : : /// Not equal operator.
807 : : ///\param lhs Reference to the first vector.
808 : : ///\param rhs Reference to the second vector.
809 : : ///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
810 : : ///\ingroup vector
811 : : //***************************************************************************
812 : : inline bool operator!=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs)
813 : : {
814 : : return !(lhs == rhs);
815 : : }
816 : :
817 : : //***************************************************************************
818 : : /// Less than operator.
819 : : ///\param lhs Reference to the first vector.
820 : : ///\param rhs Reference to the second vector.
821 : : ///\return <b>true</b> if the first vector is lexicographically less than the
822 : : /// second, otherwise <b>false</b> \ingroup vector
823 : : //***************************************************************************
824 : : inline bool operator<(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs)
825 : : {
826 : : return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
827 : : }
828 : :
829 : : //***************************************************************************
830 : : /// Greater than operator.
831 : : ///\param lhs Reference to the first vector.
832 : : ///\param rhs Reference to the second vector.
833 : : ///\return <b>true</b> if the first vector is lexicographically greater than
834 : : /// the second, otherwise <b>false</b> \ingroup vector
835 : : //***************************************************************************
836 : : inline bool operator>(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs)
837 : : {
838 : : return (rhs < lhs);
839 : : }
840 : :
841 : : //***************************************************************************
842 : : /// Less than or equal operator.
843 : : ///\param lhs Reference to the first vector.
844 : : ///\param rhs Reference to the second vector.
845 : : ///\return <b>true</b> if the first vector is lexicographically less than or
846 : : /// equal to the second, otherwise
847 : : ///< b>false</b> \ingroup vector
848 : : //***************************************************************************
849 : : inline bool operator<=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs)
850 : : {
851 : : return !(lhs > rhs);
852 : : }
853 : :
854 : : //***************************************************************************
855 : : /// Greater than or equal operator.
856 : : ///\param lhs Reference to the first vector.
857 : : ///\param rhs Reference to the second vector.
858 : : ///\return <b>true</b> if the first vector is lexicographically greater than
859 : : /// or equal to the second, otherwise
860 : : ///< b>false</b> \ingroup vector
861 : : //***************************************************************************
862 : : inline bool operator>=(const etl::pvoidvector& lhs, const etl::pvoidvector& rhs)
863 : : {
864 : : return !(lhs < rhs);
865 : : }
866 : : } // namespace etl
867 : :
868 : : #include "minmax_pop.h"
869 : :
870 : : #undef ETL_IN_PVOIDVECTOR
871 : :
872 : : #endif
|