Embedded Template Library 1.0
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>
65 TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
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>
79 TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
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>
189 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value)
190 {
191 return etl::uninitialized_fill(o_begin, o_begin + n, value);
192 }
193
194 //*****************************************************************************
199 //*****************************************************************************
200 template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
201 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count)
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>
216 TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
217 {
218 return std::uninitialized_copy(i_begin, i_end, o_begin);
219 }
220
221 //*****************************************************************************
226 //*****************************************************************************
227 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
228 TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
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>
336 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
337 {
338 return etl::uninitialized_copy(i_begin, i_begin + n, o_begin);
339 }
340
341 //*****************************************************************************
346 //*****************************************************************************
347 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
348 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
349 {
350 count += n;
351
352 return etl::uninitialized_copy(i_begin, i_begin + n, o_begin);
353 }
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>
459 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
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>
472 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
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>
584 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
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
590 return etl::uninitialized_copy_n(i_begin, n, o_begin);
591#endif
592 }
593
594 //*****************************************************************************
599 //*****************************************************************************
600 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
601 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
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
609 return etl::uninitialized_copy_n(i_begin, n, o_begin);
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 {
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
640 }
641#else
642 //*****************************************************************************
646 //*****************************************************************************
647 template <typename TOutputIterator>
649 uninitialized_default_construct(TOutputIterator /*o_begin*/, TOutputIterator /*o_end*/)
650 {
651 // Do nothing
652 }
653
654 //*****************************************************************************
658 //*****************************************************************************
659 template <typename TOutputIterator>
661 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end)
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>
681 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
682 {
683 count = int32_t(etl::distance(o_begin, o_end));
684 }
685
686 //*****************************************************************************
691 //*****************************************************************************
692 template <typename TOutputIterator, typename TCounter>
694 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
695 {
696 count += int32_t(etl::distance(o_begin, o_end));
697
699 }
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 {
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
726 }
727#else
728 //*****************************************************************************
732 //*****************************************************************************
733 template <typename TOutputIterator, typename TSize>
735 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
736 {
737 TOutputIterator o_end = o_begin + n;
738 return o_end;
739 }
740
741 //*****************************************************************************
745 //*****************************************************************************
746 template <typename TOutputIterator, typename TSize>
748 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
749 {
750 TOutputIterator o_end = o_begin + n;
751
753
754 return o_end;
755 }
756
757 //*****************************************************************************
762 //*****************************************************************************
763 template <typename TOutputIterator, typename TSize, typename TCounter>
765 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
766 {
767 TOutputIterator o_end = o_begin + n;
768
769 count += n;
770
771 return o_end;
772 }
773
774 //*****************************************************************************
779 //*****************************************************************************
780 template <typename TOutputIterator, typename TSize, typename TCounter>
782 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
783 {
784 TOutputIterator o_end = o_begin + n;
785
787
788 count += n;
789
790 return o_end;
791 }
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 {
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
818 }
819#else
820 //*****************************************************************************
824 //*****************************************************************************
825 template <typename TOutputIterator>
827 uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
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>
841 uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
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>
859 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
860 {
861 count += int32_t(etl::distance(o_begin, o_end));
862
864 }
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>
899 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
900 {
901 TOutputIterator o_end = o_begin + n;
902
904
905 return o_end;
906 }
907
908 //*****************************************************************************
913 //*****************************************************************************
914 template <typename TOutputIterator, typename TSize, typename TCounter>
915 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
916 {
917 TOutputIterator o_end = o_begin + n;
918
920
921 count += n;
922
923 return o_end;
924 }
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 {
983 }
984
985 //*****************************************************************************
990 //*****************************************************************************
991 template <typename T, typename TCounter>
992 ETL_CONSTEXPR20
993 void destroy_at(T* p, TCounter& count)
994 {
995 --count;
997 }
998#else
999 //*****************************************************************************
1003 //*****************************************************************************
1004 template <typename T>
1006 destroy_at(T* /*p*/)
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>
1043 destroy_at(T* p, TCounter& count)
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>
1094 destroy(TIterator i_begin, TIterator i_end)
1095 {
1096 while (i_begin != i_end)
1097 {
1099 ++i_begin;
1100 }
1101 }
1102
1103 //*****************************************************************************
1108 //*****************************************************************************
1109 template <typename TIterator, typename TCounter>
1111 destroy(TIterator i_begin, TIterator i_end, TCounter& count)
1112 {
1113 count -= int32_t(etl::distance(i_begin, i_end));
1114 }
1115
1116 //*****************************************************************************
1121 //*****************************************************************************
1122 template <typename TIterator, typename TCounter>
1124 destroy(TIterator i_begin, TIterator i_end, TCounter& count)
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>
1169 destroy_n(TIterator i_begin, TSize n)
1170 {
1171 return i_begin + n;
1172 }
1173
1174 //*****************************************************************************
1178 //*****************************************************************************
1179 template <typename TIterator, typename TSize>
1181 destroy_n(TIterator i_begin, TSize n)
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>
1201 destroy_n(TIterator i_begin, TSize n, TCounter& count)
1202 {
1203 count -= n;
1204 return i_begin + n;
1205 }
1206
1207 //*****************************************************************************
1212 //*****************************************************************************
1213 template <typename TIterator, typename TSize, typename TCounter>
1215 destroy_n(TIterator i_begin, TSize n, TCounter& count)
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>
1264 struct default_delete<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 //*********************************
1345 unique_ptr(pointer p_, typename etl::remove_reference<TDeleter>::type&& deleter_) ETL_NOEXCEPT
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 assert(p_ != p);
1399
1400 pointer value = p;
1401 p = p_;
1402 deleter(value);
1403 }
1404
1405 //*********************************
1406 void swap(unique_ptr& value) ETL_NOEXCEPT
1407 {
1408 using ETL_OR_STD::swap;
1409
1410 swap(p, value.p);
1411 }
1412
1413 //*********************************
1414 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
1415 {
1416 return (p != ETL_NULLPTR);
1417 }
1418
1419#if ETL_USING_STL && ETL_USING_CPP11
1420 //*********************************
1421 unique_ptr& operator =(std::nullptr_t) ETL_NOEXCEPT
1422 {
1423 reset(nullptr);
1424
1425 return *this;
1426 }
1427#else
1428 //*********************************
1429 unique_ptr& operator =(void*) ETL_NOEXCEPT
1430 {
1431 reset(NULL);
1432
1433 return *this;
1434 }
1435#endif
1436
1437#if ETL_USING_CPP11
1438 //*********************************
1439 unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT
1440 {
1441 if (&other != this)
1442 {
1443 reset(other.release());
1444 deleter = etl::move(other.deleter);
1445 }
1446
1447 return *this;
1448 }
1449#else
1450 //*********************************
1451 unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT
1452 {
1453 if (&other != this)
1454 {
1455 reset(other.release());
1456 deleter = other.deleter;
1457 }
1458
1459 return *this;
1460 }
1461#endif
1462
1463 //*********************************
1464 ETL_CONSTEXPR reference operator *() const
1465 {
1466 return *get();
1467 }
1468
1469 //*********************************
1470 ETL_CONSTEXPR pointer operator ->() const ETL_NOEXCEPT
1471 {
1472 return get();
1473 }
1474
1475 //*********************************
1476 ETL_CONSTEXPR reference operator [](size_t i) const
1477 {
1478 return p[i];
1479 }
1480
1481 private:
1482
1483 // Deleted.
1484 unique_ptr(const unique_ptr&) ETL_DELETE;
1485 unique_ptr& operator =(const unique_ptr&) ETL_DELETE;
1486
1487 pointer p;
1488 TDeleter deleter;
1489 };
1490
1491 //*****************************************************************************
1496 //*****************************************************************************
1497 template<typename T, typename TDeleter>
1498 class unique_ptr<T[], TDeleter>
1499 {
1500 public:
1501
1502 typedef T element_type;
1503 typedef T* pointer;
1504 typedef T& reference;
1505
1506 //*********************************
1507 ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT
1508 : p(ETL_NULLPTR)
1509 {
1510 }
1511
1512 //*********************************
1513 ETL_CONSTEXPR explicit unique_ptr(pointer p_) ETL_NOEXCEPT
1514 : p(p_)
1515 {
1516 }
1517
1518#if ETL_USING_CPP11
1519 //*********************************
1520 unique_ptr(unique_ptr&& other) ETL_NOEXCEPT
1521 {
1522 if (&other != this)
1523 {
1524 p = other.release();
1525 deleter = etl::move(other.deleter);
1526 }
1527 }
1528#else
1529 //*********************************
1530 unique_ptr(unique_ptr& other) ETL_NOEXCEPT
1531 {
1532 if (&other != this)
1533 {
1534 p = other.release();
1535 deleter = other.deleter;
1536 }
1537 }
1538#endif
1539
1540 //*********************************
1541 unique_ptr(pointer p_,
1543 TDeleter,
1544 typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
1545 : p(p_)
1546 , deleter(deleter_)
1547 {
1548 }
1549
1550#if ETL_USING_CPP11
1551 //*********************************
1552 unique_ptr(pointer p_, typename etl::remove_reference<TDeleter>::type&& deleter_) ETL_NOEXCEPT
1553 : p(p_)
1554 , deleter(etl::move(deleter_))
1555 {
1556 }
1557
1558 template <typename U, typename E>
1559 unique_ptr(unique_ptr<U, E>&& u) ETL_NOEXCEPT
1560 : p(u.release())
1561 , deleter(etl::forward<E>(u.get_deleter()))
1562 {
1563 }
1564#endif
1565
1566 //*********************************
1567 ~unique_ptr()
1568 {
1569 if (p != ETL_NULLPTR)
1570 {
1571 deleter(p);
1572 }
1573 }
1574
1575 //*********************************
1576 ETL_CONSTEXPR pointer get() const ETL_NOEXCEPT
1577 {
1578 return p;
1579 }
1580
1581 //*********************************
1582 TDeleter& get_deleter() ETL_NOEXCEPT
1583 {
1584 return deleter;
1585 }
1586
1587 //*********************************
1588 const TDeleter& get_deleter() const ETL_NOEXCEPT
1589 {
1590 return deleter;
1591 }
1592
1593 //*********************************
1594 pointer release() ETL_NOEXCEPT
1595 {
1596 pointer value = p;
1597 p = ETL_NULLPTR;
1598 return value;
1599 }
1600
1601 //*********************************
1602 void reset(pointer p_) ETL_NOEXCEPT
1603 {
1604 assert(p_ != p);
1605
1606 pointer value = p;
1607 p = p_;
1608 delete[] value;
1609 }
1610
1611 //*********************************
1612 void swap(unique_ptr& v) ETL_NOEXCEPT
1613 {
1614 using ETL_OR_STD::swap;
1615
1616 swap(p, v.p);
1617 }
1618
1619 //*********************************
1620 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
1621 {
1622 return (p != ETL_NULLPTR);
1623 }
1624
1625#if ETL_USING_STL && ETL_USING_CPP11
1626 //*********************************
1627 unique_ptr& operator =(std::nullptr_t) ETL_NOEXCEPT
1628 {
1629 reset(nullptr);
1630
1631 return *this;
1632 }
1633#else
1634 //*********************************
1635 unique_ptr& operator =(void*) ETL_NOEXCEPT
1636 {
1637 reset(NULL);
1638
1639 return *this;
1640 }
1641#endif
1642
1643#if ETL_USING_CPP11
1644 //*********************************
1645 unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT
1646 {
1647 if (&other != this)
1648 {
1649 reset(other.release());
1650 deleter = etl::move(other.deleter);
1651 }
1652
1653 return *this;
1654 }
1655#else
1656 //*********************************
1657 unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT
1658 {
1659 if (&other != this)
1660 {
1661 reset(other.release());
1662 deleter = other.deleter;
1663 }
1664
1665 return *this;
1666 }
1667#endif
1668
1669 //*********************************
1670 ETL_CONSTEXPR reference operator *() const
1671 {
1672 return *p;
1673 }
1674
1675 //*********************************
1676 ETL_CONSTEXPR pointer operator ->() const ETL_NOEXCEPT
1677 {
1678 return p;
1679 }
1680
1681 //*********************************
1682 ETL_CONSTEXPR reference operator [](size_t i) const
1683 {
1684 return p[i];
1685 }
1686
1687 private:
1688
1689 // Deleted.
1690 unique_ptr(const unique_ptr&) ETL_DELETE;
1691 unique_ptr& operator =(const unique_ptr&) ETL_DELETE;
1692
1693 pointer p;
1694 TDeleter deleter;
1695 };
1696}
1697
1698//*****************************************************************************
1699// Global functions for unique_ptr
1700//*****************************************************************************
1701template<typename T1, typename TD1, typename T2, typename TD2>
1702bool operator ==(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1703{
1704 return lhs.get() == rhs.get();
1705}
1706
1707//*********************************
1708template<typename T1, typename TD1, typename T2, typename TD2>
1709bool operator <(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1710{
1711 return reinterpret_cast<char*>(lhs.get()) < reinterpret_cast<char*>(rhs.get());
1712}
1713
1714//*********************************
1715template<typename T1, typename TD1, typename T2, typename TD2>
1716bool operator <=(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1717{
1718 return !(rhs < lhs);
1719}
1720
1721//*********************************
1722template<typename T1, typename TD1, typename T2, typename TD2>
1723bool operator >(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1724{
1725 return (rhs < lhs);
1726}
1727
1728//*********************************
1729template<typename T1, typename TD1, typename T2, typename TD2>
1730bool operator >=(const etl::unique_ptr<T1, TD1>&lhs, const etl::unique_ptr<T2, TD2>& rhs)
1731{
1732 return !(lhs < rhs);
1733}
1734
1735namespace etl
1736{
1737 //*****************************************************************************
1740 //*****************************************************************************
1741 template <typename T>
1744 {
1745 }
1746
1747 //*****************************************************************************
1750 //*****************************************************************************
1751 template <typename T, typename TCounter>
1753 create_default_at(T* /*p*/, TCounter& count)
1754 {
1755 ++count;
1756 }
1757
1758 //*****************************************************************************
1761 //*****************************************************************************
1762 template <typename T>
1765 {
1766 ::new (p) T;
1767 }
1768
1769 //*****************************************************************************
1772 //*****************************************************************************
1773 template <typename T, typename TCounter>
1775 create_default_at(T* p, TCounter& count)
1776 {
1777 ::new (p) T;
1778 ++count;
1779 }
1780
1781 //*****************************************************************************
1784 //*****************************************************************************
1785 template <typename T>
1787 {
1788 ::new (p) T();
1789 }
1790
1791 //*****************************************************************************
1794 //*****************************************************************************
1795 template <typename T, typename TCounter>
1796 void create_value_at(T* p, TCounter& count)
1797 {
1798 ::new (p) T();
1799 ++count;
1800 }
1801
1802 //*****************************************************************************
1805 //*****************************************************************************
1806 template <typename T>
1807 void create_copy_at(T* p, const T& value)
1808 {
1809 ::new (p) T(value);
1810 }
1811
1812#if ETL_USING_CPP11
1813 //*****************************************************************************
1816 //*****************************************************************************
1817 template <typename T>
1818 void create_copy_at(T* p, T&& value)
1819 {
1820 ::new (p) T(etl::move(value));
1821 }
1822#endif
1823
1824 //*****************************************************************************
1827 //*****************************************************************************
1828 template <typename T, typename TCounter>
1829 void create_copy_at(T* p, const T& value, TCounter& count)
1830 {
1831 ::new (p) T(value);
1832 ++count;
1833 }
1834
1835 //*****************************************************************************
1838 //*****************************************************************************
1839 template <typename T>
1841 {
1842 ::new (p) T();
1843 return *reinterpret_cast<T*>(p);
1844 }
1845
1846 //*****************************************************************************
1849 //*****************************************************************************
1850 template <typename T, typename TCounter>
1851 T& make_default_at(T* p, TCounter& count)
1852 {
1853 ::new (p) T();
1854 ++count;
1855 return *reinterpret_cast<T*>(p);
1856 }
1857
1858 //*****************************************************************************
1861 //*****************************************************************************
1862 template <typename T>
1863 T& make_copy_at(T* p, const T& other)
1864 {
1865 ::new (p) T(other);
1866 return *reinterpret_cast<T*>(p);
1867 }
1868
1869#if ETL_USING_CPP11
1870 //*****************************************************************************
1873 //*****************************************************************************
1874 template <typename T>
1875 T& make_copy_at(T* p, T&& other)
1876 {
1877 ::new (p) T(etl::move(other));
1878 return *reinterpret_cast<T*>(p);
1879 }
1880#endif
1881
1882 //*****************************************************************************
1885 //*****************************************************************************
1886 template <typename T, typename TCounter>
1887 T& make_copy_at(T* p, const T& other, TCounter& count)
1888 {
1889 ::new (p) T(other);
1890 ++count;
1891 return *reinterpret_cast<T*>(p);
1892 }
1893
1894 //*****************************************************************************
1897 //*****************************************************************************
1898 template <typename T, typename TParameter>
1899 T& make_value_at(T* p, const TParameter& value)
1900 {
1901 ::new (p) T(value);
1902 return *reinterpret_cast<T*>(p);
1903 }
1904
1905#if ETL_USING_CPP11
1906 //*****************************************************************************
1909 //*****************************************************************************
1910 template <typename T, typename TParameter>
1911 T& make_value_at(T* p, TParameter&& value)
1912 {
1913 ::new (p) T(etl::move(value));
1914 return *reinterpret_cast<T*>(p);
1915 }
1916#endif
1917
1918 //*****************************************************************************
1921 //*****************************************************************************
1922 template <typename T, typename TParameter, typename TCounter>
1923 T& make_value_at(T* p, const TParameter& value, TCounter& count)
1924 {
1925 ::new (p) T(value);
1926 ++count;
1927 return *reinterpret_cast<T*>(p);
1928 }
1929
1930 //*****************************************************************************
1934 //*****************************************************************************
1935 template <typename T>
1937 {
1938 void create_copy_at(void* p)
1939 {
1940 new (p) T(static_cast<const T&>(*this));
1941 }
1942
1943 template <typename TCounter>
1944 void create_copy_at(void* p, TCounter& count)
1945 {
1946 new (p) T(static_cast<const T&>(*this));
1947 ++count;
1948 }
1949
1950 T& make_copy_at(void* p)
1951 {
1952 new (p) T(static_cast<const T&>(*this));
1953 return *reinterpret_cast<T*>(p);
1954 }
1955
1956 template <typename TCounter>
1957 T& make_copy_at(void* p, TCounter& count)
1958 {
1959 new (p) T(static_cast<const T&>(*this));
1960 ++count;
1961 return *reinterpret_cast<T*>(p);
1962 }
1963 };
1964
1965 //*****************************************************************************
1970 //*****************************************************************************
1971 inline void memory_clear(volatile char* p, size_t n)
1972 {
1973 while (n--)
1974 {
1975 *p++ = 0;
1976 }
1977 }
1978
1979 //*****************************************************************************
1984 //*****************************************************************************
1985 template <typename T>
1986 void memory_clear(volatile T &object)
1987 {
1988 memory_clear(reinterpret_cast<volatile char*>(&object), sizeof(T));
1989 }
1990
1991 //*****************************************************************************
1997 //*****************************************************************************
1998 template <typename T>
1999 void memory_clear_range(volatile T* begin, size_t n)
2000 {
2001 memory_clear(reinterpret_cast<volatile char*>(begin), n * sizeof(T));
2002 }
2003
2004 //*****************************************************************************
2010 //*****************************************************************************
2011 template <typename T>
2012 void memory_clear_range(volatile T* begin, volatile T* end)
2013 {
2014 const size_t n = static_cast<size_t>(etl::distance(begin, end));
2015
2017 }
2018
2019 //*****************************************************************************
2025 //*****************************************************************************
2026 inline void memory_set(volatile char* p, size_t n, char value)
2027 {
2028 while (n--)
2029 {
2030 *p++ = value;
2031 }
2032 }
2033
2034 //*****************************************************************************
2040 //*****************************************************************************
2041 template <typename T>
2042 void memory_set(volatile T &object, const char value)
2043 {
2044 memory_set(reinterpret_cast<volatile char*>(&object), sizeof(T), value);
2045 }
2046
2047 //*****************************************************************************
2054 //*****************************************************************************
2055 template <typename T>
2056 void memory_set_range(volatile T* begin, size_t n, const char value)
2057 {
2058 memory_set(reinterpret_cast<volatile char*>(begin), n * sizeof(T), value);
2059 }
2060
2061 //*****************************************************************************
2068 //*****************************************************************************
2069 template <typename T>
2070 void memory_set_range(volatile T* begin, volatile T* end, const char value)
2071 {
2072 const size_t n = static_cast<size_t>(etl::distance(begin, end));
2073
2074 memory_set_range(begin, n, value);
2075 }
2076
2077 //*****************************************************************************
2083 //*****************************************************************************
2084 template <typename T>
2086 {
2088 {
2089 memory_clear(static_cast<volatile T&>(*this));
2090 }
2091 };
2092
2093 //***************************************************************************
2096 //***************************************************************************
2097 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2099 {
2100 public:
2101
2102 static ETL_CONSTANT size_t Object_Size = VObject_Size;
2103 static ETL_CONSTANT size_t N_Objects = VN_Objects;
2104 static ETL_CONSTANT size_t Alignment = VAlignment;
2105
2107 template <typename T>
2108 operator T& ()
2109 {
2110 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2111 return *reinterpret_cast<T*>(raw);
2112 }
2113
2115 template <typename T>
2116 operator const T& () const
2117 {
2118 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2119 return *reinterpret_cast<const T*>(raw);
2120 }
2121
2123 template <typename T>
2124 operator T* ()
2125 {
2126 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2127 return reinterpret_cast<T*>(raw);
2128 }
2129
2131 template <typename T>
2132 operator const T* () const
2133 {
2134 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2135 return reinterpret_cast<const T*>(raw);
2136 }
2137
2138#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
2139 alignas(VAlignment) char raw[Object_Size * N_Objects];
2140#else
2141 union
2142 {
2143 char raw[VObject_Size * VN_Objects];
2144 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment as VAlignment.
2145 };
2146#endif
2147 };
2148
2149 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2150 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Object_Size;
2151
2152 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2153 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::N_Objects;
2154
2155 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2156 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Alignment;
2157
2158 //***************************************************************************
2161 //***************************************************************************
2162 template <typename T, size_t VN_Objects>
2164 {
2165 public:
2166
2167 typedef T value_type;
2168 typedef T& reference;
2169 typedef const T& const_reference;
2170 typedef T* pointer;
2171 typedef const T* const_pointer;
2172 typedef T* iterator;
2173 typedef const T* const_iterator;
2174
2175 static ETL_CONSTANT size_t Object_Size = sizeof(T);
2176 static ETL_CONSTANT size_t N_Objects = VN_Objects;
2177 static ETL_CONSTANT size_t Alignment = etl::alignment_of<T>::value;
2178
2180 T& operator [](int i)
2181 {
2182 return reinterpret_cast<T*>(this->raw)[i];
2183 }
2184
2186 const T& operator [](int i) const
2187 {
2188 return reinterpret_cast<const T*>(this->raw)[i];
2189 }
2190
2192 operator T& ()
2193 {
2194 return *reinterpret_cast<T*>(raw);
2195 }
2196
2198 operator const T& () const
2199 {
2200 return *reinterpret_cast<const T*>(raw);
2201 }
2202
2204 operator T* ()
2205
2206 {
2207 return reinterpret_cast<T*>(raw);
2208 }
2209
2211 operator const T* () const
2212 {
2213 return reinterpret_cast<const T*>(raw);
2214 }
2215
2216 T* begin()
2217 {
2218 return reinterpret_cast<T*>(raw);
2219 }
2220
2221 const T* begin() const
2222 {
2223 return reinterpret_cast<const T*>(raw);
2224 }
2225
2226 T* end()
2227 {
2228 return reinterpret_cast<T*>(raw + (sizeof(T) * N_Objects));
2229 }
2230
2231 const T* end() const
2232 {
2233 return reinterpret_cast<const T*>(raw + (sizeof(T) * N_Objects));
2234 }
2235
2236#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
2237 alignas(Alignment) char raw[sizeof(T) * N_Objects];
2238#else
2239 union
2240 {
2241 char raw[sizeof(T) * N_Objects];
2242 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment as Alignment.
2243 };
2244#endif
2245 };
2246
2247 template <typename T, size_t VN_Objects>
2248 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Object_Size;
2249
2250 template <typename T, size_t VN_Objects>
2251 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::N_Objects;
2252
2253 template <typename T, size_t VN_Objects>
2254 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Alignment;
2255
2256#if ETL_USING_CPP11
2257 template <typename T, size_t N_Objects>
2258 using uninitialized_buffer_of_t = typename uninitialized_buffer_of<T, N_Objects>::buffer;
2259#endif
2260
2261 //***************************************************************************
2268 //***************************************************************************
2269 template <typename TPointer>
2271 mem_copy(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
2272 {
2273 return reinterpret_cast<TPointer>(memcpy(reinterpret_cast<void*>(db),
2274 reinterpret_cast<void*>(sb),
2275 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb)));
2276 }
2277
2278 //***************************************************************************
2284 //***************************************************************************
2285 template <typename TPointer>
2287 mem_copy(const TPointer sb, size_t n, TPointer db) ETL_NOEXCEPT
2288 {
2289 return reinterpret_cast<TPointer>(memcpy(reinterpret_cast<void*>(db),
2290 reinterpret_cast<void*>(sb),
2291 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n));
2292 }
2293
2294 //***************************************************************************
2300 //***************************************************************************
2301 template <typename TPointer>
2303 mem_move(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
2304 {
2305 return reinterpret_cast<TPointer>(memmove(reinterpret_cast<void*>(db),
2306 reinterpret_cast<void*>(sb),
2307 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb)));
2308 }
2309
2310 //***************************************************************************
2316 //***************************************************************************
2317 template <typename TPointer>
2319 mem_move(const TPointer sb, size_t n, TPointer db) ETL_NOEXCEPT
2320 {
2321 return reinterpret_cast<TPointer>(memmove(reinterpret_cast<void*>(db),
2322 reinterpret_cast<void*>(sb),
2323 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n));
2324 }
2325
2326 //***************************************************************************
2334 //***************************************************************************
2335 template <typename TPointer>
2336 ETL_NODISCARD
2338 mem_compare(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
2339 {
2340 return memcmp(reinterpret_cast<void*>(db),
2341 reinterpret_cast<void*>(sb),
2342 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
2343 }
2344
2345 //***************************************************************************
2353 //***************************************************************************
2354 template <typename TPointer>
2355 ETL_NODISCARD
2357 mem_compare(const TPointer sb, size_t n, TPointer db) ETL_NOEXCEPT
2358 {
2359 return memcmp(reinterpret_cast<void*>(db),
2360 reinterpret_cast<void*>(sb),
2361 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
2362 }
2363
2364 //***************************************************************************
2370 //***************************************************************************
2371 template <typename TPointer, typename T>
2373 mem_set(TPointer db, const TPointer de, T value) ETL_NOEXCEPT
2374 {
2375 return reinterpret_cast<TPointer>(memset(reinterpret_cast<void*>(db),
2376 static_cast<char>(value),
2377 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(de - db)));
2378 }
2379
2380 //***************************************************************************
2386 //***************************************************************************
2387 template <typename TPointer, typename T>
2389 mem_set(const TPointer db, size_t n, T value) ETL_NOEXCEPT
2390 {
2391 return reinterpret_cast<TPointer>(memset(reinterpret_cast<void*>(db),
2392 static_cast<char>(value),
2393 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n));
2394 }
2395
2396 //***************************************************************************
2402 //***************************************************************************
2403 template <typename TPointer, typename T>
2404 ETL_NODISCARD
2406 mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
2407 {
2408 void* result = memchr(reinterpret_cast<void*>(sb),
2409 static_cast<char>(value),
2410 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
2411
2412 return (result == 0U) ? reinterpret_cast<char*>(se) : reinterpret_cast<char*>(result);
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 const void* result = memchr(reinterpret_cast<const 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<const char*>(se) : reinterpret_cast<const char*>(result);
2432 }
2433
2434 //***************************************************************************
2440 //***************************************************************************
2441 template <typename TPointer, typename T>
2442 ETL_NODISCARD
2444 mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
2445 {
2446 void* result = memchr(reinterpret_cast<void*>(sb),
2447 static_cast<char>(value),
2448 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
2449
2450 return (result == 0U) ? reinterpret_cast<char*>(sb + n) : reinterpret_cast<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 const void* result = memchr(reinterpret_cast<const void*>(sb),
2466 static_cast<char>(value),
2467 sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
2468
2469 return (result == 0U) ? reinterpret_cast<const char*>(sb + n) : reinterpret_cast<const char*>(result);
2470 }
2471
2472#if ETL_USING_CPP11
2473 //*****************************************************************************
2475 //*****************************************************************************
2476 template <typename TObject>
2477 TObject& construct_object_at(void* p, TObject&& other)
2478 {
2479#if ETL_IS_DEBUG_BUILD
2480 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2481#endif
2482
2483 return *etl::construct_at(reinterpret_cast<typename etl::remove_reference<TObject>::type*>(p), etl::forward<TObject>(other));
2484 }
2485
2486 //*****************************************************************************
2488 //*****************************************************************************
2489 template <typename TObject, typename... TArgs>
2490 TObject& construct_object_at(void* p, TArgs&&... args)
2491 {
2492#if ETL_IS_DEBUG_BUILD
2493 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2494#endif
2495
2496 return *etl::construct_at(reinterpret_cast<TObject*>(p), etl::forward<TArgs>(args)...);
2497 }
2498#else
2499 //*****************************************************************************
2501 //*****************************************************************************
2502 template <typename TObject>
2503 TObject& construct_object_at(void* p)
2504 {
2505#if ETL_IS_DEBUG_BUILD
2506 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2507#endif
2508
2509 return *etl::construct_at(reinterpret_cast<TObject*>(p));
2510 }
2511
2512 //*****************************************************************************
2514 //*****************************************************************************
2515 template <typename TObject>
2516 TObject& construct_object_at(void* p, const TObject& other)
2517 {
2518#if ETL_IS_DEBUG_BUILD
2519 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2520#endif
2521
2522 return *etl::construct_at(reinterpret_cast<TObject*>(p), other);
2523 }
2524
2525 //*****************************************************************************
2527 //*****************************************************************************
2528 template <typename TObject, typename TArg>
2529 TObject& construct_object_at(void* p, const TArg& arg)
2530 {
2531#if ETL_IS_DEBUG_BUILD
2532 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2533#endif
2534
2535 return *etl::construct_at(reinterpret_cast<TObject*>(p), arg);
2536 }
2537#endif
2538
2539 //*****************************************************************************
2541 //*****************************************************************************
2542 template <typename TObject>
2543 TObject& get_object_at(void* p)
2544 {
2545#if ETL_IS_DEBUG_BUILD
2546 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2547#endif
2548
2549 TObject& v = *reinterpret_cast<TObject*>(p);
2550
2551 return v;
2552 }
2553
2554 //*****************************************************************************
2557 //*****************************************************************************
2558 template <typename TObject>
2559 void destroy_object_at(void* p)
2560 {
2561#if ETL_IS_DEBUG_BUILD
2562 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
2563#endif
2564
2565 TObject& v = get_object_at<TObject>(p);
2566 v.~TObject();
2567 }
2568}
2569
2570#endif
Memory misalignment exception.
Definition: alignment.h:65
T & operator[](int i)
Index operator.
Definition: memory.h:2180
Definition: memory.h:2099
Definition: memory.h:2164
#define ETL_ASSERT(b, e)
Definition: error_handler.h:316
Definition: memory.h:1293
TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter &count)
Definition: memory.h:915
TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T &value)
Definition: memory.h:65
TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T &value, TCounter &count)
Definition: memory.h:79
TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T &value, TCounter &count)
Definition: memory.h:201
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
void memory_set_range(volatile T *begin, size_t n, const char value)
Definition: memory.h:2056
TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
Definition: memory.h:899
etl::enable_if< etl::is_trivially_constructible< T >::value, void >::type create_default_at(T *)
Definition: memory.h:1743
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
void create_copy_at(T *p, const T &value)
Definition: memory.h:1807
TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter &count)
Definition: memory.h:228
void create_value_at(T *p)
Definition: memory.h:1786
T & make_value_at(T *p, const TParameter &value)
Definition: memory.h:1899
etl::enable_if< etl::is_trivially_destructible< T >::value, void >::type destroy_at(T *)
Definition: memory.h:1006
void memory_clear_range(volatile T *begin, size_t n)
Definition: memory.h:1999
void memory_set(volatile char *p, size_t n, char value)
Definition: memory.h:2026
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
T & make_default_at(T *p)
Definition: memory.h:1840
TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
Definition: memory.h:459
TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter &count)
Definition: memory.h:472
T & make_copy_at(T *p, const T &other)
Definition: memory.h:1863
T * construct_at(T *p, const TArg &arg)
Definition: memory.h:966
void memory_clear(volatile char *p, size_t n)
Definition: memory.h:1971
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
ETL_CONSTEXPR17 T * addressof(T &t)
Definition: addressof.h:51
void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter &count)
Definition: memory.h:859
TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter &count)
Definition: memory.h:348
Definition: memory.h:1937
Definition: memory.h:1238
Definition: memory.h:2086
add_rvalue_reference
Definition: type_traits_generator.h:1327
conditional
Definition: type_traits_generator.h:1160
enable_if
Definition: type_traits_generator.h:1191
is_const
Definition: type_traits_generator.h:908
is_reference
Definition: type_traits_generator.h:1111
is_same
Definition: type_traits_generator.h:1041
bitset_ext
Definition: absolute.h:38
void destroy_object_at(void *p)
Definition: memory.h:2559
ETL_NODISCARD etl::enable_if< etl::is_trivially_copyable< typenameetl::iterator_traits< TPointer >::value_type >::value, int >::type mem_compare(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
Definition: memory.h:2338
TObject & construct_object_at(void *p)
Default construct the container at 'p'.
Definition: memory.h:2503
etl::enable_if< etl::is_trivially_copyable< typenameetl::iterator_traits< TPointer >::value_type >::value, TPointer >::type mem_set(TPointer db, const TPointer de, T value) ETL_NOEXCEPT
Definition: memory.h:2373
void swap(etl::array< T, SIZE > &lhs, etl::array< T, SIZE > &rhs)
Template deduction guides.
Definition: array.h:621
etl::enable_if< etl::is_trivially_copyable< typenameetl::iterator_traits< TPointer >::value_type >::value, TPointer >::type mem_move(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
Definition: memory.h:2303
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition: iterator.h:931
void destroy(const T *const p)
Destroys the object.
Definition: variant_pool_generator.h:256
ETL_NODISCARD etl::enable_if< etl::is_pointer< TPointer >::value &&!etl::is_const< typenameetl::remove_pointer< TPointer >::type >::value, char * >::type mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
Definition: memory.h:2406
etl::enable_if< etl::is_trivially_copyable< typenameetl::iterator_traits< TPointer >::value_type >::value, TPointer >::type mem_copy(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
Definition: memory.h:2271
TObject & get_object_at(void *p)
Get the container at 'p'.
Definition: memory.h:2543
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition: iterator.h:961
etl::enable_if<!etl::is_trivially_destructible< typenameetl::iterator_traits< TIterator >::value_type >::value, void >::type destroy(TIterator i_begin, TIterator i_end, TCounter &count)
Definition: memory.h:1124
etl::enable_if<!etl::is_trivially_constructible< typenameetl::iterator_traits< TOutputIterator >::value_type >::value, void >::type uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter &count)
Definition: memory.h:694
etl::enable_if<!etl::is_trivially_destructible< typenameetl::iterator_traits< TIterator >::value_type >::value, TIterator >::type destroy_n(TIterator i_begin, TSize n, TCounter &count)
Definition: memory.h:1215
etl::enable_if<!etl::is_trivially_destructible< T >::value, void >::type destroy_at(T *p, TCounter &count)
Definition: memory.h:1043
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, TCounter &count)
Definition: memory.h:782