Embedded Template Library 1.0
Loading...
Searching...
No Matches
memory.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) 2017 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_MEMORY_INCLUDED
32#define ETL_MEMORY_INCLUDED
33
34#include "platform.h"
35#include "algorithm.h"
36#include "type_traits.h"
37#include "iterator.h"
38#include "utility.h"
39#include "nullptr.h"
40#include "alignment.h"
41#include "placement_new.h"
42
43#include "private/addressof.h"
44
45#include <assert.h>
46#include <string.h>
47
48#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
49 #include <memory>
50#endif
51
54
55namespace etl
56{
57 //*****************************************************************************
60 //*****************************************************************************
61 template <typename T>
62 ETL_CONSTEXPR T* to_address(T* p)
63 {
64 return p;
65 }
66
67 //*****************************************************************************
71 //*****************************************************************************
72 template <typename Iterator>
73 ETL_CONSTEXPR typename Iterator::pointer to_address(const Iterator& itr)
74 {
75 return etl::to_address(itr.operator->());
76 }
77
78#if ETL_USING_STL
79 //*****************************************************************************
84 //*****************************************************************************
85 template <typename TOutputIterator, typename T>
87 {
88 std::uninitialized_fill(o_begin, o_end, value);
89
90 return o_end;
91 }
92
93 //*****************************************************************************
98 //*****************************************************************************
99 template <typename TOutputIterator, typename T, typename TCounter>
101 {
102 count += int32_t(etl::distance(o_begin, o_end));
103
104 std::uninitialized_fill(o_begin, o_end, value);
105
106 return o_end;
107 }
108#else
109 //*****************************************************************************
113 //*****************************************************************************
114 template <typename TOutputIterator, typename T>
116 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
117 {
118 etl::fill(o_begin, o_end, value);
119
120 return o_end;
121 }
122
123 //*****************************************************************************
127 //*****************************************************************************
128 template <typename TOutputIterator, typename T>
130 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
131 {
132 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
133
134 while (o_begin != o_end)
135 {
136 ::new (static_cast<void*>(etl::to_address(o_begin))) value_type(value);
137 ++o_begin;
138 }
139
140 return o_end;
141 }
142
143 //*****************************************************************************
148 //*****************************************************************************
149 template <typename TOutputIterator, typename T, typename TCounter>
151 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
152 {
153 count += int32_t(etl::distance(o_begin, o_end));
154
155 etl::fill(o_begin, o_end, value);
156
157 return o_end;
158 }
159
160 //*****************************************************************************
165 //*****************************************************************************
166 template <typename TOutputIterator, typename T, typename TCounter>
168 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
169 {
170 count += int32_t(etl::distance(o_begin, o_end));
171
172 etl::uninitialized_fill(o_begin, o_end, value);
173
174 return o_end;
175 }
176#endif
177
178#if ETL_USING_STL && ETL_USING_CPP11
179 //*****************************************************************************
183 //*****************************************************************************
184 template <typename TOutputIterator, typename TSize, typename T>
185 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value)
186 {
187 return std::uninitialized_fill_n(o_begin, n, value);
188 }
189
190 //*****************************************************************************
195 //*****************************************************************************
196 template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
197 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count)
198 {
199 count += n;
200
201 return std::uninitialized_fill_n(o_begin, n, value);
202 }
203#else
204 //*****************************************************************************
208 //*****************************************************************************
209 template <typename TOutputIterator, typename TSize, typename T>
214
215 //*****************************************************************************
220 //*****************************************************************************
221 template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
223 {
224 count += n;
225
226 return etl::uninitialized_fill(o_begin, o_begin + n, value);
227 }
228#endif
229
230#if ETL_USING_STL
231 //*****************************************************************************
235 //*****************************************************************************
236 template <typename TInputIterator, typename TOutputIterator>
241
242 //*****************************************************************************
247 //*****************************************************************************
248 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
250 {
251 count += int32_t(etl::distance(i_begin, i_end));
252
253 return std::uninitialized_copy(i_begin, i_end, o_begin);
254 }
255#else
256 //*****************************************************************************
260 //*****************************************************************************
261 template <typename TInputIterator, typename TOutputIterator>
263 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
264 {
265 return etl::copy(i_begin, i_end, o_begin);
266 }
267
268 //*****************************************************************************
272 //*****************************************************************************
273 template <typename TInputIterator, typename TOutputIterator>
275 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
276 {
277 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
278
279 TOutputIterator o_end = o_begin;
280
281 while (i_begin != i_end)
282 {
283 ::new (static_cast<void*>(etl::to_address(o_end))) value_type(*i_begin);
284 ++i_begin;
285 ++o_end;
286 }
287
288 return o_end;
289 }
290
291 //*****************************************************************************
296 //*****************************************************************************
297 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
299 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
300 {
301 TOutputIterator o_end = etl::copy(i_begin, i_end, o_begin);
302 count += int32_t(etl::distance(i_begin, i_end));
303
304 return o_end;
305 }
306
307 //*****************************************************************************
312 //*****************************************************************************
313 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
315 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
316 {
317 TOutputIterator o_end = etl::uninitialized_copy(i_begin, i_end, o_begin);
318
319 count += int32_t(etl::distance(i_begin, i_end));
320
321 return o_end;
322 }
323#endif
324
325#if ETL_USING_STL && ETL_USING_CPP11
326 //*****************************************************************************
330 //*****************************************************************************
331 template <typename TInputIterator, typename TSize, typename TOutputIterator>
332 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
333 {
334 return std::uninitialized_copy_n(i_begin, n, o_begin);
335 }
336
337 //*****************************************************************************
342 //*****************************************************************************
343 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
344 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
345 {
346 count += n;
347
348 return std::uninitialized_copy_n(i_begin, n, o_begin);
349 }
350#else
351 //*****************************************************************************
355 //*****************************************************************************
356 template <typename TInputIterator, typename TSize, typename TOutputIterator>
361
362 //*****************************************************************************
367 //*****************************************************************************
368 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
375#endif
376
377#if ETL_USING_CPP11
378#if ETL_USING_STL && ETL_USING_CPP17
379 //*****************************************************************************
383 //*****************************************************************************
384 template <typename TInputIterator, typename TOutputIterator>
385 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
386 {
387 return std::uninitialized_move(i_begin, i_end, o_begin);
388 }
389
390 //*****************************************************************************
395 //*****************************************************************************
396 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
397 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
398 {
399 count += int32_t(etl::distance(i_begin, i_end));
400
401 return std::uninitialized_move(i_begin, i_end, o_begin);
402 }
403#else
404 //*****************************************************************************
408 //*****************************************************************************
409 template <typename TInputIterator, typename TOutputIterator>
411 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
412 {
413 return etl::move(i_begin, i_end, o_begin);
414 }
415
416 //*****************************************************************************
420 //*****************************************************************************
421 template <typename TInputIterator, typename TOutputIterator>
423 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
424 {
425 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
426
427 TOutputIterator o_end = o_begin;
428
429 while (i_begin != i_end)
430 {
431 ::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
432 ++i_begin;
433 ++o_end;
434 }
435
436 return o_end;
437 }
438
439 //*****************************************************************************
444 //*****************************************************************************
445 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
447 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
448 {
449 TOutputIterator o_end = etl::move(i_begin, i_end, o_begin);
450 count += int32_t(etl::distance(i_begin, i_end));
451
452 return o_end;
453 }
454
455 //*****************************************************************************
460 //*****************************************************************************
461 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
463 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
464 {
465 TOutputIterator o_end = etl::uninitialized_move(i_begin, i_end, o_begin);
466
467 count += int32_t(etl::distance(i_begin, i_end));
468
469 return o_end;
470 }
471#endif
472#else
473 // C++03
474 //*****************************************************************************
478 //*****************************************************************************
479 template <typename TInputIterator, typename TOutputIterator>
481 {
482 // Move not supported. Defer to copy.
483 return ETL_OR_STD::uninitialized_copy(i_begin, i_end, o_begin);
484 }
485
486 //*****************************************************************************
491 //*****************************************************************************
492 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
494 {
495 count += int32_t(etl::distance(i_begin, i_end));
496
497 // Move not supported. Defer to copy.
498 return ETL_OR_STD::uninitialized_copy(i_begin, i_end, o_begin);
499 }
500#endif
501
502#if ETL_USING_CPP11
503#if ETL_USING_STL && ETL_USING_CPP17
504 //*****************************************************************************
508 //*****************************************************************************
509 template <typename TInputIterator, typename TSize, typename TOutputIterator>
510 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
511 {
512 return std::uninitialized_move(i_begin, i_begin + n, o_begin);
513 }
514
515 //*****************************************************************************
520 //*****************************************************************************
521 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
522 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
523 {
524 count += TCounter(n);
525
526 return std::uninitialized_move(i_begin, i_begin + n, o_begin);
527 }
528#else
529 //*****************************************************************************
533 //*****************************************************************************
534 template <typename TInputIterator, typename TSize, typename TOutputIterator>
536 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
537 {
538 return etl::move(i_begin, i_begin + n, o_begin);
539 }
540
541 //*****************************************************************************
545 //*****************************************************************************
546 template <typename TInputIterator, typename TSize, typename TOutputIterator>
548 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
549 {
550 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
551
552 TOutputIterator o_end = o_begin;
553
554 while (n-- != 0)
555 {
556 ::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
557 ++i_begin;
558 ++o_end;
559 }
560
561 return o_end;
562 }
563
564 //*****************************************************************************
569 //*****************************************************************************
570 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
572 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
573 {
574 TOutputIterator o_end = etl::move(i_begin, i_begin + n, o_begin);
575 count += TCounter(n);
576
577 return o_end;
578 }
579
580 //*****************************************************************************
585 //*****************************************************************************
586 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
588 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
589 {
590 TOutputIterator o_end = etl::uninitialized_move(i_begin, i_begin + n, o_begin);
591
592 count += TCounter(n);
593
594 return o_end;
595 }
596#endif
597#else
598 // C++03
599 //*****************************************************************************
603 //*****************************************************************************
604 template <typename TInputIterator, typename TSize, typename TOutputIterator>
606 {
607 // Move not supported. Defer to copy.
608#if ETL_USING_CPP11
609 return std::uninitialized_copy_n(i_begin, n, o_begin);
610#else
612#endif
613 }
614
615 //*****************************************************************************
620 //*****************************************************************************
621 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
623 {
624 count += TCounter(n);
625
626 // Move not supported. Defer to copy.
627#if ETL_USING_CPP11
628 return std::uninitialized_copy_n(i_begin, n, o_begin);
629#else
631#endif
632 }
633#endif
634
635#if ETL_USING_STL && ETL_USING_CPP17
636 //*****************************************************************************
640 //*****************************************************************************
641 template <typename TOutputIterator>
643 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end)
644 {
645 std::uninitialized_default_construct(o_begin, o_end);
646 }
647
648 //*****************************************************************************
653 //*****************************************************************************
654 template <typename TOutputIterator, typename TCounter>
656 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
657 {
658 count = int32_t(etl::distance(o_begin, o_end));
659
660 std::uninitialized_default_construct(o_begin, o_end);
661 }
662#else
663 //*****************************************************************************
667 //*****************************************************************************
668 template <typename TOutputIterator>
671 {
672 // Do nothing
673 }
674
675 //*****************************************************************************
679 //*****************************************************************************
680 template <typename TOutputIterator>
683 {
684
685 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
686
687 while (o_begin != o_end)
688 {
689 ::new (static_cast<void*>(etl::to_address(o_begin))) value_type;
690 ++o_begin;
691 }
692 }
693
694 //*****************************************************************************
699 //*****************************************************************************
700 template <typename TOutputIterator, typename TCounter>
706
707 //*****************************************************************************
712 //*****************************************************************************
713 template <typename TOutputIterator, typename TCounter>
721#endif
722
723#if ETL_USING_STL && ETL_USING_CPP17
724 //*****************************************************************************
728 //*****************************************************************************
729 template <typename TOutputIterator, typename TSize>
730 TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
731 {
732 return std::uninitialized_default_construct_n(o_begin, n);
733 }
734
735 //*****************************************************************************
740 //*****************************************************************************
741 template <typename TOutputIterator, typename TSize, typename TCounter>
742 TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
743 {
744 count += n;
745
746 return std::uninitialized_default_construct_n(o_begin, n);
747 }
748#else
749 //*****************************************************************************
753 //*****************************************************************************
754 template <typename TOutputIterator, typename TSize>
761
762 //*****************************************************************************
766 //*****************************************************************************
767 template <typename TOutputIterator, typename TSize>
777
778 //*****************************************************************************
783 //*****************************************************************************
784 template <typename TOutputIterator, typename TSize, typename TCounter>
787 {
789
790 count += n;
791
792 return o_end;
793 }
794
795 //*****************************************************************************
800 //*****************************************************************************
801 template <typename TOutputIterator, typename TSize, typename TCounter>
813#endif
814
815#if ETL_USING_STL && ETL_USING_CPP17
816 //*****************************************************************************
820 //*****************************************************************************
821 template <typename TOutputIterator>
822 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
823 {
824 std::uninitialized_value_construct(o_begin, o_end);
825 }
826
827 //*****************************************************************************
832 //*****************************************************************************
833 template <typename TOutputIterator, typename TCounter>
834 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
835 {
836 count += int32_t(etl::distance(o_begin, o_end));
837
838 std::uninitialized_value_construct(o_begin, o_end);
839 }
840#else
841 //*****************************************************************************
845 //*****************************************************************************
846 template <typename TOutputIterator>
849 {
850 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
851
852 etl::fill(o_begin, o_end, value_type());
853 }
854
855 //*****************************************************************************
859 //*****************************************************************************
860 template <typename TOutputIterator>
863 {
864 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
865
866 while (o_begin != o_end)
867 {
868 ::new (static_cast<void*>(etl::to_address(o_begin))) value_type();
869 ++o_begin;
870 }
871 }
872
873 //*****************************************************************************
878 //*****************************************************************************
879 template <typename TOutputIterator, typename TCounter>
886#endif
887
888#if ETL_USING_STL && ETL_USING_CPP17
889 //*****************************************************************************
893 //*****************************************************************************
894 template <typename TOutputIterator, typename TSize>
895 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
896 {
897 return std::uninitialized_value_construct_n(o_begin, n);
898 }
899
900 //*****************************************************************************
905 //*****************************************************************************
906 template <typename TOutputIterator, typename TSize, typename TCounter>
907 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
908 {
909 count += n;
910
911 return std::uninitialized_value_construct_n(o_begin, n);
912 }
913#else
914 //*****************************************************************************
918 //*****************************************************************************
919 template <typename TOutputIterator, typename TSize>
928
929 //*****************************************************************************
934 //*****************************************************************************
935 template <typename TOutputIterator, typename TSize, typename TCounter>
946#endif
947
948#if ETL_USING_STL && ETL_USING_CPP20
949 //*****************************************************************************
953 //*****************************************************************************
954 template <typename T, typename... TArgs>
955 ETL_CONSTEXPR20 T* construct_at(T* p, TArgs&&... args)
956 {
957 return std::construct_at(p, etl::forward<TArgs>(args)...);
958 }
959#elif ETL_USING_CPP11
960 //*****************************************************************************
964 //*****************************************************************************
965 template <typename T, typename... TArgs>
966 T* construct_at(T* p, TArgs&&... args)
967 {
968 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T(etl::forward<TArgs>(args)...);
969 }
970#else
971 //*****************************************************************************
975 //*****************************************************************************
976 template <typename T>
978 {
979 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T();
980 }
981 //*****************************************************************************
985 //*****************************************************************************
986 template <typename T, typename TArg>
987 T* construct_at(T* p, const TArg& arg)
988 {
989 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T(arg);
990 }
991#endif
992
993#if ETL_USING_STL && ETL_USING_CPP20
994 //*****************************************************************************
998//*****************************************************************************
999 template <typename T>
1000 ETL_CONSTEXPR20
1001 void destroy_at(T* p)
1002 {
1003 std::destroy_at(p);
1004 }
1005
1006 //*****************************************************************************
1011 //*****************************************************************************
1012 template <typename T, typename TCounter>
1013 ETL_CONSTEXPR20
1014 void destroy_at(T* p, TCounter& count)
1015 {
1016 --count;
1017 std::destroy_at(p);
1018 }
1019#else
1020 //*****************************************************************************
1024 //*****************************************************************************
1025 template <typename T>
1028 {
1029 }
1030
1031 //*****************************************************************************
1035 //*****************************************************************************
1036 template <typename T>
1039 {
1040 p->~T();
1041 }
1042
1043 //*****************************************************************************
1048 //*****************************************************************************
1049 template <typename T, typename TCounter>
1051 destroy_at(T* /*p*/, TCounter& count)
1052 {
1053 --count;
1054 }
1055
1056 //*****************************************************************************
1061 //*****************************************************************************
1062 template <typename T, typename TCounter>
1065 {
1066 p->~T();
1067 --count;
1068 }
1069#endif
1070
1071#if ETL_USING_STL && ETL_USING_CPP17
1072 //*****************************************************************************
1076 //*****************************************************************************
1077 template <typename TIterator>
1078 void destroy(TIterator i_begin, TIterator i_end)
1079 {
1080 std::destroy(i_begin, i_end);
1081 }
1082
1083 //*****************************************************************************
1088 //*****************************************************************************
1089 template <typename TIterator, typename TCounter>
1090 void destroy(TIterator i_begin, TIterator i_end, TCounter& count)
1091 {
1092 count -= int32_t(etl::distance(i_begin, i_end));
1093
1094 std::destroy(i_begin, i_end);
1095 }
1096#else
1097 //*****************************************************************************
1101 //*****************************************************************************
1102 template <typename TIterator>
1104 destroy(TIterator /*i_begin*/, TIterator /*i_end*/)
1105 {
1106 }
1107
1108 //*****************************************************************************
1112 //*****************************************************************************
1113 template <typename TIterator>
1116 {
1117 while (i_begin != i_end)
1118 {
1120 ++i_begin;
1121 }
1122 }
1123
1124 //*****************************************************************************
1129 //*****************************************************************************
1130 template <typename TIterator, typename TCounter>
1133 {
1134 count -= int32_t(etl::distance(i_begin, i_end));
1135 }
1136
1137 //*****************************************************************************
1142 //*****************************************************************************
1143 template <typename TIterator, typename TCounter>
1146 {
1147 count -= int32_t(etl::distance(i_begin, i_end));
1148
1149 while (i_begin != i_end)
1150 {
1152 ++i_begin;
1153 }
1154 }
1155#endif
1156
1157#if ETL_USING_STL && ETL_USING_CPP17
1158 //*****************************************************************************
1162 //*****************************************************************************
1163 template <typename TIterator, typename TSize>
1164 TIterator destroy_n(TIterator i_begin, TSize n)
1165 {
1166 return std::destroy_n(i_begin, n);
1167 }
1168
1169 //*****************************************************************************
1174 //*****************************************************************************
1175 template <typename TIterator, typename TSize, typename TCounter>
1176 TIterator destroy_n(TIterator i_begin, TSize n, TCounter& count)
1177 {
1178 count -= n;
1179
1180 return std::destroy_n(i_begin, n);
1181 }
1182#else
1183 //*****************************************************************************
1187 //*****************************************************************************
1188 template <typename TIterator, typename TSize>
1191 {
1192 return i_begin + n;
1193 }
1194
1195 //*****************************************************************************
1199 //*****************************************************************************
1200 template <typename TIterator, typename TSize>
1203 {
1204 while (n > 0)
1205 {
1207 ++i_begin;
1208 --n;
1209 }
1210
1211 return i_begin;
1212 }
1213
1214 //*****************************************************************************
1219 //*****************************************************************************
1220 template <typename TIterator, typename TSize, typename TCounter>
1223 {
1224 count -= n;
1225 return i_begin + n;
1226 }
1227
1228 //*****************************************************************************
1233 //*****************************************************************************
1234 template <typename TIterator, typename TSize, typename TCounter>
1237 {
1238 count -= n;
1239
1240 while (n > 0)
1241 {
1243 ++i_begin;
1244 --n;
1245 }
1246
1247 return i_begin;
1248 }
1249#endif
1250
1251 //*****************************************************************************
1256 //*****************************************************************************
1257 template <typename T>
1259 {
1260 //*********************************
1261 ETL_CONSTEXPR default_delete() ETL_NOEXCEPT
1262 {
1263 }
1264
1265 //*********************************
1266 template <typename U>
1267 default_delete(const default_delete<U>&) ETL_NOEXCEPT
1268 {
1269 }
1270
1271 //*********************************
1272 void operator()(T * p) const ETL_NOEXCEPT
1273 {
1274 delete p;
1275 }
1276 };
1277
1278 //*****************************************************************************
1283 //*****************************************************************************
1284 template <typename T>
1286 {
1287 //*********************************
1288 ETL_CONSTEXPR default_delete() ETL_NOEXCEPT
1289 {
1290 }
1291
1292 //*********************************
1293 template <typename U>
1294 default_delete(const default_delete<U>&) ETL_NOEXCEPT
1295 {
1296 }
1297
1298 //*********************************
1299 template <class U>
1300 void operator()(U* p) const
1301 {
1302 delete[] p;
1303 }
1304 };
1305
1306 //*****************************************************************************
1311 //*****************************************************************************
1312 template <typename T, typename TDeleter = etl::default_delete<T> >
1314 {
1315 public:
1316
1317 typedef T element_type;
1318 typedef T* pointer;
1319 typedef T& reference;
1320
1321 //*********************************
1322 ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT
1323 : p(ETL_NULLPTR)
1324 {
1325 }
1326
1327 //*********************************
1328 ETL_CONSTEXPR explicit unique_ptr(pointer p_) ETL_NOEXCEPT
1329 : p(p_)
1330 {
1331 }
1332
1333#if ETL_USING_CPP11
1334 //*********************************
1335 unique_ptr(unique_ptr&& other) ETL_NOEXCEPT
1336 {
1337 if (&other != this)
1338 {
1339 p = other.release();
1340 deleter = etl::move(other.deleter);
1341 }
1342 }
1343#else
1344 //*********************************
1345 unique_ptr(unique_ptr& other) ETL_NOEXCEPT
1346 {
1347 if (&other != this)
1348 {
1349 p = other.release();
1350 deleter = other.deleter;
1351 }
1352 }
1353#endif
1354
1355 //*********************************
1357 TDeleter,
1358 typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
1359 : p(p_)
1360 , deleter(deleter_)
1361 {
1362 }
1363
1364#if ETL_USING_CPP11
1365 //*********************************
1367 : p(p_)
1368 , deleter(etl::move(deleter_))
1369 {
1370 }
1371
1372 template <typename U, typename E>
1373 unique_ptr(unique_ptr<U, E>&& u) ETL_NOEXCEPT
1374 : p(u.release())
1375 , deleter(etl::forward<E>(u.get_deleter()))
1376 {
1377 }
1378#endif
1379
1380 //*********************************
1381 ~unique_ptr()
1382 {
1383 if (p != ETL_NULLPTR)
1384 {
1385 deleter(p);
1386 }
1387 }
1388
1389 //*********************************
1390 ETL_CONSTEXPR pointer get() const ETL_NOEXCEPT
1391 {
1392 return p;
1393 }
1394
1395 //*********************************
1396 TDeleter& get_deleter() ETL_NOEXCEPT
1397 {
1398 return deleter;
1399 }
1400
1401 //*********************************
1402 const TDeleter& get_deleter() const ETL_NOEXCEPT
1403 {
1404 return deleter;
1405 }
1406
1407 //*********************************
1408 pointer release() ETL_NOEXCEPT
1409 {
1410 pointer value = p;
1411 p = ETL_NULLPTR;
1412
1413 return value;
1414 }
1415
1416 //*********************************
1417 void reset(pointer p_ = pointer()) ETL_NOEXCEPT
1418 {
1419 if (p_ == ETL_NULLPTR || p_ != p)
1420 {
1421 pointer value = p;
1422 p = p_;
1423
1424 if (value != ETL_NULLPTR)
1425 {
1426 deleter(value);
1427 }
1428 }
1429 }
1430
1431 //*********************************
1432 void swap(unique_ptr& value) ETL_NOEXCEPT
1433 {
1434 using ETL_OR_STD::swap;
1435
1436 swap(p, value.p);
1437 }
1438
1439 //*********************************
1440 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
1441 {
1442 return (p != ETL_NULLPTR);
1443 }
1444
1445 //*********************************
1446 unique_ptr& operator =(etl::nullptr_t) ETL_NOEXCEPT
1447 {
1448 if (p)
1449 {
1450 reset(ETL_NULLPTR);
1451 }
1452
1453 return *this;
1454 }
1455
1456#if ETL_USING_CPP11
1457 //*********************************
1458 unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT
1459 {
1460 if (&other != this)
1461 {
1462 reset(other.release());
1463 deleter = etl::move(other.deleter);
1464 }
1465
1466 return *this;
1467 }
1468#else
1469 //*********************************
1470 unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT
1471 {
1472 if (&other != this)
1473 {
1474 reset(other.release());
1475 deleter = other.deleter;
1476 }
1477
1478 return *this;
1479 }
1480#endif
1481
1482 //*********************************
1483 ETL_CONSTEXPR reference operator *() const
1484 {
1485 return *get();
1486 }
1487
1488 //*********************************
1489 ETL_CONSTEXPR pointer operator ->() const ETL_NOEXCEPT
1490 {
1491 return get();
1492 }
1493
1494 //*********************************
1495 ETL_CONSTEXPR reference operator [](size_t i) const
1496 {
1497 return p[i];
1498 }
1499
1500 private:
1501
1502 // Deleted.
1503 unique_ptr(const unique_ptr&) ETL_DELETE;
1504 unique_ptr& operator =(const unique_ptr&) ETL_DELETE;
1505
1506 pointer p;
1507 TDeleter deleter;
1508 };
1509
1510 //*****************************************************************************
1515 //*****************************************************************************
1516 template<typename T, typename TDeleter>
1518 {
1519 public:
1520
1521 typedef T element_type;
1522 typedef T* pointer;
1523 typedef T& reference;
1524
1525 //*********************************
1526 ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT
1527 : p(ETL_NULLPTR)
1528 {
1529 }
1530
1531 //*********************************
1532 ETL_CONSTEXPR explicit unique_ptr(pointer p_) ETL_NOEXCEPT
1533 : p(p_)
1534 {
1535 }
1536
1537#if ETL_USING_CPP11
1538 //*********************************
1539 unique_ptr(unique_ptr&& other) ETL_NOEXCEPT
1540 {
1541 if (&other != this)
1542 {
1543 p = other.release();
1544 deleter = etl::move(other.deleter);
1545 }
1546 }
1547#else
1548 //*********************************
1549 unique_ptr(unique_ptr& other) ETL_NOEXCEPT
1550 {
1551 if (&other != this)
1552 {
1553 p = other.release();
1554 deleter = other.deleter;
1555 }
1556 }
1557#endif
1558
1559 //*********************************
1562 TDeleter,
1563 typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
1564 : p(p_)
1565 , deleter(deleter_)
1566 {
1567 }
1568
1569#if ETL_USING_CPP11
1570 //*********************************
1572 : p(p_)
1573 , deleter(etl::move(deleter_))
1574 {
1575 }
1576
1577 template <typename U, typename E>
1578 unique_ptr(unique_ptr<U, E>&& u) ETL_NOEXCEPT
1579 : p(u.release())
1580 , deleter(etl::forward<E>(u.get_deleter()))
1581 {
1582 }
1583#endif
1584
1585 //*********************************
1586 ~unique_ptr()
1587 {
1588 if (p != ETL_NULLPTR)
1589 {
1590 deleter(p);
1591 }
1592 }
1593
1594 //*********************************
1595 ETL_CONSTEXPR pointer get() const ETL_NOEXCEPT
1596 {
1597 return p;
1598 }
1599
1600 //*********************************
1601 TDeleter& get_deleter() ETL_NOEXCEPT
1602 {
1603 return deleter;
1604 }
1605
1606 //*********************************
1607 const TDeleter& get_deleter() const ETL_NOEXCEPT
1608 {
1609 return deleter;
1610 }
1611
1612 //*********************************
1613 pointer release() ETL_NOEXCEPT
1614 {
1615 pointer value = p;
1616 p = ETL_NULLPTR;
1617 return value;
1618 }
1619
1620 //*********************************
1621 void reset(pointer p_) ETL_NOEXCEPT
1622 {
1623 if (p_ != p)
1624 {
1625 pointer value = p;
1626 p = p_;
1627
1628 if (value != ETL_NULLPTR)
1629 {
1630 deleter(value);
1631 }
1632 }
1633 }
1634
1635 void reset(etl::nullptr_t = ETL_NULLPTR) ETL_NOEXCEPT
1636 {
1637 reset(pointer());
1638 }
1639
1640 //*********************************
1641 void swap(unique_ptr& v) ETL_NOEXCEPT
1642 {
1643 using ETL_OR_STD::swap;
1644
1645 swap(p, v.p);
1646 }
1647
1648 //*********************************
1649 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
1650 {
1651 return (p != ETL_NULLPTR);
1652 }
1653
1654 //*********************************
1655 unique_ptr& operator =(etl::nullptr_t) ETL_NOEXCEPT
1656 {
1657 reset(ETL_NULLPTR);
1658
1659 return *this;
1660 }
1661
1662#if ETL_USING_CPP11
1663 //*********************************
1664 unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT
1665 {
1666 if (&other != this)
1667 {
1668 reset(other.release());
1669 deleter = etl::move(other.deleter);
1670 }
1671
1672 return *this;
1673 }
1674#else
1675 //*********************************
1676 unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT
1677 {
1678 if (&other != this)
1679 {
1680 reset(other.release());
1681 deleter = other.deleter;
1682 }
1683
1684 return *this;
1685 }
1686#endif
1687
1688 //*********************************
1689 ETL_CONSTEXPR reference operator *() const
1690 {
1691 return *p;
1692 }
1693
1694 //*********************************
1695 ETL_CONSTEXPR pointer operator ->() const ETL_NOEXCEPT
1696 {
1697 return p;
1698 }
1699
1700 //*********************************
1701 ETL_CONSTEXPR reference operator [](size_t i) const
1702 {
1703 return p[i];
1704 }
1705
1706 private:
1707
1708 // Deleted.
1709 unique_ptr(const unique_ptr&) ETL_DELETE;
1710 unique_ptr& operator =(const unique_ptr&) ETL_DELETE;
1711
1712 pointer p;
1713 TDeleter deleter;
1714 };
1715}
1716
1717//*****************************************************************************
1718// Global functions for unique_ptr
1719//*****************************************************************************
1720template<typename T1, typename TD1, typename T2, typename TD2>
1721bool operator ==(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1722{
1723 return lhs.get() == rhs.get();
1724}
1725
1726//*********************************
1727template<typename T1, typename TD1, typename T2, typename TD2>
1728bool operator <(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1729{
1730 return reinterpret_cast<char*>(lhs.get()) < reinterpret_cast<char*>(rhs.get());
1731}
1732
1733//*********************************
1734template<typename T1, typename TD1, typename T2, typename TD2>
1735bool operator <=(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1736{
1737 return !(rhs < lhs);
1738}
1739
1740//*********************************
1741template<typename T1, typename TD1, typename T2, typename TD2>
1742bool operator >(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1743{
1744 return (rhs < lhs);
1745}
1746
1747//*********************************
1748template<typename T1, typename TD1, typename T2, typename TD2>
1749bool operator >=(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1750{
1751 return !(lhs < rhs);
1752}
1753
1754namespace etl
1755{
1756 //*****************************************************************************
1759 //*****************************************************************************
1760 template <typename T>
1762 create_default_at(T* /*p*/)
1763 {
1764 }
1765
1766 //*****************************************************************************
1769 //*****************************************************************************
1770 template <typename T, typename TCounter>
1772 create_default_at(T* /*p*/, TCounter& count)
1773 {
1774 ++count;
1775 }
1776
1777 //*****************************************************************************
1780 //*****************************************************************************
1781 template <typename T>
1783 create_default_at(T* p)
1784 {
1785 ::new (p) T;
1786 }
1787
1788 //*****************************************************************************
1791 //*****************************************************************************
1792 template <typename T, typename TCounter>
1794 create_default_at(T* p, TCounter& count)
1795 {
1796 ::new (p) T;
1797 ++count;
1798 }
1799
1800 //*****************************************************************************
1803 //*****************************************************************************
1804 template <typename T>
1805 void create_value_at(T* p)
1806 {
1807 ::new (p) T();
1808 }
1809
1810 //*****************************************************************************
1813 //*****************************************************************************
1814 template <typename T, typename TCounter>
1815 void create_value_at(T* p, TCounter& count)
1816 {
1817 ::new (p) T();
1818 ++count;
1819 }
1820
1821 //*****************************************************************************
1824 //*****************************************************************************
1825 template <typename T>
1826 void create_copy_at(T* p, const T& value)
1827 {
1828 ::new (p) T(value);
1829 }
1830
1831#if ETL_USING_CPP11
1832 //*****************************************************************************
1835 //*****************************************************************************
1836 template <typename T>
1837 void create_copy_at(T* p, T&& value)
1838 {
1839 ::new (p) T(etl::move(value));
1840 }
1841#endif
1842
1843 //*****************************************************************************
1846 //*****************************************************************************
1847 template <typename T, typename TCounter>
1848 void create_copy_at(T* p, const T& value, TCounter& count)
1849 {
1850 ::new (p) T(value);
1851 ++count;
1852 }
1853
1854 //*****************************************************************************
1857 //*****************************************************************************
1858 template <typename T>
1859 T& make_default_at(T* p)
1860 {
1861 ::new (p) T();
1862 return *reinterpret_cast<T*>(p);
1863 }
1864
1865 //*****************************************************************************
1868 //*****************************************************************************
1869 template <typename T, typename TCounter>
1870 T& make_default_at(T* p, TCounter& count)
1871 {
1872 ::new (p) T();
1873 ++count;
1874 return *reinterpret_cast<T*>(p);
1875 }
1876
1877 //*****************************************************************************
1880 //*****************************************************************************
1881 template <typename T>
1882 T& make_copy_at(T* p, const T& other)
1883 {
1884 ::new (p) T(other);
1885 return *reinterpret_cast<T*>(p);
1886 }
1887
1888#if ETL_USING_CPP11
1889 //*****************************************************************************
1892 //*****************************************************************************
1893 template <typename T>
1894 T& make_copy_at(T* p, T&& other)
1895 {
1896 ::new (p) T(etl::move(other));
1897 return *reinterpret_cast<T*>(p);
1898 }
1899#endif
1900
1901 //*****************************************************************************
1904 //*****************************************************************************
1905 template <typename T, typename TCounter>
1906 T& make_copy_at(T* p, const T& other, TCounter& count)
1907 {
1908 ::new (p) T(other);
1909 ++count;
1910 return *reinterpret_cast<T*>(p);
1911 }
1912
1913 //*****************************************************************************
1916 //*****************************************************************************
1917 template <typename T, typename TParameter>
1918 T& make_value_at(T* p, const TParameter& value)
1919 {
1920 ::new (p) T(value);
1921 return *reinterpret_cast<T*>(p);
1922 }
1923
1924#if ETL_USING_CPP11
1925 //*****************************************************************************
1928 //*****************************************************************************
1929 template <typename T, typename TParameter>
1930 T& make_value_at(T* p, TParameter&& value)
1931 {
1932 ::new (p) T(etl::move(value));
1933 return *reinterpret_cast<T*>(p);
1934 }
1935#endif
1936
1937 //*****************************************************************************
1940 //*****************************************************************************
1941 template <typename T, typename TParameter, typename TCounter>
1942 T& make_value_at(T* p, const TParameter& value, TCounter& count)
1943 {
1944 ::new (p) T(value);
1945 ++count;
1946 return *reinterpret_cast<T*>(p);
1947 }
1948
1949 //*****************************************************************************
1953 //*****************************************************************************
1954 template <typename T>
1955 struct create_copy
1956 {
1957 void create_copy_at(void* p)
1958 {
1959 new (p) T(static_cast<const T&>(*this));
1960 }
1961
1962 template <typename TCounter>
1963 void create_copy_at(void* p, TCounter& count)
1964 {
1965 new (p) T(static_cast<const T&>(*this));
1966 ++count;
1967 }
1968
1969 T& make_copy_at(void* p)
1970 {
1971 new (p) T(static_cast<const T&>(*this));
1972 return *reinterpret_cast<T*>(p);
1973 }
1974
1975 template <typename TCounter>
1976 T& make_copy_at(void* p, TCounter& count)
1977 {
1978 new (p) T(static_cast<const T&>(*this));
1979 ++count;
1980 return *reinterpret_cast<T*>(p);
1981 }
1982 };
1983
1984 //*****************************************************************************
1989 //*****************************************************************************
1990 inline void memory_clear(volatile char* p, size_t n)
1991 {
1992 while (n--)
1993 {
1994 *p++ = 0;
1995 }
1996 }
1997
1998 //*****************************************************************************
2003 //*****************************************************************************
2004 template <typename T>
2005 void memory_clear(volatile T &object)
2006 {
2007 memory_clear(reinterpret_cast<volatile char*>(&object), sizeof(T));
2008 }
2009
2010 //*****************************************************************************
2016 //*****************************************************************************
2017 template <typename T>
2018 void memory_clear_range(volatile T* begin, size_t n)
2019 {
2020 memory_clear(reinterpret_cast<volatile char*>(begin), n * sizeof(T));
2021 }
2022
2023 //*****************************************************************************
2029 //*****************************************************************************
2030 template <typename T>
2031 void memory_clear_range(volatile T* begin, volatile T* end)
2032 {
2033 const size_t n = static_cast<size_t>(etl::distance(begin, end));
2034
2035 memory_clear_range(begin, n);
2036 }
2037
2038 //*****************************************************************************
2044 //*****************************************************************************
2045 inline void memory_set(volatile char* p, size_t n, char value)
2046 {
2047 while (n--)
2048 {
2049 *p++ = value;
2050 }
2051 }
2052
2053 //*****************************************************************************
2059 //*****************************************************************************
2060 template <typename T>
2061 void memory_set(volatile T &object, const char value)
2062 {
2063 memory_set(reinterpret_cast<volatile char*>(&object), sizeof(T), value);
2064 }
2065
2066 //*****************************************************************************
2073 //*****************************************************************************
2074 template <typename T>
2075 void memory_set_range(volatile T* begin, size_t n, const char value)
2076 {
2077 memory_set(reinterpret_cast<volatile char*>(begin), n * sizeof(T), value);
2078 }
2079
2080 //*****************************************************************************
2087 //*****************************************************************************
2088 template <typename T>
2089 void memory_set_range(volatile T* begin, volatile T* end, const char value)
2090 {
2091 const size_t n = static_cast<size_t>(etl::distance(begin, end));
2092
2093 memory_set_range(begin, n, value);
2094 }
2095
2096 //*****************************************************************************
2102 //*****************************************************************************
2103 template <typename T>
2104 struct wipe_on_destruct
2105 {
2106 ~wipe_on_destruct()
2107 {
2108 memory_clear(static_cast<volatile T&>(*this));
2109 }
2110 };
2111
2112 //***************************************************************************
2115 //***************************************************************************
2116 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2117 class uninitialized_buffer
2118 {
2119 public:
2120
2121 static ETL_CONSTANT size_t Object_Size = VObject_Size;
2122 static ETL_CONSTANT size_t N_Objects = VN_Objects;
2123 static ETL_CONSTANT size_t Alignment = VAlignment;
2124
2126 template <typename T>
2127 operator T& ()
2128 {
2129 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2130 return *reinterpret_cast<T*>(raw);
2131 }
2132
2134 template <typename T>
2135 operator const T& () const
2136 {
2137 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2138 return *reinterpret_cast<const T*>(raw);
2139 }
2140
2142 template <typename T>
2143 operator T* ()
2144 {
2145 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2146 return reinterpret_cast<T*>(raw);
2147 }
2148
2150 template <typename T>
2151 operator const T* () const
2152 {
2153 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2154 return reinterpret_cast<const T*>(raw);
2155 }
2156
2157#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
2158 alignas(VAlignment) char raw[Object_Size * N_Objects];
2159#else
2160 union
2161 {
2162 char raw[VObject_Size * VN_Objects];
2163 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment as VAlignment.
2164 };
2165#endif
2166 };
2167
2168 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2169 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Object_Size;
2170
2171 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2172 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::N_Objects;
2173
2174 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2175 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Alignment;
2176
2177 //***************************************************************************
2180 //***************************************************************************
2181 template <typename T, size_t VN_Objects>
2182 class uninitialized_buffer_of
2183 {
2184 public:
2185
2186 typedef T value_type;
2187 typedef T& reference;
2188 typedef const T& const_reference;
2189 typedef T* pointer;
2190 typedef const T* const_pointer;
2191 typedef T* iterator;
2192 typedef const T* const_iterator;
2193
2194 static ETL_CONSTANT size_t Object_Size = sizeof(T);
2195 static ETL_CONSTANT size_t N_Objects = VN_Objects;
2196 static ETL_CONSTANT size_t Alignment = etl::alignment_of<T>::value;
2197
2199 T& operator [](int i)
2200 {
2201 return reinterpret_cast<T*>(this->raw)[i];
2202 }
2203
2205 const T& operator [](int i) const
2206 {
2207 return reinterpret_cast<const T*>(this->raw)[i];
2208 }
2209
2211 operator T& ()
2212 {
2213 return *reinterpret_cast<T*>(raw);
2214 }
2215
2217 operator const T& () const
2218 {
2219 return *reinterpret_cast<const T*>(raw);
2220 }
2221
2223 operator T* ()
2224
2225 {
2226 return reinterpret_cast<T*>(raw);
2227 }
2228
2230 operator const T* () const
2231 {
2232 return reinterpret_cast<const T*>(raw);
2233 }
2234
2235 T* begin()
2236 {
2237 return reinterpret_cast<T*>(raw);
2238 }
2239
2240 const T* begin() const
2241 {
2242 return reinterpret_cast<const T*>(raw);
2243 }
2244
2245 T* end()
2246 {
2247 return reinterpret_cast<T*>(raw + (sizeof(T) * N_Objects));
2248 }
2249
2250 const T* end() const
2251 {
2252 return reinterpret_cast<const T*>(raw + (sizeof(T) * N_Objects));
2253 }
2254
2255#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
2256 alignas(Alignment) char raw[sizeof(T) * N_Objects];
2257#else
2258 union
2259 {
2260 char raw[sizeof(T) * N_Objects];
2261 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment as Alignment.
2262 };
2263#endif
2264 };
2265
2266 template <typename T, size_t VN_Objects>
2267 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Object_Size;
2268
2269 template <typename T, size_t VN_Objects>
2270 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::N_Objects;
2271
2272 template <typename T, size_t VN_Objects>
2273 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Alignment;
2274
2275#if ETL_USING_CPP11
2276 template <typename T, size_t N_Objects>
2277 using uninitialized_buffer_of_t = typename uninitialized_buffer_of<T, N_Objects>::buffer;
2278#endif
2279
2280 //***************************************************************************
2287 //***************************************************************************
2288 template <typename T>
2290 mem_copy(const T* sb, const T* se, T* db) ETL_NOEXCEPT
2291 {
2292 return reinterpret_cast<T*>(memcpy(reinterpret_cast<void*>(db),
2293 reinterpret_cast<const void*>(sb),
2294 sizeof(typename etl::iterator_traits<T*>::value_type) * static_cast<size_t>(se - sb)));
2295 }
2296
2297 //***************************************************************************
2303 //***************************************************************************
2304 template <typename T>
2306 mem_copy(const T* sb, size_t n, T* db) ETL_NOEXCEPT
2307 {
2308 return reinterpret_cast<T*>(memcpy(reinterpret_cast<void*>(db),
2309 reinterpret_cast<const void*>(sb),
2310 sizeof(typename etl::iterator_traits<T*>::value_type) * n));
2311 }
2312
2313 //***************************************************************************
2319 //***************************************************************************
2320 template <typename T>
2322 mem_move(const T* sb, const T* se, T* db) ETL_NOEXCEPT
2323 {
2324 return reinterpret_cast<T*>(memmove(reinterpret_cast<void*>(db),
2325 reinterpret_cast<const void*>(sb),
2326 sizeof(typename etl::iterator_traits<T*>::value_type) * static_cast<size_t>(se - sb)));
2327 }
2328
2329 //***************************************************************************
2335 //***************************************************************************
2336 template <typename T>
2338 mem_move(const T* sb, size_t n, T* db) ETL_NOEXCEPT
2339 {
2340 return reinterpret_cast<T*>(memmove(reinterpret_cast<void*>(db),
2341 reinterpret_cast<const void*>(sb),
2342 sizeof(typename etl::iterator_traits<T*>::value_type) * n));
2343 }
2344
2345 //***************************************************************************
2353 //***************************************************************************
2354 template <typename T>
2355 ETL_NODISCARD
2357 mem_compare(const T* sb, const T* se, const T* db) ETL_NOEXCEPT
2358 {
2359 return memcmp(reinterpret_cast<const void*>(db),
2360 reinterpret_cast<const void*>(sb),
2361 sizeof(typename etl::iterator_traits<T*>::value_type) * static_cast<size_t>(se - sb));
2362 }
2363
2364 //***************************************************************************
2372 //***************************************************************************
2373 template <typename T>
2374 ETL_NODISCARD
2376 mem_compare(const T* sb, size_t n, const T* db) ETL_NOEXCEPT
2377 {
2378 return memcmp(reinterpret_cast<const void*>(db),
2379 reinterpret_cast<const void*>(sb),
2380 sizeof(typename etl::iterator_traits<T*>::value_type) * n);
2381 }
2382
2383 //***************************************************************************
2389 //***************************************************************************
2390 template <typename TPointer, typename T>
2392 mem_set(TPointer db, const TPointer de, T value) ETL_NOEXCEPT
2393 {
2394 return reinterpret_cast<TPointer>(memset(reinterpret_cast<void*>(db),
2395 static_cast<char>(value),
2396 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(de - db)));
2397 }
2398
2399 //***************************************************************************
2405 //***************************************************************************
2406 template <typename TPointer, typename T>
2408 mem_set(TPointer db, size_t n, T value) ETL_NOEXCEPT
2409 {
2410 return reinterpret_cast<TPointer>(memset(reinterpret_cast<void*>(db),
2411 static_cast<char>(value),
2412 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n));
2413 }
2414
2415 //***************************************************************************
2421 //***************************************************************************
2422 template <typename TPointer, typename T>
2423 ETL_NODISCARD
2425 mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
2426 {
2427 void* result = memchr(reinterpret_cast<void*>(sb),
2428 static_cast<char>(value),
2429 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
2430
2431 return (result == 0U) ? reinterpret_cast<char*>(se) : reinterpret_cast<char*>(result);
2432 }
2433
2434 //***************************************************************************
2440 //***************************************************************************
2441 template <typename TPointer, typename T>
2442 ETL_NODISCARD
2444 mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
2445 {
2446 const void* result = memchr(reinterpret_cast<const void*>(sb),
2447 static_cast<char>(value),
2448 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
2449
2450 return (result == 0U) ? reinterpret_cast<const char*>(se) : reinterpret_cast<const char*>(result);
2451 }
2452
2453 //***************************************************************************
2459 //***************************************************************************
2460 template <typename TPointer, typename T>
2461 ETL_NODISCARD
2463 mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
2464 {
2465 void* result = memchr(reinterpret_cast<void*>(sb),
2466 static_cast<char>(value),
2467 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
2468
2469 return (result == 0U) ? reinterpret_cast<char*>(sb + n) : reinterpret_cast<char*>(result);
2470 }
2471
2472 //***************************************************************************
2478 //***************************************************************************
2479 template <typename TPointer, typename T>
2480 ETL_NODISCARD
2482 mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
2483 {
2484 const void* result = memchr(reinterpret_cast<const void*>(sb),
2485 static_cast<char>(value),
2486 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
2487
2488 return (result == 0U) ? reinterpret_cast<const char*>(sb + n) : reinterpret_cast<const char*>(result);
2489 }
2490
2491#if ETL_USING_CPP11
2492 //*****************************************************************************
2494 //*****************************************************************************
2495 template <typename TObject>
2496 TObject& construct_object_at(void* p, TObject&& other)
2497 {
2498#if ETL_IS_DEBUG_BUILD
2499 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2500#endif
2501
2502 return *etl::construct_at(reinterpret_cast<typename etl::remove_reference<TObject>::type*>(p), etl::forward<TObject>(other));
2503 }
2504
2505 //*****************************************************************************
2507 //*****************************************************************************
2508 template <typename TObject, typename... TArgs>
2509 TObject& construct_object_at(void* p, TArgs&&... args)
2510 {
2511#if ETL_IS_DEBUG_BUILD
2512 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2513#endif
2514
2515 return *etl::construct_at(reinterpret_cast<TObject*>(p), etl::forward<TArgs>(args)...);
2516 }
2517#else
2518 //*****************************************************************************
2520 //*****************************************************************************
2521 template <typename TObject>
2522 TObject& construct_object_at(void* p)
2523 {
2524#if ETL_IS_DEBUG_BUILD
2525 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2526#endif
2527
2528 return *etl::construct_at(reinterpret_cast<TObject*>(p));
2529 }
2530
2531 //*****************************************************************************
2533 //*****************************************************************************
2534 template <typename TObject>
2535 TObject& construct_object_at(void* p, const TObject& other)
2536 {
2537#if ETL_IS_DEBUG_BUILD
2538 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2539#endif
2540
2541 return *etl::construct_at(reinterpret_cast<TObject*>(p), other);
2542 }
2543
2544 //*****************************************************************************
2546 //*****************************************************************************
2547 template <typename TObject, typename TArg>
2548 TObject& construct_object_at(void* p, const TArg& arg)
2549 {
2550#if ETL_IS_DEBUG_BUILD
2551 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2552#endif
2553
2554 return *etl::construct_at(reinterpret_cast<TObject*>(p), arg);
2555 }
2556#endif
2557
2558 //*****************************************************************************
2560 //*****************************************************************************
2561 template <typename TObject>
2562 TObject& get_object_at(void* p)
2563 {
2564#if ETL_IS_DEBUG_BUILD
2565 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2566#endif
2567
2568 TObject& v = *reinterpret_cast<TObject*>(p);
2569
2570 return v;
2571 }
2572
2573 //*****************************************************************************
2576 //*****************************************************************************
2577 template <typename TObject>
2578 void destroy_object_at(void* p)
2579 {
2580#if ETL_IS_DEBUG_BUILD
2581 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2582#endif
2583
2584 TObject& v = get_object_at<TObject>(p);
2585 v.~TObject();
2586 }
2587}
2588
2589#endif
Definition nullptr.h:42
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
Definition memory.h:1314
TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T &value)
Definition memory.h:86
etl::enable_if< etl::is_trivially_constructible< typenameetl::iterator_traits< TOutputIterator >::value_type >::value, void >::type uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
Definition memory.h:848
TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
Definition memory.h:920
etl::enable_if< etl::is_trivially_constructible< typenameetl::iterator_traits< TOutputIterator >::value_type >::value, TOutputIterator >::type uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
Definition memory.h:756
T * construct_at(T *p)
Definition memory.h:977
etl::enable_if< etl::is_trivially_destructible< T >::value, void >::type destroy_at(T *)
Definition memory.h:1027
TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
Definition memory.h:605
TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
Definition memory.h:357
etl::enable_if< etl::is_trivially_destructible< typenameetl::iterator_traits< TIterator >::value_type >::value, TIterator >::type destroy_n(TIterator i_begin, TSize n)
Definition memory.h:1190
TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
Definition memory.h:480
TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
Definition memory.h:237
etl::enable_if< etl::is_trivially_constructible< typenameetl::iterator_traits< TOutputIterator >::value_type >::value, void >::type uninitialized_default_construct(TOutputIterator, TOutputIterator)
Definition memory.h:670
TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T &value)
Definition memory.h:210
Definition memory.h:1259
add_rvalue_reference
Definition type_traits_generator.h:1322
conditional
Definition type_traits_generator.h:1155
is_reference
Definition type_traits_generator.h:1106
is_same
Definition type_traits_generator.h:1036
bitset_ext
Definition absolute.h:38
ETL_CONSTEXPR T * to_address(T *p)
Definition memory.h:62
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:962
void destroy(const T *const p)
Destroys the object.
Definition variant_pool_generator.h:370
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition iterator.h:992
add_lvalue_reference
Definition type_traits_generator.h:1265
pair holds two objects of arbitrary type
Definition utility.h:164