Embedded Template Library 1.0
Loading...
Searching...
No Matches
indirect_vector.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2019 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_INDIRECT_VECTOR_INCLUDED
32#define ETL_INDIRECT_VECTOR_INCLUDED
33
34#include "platform.h"
35#include "functional.h"
36#include "initializer_list.h"
37#include "iterator.h"
38#include "pool.h"
39#include "static_assert.h"
40#include "utility.h"
41#include "vector.h"
42
43//*****************************************************************************
48//*****************************************************************************
49
50namespace etl
51{
52 //***************************************************************************
55 //***************************************************************************
56 class indirect_vector_buffer_missmatch : public vector_exception
57 {
58 public:
59
60 indirect_vector_buffer_missmatch(string_type file_name_, numeric_type line_number_)
61 : vector_exception(ETL_ERROR_TEXT("indirect_vector:buffer_missmatch", ETL_INDIRECT_VECTOR_FILE_ID"A"), file_name_, line_number_)
62 {
63 }
64 };
65
66 //***************************************************************************
71 //***************************************************************************
72 template <typename T>
74 {
75 public:
76
77 typedef T value_type;
78 typedef T& reference;
79 typedef const T& const_reference;
80#if ETL_USING_CPP11
81 typedef T&& rvalue_reference;
82#endif
83 typedef T* pointer;
84 typedef const T* const_pointer;
85
86 typedef typename etl::ivector<T*>::iterator indirect_iterator;
87 typedef typename etl::ivector<T*>::const_iterator indirect_const_iterator;
88
89 typedef typename etl::ivector<T*>::size_type size_type;
90 typedef typename etl::ivector<T*>::difference_type difference_type;
91
92 //*************************************************************************
94 //*************************************************************************
95 template <typename TUnaryFunction, typename TReturnType = void>
96 class unary_function_adaptor
97 {
98 public:
99
100 unary_function_adaptor(TUnaryFunction unary_function_)
101 : unary_function(unary_function_)
102 {
103 }
104
105 TReturnType operator()(const_pointer indirect_itr)
106 {
107 return unary_function(*indirect_itr);
108 }
109
110 TUnaryFunction unary_function;
111 };
112
113 //*************************************************************************
114 template <typename TUnaryFunction>
115 class unary_function_adaptor<TUnaryFunction, void>
116 {
117 public:
118
119 unary_function_adaptor(TUnaryFunction unary_function_)
120 : unary_function(unary_function_)
121 {
122 }
123
124 void operator()(const_pointer indirect_itr)
125 {
126 unary_function(*indirect_itr);
127 }
128
129 TUnaryFunction unary_function;
130 };
131
132 //*************************************************************************
134 //*************************************************************************
135 template <typename TBinaryFunction, typename TReturnType = void>
136 class binary_function_adaptor
137 {
138 public:
139
140 binary_function_adaptor(TBinaryFunction binary_function_)
141 : binary_function(binary_function_)
142 {
143 }
144
145 TReturnType operator()(const_pointer indirect_itr_lhs, const_pointer indirect_itr_rhs)
146 {
147 return binary_function(*indirect_itr_lhs, *indirect_itr_rhs);
148 }
149
150 TBinaryFunction binary_function;
151 };
152
153 //*************************************************************************
154 template <typename TBinaryFunction>
155 class binary_function_adaptor<TBinaryFunction, void>
156 {
157 public:
158
159 binary_function_adaptor(TBinaryFunction binary_function_)
160 : binary_function(binary_function_)
161 {
162 }
163
164 void operator()(const_pointer indirect_itr_lhs, const_pointer indirect_itr_rhs)
165 {
166 binary_function(*indirect_itr_lhs, *indirect_itr_rhs);
167 }
168
169 TBinaryFunction binary_function;
170 };
171
172 //*************************************************************************
174 //*************************************************************************
175 class iterator : public etl::iterator<ETL_OR_STD::random_access_iterator_tag, T>
176 {
177 public:
178
179 friend class iindirect_vector;
180 friend class const_iterator;
181
182 iterator()
183 : lookup_itr()
184 {
185 }
186
187 iterator(const iterator& other)
188 : lookup_itr(other.lookup_itr)
189 {
190 }
191
192 iterator& operator++()
193 {
194 ++lookup_itr;
195 return *this;
196 }
197
198 iterator operator++(int)
199 {
200 iterator temp(*this);
201 ++lookup_itr;
202 return temp;
203 }
204
205 iterator& operator--()
206 {
207 --lookup_itr;
208 return *this;
209 }
210
211 iterator operator--(int)
212 {
213 iterator temp(*this);
214 --lookup_itr;
215 return temp;
216 }
217
218 iterator& operator=(const iterator& other)
219 {
220 lookup_itr = other.lookup_itr;
221 return *this;
222 }
223
224 iterator operator+=(difference_type n)
225 {
226 lookup_itr += n;
227 return *this;
228 }
229
230 iterator operator-=(difference_type n)
231 {
232 lookup_itr -= n;
233 return *this;
234 }
235
236 reference operator*() const
237 {
238 return **lookup_itr;
239 }
240
241 pointer operator&() const
242 {
243 return &(**lookup_itr);
244 }
245
246 pointer operator->() const
247 {
248 return &(**lookup_itr);
249 }
250
251 friend iterator operator+(const iterator& lhs, difference_type offset)
252 {
253 iterator result(lhs);
254 result += offset;
255 return result;
256 }
257
258 friend iterator operator-(const iterator& lhs, difference_type offset)
259 {
260 iterator result(lhs);
261 result -= offset;
262 return result;
263 }
264
265 indirect_iterator indirection()
266 {
267 return lookup_itr;
268 }
269
270 indirect_const_iterator indirection() const
271 {
272 return lookup_itr;
273 }
274
275 friend difference_type operator-(const iterator& lhs, const iterator& rhs)
276 {
277 return lhs.lookup_itr - rhs.lookup_itr;
278 }
279
280 friend bool operator==(const iterator& lhs, const iterator& rhs)
281 {
282 return lhs.lookup_itr == rhs.lookup_itr;
283 }
284
285 friend bool operator!=(const iterator& lhs, const iterator& rhs)
286 {
287 return !(lhs == rhs);
288 }
289
290 friend bool operator<(const iterator& lhs, const iterator& rhs)
291 {
292 return lhs.lookup_itr < rhs.lookup_itr;
293 }
294
295 friend bool operator<=(const iterator& lhs, const iterator& rhs)
296 {
297 return lhs.lookup_itr <= rhs.lookup_itr;
298 }
299
300 private:
301
302 iterator(indirect_iterator itr_)
303 : lookup_itr(itr_)
304 {
305 }
306
307 indirect_iterator lookup_itr;
308 };
309
310 //*************************************************************************
312 //*************************************************************************
313 class const_iterator : public etl::iterator<ETL_OR_STD::random_access_iterator_tag, const T>
314 {
315 public:
316
317 friend class iindirect_vector;
318
319 const_iterator()
320 : lookup_itr()
321 {
322 }
323
324 const_iterator(const const_iterator& other)
325 : lookup_itr(other.lookup_itr)
326 {
327 }
328
329 const_iterator(const typename iindirect_vector::iterator& other)
330 : lookup_itr(other.lookup_itr)
331 {
332 }
333
334 const_iterator& operator++()
335 {
336 ++lookup_itr;
337 return *this;
338 }
339
340 const_iterator operator++(int)
341 {
342 const_iterator temp(*this);
343 ++lookup_itr;
344 return temp;
345 }
346
347 const_iterator& operator--()
348 {
349 --lookup_itr;
350 return *this;
351 }
352
353 const_iterator operator--(int)
354 {
355 const_iterator temp(*this);
356 --lookup_itr;
357 return temp;
358 }
359
360 const_iterator operator+=(difference_type n)
361 {
362 lookup_itr += n;
363 return *this;
364 }
365
366 const_iterator operator-=(difference_type n)
367 {
368 lookup_itr -= n;
369 return *this;
370 }
371
372 const_iterator& operator=(const const_iterator& other)
373 {
374 lookup_itr = other.lookup_itr;
375 return *this;
376 }
377
378 const_reference operator*() const
379 {
380 return **lookup_itr;
381 }
382
383 const_pointer operator&() const
384 {
385 return &(**lookup_itr);
386 }
387
388 const_pointer operator->() const
389 {
390 return &(**lookup_itr);
391 }
392
393 indirect_const_iterator indirection() const
394 {
395 return lookup_itr;
396 }
397
398 friend const_iterator operator+(const const_iterator& lhs, difference_type offset)
399 {
400 const_iterator result(lhs);
401 result += offset;
402 return result;
403 }
404
405 friend const_iterator operator-(const const_iterator& lhs, difference_type offset)
406 {
407 const_iterator result(lhs);
408 result -= offset;
409 return result;
410 }
411
412 friend difference_type operator-(const const_iterator& lhs, const const_iterator& rhs)
413 {
414 return lhs.lookup_itr - rhs.lookup_itr;
415 }
416
417 friend bool operator==(const const_iterator& lhs, const const_iterator& rhs)
418 {
419 return lhs.lookup_itr == rhs.lookup_itr;
420 }
421
422 friend bool operator!=(const const_iterator& lhs, const const_iterator& rhs)
423 {
424 return !(lhs == rhs);
425 }
426
427 friend bool operator<(const const_iterator& lhs, const const_iterator& rhs)
428 {
429 return lhs.lookup_itr < rhs.lookup_itr;
430 }
431
432 friend bool operator<=(const const_iterator& lhs, const const_iterator& rhs)
433 {
434 return lhs.lookup_itr <= rhs.lookup_itr;
435 }
436
437 private:
438
439 typedef typename etl::ivector<T*>::const_iterator lookup_itr_t;
440
441 const_iterator(indirect_const_iterator itr_)
442 : lookup_itr(itr_)
443 {
444 }
445
446 indirect_const_iterator lookup_itr;
447 };
448
449 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
450 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
451
452 protected:
453
454 typedef typename etl::parameter_type<T>::type parameter_t;
455
456 public:
457
458 //*********************************************************************
461 //*********************************************************************
463 {
464 return iterator(lookup.begin());
465 }
466
467 //*********************************************************************
470 //*********************************************************************
472 {
473 return const_iterator(lookup.begin());
474 }
475
476 //*********************************************************************
479 //*********************************************************************
481 {
482 return iterator(lookup.end());
483 }
484
485 //*********************************************************************
488 //*********************************************************************
490 {
491 return const_iterator(lookup.end());
492 }
493
494 //*********************************************************************
497 //*********************************************************************
499 {
500 return const_iterator(lookup.begin());
501 }
502
503 //*********************************************************************
506 //*********************************************************************
508 {
509 return const_iterator(lookup.cend());
510 }
511
512 //*********************************************************************
516 //*********************************************************************
517 reverse_iterator rbegin()
518 {
519 return reverse_iterator(end());
520 }
521
522 //*********************************************************************
526 //*********************************************************************
527 const_reverse_iterator rbegin() const
528 {
529 return const_reverse_iterator(end());
530 }
531
532 //*********************************************************************
535 //*********************************************************************
536 reverse_iterator rend()
537 {
538 return reverse_iterator(begin());
539 }
540
541 //*********************************************************************
544 //*********************************************************************
545 const_reverse_iterator rend() const
546 {
547 return const_reverse_iterator(begin());
548 }
549
550 //*********************************************************************
555 //*********************************************************************
556 const_reverse_iterator crbegin() const
557 {
558 return const_reverse_iterator(cend());
559 }
560
561 //*********************************************************************
564 //*********************************************************************
565 const_reverse_iterator crend() const
566 {
567 return const_reverse_iterator(cbegin());
568 }
569
570 //*********************************************************************
575 //*********************************************************************
576 void resize(size_t new_size)
577 {
578 resize(new_size, T());
579 }
580
581 //*********************************************************************
588 //*********************************************************************
589 void resize(size_t new_size, const_reference value)
590 {
591 ETL_ASSERT(new_size <= capacity(), ETL_ERROR(vector_full));
592
593 if (new_size <= capacity())
594 {
595 if (new_size > size())
596 {
597 size_type n = new_size - size();
598
599 while (n-- != 0U)
600 {
601 T* p = storage.create<T>(value);
602 lookup.push_back(p);
603 }
604 }
605 else
606 {
607 size_type n = size() - new_size;
608
609 while (n-- != 0U)
610 {
611 pop_back();
612 }
613 }
614 }
615 }
616
617 //*********************************************************************
622 //*********************************************************************
623 void reserve(size_t n)
624 {
625 (void)n; // Stop 'unused parameter' warning in release mode.
626 ETL_ASSERT(n <= capacity(), ETL_ERROR(vector_out_of_bounds));
627 }
628
629 //*********************************************************************
633 //*********************************************************************
634 reference operator[](size_t i)
635 {
636 return *lookup[i];
637 }
638
639 //*********************************************************************
643 //*********************************************************************
644 const_reference operator[](size_t i) const
645 {
646 return *lookup[i];
647 }
648
649 //*********************************************************************
655 //*********************************************************************
656 reference at(size_t i)
657 {
658 return *lookup.at(i);
659 }
660
661 //*********************************************************************
667 //*********************************************************************
668 const_reference at(size_t i) const
669 {
670 return *lookup.at(i);
671 }
672
673 //*********************************************************************
678 //*********************************************************************
679 reference front()
680 {
681 return *(lookup.front());
682 }
683
684 //*********************************************************************
689 //*********************************************************************
690 const_reference front() const
691 {
692 return *(lookup.front());
693 }
694
695 //*********************************************************************
700 //*********************************************************************
701 reference back()
702 {
703 return *(lookup.back());
704 }
705
706 //*********************************************************************
711 //*********************************************************************
712 const_reference back() const
713 {
714 return *(lookup.back());
715 }
716
717 //*********************************************************************
725 //*********************************************************************
726 template <typename TIterator>
727 void assign(TIterator first, TIterator last)
728 {
729 ETL_STATIC_ASSERT((etl::is_same<typename etl::remove_cv<T>::type,
730 typename etl::remove_cv< typename etl::iterator_traits< TIterator>::value_type>::type>::value),
731 "Iterator type does not match container type");
732
733#if ETL_IS_DEBUG_BUILD
734 difference_type d = etl::distance(first, last);
735 ETL_ASSERT(static_cast<size_t>(d) <= capacity(), ETL_ERROR(vector_full));
736#endif
737
738 initialise();
739
740 while (first != last)
741 {
742 T* p = storage.create<T>(*first);
743 lookup.push_back(p);
744 ++first;
745 }
746 }
747
748 //*********************************************************************
754 //*********************************************************************
755 void assign(size_t n, parameter_t value)
756 {
757 ETL_ASSERT(n <= capacity(), ETL_ERROR(vector_full));
758
759 initialise();
760
761 while (n-- != 0U)
762 {
763 T* p = storage.create<T>(value);
764 lookup.push_back(p);
765 }
766 }
767
768 //*************************************************************************
770 //*************************************************************************
771 void clear()
772 {
773 initialise();
774 }
775
776 //*************************************************************************
778 //*************************************************************************
779 void fill(const T& value)
780 {
781 etl::fill(begin(), end(), value);
782 }
783
784 //*********************************************************************
789 //*********************************************************************
790 void push_back(const_reference value)
791 {
792 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(vector_full));
793
794 T* p = storage.create<T>(value);
795 lookup.push_back(p);
796 }
797
798#if ETL_USING_CPP11
799 //*********************************************************************
804 //*********************************************************************
805 void push_back(rvalue_reference value)
806 {
807 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(vector_full));
808
809 T* p = storage.create<T>(etl::move(value));
810 lookup.push_back(p);
811 }
812#endif
813
814#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VECTOR_FORCE_CPP03_IMPLEMENTATION)
815 //*********************************************************************
820 //*********************************************************************
821 template <typename... Args>
822 reference emplace_back(Args&&... args)
823 {
824 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
825
826 T* p = storage.create<T>(etl::forward<Args>(args)...);
827 lookup.push_back(p);
828 return back();
829 }
830#else
831 //*********************************************************************
836 //*********************************************************************
837 reference emplace_back()
838 {
839 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
840
841 T* p = storage.create<T>();
842 lookup.push_back(p);
843 return back();
844 }
845
846 //*********************************************************************
851 //*********************************************************************
852 template <typename T1>
853 reference emplace_back(const T1& value1)
854 {
855 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
856
857 T* p = storage.create<T>(value1);
858 lookup.push_back(p);
859 return back();
860 }
861
862 //*********************************************************************
867 //*********************************************************************
868 template <typename T1, typename T2>
869 reference emplace_back(const T1& value1, const T2& value2)
870 {
871 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
872
873 T* p = storage.create<T>(value1, value2);
874 lookup.push_back(p);
875 return back();
876 }
877
878 //*********************************************************************
883 //*********************************************************************
884 template <typename T1, typename T2, typename T3>
885 reference emplace_back(const T1& value1, const T2& value2, const T3& value3)
886 {
887 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
888
889 T* p = storage.create<T>(value1, value2, value3);
890 lookup.push_back(p);
891 return back();
892 }
893
894 //*********************************************************************
899 //*********************************************************************
900 template <typename T1, typename T2, typename T3, typename T4>
901 reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
902 {
903 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
904
905 T* p = storage.create<T>(value1, value2, value3, value4);
906 lookup.push_back(p);
907 return back();
908 }
909#endif
910
911 //*************************************************************************
913 //*************************************************************************
914 void pop_back()
915 {
916 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(vector_empty));
917
918 reference object = back();
919 storage.destroy<T>(etl::addressof(object));
920 lookup.pop_back();
921 }
922
923 //*********************************************************************
929 //*********************************************************************
930 iterator insert(const_iterator position, const_reference value)
931 {
932 ETL_ASSERT(size() != capacity(), ETL_ERROR(vector_full));
933 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
934
935 T* p = storage.create<T>(value);
936 position = iterator(lookup.insert(position.lookup_itr, p));
937
938 return to_iterator(position);
939 }
940
941#if ETL_USING_CPP11
942 //*********************************************************************
948 //*********************************************************************
949 iterator insert(const_iterator position, rvalue_reference value)
950 {
951 ETL_ASSERT(size() != capacity(), ETL_ERROR(vector_full));
952 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
953
954 T* p = storage.create<T>(etl::move(value));
955 position = iterator(lookup.insert(position.lookup_itr, p));
956
957 return to_iterator(position);
958 }
959#endif
960
961 //*************************************************************************
963 //*************************************************************************
964#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VECTOR_FORCE_CPP03_IMPLEMENTATION)
965 template <typename... Args>
966 iterator emplace(const_iterator position, Args&&... args)
967 {
968 ETL_ASSERT(!full(), ETL_ERROR(vector_full));
969 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
970
971 T* p = storage.create<T>(etl::forward<Args>(args)...);
972 position = iterator(lookup.insert(position.lookup_itr, p));
973
974 return to_iterator(position);
975 }
976#else
978 {
979 ETL_ASSERT(!full(), ETL_ERROR(vector_full));
980 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
981
982 T* p = storage.create<T>();
983 position = iterator(lookup.insert(position.lookup_itr, p));
984
985 return to_iterator(position);
986 }
987
988 template <typename T1>
989 iterator emplace(const_iterator position, const T1& value1)
990 {
991 ETL_ASSERT(!full(), ETL_ERROR(vector_full));
992 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
993
994 T* p = storage.create<T>(value1);
995 position = iterator(lookup.insert(position.lookup_itr, p));
996
997 return to_iterator(position);
998 }
999
1000 template <typename T1, typename T2>
1001 iterator emplace(const_iterator position, const T1& value1, const T2& value2)
1002 {
1003 ETL_ASSERT(!full(), ETL_ERROR(vector_full));
1004 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
1005
1006 T* p = storage.create<T>(value1, value2);
1007 position = iterator(lookup.insert(position.lookup_itr, p));
1008
1009 return to_iterator(position);
1010 }
1011
1012 template <typename T1, typename T2, typename T3>
1013 iterator emplace(const_iterator position, const T1& value1, const T2& value2, const T3& value3)
1014 {
1015 ETL_ASSERT(!full(), ETL_ERROR(vector_full));
1016 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
1017
1018 T* p = storage.create<T>(value1, value2, value3);
1019 position = iterator(lookup.insert(position.lookup_itr, p));
1020
1021 return to_iterator(position);
1022 }
1023
1024 template <typename T1, typename T2, typename T3, typename T4>
1025 iterator emplace(const_iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
1026 {
1027 ETL_ASSERT(!full(), ETL_ERROR(vector_full));
1028 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
1029
1030 T* p = storage.create<T>(value1, value2, value3, value4);
1031 position = iterator(lookup.insert(position.lookup_itr, p));
1032
1033 return to_iterator(position);
1034 }
1035#endif
1036
1037 //*********************************************************************
1044 //*********************************************************************
1045 iterator insert(const_iterator position, size_t n, parameter_t value)
1046 {
1047 ETL_ASSERT((size() + n) <= capacity(), ETL_ERROR(vector_full));
1048 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
1049
1050 iterator position_ = to_iterator(position);
1051
1052 // Make space for the new lookup pointers.
1053 typename etl::ivector<T*>::iterator lookup_itr = position_.lookup_itr;
1054 lookup.insert(lookup_itr, n, ETL_NULLPTR);
1055
1056 while (n-- != 0U)
1057 {
1058 T* p = storage.create<T>(value);
1059 *lookup_itr++ = p;
1060 }
1061
1062 return position_;
1063 }
1064
1065 //*********************************************************************
1072 //*********************************************************************
1073 template <class TIterator>
1074 iterator insert(const_iterator position, TIterator first, TIterator last)
1075 {
1076 size_t count = size_t(etl::distance(first, last));
1077
1078 ETL_ASSERT((size() + count) <= capacity(), ETL_ERROR(vector_full));
1079 ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
1080
1081 // Make space for the new lookup pointers.
1082 typename etl::ivector<T*>::iterator lookup_itr = to_iterator(position).lookup_itr;
1083 lookup.insert(lookup_itr, count, ETL_NULLPTR);
1084
1085 while (first != last)
1086 {
1087 T* p = storage.create<T>(*first);
1088 *lookup_itr++ = p;
1089 ++first;
1090 }
1091
1092 return to_iterator(position);
1093 }
1094
1095 //*********************************************************************
1100 //*********************************************************************
1102 {
1103 ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(vector_out_of_bounds));
1104
1105 storage.destroy<T>(etl::addressof(*i_element));
1106
1107 return iterator(lookup.erase(i_element.lookup_itr));
1108 }
1109
1110 //*********************************************************************
1115 //*********************************************************************
1117 {
1118 ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(vector_out_of_bounds));
1119
1120 storage.destroy<T>(etl::addressof(*i_element));
1121
1122 return iterator(lookup.erase(i_element.lookup_itr));
1123 }
1124
1125 //*********************************************************************
1133 //*********************************************************************
1135 {
1136 ETL_ASSERT_CHECK_EXTRA(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(vector_out_of_bounds));
1137
1138 iterator element = to_iterator(first);
1139
1140 while (element != last)
1141 {
1142 storage.destroy<T>(etl::addressof(*element));
1143 ++element;
1144 }
1145
1146 lookup.erase(first.lookup_itr, last.lookup_itr);
1147
1148 return to_iterator(last);
1149 }
1150
1151 //*************************************************************************
1153 //*************************************************************************
1155 {
1156 if (&rhs != this)
1157 {
1158 assign(rhs.cbegin(), rhs.cend());
1159 }
1160
1161 return *this;
1162 }
1163
1164#if ETL_USING_CPP11
1165 //*************************************************************************
1167 //*************************************************************************
1169 {
1170 if (&rhs != this)
1171 {
1172 clear();
1173 iterator itr = rhs.begin();
1174 while (itr != rhs.end())
1175 {
1176 push_back(etl::move(*itr));
1177 ++itr;
1178 }
1179
1180 rhs.initialise();
1181 }
1182
1183 return *this;
1184 }
1185#endif
1186
1187 //*************************************************************************
1190 //*************************************************************************
1191 size_type size() const
1192 {
1193 return lookup.size();
1194 }
1195
1196 //*************************************************************************
1199 //*************************************************************************
1200 size_type capacity() const
1201 {
1202 return lookup.capacity();
1203 }
1204
1205 //*************************************************************************
1208 //*************************************************************************
1209 bool empty() const
1210 {
1211 return lookup.empty();
1212 }
1213
1214 //*************************************************************************
1217 //*************************************************************************
1218 bool full() const
1219 {
1220 return lookup.full();
1221 }
1222
1223 //*************************************************************************
1226 //*************************************************************************
1227 size_type max_size() const
1228 {
1229 return lookup.max_size();
1230 }
1231
1232 //*************************************************************************
1235 //*************************************************************************
1236 size_type available() const
1237 {
1238 return lookup.available();
1239 }
1240
1241 protected:
1242
1243 //*********************************************************************
1245 //*********************************************************************
1247 : lookup(lookup_)
1248 , storage(storage_)
1249 {
1250 }
1251
1252 //*********************************************************************
1254 //*********************************************************************
1256 {
1257 if ETL_IF_CONSTEXPR (etl::is_trivially_destructible<T>::value)
1258 {
1259 storage.release_all();
1260 }
1261 else
1262 {
1263 iterator itr = begin();
1264
1265 while (itr != end())
1266 {
1267 storage.destroy<T>(etl::addressof(*itr));
1268 ++itr;
1269 }
1270 }
1271
1272 lookup.clear();
1273 }
1274
1275#if ETL_USING_CPP11
1276 //*********************************************************************
1278 //*********************************************************************
1279 void move_container(iindirect_vector&& other)
1280 {
1281 if (this != &other)
1282 {
1283 initialise();
1284
1285 typename iindirect_vector<T>::iterator itr = other.begin();
1286
1287 while (itr != other.end())
1288 {
1289 push_back(etl::move(*itr));
1290 ++itr;
1291 }
1292
1293 other.initialise();
1294 }
1295 }
1296#endif
1297
1298 etl::ivector<T*>& lookup;
1299 etl::ipool& storage;
1300
1301 private:
1302
1303 // Disable copy construction.
1304 iindirect_vector(const iindirect_vector&) ETL_DELETE;
1305
1306 //*************************************************************************
1308 //*************************************************************************
1309#if defined(ETL_POLYMORPHIC_INDIRECT_VECTOR) || defined(ETL_POLYMORPHIC_CONTAINERS)
1310
1311 public:
1312
1313 virtual
1314#else
1315
1316 protected:
1317#endif
1319 {
1320 }
1321
1322 protected:
1323
1324 //*************************************************************************
1326 //*************************************************************************
1328 {
1329 return iterator(const_cast<indirect_iterator>(itr.lookup_itr));
1330 }
1331 };
1332
1333 //***************************************************************************
1339 //***************************************************************************
1340 template <typename T>
1342 {
1343 return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
1344 }
1345
1346 //***************************************************************************
1352 //***************************************************************************
1353 template <typename T>
1355 {
1356 return !(lhs == rhs);
1357 }
1358
1359 //***************************************************************************
1365 //***************************************************************************
1366 template <typename T>
1368 {
1369 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
1370 }
1371
1372 //***************************************************************************
1379 //***************************************************************************
1380 template <typename T>
1382 {
1383 return (rhs < lhs);
1384 }
1385
1386 //***************************************************************************
1393 //***************************************************************************
1394 template <typename T>
1396 {
1397 return !(lhs > rhs);
1398 }
1399
1400 //***************************************************************************
1407 //***************************************************************************
1408 template <typename T>
1410 {
1411 return !(lhs < rhs);
1412 }
1413
1414 //***************************************************************************
1419 //***************************************************************************
1420 template <typename T, const size_t MAX_SIZE_>
1422 {
1423 public:
1424
1425 ETL_STATIC_ASSERT((MAX_SIZE_ > 0U), "Zero capacity etl::indirect_vector is not valid");
1426
1427 static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
1428
1429 //*************************************************************************
1431 //*************************************************************************
1433 : etl::iindirect_vector<T>(lookup_vector, storage_pool)
1434 {
1435 }
1436
1437 //*************************************************************************
1440 //*************************************************************************
1441 explicit indirect_vector(size_t initial_size)
1442 : etl::iindirect_vector<T>(lookup_vector, storage_pool)
1443 {
1444 this->resize(initial_size);
1445 }
1446
1447 //*************************************************************************
1451 //*************************************************************************
1452 indirect_vector(size_t initial_size, typename etl::iindirect_vector<T>::parameter_t value)
1453 : etl::iindirect_vector<T>(lookup_vector, storage_pool)
1454 {
1455 this->resize(initial_size, value);
1456 }
1457
1458 //*************************************************************************
1463 //*************************************************************************
1464 template <typename TIterator>
1465 indirect_vector(TIterator first, TIterator last)
1466 : etl::iindirect_vector<T>(lookup_vector, storage_pool)
1467 {
1468 this->assign(first, last);
1469 }
1470
1471#if ETL_HAS_INITIALIZER_LIST
1472 //*************************************************************************
1474 //*************************************************************************
1475 indirect_vector(std::initializer_list<T> init)
1476 : etl::iindirect_vector<T>(lookup_vector, storage_pool)
1477 {
1478 this->assign(init.begin(), init.end());
1479 }
1480#endif
1481
1482 //*************************************************************************
1484 //*************************************************************************
1486 : etl::iindirect_vector<T>(lookup_vector, storage_pool)
1487 {
1488 this->assign(other.begin(), other.end());
1489 }
1490
1491 //*************************************************************************
1493 //*************************************************************************
1495 {
1496 if (&rhs != this)
1497 {
1498 this->assign(rhs.cbegin(), rhs.cend());
1499 }
1500
1501 return *this;
1502 }
1503
1504#if ETL_USING_CPP11
1505 //*************************************************************************
1507 //*************************************************************************
1509 : etl::iindirect_vector<T>(lookup_vector, storage_pool)
1510 {
1511 this->move_container(etl::move(other));
1512 }
1513
1514 //*************************************************************************
1516 //*************************************************************************
1518 {
1519 this->move_container(etl::move(rhs));
1520
1521 return *this;
1522 }
1523#endif
1524
1525 //*************************************************************************
1527 //*************************************************************************
1529 {
1530 this->clear();
1531 }
1532
1533 private:
1534
1535 etl::vector<T*, MAX_SIZE> lookup_vector;
1536 etl::pool<T, MAX_SIZE> storage_pool;
1537 };
1538
1539 template <typename T, const size_t MAX_SIZE_>
1540 ETL_CONSTANT size_t indirect_vector<T, MAX_SIZE_>::MAX_SIZE;
1541
1542 //*************************************************************************
1544 //*************************************************************************
1545#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
1546 template <typename T, typename... Ts>
1547 indirect_vector(T, Ts...) -> indirect_vector<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 1U + sizeof...(Ts)>;
1548#endif
1549
1550 //*************************************************************************
1552 //*************************************************************************
1553#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
1554 template <typename... T>
1555 constexpr auto make_indirect_vector(T&&... t) -> etl::indirect_vector<typename etl::common_type_t<T...>, sizeof...(T)>
1556 {
1557 return {etl::forward<T>(t)...};
1558 }
1559#endif
1560
1561 //***************************************************************************
1566 //***************************************************************************
1567 template <typename T>
1569 {
1570 public:
1571
1572 //*************************************************************************
1574 //*************************************************************************
1576 : etl::iindirect_vector<T>(lookup_, pool_)
1577 {
1578 ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
1579 }
1580
1581 //*************************************************************************
1584 //*************************************************************************
1585 explicit indirect_vector_ext(size_t initial_size, etl::ivector<T*>& lookup_, etl::ipool& pool_)
1586 : etl::iindirect_vector<T>(lookup_, pool_)
1587 {
1588 ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
1589 this->resize(initial_size);
1590 }
1591
1592 //*************************************************************************
1596 //*************************************************************************
1597 indirect_vector_ext(size_t initial_size, typename etl::iindirect_vector<T>::parameter_t value, etl::ivector<T*>& lookup_, etl::ipool& pool_)
1598 : etl::iindirect_vector<T>(lookup_, pool_)
1599 {
1600 ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
1601 this->resize(initial_size, value);
1602 }
1603
1604 //*************************************************************************
1609 //*************************************************************************
1610 template <typename TIterator>
1611 indirect_vector_ext(TIterator first, TIterator last, etl::ivector<T*>& lookup_, etl::ipool& pool_)
1612 : etl::iindirect_vector<T>(lookup_, pool_)
1613 {
1614 ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
1615 this->assign(first, last);
1616 }
1617
1618#if ETL_HAS_INITIALIZER_LIST
1619 //*************************************************************************
1621 //*************************************************************************
1622 indirect_vector_ext(std::initializer_list<T> init, etl::ivector<T*>& lookup_, etl::ipool& pool_)
1623 : etl::iindirect_vector<T>(lookup_, pool_)
1624 {
1625 ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
1626 this->assign(init.begin(), init.end());
1627 }
1628#endif
1629
1630 //*************************************************************************
1632 //*************************************************************************
1634 : etl::iindirect_vector<T>(lookup_, pool_)
1635 {
1636 ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
1637 this->assign(other.begin(), other.end());
1638 }
1639
1640 //*************************************************************************
1642 //*************************************************************************
1644
1645 //*************************************************************************
1647 //*************************************************************************
1649 {
1650 if (&rhs != this)
1651 {
1652 this->assign(rhs.cbegin(), rhs.cend());
1653 }
1654
1655 return *this;
1656 }
1657
1658#if ETL_USING_CPP11
1659 //*************************************************************************
1661 //*************************************************************************
1663 : etl::iindirect_vector<T>(lookup_, pool_)
1664 {
1665 ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
1666 this->move_container(etl::move(other));
1667 }
1668
1669 //*************************************************************************
1671 //*************************************************************************
1672 indirect_vector_ext(indirect_vector_ext&& other) ETL_DELETE;
1673
1674 //*************************************************************************
1676 //*************************************************************************
1678 {
1679 this->move_container(etl::move(rhs));
1680
1681 return *this;
1682 }
1683#endif
1684
1685 //*************************************************************************
1687 //*************************************************************************
1689 {
1690 this->clear();
1691 }
1692 };
1693} // namespace etl
1694
1695#endif
const_iterator.
Definition indirect_vector.h:314
iterator.
Definition indirect_vector.h:176
ETL_CONSTEXPR14 bool operator!=(const etl::bitset< Active_Bits, TElement > &lhs, const etl::bitset< Active_Bits, TElement > &rhs) ETL_NOEXCEPT
Definition bitset_new.h:2529
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
reference at(size_t i)
Definition indirect_vector.h:656
const_reverse_iterator crend() const
Definition indirect_vector.h:565
void resize(size_t new_size)
Definition indirect_vector.h:576
iterator to_iterator(const_iterator itr) const
Convert from const_iterator to iterator.
Definition indirect_vector.h:1327
void clear()
Clears the indirect_vector.
Definition indirect_vector.h:771
indirect_vector_ext & operator=(const indirect_vector_ext &rhs)
Assignment operator.
Definition indirect_vector.h:1648
indirect_vector_ext(size_t initial_size, typename etl::iindirect_vector< T >::parameter_t value, etl::ivector< T * > &lookup_, etl::ipool &pool_)
Definition indirect_vector.h:1597
~indirect_vector()
Destructor.
Definition indirect_vector.h:1528
void assign(TIterator first, TIterator last)
Definition indirect_vector.h:727
size_type available() const
Definition indirect_vector.h:1236
const_reference operator[](size_t i) const
Definition indirect_vector.h:644
indirect_vector_ext(const indirect_vector_ext &other) ETL_DELETE
Copy constructor (Deleted).
reference back()
Definition indirect_vector.h:701
iindirect_vector & operator=(const iindirect_vector &rhs)
Assignment operator.
Definition indirect_vector.h:1154
iterator end()
Definition indirect_vector.h:480
const_iterator end() const
Definition indirect_vector.h:489
indirect_vector_ext(size_t initial_size, etl::ivector< T * > &lookup_, etl::ipool &pool_)
Definition indirect_vector.h:1585
bool empty() const
Definition indirect_vector.h:1209
indirect_vector(size_t initial_size, typename etl::iindirect_vector< T >::parameter_t value)
Definition indirect_vector.h:1452
reference emplace_back(const T1 &value1, const T2 &value2, const T3 &value3)
Definition indirect_vector.h:885
reverse_iterator rend()
Definition indirect_vector.h:536
indirect_vector_ext(const indirect_vector_ext &other, etl::ivector< T * > &lookup_, etl::ipool &pool_)
Construct a copy.
Definition indirect_vector.h:1633
reference emplace_back(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition indirect_vector.h:901
iterator erase(const_iterator i_element)
Definition indirect_vector.h:1116
void reserve(size_t n)
Definition indirect_vector.h:623
void pop_back()
Removes an element from the end of the indirect_vector.
Definition indirect_vector.h:914
bool full() const
Definition indirect_vector.h:1218
size_type size() const
Definition indirect_vector.h:1191
const_iterator cend() const
Definition indirect_vector.h:507
void assign(size_t n, parameter_t value)
Definition indirect_vector.h:755
indirect_vector(const indirect_vector &other)
Copy constructor.
Definition indirect_vector.h:1485
const_iterator cbegin() const
Definition indirect_vector.h:498
const_reference back() const
Definition indirect_vector.h:712
const_reference front() const
Definition indirect_vector.h:690
indirect_vector_ext(etl::ivector< T * > &lookup_, etl::ipool &pool_)
Constructor.
Definition indirect_vector.h:1575
indirect_vector(size_t initial_size)
Definition indirect_vector.h:1441
~iindirect_vector()
Destructor.
Definition indirect_vector.h:1318
indirect_vector()
Constructor.
Definition indirect_vector.h:1432
size_type max_size() const
Definition indirect_vector.h:1227
const_iterator begin() const
Definition indirect_vector.h:471
void initialise()
Initialise the indirect_vector.
Definition indirect_vector.h:1255
~indirect_vector_ext()
Destructor.
Definition indirect_vector.h:1688
const_reference at(size_t i) const
Definition indirect_vector.h:668
reference emplace_back(const T1 &value1, const T2 &value2)
Definition indirect_vector.h:869
iterator begin()
Definition indirect_vector.h:462
void fill(const T &value)
Fills the buffer.
Definition indirect_vector.h:779
iterator insert(const_iterator position, TIterator first, TIterator last)
Definition indirect_vector.h:1074
iterator emplace(const_iterator position)
Emplaces a value to the vector at the specified position.
Definition indirect_vector.h:977
const_reverse_iterator rend() const
Definition indirect_vector.h:545
const_reverse_iterator rbegin() const
Definition indirect_vector.h:527
void resize(size_t new_size, const_reference value)
Definition indirect_vector.h:589
iterator erase(iterator i_element)
Definition indirect_vector.h:1101
indirect_vector(TIterator first, TIterator last)
Definition indirect_vector.h:1465
reverse_iterator rbegin()
Definition indirect_vector.h:517
const_reverse_iterator crbegin() const
Definition indirect_vector.h:556
indirect_vector & operator=(const indirect_vector &rhs)
Assignment operator.
Definition indirect_vector.h:1494
iterator erase(const_iterator first, const_iterator last)
Definition indirect_vector.h:1134
reference emplace_back(const T1 &value1)
Definition indirect_vector.h:853
reference front()
Definition indirect_vector.h:679
indirect_vector_ext(TIterator first, TIterator last, etl::ivector< T * > &lookup_, etl::ipool &pool_)
Definition indirect_vector.h:1611
reference emplace_back()
Definition indirect_vector.h:837
size_type capacity() const
Definition indirect_vector.h:1200
iindirect_vector(etl::ivector< T * > &lookup_, etl::ipool &storage_)
Constructor.
Definition indirect_vector.h:1246
reference operator[](size_t i)
Definition indirect_vector.h:634
void push_back(const_reference value)
Definition indirect_vector.h:790
iterator insert(const_iterator position, const_reference value)
Definition indirect_vector.h:930
iterator insert(const_iterator position, size_t n, parameter_t value)
Definition indirect_vector.h:1045
Definition indirect_vector.h:74
Definition indirect_vector.h:1422
Template deduction guides.
Definition indirect_vector.h:1569
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
size_t capacity() const
Returns the maximum number of items in the pool.
Definition ipool.h:506
T * create()
Definition ipool.h:350
Definition ipool.h:109
Definition pool.h:54
void push_back(parameter_t value)
Definition ivectorpointer.h:354
size_type capacity() const
Definition vector_base.h:131
iterator insert(const_iterator position, parameter_t value)
Definition ivectorpointer.h:401
Definition indirect_vector.h:57
Definition vector.h:71
Definition vector.h:1277
Definition vector_base.h:80
Definition vector_base.h:66
Definition vector_base.h:94
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1081
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1133
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1147
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1093
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1106
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1120
iterator
Definition iterator.h:424
etl::conditional< etl::is_fundamental< T >::value||etl::is_pointer< T >::value, T, constT & >::type type
By default fundamental and pointer types are passed by value.
Definition parameter_type.h:46
remove_cv
Definition type_traits.h:325