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#if ETL_USING_STL
58 //*****************************************************************************
63 //*****************************************************************************
64 template <typename TOutputIterator, typename T>
66 {
67 std::uninitialized_fill(o_begin, o_end, value);
68
69 return o_end;
70 }
71
72 //*****************************************************************************
77 //*****************************************************************************
78 template <typename TOutputIterator, typename T, typename TCounter>
80 {
81 count += int32_t(etl::distance(o_begin, o_end));
82
83 std::uninitialized_fill(o_begin, o_end, value);
84
85 return o_end;
86 }
87#else
88 //*****************************************************************************
92 //*****************************************************************************
93 template <typename TOutputIterator, typename T>
95 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
96 {
97 etl::fill(o_begin, o_end, value);
98
99 return o_end;
100 }
101
102 //*****************************************************************************
106 //*****************************************************************************
107 template <typename TOutputIterator, typename T>
109 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
110 {
111 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
112
113 while (o_begin != o_end)
114 {
115 ::new (static_cast<void*>(etl::addressof(*o_begin))) value_type(value);
116 ++o_begin;
117 }
118
119 return o_end;
120 }
121
122 //*****************************************************************************
127 //*****************************************************************************
128 template <typename TOutputIterator, typename T, typename TCounter>
130 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
131 {
132 count += int32_t(etl::distance(o_begin, o_end));
133
134 etl::fill(o_begin, o_end, value);
135
136 return o_end;
137 }
138
139 //*****************************************************************************
144 //*****************************************************************************
145 template <typename TOutputIterator, typename T, typename TCounter>
147 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
148 {
149 count += int32_t(etl::distance(o_begin, o_end));
150
151 etl::uninitialized_fill(o_begin, o_end, value);
152
153 return o_end;
154 }
155#endif
156
157#if ETL_USING_STL && ETL_USING_CPP11
158 //*****************************************************************************
162 //*****************************************************************************
163 template <typename TOutputIterator, typename TSize, typename T>
164 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value)
165 {
166 return std::uninitialized_fill_n(o_begin, n, value);
167 }
168
169 //*****************************************************************************
174 //*****************************************************************************
175 template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
176 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count)
177 {
178 count += n;
179
180 return std::uninitialized_fill_n(o_begin, n, value);
181 }
182#else
183 //*****************************************************************************
187 //*****************************************************************************
188 template <typename TOutputIterator, typename TSize, typename T>
193
194 //*****************************************************************************
199 //*****************************************************************************
200 template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
202 {
203 count += n;
204
205 return etl::uninitialized_fill(o_begin, o_begin + n, value);
206 }
207#endif
208
209#if ETL_USING_STL
210 //*****************************************************************************
214 //*****************************************************************************
215 template <typename TInputIterator, typename TOutputIterator>
220
221 //*****************************************************************************
226 //*****************************************************************************
227 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
229 {
230 count += int32_t(etl::distance(i_begin, i_end));
231
232 return std::uninitialized_copy(i_begin, i_end, o_begin);
233 }
234#else
235 //*****************************************************************************
239 //*****************************************************************************
240 template <typename TInputIterator, typename TOutputIterator>
242 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
243 {
244 return etl::copy(i_begin, i_end, o_begin);
245 }
246
247 //*****************************************************************************
251 //*****************************************************************************
252 template <typename TInputIterator, typename TOutputIterator>
254 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
255 {
256 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
257
258 TOutputIterator o_end = o_begin;
259
260 while (i_begin != i_end)
261 {
262 ::new (static_cast<void*>(etl::addressof(*o_end))) value_type(*i_begin);
263 ++i_begin;
264 ++o_end;
265 }
266
267 return o_end;
268 }
269
270 //*****************************************************************************
275 //*****************************************************************************
276 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
278 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
279 {
280 TOutputIterator o_end = etl::copy(i_begin, i_end, o_begin);
281 count += int32_t(etl::distance(i_begin, i_end));
282
283 return o_end;
284 }
285
286 //*****************************************************************************
291 //*****************************************************************************
292 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
294 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
295 {
296 TOutputIterator o_end = etl::uninitialized_copy(i_begin, i_end, o_begin);
297
298 count += int32_t(etl::distance(i_begin, i_end));
299
300 return o_end;
301 }
302#endif
303
304#if ETL_USING_STL && ETL_USING_CPP11
305 //*****************************************************************************
309 //*****************************************************************************
310 template <typename TInputIterator, typename TSize, typename TOutputIterator>
311 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
312 {
313 return std::uninitialized_copy_n(i_begin, n, o_begin);
314 }
315
316 //*****************************************************************************
321 //*****************************************************************************
322 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
323 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
324 {
325 count += n;
326
327 return std::uninitialized_copy_n(i_begin, n, o_begin);
328 }
329#else
330 //*****************************************************************************
334 //*****************************************************************************
335 template <typename TInputIterator, typename TSize, typename TOutputIterator>
340
341 //*****************************************************************************
346 //*****************************************************************************
347 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
354#endif
355
356#if ETL_USING_CPP11
357#if ETL_USING_STL && ETL_USING_CPP17
358 //*****************************************************************************
362 //*****************************************************************************
363 template <typename TInputIterator, typename TOutputIterator>
364 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
365 {
366 return std::uninitialized_move(i_begin, i_end, o_begin);
367 }
368
369 //*****************************************************************************
374 //*****************************************************************************
375 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
376 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
377 {
378 count += int32_t(etl::distance(i_begin, i_end));
379
380 return std::uninitialized_move(i_begin, i_end, o_begin);
381 }
382#else
383 //*****************************************************************************
387 //*****************************************************************************
388 template <typename TInputIterator, typename TOutputIterator>
390 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
391 {
392 return etl::move(i_begin, i_end, o_begin);
393 }
394
395 //*****************************************************************************
399 //*****************************************************************************
400 template <typename TInputIterator, typename TOutputIterator>
402 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
403 {
404 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
405
406 TOutputIterator o_end = o_begin;
407
408 while (i_begin != i_end)
409 {
410 ::new (static_cast<void*>(etl::addressof(*o_end))) value_type(etl::move(*i_begin));
411 ++i_begin;
412 ++o_end;
413 }
414
415 return o_end;
416 }
417
418 //*****************************************************************************
423 //*****************************************************************************
424 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
426 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
427 {
428 TOutputIterator o_end = etl::move(i_begin, i_end, o_begin);
429 count += int32_t(etl::distance(i_begin, i_end));
430
431 return o_end;
432 }
433
434 //*****************************************************************************
439 //*****************************************************************************
440 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
442 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
443 {
444 TOutputIterator o_end = etl::uninitialized_move(i_begin, i_end, o_begin);
445
446 count += int32_t(etl::distance(i_begin, i_end));
447
448 return o_end;
449 }
450#endif
451#else
452 // C++03
453 //*****************************************************************************
457 //*****************************************************************************
458 template <typename TInputIterator, typename TOutputIterator>
460 {
461 // Move not supported. Defer to copy.
462 return ETL_OR_STD::uninitialized_copy(i_begin, i_end, o_begin);
463 }
464
465 //*****************************************************************************
470 //*****************************************************************************
471 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
473 {
474 count += int32_t(etl::distance(i_begin, i_end));
475
476 // Move not supported. Defer to copy.
477 return ETL_OR_STD::uninitialized_copy(i_begin, i_end, o_begin);
478 }
479#endif
480
481#if ETL_USING_CPP11
482#if ETL_USING_STL && ETL_USING_CPP17
483 //*****************************************************************************
487 //*****************************************************************************
488 template <typename TInputIterator, typename TSize, typename TOutputIterator>
489 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
490 {
491 return std::uninitialized_move(i_begin, i_begin + n, o_begin);
492 }
493
494 //*****************************************************************************
499 //*****************************************************************************
500 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
501 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
502 {
503 count += TCounter(n);
504
505 return std::uninitialized_move(i_begin, i_begin + n, o_begin);
506 }
507#else
508 //*****************************************************************************
512 //*****************************************************************************
513 template <typename TInputIterator, typename TSize, typename TOutputIterator>
515 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
516 {
517 return etl::move(i_begin, i_begin + n, o_begin);
518 }
519
520 //*****************************************************************************
524 //*****************************************************************************
525 template <typename TInputIterator, typename TSize, typename TOutputIterator>
527 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
528 {
529 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
530
531 TOutputIterator o_end = o_begin;
532
533 while (n-- != 0)
534 {
535 ::new (static_cast<void*>(etl::addressof(*o_end))) value_type(etl::move(*i_begin));
536 ++i_begin;
537 ++o_end;
538 }
539
540 return o_end;
541 }
542
543 //*****************************************************************************
548 //*****************************************************************************
549 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
551 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
552 {
553 TOutputIterator o_end = etl::move(i_begin, i_begin + n, o_begin);
554 count += TCounter(n);
555
556 return o_end;
557 }
558
559 //*****************************************************************************
564 //*****************************************************************************
565 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
567 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
568 {
569 TOutputIterator o_end = etl::uninitialized_move(i_begin, i_begin + n, o_begin);
570
571 count += TCounter(n);
572
573 return o_end;
574 }
575#endif
576#else
577 // C++03
578 //*****************************************************************************
582 //*****************************************************************************
583 template <typename TInputIterator, typename TSize, typename TOutputIterator>
585 {
586 // Move not supported. Defer to copy.
587#if ETL_USING_CPP11
588 return std::uninitialized_copy_n(i_begin, n, o_begin);
589#else
591#endif
592 }
593
594 //*****************************************************************************
599 //*****************************************************************************
600 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
602 {
603 count += TCounter(n);
604
605 // Move not supported. Defer to copy.
606#if ETL_USING_CPP11
607 return std::uninitialized_copy_n(i_begin, n, o_begin);
608#else
610#endif
611 }
612#endif
613
614#if ETL_USING_STL && ETL_USING_CPP17
615 //*****************************************************************************
619 //*****************************************************************************
620 template <typename TOutputIterator>
622 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end)
623 {
624 std::uninitialized_default_construct(o_begin, o_end);
625 }
626
627 //*****************************************************************************
632 //*****************************************************************************
633 template <typename TOutputIterator, typename TCounter>
635 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
636 {
637 count = int32_t(etl::distance(o_begin, o_end));
638
639 std::uninitialized_default_construct(o_begin, o_end);
640 }
641#else
642 //*****************************************************************************
646 //*****************************************************************************
647 template <typename TOutputIterator>
650 {
651 // Do nothing
652 }
653
654 //*****************************************************************************
658 //*****************************************************************************
659 template <typename TOutputIterator>
662 {
663
664 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
665
666 while (o_begin != o_end)
667 {
668 ::new (static_cast<void*>(etl::addressof(*o_begin))) value_type;
669 ++o_begin;
670 }
671 }
672
673 //*****************************************************************************
678 //*****************************************************************************
679 template <typename TOutputIterator, typename TCounter>
685
686 //*****************************************************************************
691 //*****************************************************************************
692 template <typename TOutputIterator, typename TCounter>
700#endif
701
702#if ETL_USING_STL && ETL_USING_CPP17
703 //*****************************************************************************
707 //*****************************************************************************
708 template <typename TOutputIterator, typename TSize>
709 TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
710 {
711 return std::uninitialized_default_construct_n(o_begin, n);
712 }
713
714 //*****************************************************************************
719 //*****************************************************************************
720 template <typename TOutputIterator, typename TSize, typename TCounter>
721 TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
722 {
723 count += n;
724
725 return std::uninitialized_default_construct_n(o_begin, n);
726 }
727#else
728 //*****************************************************************************
732 //*****************************************************************************
733 template <typename TOutputIterator, typename TSize>
740
741 //*****************************************************************************
745 //*****************************************************************************
746 template <typename TOutputIterator, typename TSize>
756
757 //*****************************************************************************
762 //*****************************************************************************
763 template <typename TOutputIterator, typename TSize, typename TCounter>
766 {
768
769 count += n;
770
771 return o_end;
772 }
773
774 //*****************************************************************************
779 //*****************************************************************************
780 template <typename TOutputIterator, typename TSize, typename TCounter>
792#endif
793
794#if ETL_USING_STL && ETL_USING_CPP17
795 //*****************************************************************************
799 //*****************************************************************************
800 template <typename TOutputIterator>
801 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
802 {
803 std::uninitialized_value_construct(o_begin, o_end);
804 }
805
806 //*****************************************************************************
811 //*****************************************************************************
812 template <typename TOutputIterator, typename TCounter>
813 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
814 {
815 count += int32_t(etl::distance(o_begin, o_end));
816
817 std::uninitialized_value_construct(o_begin, o_end);
818 }
819#else
820 //*****************************************************************************
824 //*****************************************************************************
825 template <typename TOutputIterator>
828 {
829 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
830
831 etl::fill(o_begin, o_end, value_type());
832 }
833
834 //*****************************************************************************
838 //*****************************************************************************
839 template <typename TOutputIterator>
842 {
843 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
844
845 while (o_begin != o_end)
846 {
847 ::new (static_cast<void*>(etl::addressof(*o_begin))) value_type();
848 ++o_begin;
849 }
850 }
851
852 //*****************************************************************************
857 //*****************************************************************************
858 template <typename TOutputIterator, typename TCounter>
865#endif
866
867#if ETL_USING_STL && ETL_USING_CPP17
868 //*****************************************************************************
872 //*****************************************************************************
873 template <typename TOutputIterator, typename TSize>
874 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
875 {
876 return std::uninitialized_value_construct_n(o_begin, n);
877 }
878
879 //*****************************************************************************
884 //*****************************************************************************
885 template <typename TOutputIterator, typename TSize, typename TCounter>
886 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
887 {
888 count += n;
889
890 return std::uninitialized_value_construct_n(o_begin, n);
891 }
892#else
893 //*****************************************************************************
897 //*****************************************************************************
898 template <typename TOutputIterator, typename TSize>
907
908 //*****************************************************************************
913 //*****************************************************************************
914 template <typename TOutputIterator, typename TSize, typename TCounter>
925#endif
926
927#if ETL_USING_STL && ETL_USING_CPP20
928 //*****************************************************************************
932 //*****************************************************************************
933 template <typename T, typename... TArgs>
934 ETL_CONSTEXPR20 T* construct_at(T* p, TArgs&&... args)
935 {
936 return std::construct_at(p, etl::forward<TArgs>(args)...);
937 }
938#elif ETL_USING_CPP11
939 //*****************************************************************************
943 //*****************************************************************************
944 template <typename T, typename... TArgs>
945 T* construct_at(T* p, TArgs&&... args)
946 {
947 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T(etl::forward<TArgs>(args)...);
948 }
949#else
950 //*****************************************************************************
954 //*****************************************************************************
955 template <typename T>
957 {
958 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T();
959 }
960 //*****************************************************************************
964 //*****************************************************************************
965 template <typename T, typename TArg>
966 T* construct_at(T* p, const TArg& arg)
967 {
968 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T(arg);
969 }
970#endif
971
972#if ETL_USING_STL && ETL_USING_CPP20
973 //*****************************************************************************
977//*****************************************************************************
978 template <typename T>
979 ETL_CONSTEXPR20
980 void destroy_at(T* p)
981 {
982 std::destroy_at(p);
983 }
984
985 //*****************************************************************************
990 //*****************************************************************************
991 template <typename T, typename TCounter>
992 ETL_CONSTEXPR20
993 void destroy_at(T* p, TCounter& count)
994 {
995 --count;
996 std::destroy_at(p);
997 }
998#else
999 //*****************************************************************************
1003 //*****************************************************************************
1004 template <typename T>
1007 {
1008 }
1009
1010 //*****************************************************************************
1014 //*****************************************************************************
1015 template <typename T>
1018 {
1019 p->~T();
1020 }
1021
1022 //*****************************************************************************
1027 //*****************************************************************************
1028 template <typename T, typename TCounter>
1030 destroy_at(T* /*p*/, TCounter& count)
1031 {
1032 --count;
1033 }
1034
1035 //*****************************************************************************
1040 //*****************************************************************************
1041 template <typename T, typename TCounter>
1044 {
1045 p->~T();
1046 --count;
1047 }
1048#endif
1049
1050#if ETL_USING_STL && ETL_USING_CPP17
1051 //*****************************************************************************
1055 //*****************************************************************************
1056 template <typename TIterator>
1057 void destroy(TIterator i_begin, TIterator i_end)
1058 {
1059 std::destroy(i_begin, i_end);
1060 }
1061
1062 //*****************************************************************************
1067 //*****************************************************************************
1068 template <typename TIterator, typename TCounter>
1069 void destroy(TIterator i_begin, TIterator i_end, TCounter& count)
1070 {
1071 count -= int32_t(etl::distance(i_begin, i_end));
1072
1073 std::destroy(i_begin, i_end);
1074 }
1075#else
1076 //*****************************************************************************
1080 //*****************************************************************************
1081 template <typename TIterator>
1083 destroy(TIterator /*i_begin*/, TIterator /*i_end*/)
1084 {
1085 }
1086
1087 //*****************************************************************************
1091 //*****************************************************************************
1092 template <typename TIterator>
1095 {
1096 while (i_begin != i_end)
1097 {
1099 ++i_begin;
1100 }
1101 }
1102
1103 //*****************************************************************************
1108 //*****************************************************************************
1109 template <typename TIterator, typename TCounter>
1112 {
1113 count -= int32_t(etl::distance(i_begin, i_end));
1114 }
1115
1116 //*****************************************************************************
1121 //*****************************************************************************
1122 template <typename TIterator, typename TCounter>
1125 {
1126 count -= int32_t(etl::distance(i_begin, i_end));
1127
1128 while (i_begin != i_end)
1129 {
1131 ++i_begin;
1132 }
1133 }
1134#endif
1135
1136#if ETL_USING_STL && ETL_USING_CPP17
1137 //*****************************************************************************
1141 //*****************************************************************************
1142 template <typename TIterator, typename TSize>
1143 TIterator destroy_n(TIterator i_begin, TSize n)
1144 {
1145 return std::destroy_n(i_begin, n);
1146 }
1147
1148 //*****************************************************************************
1153 //*****************************************************************************
1154 template <typename TIterator, typename TSize, typename TCounter>
1155 TIterator destroy_n(TIterator i_begin, TSize n, TCounter& count)
1156 {
1157 count -= n;
1158
1159 return std::destroy_n(i_begin, n);
1160 }
1161#else
1162 //*****************************************************************************
1166 //*****************************************************************************
1167 template <typename TIterator, typename TSize>
1170 {
1171 return i_begin + n;
1172 }
1173
1174 //*****************************************************************************
1178 //*****************************************************************************
1179 template <typename TIterator, typename TSize>
1182 {
1183 while (n > 0)
1184 {
1186 ++i_begin;
1187 --n;
1188 }
1189
1190 return i_begin;
1191 }
1192
1193 //*****************************************************************************
1198 //*****************************************************************************
1199 template <typename TIterator, typename TSize, typename TCounter>
1202 {
1203 count -= n;
1204 return i_begin + n;
1205 }
1206
1207 //*****************************************************************************
1212 //*****************************************************************************
1213 template <typename TIterator, typename TSize, typename TCounter>
1216 {
1217 count -= n;
1218
1219 while (n > 0)
1220 {
1222 ++i_begin;
1223 --n;
1224 }
1225
1226 return i_begin;
1227 }
1228#endif
1229
1230 //*****************************************************************************
1235 //*****************************************************************************
1236 template <typename T>
1238 {
1239 //*********************************
1240 ETL_CONSTEXPR default_delete() ETL_NOEXCEPT
1241 {
1242 }
1243
1244 //*********************************
1245 template <typename U>
1246 default_delete(const default_delete<U>&) ETL_NOEXCEPT
1247 {
1248 }
1249
1250 //*********************************
1251 void operator()(T * p) const ETL_NOEXCEPT
1252 {
1253 delete p;
1254 }
1255 };
1256
1257 //*****************************************************************************
1262 //*****************************************************************************
1263 template <typename T>
1265 {
1266 //*********************************
1267 ETL_CONSTEXPR default_delete() ETL_NOEXCEPT
1268 {
1269 }
1270
1271 //*********************************
1272 template <typename U>
1273 default_delete(const default_delete<U>&) ETL_NOEXCEPT
1274 {
1275 }
1276
1277 //*********************************
1278 template <class U>
1279 void operator()(U* p) const
1280 {
1281 delete[] p;
1282 }
1283 };
1284
1285 //*****************************************************************************
1290 //*****************************************************************************
1291 template <typename T, typename TDeleter = etl::default_delete<T> >
1293 {
1294 public:
1295
1296 typedef T element_type;
1297 typedef T* pointer;
1298 typedef T& reference;
1299
1300 //*********************************
1301 ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT
1302 : p(ETL_NULLPTR)
1303 {
1304 }
1305
1306 //*********************************
1307 ETL_CONSTEXPR explicit unique_ptr(pointer p_) ETL_NOEXCEPT
1308 : p(p_)
1309 {
1310 }
1311
1312#if ETL_USING_CPP11
1313 //*********************************
1314 unique_ptr(unique_ptr&& other) ETL_NOEXCEPT
1315 {
1316 if (&other != this)
1317 {
1318 p = other.release();
1319 deleter = etl::move(other.deleter);
1320 }
1321 }
1322#else
1323 //*********************************
1324 unique_ptr(unique_ptr& other) ETL_NOEXCEPT
1325 {
1326 if (&other != this)
1327 {
1328 p = other.release();
1329 deleter = other.deleter;
1330 }
1331 }
1332#endif
1333
1334 //*********************************
1336 TDeleter,
1337 typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
1338 : p(p_)
1339 , deleter(deleter_)
1340 {
1341 }
1342
1343#if ETL_USING_CPP11
1344 //*********************************
1346 : p(p_)
1347 , deleter(etl::move(deleter_))
1348 {
1349 }
1350
1351 template <typename U, typename E>
1352 unique_ptr(unique_ptr<U, E>&& u) ETL_NOEXCEPT
1353 : p(u.release())
1354 , deleter(etl::forward<E>(u.get_deleter()))
1355 {
1356 }
1357#endif
1358
1359 //*********************************
1360 ~unique_ptr()
1361 {
1362 if (p != ETL_NULLPTR)
1363 {
1364 deleter(p);
1365 }
1366 }
1367
1368 //*********************************
1369 ETL_CONSTEXPR pointer get() const ETL_NOEXCEPT
1370 {
1371 return p;
1372 }
1373
1374 //*********************************
1375 TDeleter& get_deleter() ETL_NOEXCEPT
1376 {
1377 return deleter;
1378 }
1379
1380 //*********************************
1381 const TDeleter& get_deleter() const ETL_NOEXCEPT
1382 {
1383 return deleter;
1384 }
1385
1386 //*********************************
1387 pointer release() ETL_NOEXCEPT
1388 {
1389 pointer value = p;
1390 p = ETL_NULLPTR;
1391
1392 return value;
1393 }
1394
1395 //*********************************
1396 void reset(pointer p_ = pointer()) ETL_NOEXCEPT
1397 {
1398 if (p_ == ETL_NULLPTR || p_ != p)
1399 {
1400 pointer value = p;
1401 p = p_;
1402
1403 if (value != ETL_NULLPTR)
1404 {
1405 deleter(value);
1406 }
1407 }
1408 }
1409
1410 //*********************************
1411 void swap(unique_ptr& value) ETL_NOEXCEPT
1412 {
1413 using ETL_OR_STD::swap;
1414
1415 swap(p, value.p);
1416 }
1417
1418 //*********************************
1419 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
1420 {
1421 return (p != ETL_NULLPTR);
1422 }
1423
1424 //*********************************
1425 unique_ptr& operator =(etl::nullptr_t) ETL_NOEXCEPT
1426 {
1427 if (p)
1428 {
1429 reset(ETL_NULLPTR);
1430 }
1431
1432 return *this;
1433 }
1434
1435#if ETL_USING_CPP11
1436 //*********************************
1437 unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT
1438 {
1439 if (&other != this)
1440 {
1441 reset(other.release());
1442 deleter = etl::move(other.deleter);
1443 }
1444
1445 return *this;
1446 }
1447#else
1448 //*********************************
1449 unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT
1450 {
1451 if (&other != this)
1452 {
1453 reset(other.release());
1454 deleter = other.deleter;
1455 }
1456
1457 return *this;
1458 }
1459#endif
1460
1461 //*********************************
1462 ETL_CONSTEXPR reference operator *() const
1463 {
1464 return *get();
1465 }
1466
1467 //*********************************
1468 ETL_CONSTEXPR pointer operator ->() const ETL_NOEXCEPT
1469 {
1470 return get();
1471 }
1472
1473 //*********************************
1474 ETL_CONSTEXPR reference operator [](size_t i) const
1475 {
1476 return p[i];
1477 }
1478
1479 private:
1480
1481 // Deleted.
1482 unique_ptr(const unique_ptr&) ETL_DELETE;
1483 unique_ptr& operator =(const unique_ptr&) ETL_DELETE;
1484
1485 pointer p;
1486 TDeleter deleter;
1487 };
1488
1489 //*****************************************************************************
1494 //*****************************************************************************
1495 template<typename T, typename TDeleter>
1497 {
1498 public:
1499
1500 typedef T element_type;
1501 typedef T* pointer;
1502 typedef T& reference;
1503
1504 //*********************************
1505 ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT
1506 : p(ETL_NULLPTR)
1507 {
1508 }
1509
1510 //*********************************
1511 ETL_CONSTEXPR explicit unique_ptr(pointer p_) ETL_NOEXCEPT
1512 : p(p_)
1513 {
1514 }
1515
1516#if ETL_USING_CPP11
1517 //*********************************
1518 unique_ptr(unique_ptr&& other) ETL_NOEXCEPT
1519 {
1520 if (&other != this)
1521 {
1522 p = other.release();
1523 deleter = etl::move(other.deleter);
1524 }
1525 }
1526#else
1527 //*********************************
1528 unique_ptr(unique_ptr& other) ETL_NOEXCEPT
1529 {
1530 if (&other != this)
1531 {
1532 p = other.release();
1533 deleter = other.deleter;
1534 }
1535 }
1536#endif
1537
1538 //*********************************
1541 TDeleter,
1542 typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
1543 : p(p_)
1544 , deleter(deleter_)
1545 {
1546 }
1547
1548#if ETL_USING_CPP11
1549 //*********************************
1551 : p(p_)
1552 , deleter(etl::move(deleter_))
1553 {
1554 }
1555
1556 template <typename U, typename E>
1557 unique_ptr(unique_ptr<U, E>&& u) ETL_NOEXCEPT
1558 : p(u.release())
1559 , deleter(etl::forward<E>(u.get_deleter()))
1560 {
1561 }
1562#endif
1563
1564 //*********************************
1565 ~unique_ptr()
1566 {
1567 if (p != ETL_NULLPTR)
1568 {
1569 deleter(p);
1570 }
1571 }
1572
1573 //*********************************
1574 ETL_CONSTEXPR pointer get() const ETL_NOEXCEPT
1575 {
1576 return p;
1577 }
1578
1579 //*********************************
1580 TDeleter& get_deleter() ETL_NOEXCEPT
1581 {
1582 return deleter;
1583 }
1584
1585 //*********************************
1586 const TDeleter& get_deleter() const ETL_NOEXCEPT
1587 {
1588 return deleter;
1589 }
1590
1591 //*********************************
1592 pointer release() ETL_NOEXCEPT
1593 {
1594 pointer value = p;
1595 p = ETL_NULLPTR;
1596 return value;
1597 }
1598
1599 //*********************************
1600 void reset(pointer p_) ETL_NOEXCEPT
1601 {
1602 if (p_ != p)
1603 {
1604 pointer value = p;
1605 p = p_;
1606
1607 if (value != ETL_NULLPTR)
1608 {
1609 deleter(value);
1610 }
1611 }
1612 }
1613
1614 void reset(etl::nullptr_t = ETL_NULLPTR) ETL_NOEXCEPT
1615 {
1616 reset(pointer());
1617 }
1618
1619 //*********************************
1620 void swap(unique_ptr& v) ETL_NOEXCEPT
1621 {
1622 using ETL_OR_STD::swap;
1623
1624 swap(p, v.p);
1625 }
1626
1627 //*********************************
1628 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
1629 {
1630 return (p != ETL_NULLPTR);
1631 }
1632
1633 //*********************************
1634 unique_ptr& operator =(etl::nullptr_t) ETL_NOEXCEPT
1635 {
1636 reset(ETL_NULLPTR);
1637
1638 return *this;
1639 }
1640
1641#if ETL_USING_CPP11
1642 //*********************************
1643 unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT
1644 {
1645 if (&other != this)
1646 {
1647 reset(other.release());
1648 deleter = etl::move(other.deleter);
1649 }
1650
1651 return *this;
1652 }
1653#else
1654 //*********************************
1655 unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT
1656 {
1657 if (&other != this)
1658 {
1659 reset(other.release());
1660 deleter = other.deleter;
1661 }
1662
1663 return *this;
1664 }
1665#endif
1666
1667 //*********************************
1668 ETL_CONSTEXPR reference operator *() const
1669 {
1670 return *p;
1671 }
1672
1673 //*********************************
1674 ETL_CONSTEXPR pointer operator ->() const ETL_NOEXCEPT
1675 {
1676 return p;
1677 }
1678
1679 //*********************************
1680 ETL_CONSTEXPR reference operator [](size_t i) const
1681 {
1682 return p[i];
1683 }
1684
1685 private:
1686
1687 // Deleted.
1688 unique_ptr(const unique_ptr&) ETL_DELETE;
1689 unique_ptr& operator =(const unique_ptr&) ETL_DELETE;
1690
1691 pointer p;
1692 TDeleter deleter;
1693 };
1694}
1695
1696//*****************************************************************************
1697// Global functions for unique_ptr
1698//*****************************************************************************
1699template<typename T1, typename TD1, typename T2, typename TD2>
1700bool operator ==(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1701{
1702 return lhs.get() == rhs.get();
1703}
1704
1705//*********************************
1706template<typename T1, typename TD1, typename T2, typename TD2>
1707bool operator <(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1708{
1709 return reinterpret_cast<char*>(lhs.get()) < reinterpret_cast<char*>(rhs.get());
1710}
1711
1712//*********************************
1713template<typename T1, typename TD1, typename T2, typename TD2>
1714bool operator <=(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1715{
1716 return !(rhs < lhs);
1717}
1718
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 (rhs < lhs);
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 !(lhs < rhs);
1731}
1732
1733namespace etl
1734{
1735 //*****************************************************************************
1738 //*****************************************************************************
1739 template <typename T>
1741 create_default_at(T* /*p*/)
1742 {
1743 }
1744
1745 //*****************************************************************************
1748 //*****************************************************************************
1749 template <typename T, typename TCounter>
1751 create_default_at(T* /*p*/, TCounter& count)
1752 {
1753 ++count;
1754 }
1755
1756 //*****************************************************************************
1759 //*****************************************************************************
1760 template <typename T>
1762 create_default_at(T* p)
1763 {
1764 ::new (p) T;
1765 }
1766
1767 //*****************************************************************************
1770 //*****************************************************************************
1771 template <typename T, typename TCounter>
1773 create_default_at(T* p, TCounter& count)
1774 {
1775 ::new (p) T;
1776 ++count;
1777 }
1778
1779 //*****************************************************************************
1782 //*****************************************************************************
1783 template <typename T>
1784 void create_value_at(T* p)
1785 {
1786 ::new (p) T();
1787 }
1788
1789 //*****************************************************************************
1792 //*****************************************************************************
1793 template <typename T, typename TCounter>
1794 void create_value_at(T* p, TCounter& count)
1795 {
1796 ::new (p) T();
1797 ++count;
1798 }
1799
1800 //*****************************************************************************
1803 //*****************************************************************************
1804 template <typename T>
1805 void create_copy_at(T* p, const T& value)
1806 {
1807 ::new (p) T(value);
1808 }
1809
1810#if ETL_USING_CPP11
1811 //*****************************************************************************
1814 //*****************************************************************************
1815 template <typename T>
1816 void create_copy_at(T* p, T&& value)
1817 {
1818 ::new (p) T(etl::move(value));
1819 }
1820#endif
1821
1822 //*****************************************************************************
1825 //*****************************************************************************
1826 template <typename T, typename TCounter>
1827 void create_copy_at(T* p, const T& value, TCounter& count)
1828 {
1829 ::new (p) T(value);
1830 ++count;
1831 }
1832
1833 //*****************************************************************************
1836 //*****************************************************************************
1837 template <typename T>
1838 T& make_default_at(T* p)
1839 {
1840 ::new (p) T();
1841 return *reinterpret_cast<T*>(p);
1842 }
1843
1844 //*****************************************************************************
1847 //*****************************************************************************
1848 template <typename T, typename TCounter>
1849 T& make_default_at(T* p, TCounter& count)
1850 {
1851 ::new (p) T();
1852 ++count;
1853 return *reinterpret_cast<T*>(p);
1854 }
1855
1856 //*****************************************************************************
1859 //*****************************************************************************
1860 template <typename T>
1861 T& make_copy_at(T* p, const T& other)
1862 {
1863 ::new (p) T(other);
1864 return *reinterpret_cast<T*>(p);
1865 }
1866
1867#if ETL_USING_CPP11
1868 //*****************************************************************************
1871 //*****************************************************************************
1872 template <typename T>
1873 T& make_copy_at(T* p, T&& other)
1874 {
1875 ::new (p) T(etl::move(other));
1876 return *reinterpret_cast<T*>(p);
1877 }
1878#endif
1879
1880 //*****************************************************************************
1883 //*****************************************************************************
1884 template <typename T, typename TCounter>
1885 T& make_copy_at(T* p, const T& other, TCounter& count)
1886 {
1887 ::new (p) T(other);
1888 ++count;
1889 return *reinterpret_cast<T*>(p);
1890 }
1891
1892 //*****************************************************************************
1895 //*****************************************************************************
1896 template <typename T, typename TParameter>
1897 T& make_value_at(T* p, const TParameter& value)
1898 {
1899 ::new (p) T(value);
1900 return *reinterpret_cast<T*>(p);
1901 }
1902
1903#if ETL_USING_CPP11
1904 //*****************************************************************************
1907 //*****************************************************************************
1908 template <typename T, typename TParameter>
1909 T& make_value_at(T* p, TParameter&& value)
1910 {
1911 ::new (p) T(etl::move(value));
1912 return *reinterpret_cast<T*>(p);
1913 }
1914#endif
1915
1916 //*****************************************************************************
1919 //*****************************************************************************
1920 template <typename T, typename TParameter, typename TCounter>
1921 T& make_value_at(T* p, const TParameter& value, TCounter& count)
1922 {
1923 ::new (p) T(value);
1924 ++count;
1925 return *reinterpret_cast<T*>(p);
1926 }
1927
1928 //*****************************************************************************
1932 //*****************************************************************************
1933 template <typename T>
1934 struct create_copy
1935 {
1936 void create_copy_at(void* p)
1937 {
1938 new (p) T(static_cast<const T&>(*this));
1939 }
1940
1941 template <typename TCounter>
1942 void create_copy_at(void* p, TCounter& count)
1943 {
1944 new (p) T(static_cast<const T&>(*this));
1945 ++count;
1946 }
1947
1948 T& make_copy_at(void* p)
1949 {
1950 new (p) T(static_cast<const T&>(*this));
1951 return *reinterpret_cast<T*>(p);
1952 }
1953
1954 template <typename TCounter>
1955 T& make_copy_at(void* p, TCounter& count)
1956 {
1957 new (p) T(static_cast<const T&>(*this));
1958 ++count;
1959 return *reinterpret_cast<T*>(p);
1960 }
1961 };
1962
1963 //*****************************************************************************
1968 //*****************************************************************************
1969 inline void memory_clear(volatile char* p, size_t n)
1970 {
1971 while (n--)
1972 {
1973 *p++ = 0;
1974 }
1975 }
1976
1977 //*****************************************************************************
1982 //*****************************************************************************
1983 template <typename T>
1984 void memory_clear(volatile T &object)
1985 {
1986 memory_clear(reinterpret_cast<volatile char*>(&object), sizeof(T));
1987 }
1988
1989 //*****************************************************************************
1995 //*****************************************************************************
1996 template <typename T>
1997 void memory_clear_range(volatile T* begin, size_t n)
1998 {
1999 memory_clear(reinterpret_cast<volatile char*>(begin), n * sizeof(T));
2000 }
2001
2002 //*****************************************************************************
2008 //*****************************************************************************
2009 template <typename T>
2010 void memory_clear_range(volatile T* begin, volatile T* end)
2011 {
2012 const size_t n = static_cast<size_t>(etl::distance(begin, end));
2013
2014 memory_clear_range(begin, n);
2015 }
2016
2017 //*****************************************************************************
2023 //*****************************************************************************
2024 inline void memory_set(volatile char* p, size_t n, char value)
2025 {
2026 while (n--)
2027 {
2028 *p++ = value;
2029 }
2030 }
2031
2032 //*****************************************************************************
2038 //*****************************************************************************
2039 template <typename T>
2040 void memory_set(volatile T &object, const char value)
2041 {
2042 memory_set(reinterpret_cast<volatile char*>(&object), sizeof(T), value);
2043 }
2044
2045 //*****************************************************************************
2052 //*****************************************************************************
2053 template <typename T>
2054 void memory_set_range(volatile T* begin, size_t n, const char value)
2055 {
2056 memory_set(reinterpret_cast<volatile char*>(begin), n * sizeof(T), value);
2057 }
2058
2059 //*****************************************************************************
2066 //*****************************************************************************
2067 template <typename T>
2068 void memory_set_range(volatile T* begin, volatile T* end, const char value)
2069 {
2070 const size_t n = static_cast<size_t>(etl::distance(begin, end));
2071
2072 memory_set_range(begin, n, value);
2073 }
2074
2075 //*****************************************************************************
2081 //*****************************************************************************
2082 template <typename T>
2083 struct wipe_on_destruct
2084 {
2085 ~wipe_on_destruct()
2086 {
2087 memory_clear(static_cast<volatile T&>(*this));
2088 }
2089 };
2090
2091 //***************************************************************************
2094 //***************************************************************************
2095 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2096 class uninitialized_buffer
2097 {
2098 public:
2099
2100 static ETL_CONSTANT size_t Object_Size = VObject_Size;
2101 static ETL_CONSTANT size_t N_Objects = VN_Objects;
2102 static ETL_CONSTANT size_t Alignment = VAlignment;
2103
2105 template <typename T>
2106 operator T& ()
2107 {
2108 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2109 return *reinterpret_cast<T*>(raw);
2110 }
2111
2113 template <typename T>
2114 operator const T& () const
2115 {
2116 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2117 return *reinterpret_cast<const T*>(raw);
2118 }
2119
2121 template <typename T>
2122 operator T* ()
2123 {
2124 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2125 return reinterpret_cast<T*>(raw);
2126 }
2127
2129 template <typename T>
2130 operator const T* () const
2131 {
2132 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2133 return reinterpret_cast<const T*>(raw);
2134 }
2135
2136#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
2137 alignas(VAlignment) char raw[Object_Size * N_Objects];
2138#else
2139 union
2140 {
2141 char raw[VObject_Size * VN_Objects];
2142 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment as VAlignment.
2143 };
2144#endif
2145 };
2146
2147 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2148 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Object_Size;
2149
2150 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2151 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::N_Objects;
2152
2153 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2154 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Alignment;
2155
2156 //***************************************************************************
2159 //***************************************************************************
2160 template <typename T, size_t VN_Objects>
2161 class uninitialized_buffer_of
2162 {
2163 public:
2164
2165 typedef T value_type;
2166 typedef T& reference;
2167 typedef const T& const_reference;
2168 typedef T* pointer;
2169 typedef const T* const_pointer;
2170 typedef T* iterator;
2171 typedef const T* const_iterator;
2172
2173 static ETL_CONSTANT size_t Object_Size = sizeof(T);
2174 static ETL_CONSTANT size_t N_Objects = VN_Objects;
2175 static ETL_CONSTANT size_t Alignment = etl::alignment_of<T>::value;
2176
2178 T& operator [](int i)
2179 {
2180 return reinterpret_cast<T*>(this->raw)[i];
2181 }
2182
2184 const T& operator [](int i) const
2185 {
2186 return reinterpret_cast<const T*>(this->raw)[i];
2187 }
2188
2190 operator T& ()
2191 {
2192 return *reinterpret_cast<T*>(raw);
2193 }
2194
2196 operator const T& () const
2197 {
2198 return *reinterpret_cast<const T*>(raw);
2199 }
2200
2202 operator T* ()
2203
2204 {
2205 return reinterpret_cast<T*>(raw);
2206 }
2207
2209 operator const T* () const
2210 {
2211 return reinterpret_cast<const T*>(raw);
2212 }
2213
2214 T* begin()
2215 {
2216 return reinterpret_cast<T*>(raw);
2217 }
2218
2219 const T* begin() const
2220 {
2221 return reinterpret_cast<const T*>(raw);
2222 }
2223
2224 T* end()
2225 {
2226 return reinterpret_cast<T*>(raw + (sizeof(T) * N_Objects));
2227 }
2228
2229 const T* end() const
2230 {
2231 return reinterpret_cast<const T*>(raw + (sizeof(T) * N_Objects));
2232 }
2233
2234#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
2235 alignas(Alignment) char raw[sizeof(T) * N_Objects];
2236#else
2237 union
2238 {
2239 char raw[sizeof(T) * N_Objects];
2240 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment as Alignment.
2241 };
2242#endif
2243 };
2244
2245 template <typename T, size_t VN_Objects>
2246 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Object_Size;
2247
2248 template <typename T, size_t VN_Objects>
2249 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::N_Objects;
2250
2251 template <typename T, size_t VN_Objects>
2252 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Alignment;
2253
2254#if ETL_USING_CPP11
2255 template <typename T, size_t N_Objects>
2256 using uninitialized_buffer_of_t = typename uninitialized_buffer_of<T, N_Objects>::buffer;
2257#endif
2258
2259 //***************************************************************************
2266 //***************************************************************************
2267 template <typename TPointer>
2269 mem_copy(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
2270 {
2271 return reinterpret_cast<TPointer>(memcpy(reinterpret_cast<void*>(db),
2272 reinterpret_cast<void*>(sb),
2273 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb)));
2274 }
2275
2276 //***************************************************************************
2282 //***************************************************************************
2283 template <typename TPointer>
2285 mem_copy(const TPointer sb, size_t n, TPointer db) ETL_NOEXCEPT
2286 {
2287 return reinterpret_cast<TPointer>(memcpy(reinterpret_cast<void*>(db),
2288 reinterpret_cast<void*>(sb),
2289 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n));
2290 }
2291
2292 //***************************************************************************
2298 //***************************************************************************
2299 template <typename TPointer>
2301 mem_move(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
2302 {
2303 return reinterpret_cast<TPointer>(memmove(reinterpret_cast<void*>(db),
2304 reinterpret_cast<void*>(sb),
2305 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb)));
2306 }
2307
2308 //***************************************************************************
2314 //***************************************************************************
2315 template <typename TPointer>
2317 mem_move(const TPointer sb, size_t n, TPointer db) ETL_NOEXCEPT
2318 {
2319 return reinterpret_cast<TPointer>(memmove(reinterpret_cast<void*>(db),
2320 reinterpret_cast<void*>(sb),
2321 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n));
2322 }
2323
2324 //***************************************************************************
2332 //***************************************************************************
2333 template <typename TPointer>
2334 ETL_NODISCARD
2336 mem_compare(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
2337 {
2338 return memcmp(reinterpret_cast<void*>(db),
2339 reinterpret_cast<void*>(sb),
2340 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
2341 }
2342
2343 //***************************************************************************
2351 //***************************************************************************
2352 template <typename TPointer>
2353 ETL_NODISCARD
2355 mem_compare(const TPointer sb, size_t n, TPointer db) ETL_NOEXCEPT
2356 {
2357 return memcmp(reinterpret_cast<void*>(db),
2358 reinterpret_cast<void*>(sb),
2359 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
2360 }
2361
2362 //***************************************************************************
2368 //***************************************************************************
2369 template <typename TPointer, typename T>
2371 mem_set(TPointer db, const TPointer de, T value) ETL_NOEXCEPT
2372 {
2373 return reinterpret_cast<TPointer>(memset(reinterpret_cast<void*>(db),
2374 static_cast<char>(value),
2375 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(de - db)));
2376 }
2377
2378 //***************************************************************************
2384 //***************************************************************************
2385 template <typename TPointer, typename T>
2387 mem_set(const TPointer db, size_t n, T value) ETL_NOEXCEPT
2388 {
2389 return reinterpret_cast<TPointer>(memset(reinterpret_cast<void*>(db),
2390 static_cast<char>(value),
2391 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n));
2392 }
2393
2394 //***************************************************************************
2400 //***************************************************************************
2401 template <typename TPointer, typename T>
2402 ETL_NODISCARD
2404 mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
2405 {
2406 void* result = memchr(reinterpret_cast<void*>(sb),
2407 static_cast<char>(value),
2408 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
2409
2410 return (result == 0U) ? reinterpret_cast<char*>(se) : reinterpret_cast<char*>(result);
2411 }
2412
2413 //***************************************************************************
2419 //***************************************************************************
2420 template <typename TPointer, typename T>
2421 ETL_NODISCARD
2423 mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
2424 {
2425 const void* result = memchr(reinterpret_cast<const void*>(sb),
2426 static_cast<char>(value),
2427 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
2428
2429 return (result == 0U) ? reinterpret_cast<const char*>(se) : reinterpret_cast<const char*>(result);
2430 }
2431
2432 //***************************************************************************
2438 //***************************************************************************
2439 template <typename TPointer, typename T>
2440 ETL_NODISCARD
2442 mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
2443 {
2444 void* result = memchr(reinterpret_cast<void*>(sb),
2445 static_cast<char>(value),
2446 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
2447
2448 return (result == 0U) ? reinterpret_cast<char*>(sb + n) : reinterpret_cast<char*>(result);
2449 }
2450
2451 //***************************************************************************
2457 //***************************************************************************
2458 template <typename TPointer, typename T>
2459 ETL_NODISCARD
2461 mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
2462 {
2463 const void* result = memchr(reinterpret_cast<const void*>(sb),
2464 static_cast<char>(value),
2465 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
2466
2467 return (result == 0U) ? reinterpret_cast<const char*>(sb + n) : reinterpret_cast<const char*>(result);
2468 }
2469
2470#if ETL_USING_CPP11
2471 //*****************************************************************************
2473 //*****************************************************************************
2474 template <typename TObject>
2475 TObject& construct_object_at(void* p, TObject&& other)
2476 {
2477#if ETL_IS_DEBUG_BUILD
2478 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2479#endif
2480
2481 return *etl::construct_at(reinterpret_cast<typename etl::remove_reference<TObject>::type*>(p), etl::forward<TObject>(other));
2482 }
2483
2484 //*****************************************************************************
2486 //*****************************************************************************
2487 template <typename TObject, typename... TArgs>
2488 TObject& construct_object_at(void* p, TArgs&&... args)
2489 {
2490#if ETL_IS_DEBUG_BUILD
2491 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2492#endif
2493
2494 return *etl::construct_at(reinterpret_cast<TObject*>(p), etl::forward<TArgs>(args)...);
2495 }
2496#else
2497 //*****************************************************************************
2499 //*****************************************************************************
2500 template <typename TObject>
2501 TObject& construct_object_at(void* p)
2502 {
2503#if ETL_IS_DEBUG_BUILD
2504 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2505#endif
2506
2507 return *etl::construct_at(reinterpret_cast<TObject*>(p));
2508 }
2509
2510 //*****************************************************************************
2512 //*****************************************************************************
2513 template <typename TObject>
2514 TObject& construct_object_at(void* p, const TObject& other)
2515 {
2516#if ETL_IS_DEBUG_BUILD
2517 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2518#endif
2519
2520 return *etl::construct_at(reinterpret_cast<TObject*>(p), other);
2521 }
2522
2523 //*****************************************************************************
2525 //*****************************************************************************
2526 template <typename TObject, typename TArg>
2527 TObject& construct_object_at(void* p, const TArg& arg)
2528 {
2529#if ETL_IS_DEBUG_BUILD
2530 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2531#endif
2532
2533 return *etl::construct_at(reinterpret_cast<TObject*>(p), arg);
2534 }
2535#endif
2536
2537 //*****************************************************************************
2539 //*****************************************************************************
2540 template <typename TObject>
2541 TObject& get_object_at(void* p)
2542 {
2543#if ETL_IS_DEBUG_BUILD
2544 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2545#endif
2546
2547 TObject& v = *reinterpret_cast<TObject*>(p);
2548
2549 return v;
2550 }
2551
2552 //*****************************************************************************
2555 //*****************************************************************************
2556 template <typename TObject>
2557 void destroy_object_at(void* p)
2558 {
2559#if ETL_IS_DEBUG_BUILD
2560 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2561#endif
2562
2563 TObject& v = get_object_at<TObject>(p);
2564 v.~TObject();
2565 }
2566}
2567
2568#endif
Definition nullptr.h:42
#define ETL_ASSERT(b, e)
Definition error_handler.h:316
Definition memory.h:1293
TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T &value)
Definition memory.h:65
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:827
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
Definition memory.h:899
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:735
T * construct_at(T *p)
Definition memory.h:956
etl::enable_if< etl::is_trivially_destructible< T >::value, void >::type destroy_at(T *)
Definition memory.h:1006
TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
Definition memory.h:584
TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
Definition memory.h:336
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:1169
TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
Definition memory.h:459
TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
Definition memory.h:216
etl::enable_if< etl::is_trivially_constructible< typenameetl::iterator_traits< TOutputIterator >::value_type >::value, void >::type uninitialized_default_construct(TOutputIterator, TOutputIterator)
Definition memory.h:649
TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T &value)
Definition memory.h:189
Definition memory.h:1238
add_rvalue_reference
Definition type_traits_generator.h:1327
conditional
Definition type_traits_generator.h:1160
is_reference
Definition type_traits_generator.h:1111
is_same
Definition type_traits_generator.h:1041
bitset_ext
Definition absolute.h:38
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:1270
pair holds two objects of arbitrary type
Definition utility.h:164