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 "alignment.h"
37#include "iterator.h"
38#include "nullptr.h"
39#include "placement_new.h"
40#include "type_traits.h"
41#include "utility.h"
42
43#include "private/addressof.h"
44
45#include <assert.h>
46#include <string.h>
47
48#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
49 #include <memory>
50#endif
51
54
55namespace etl
56{
57 //*****************************************************************************
60 //*****************************************************************************
61 template <typename T>
62 ETL_CONSTEXPR T* to_address(T* p) ETL_NOEXCEPT
63 {
64 return p;
65 }
66
67 //*****************************************************************************
71 //*****************************************************************************
72 template <typename Iterator>
73 ETL_CONSTEXPR typename Iterator::pointer to_address(const Iterator& itr) ETL_NOEXCEPT
74 {
75 return etl::to_address(itr.operator->());
76 }
77
78#if ETL_USING_STL
79 //*****************************************************************************
84 //*****************************************************************************
85 template <typename TOutputIterator, typename T>
86 TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
87 {
88 std::uninitialized_fill(o_begin, o_end, value);
89
90 return o_end;
91 }
92
93 //*****************************************************************************
98 //*****************************************************************************
99 template <typename TOutputIterator, typename T, typename TCounter>
100 TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
101 {
102 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
103
104 std::uninitialized_fill(o_begin, o_end, value);
105
106 return o_end;
107 }
108#else
109 //*****************************************************************************
113 //*****************************************************************************
114 template <typename TOutputIterator, typename T>
115 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
116 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
117 {
118 etl::fill(o_begin, o_end, value);
119
120 return o_end;
121 }
122
123 //*****************************************************************************
127 //*****************************************************************************
128 template <typename TOutputIterator, typename T>
129 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
130 TOutputIterator>::type
131 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
132 {
133 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
134
135 while (o_begin != o_end)
136 {
137 ::new (static_cast<void*>(etl::to_address(o_begin))) value_type(value);
138 ++o_begin;
139 }
140
141 return o_end;
142 }
143
144 //*****************************************************************************
149 //*****************************************************************************
150 template <typename TOutputIterator, typename T, typename TCounter>
151 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
152 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
153 {
154 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
155
156 etl::fill(o_begin, o_end, value);
157
158 return o_end;
159 }
160
161 //*****************************************************************************
166 //*****************************************************************************
167 template <typename TOutputIterator, typename T, typename TCounter>
168 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
169 TOutputIterator>::type
170 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
171 {
172 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
173
174 etl::uninitialized_fill(o_begin, o_end, value);
175
176 return o_end;
177 }
178#endif
179
180#if ETL_USING_STL && ETL_USING_CPP11
181 //*****************************************************************************
185 //*****************************************************************************
186 template <typename TOutputIterator, typename TSize, typename T>
187 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value)
188 {
189 return std::uninitialized_fill_n(o_begin, n, value);
190 }
191
192 //*****************************************************************************
197 //*****************************************************************************
198 template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
199 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count)
200 {
201 count += n;
202
203 return std::uninitialized_fill_n(o_begin, n, value);
204 }
205#else
206 //*****************************************************************************
210 //*****************************************************************************
211 template <typename TOutputIterator, typename TSize, typename T>
212 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value)
213 {
214 return etl::uninitialized_fill(o_begin, o_begin + n, value);
215 }
216
217 //*****************************************************************************
222 //*****************************************************************************
223 template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
224 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count)
225 {
226 count += n;
227
228 return etl::uninitialized_fill(o_begin, o_begin + n, value);
229 }
230#endif
231
232#if ETL_USING_STL
233 //*****************************************************************************
237 //*****************************************************************************
238 template <typename TInputIterator, typename TOutputIterator>
239 TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
240 {
241 return std::uninitialized_copy(i_begin, i_end, o_begin);
242 }
243
244 //*****************************************************************************
249 //*****************************************************************************
250 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
251 TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
252 {
253 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
254
255 return std::uninitialized_copy(i_begin, i_end, o_begin);
256 }
257#else
258 //*****************************************************************************
262 //*****************************************************************************
263 template <typename TInputIterator, typename TOutputIterator>
264 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
265 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
266 {
267 return etl::copy(i_begin, i_end, o_begin);
268 }
269
270 //*****************************************************************************
274 //*****************************************************************************
275 template <typename TInputIterator, typename TOutputIterator>
276 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
277 TOutputIterator>::type
278 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
279 {
280 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
281
282 TOutputIterator o_end = o_begin;
283
284 while (i_begin != i_end)
285 {
286 ::new (static_cast<void*>(etl::to_address(o_end))) value_type(*i_begin);
287 ++i_begin;
288 ++o_end;
289 }
290
291 return o_end;
292 }
293
294 //*****************************************************************************
299 //*****************************************************************************
300 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
301 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
302 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
303 {
304 TOutputIterator o_end = etl::copy(i_begin, i_end, o_begin);
305 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
306
307 return o_end;
308 }
309
310 //*****************************************************************************
315 //*****************************************************************************
316 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
317 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
318 TOutputIterator>::type
319 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
320 {
321 TOutputIterator o_end = etl::uninitialized_copy(i_begin, i_end, o_begin);
322
323 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
324
325 return o_end;
326 }
327#endif
328
329#if ETL_USING_CPP17
330 namespace ranges
331 {
332 //*****************************************************************************
336 //*****************************************************************************
337 struct uninitialized_copy_fn
338 {
339 template <class I, class S1, class O, class S2, typename = etl::enable_if_t<!etl::is_range_v<I>>>
340 ranges::uninitialized_copy_result<I, O> operator()(I ifirst, S1 ilast, O ofirst, S2 olast) const
341 {
342 using value_type = typename etl::iterator_traits<O>::value_type;
343
344 O ofirst_original = ofirst;
345
346 #if ETL_USING_EXCEPTIONS
347 try
348 {
349 #endif
350 for (; ifirst != ilast && ofirst != olast; ++ifirst, ++ofirst)
351 {
352 ::new (static_cast<void*>(etl::to_address(ofirst))) value_type(*ifirst);
353 }
354
355 return {etl::move(ifirst), etl::move(ofirst)};
356 #if ETL_USING_EXCEPTIONS
357 }
358 catch (...)
359 {
360 for (; ofirst_original != ofirst; ++ofirst_original)
361 {
362 etl::to_address(ofirst_original)->~value_type();
363 }
364 throw;
365 }
366 #endif
367 }
368
369 template <class IR, class OR, typename = etl::enable_if_t<etl::is_range_v<IR>>>
370 ranges::uninitialized_copy_result<ranges::borrowed_iterator_t<IR>, ranges::borrowed_iterator_t<OR>> operator()(IR&& in_range,
371 OR&& out_range) const
372 {
373 return (*this)(ranges::begin(in_range), ranges::end(in_range), ranges::begin(out_range), ranges::end(out_range));
374 }
375 };
376
377 inline constexpr uninitialized_copy_fn uninitialized_copy{};
378
379 //*****************************************************************************
383 //*****************************************************************************
384 struct uninitialized_copy_n_fn
385 {
386 template <class I, class O, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
387 ranges::uninitialized_copy_n_result<I, O> operator()(I ifirst, etl::iter_difference_t<I> n, O ofirst, S olast) const
388 {
389 using value_type = typename etl::iterator_traits<O>::value_type;
390
391 O ofirst_original = ofirst;
392
393 #if ETL_USING_EXCEPTIONS
394 try
395 {
396 #endif
397 for (; n > 0 && ofirst != olast; ++ifirst, ++ofirst, --n)
398 {
399 ::new (static_cast<void*>(etl::to_address(ofirst))) value_type(*ifirst);
400 }
401
402 return {etl::move(ifirst), etl::move(ofirst)};
403 #if ETL_USING_EXCEPTIONS
404 }
405 catch (...)
406 {
407 for (; ofirst_original != ofirst; ++ofirst_original)
408 {
409 etl::to_address(ofirst_original)->~value_type();
410 }
411 throw;
412 }
413 #endif
414 }
415 };
416
417 inline constexpr uninitialized_copy_n_fn uninitialized_copy_n{};
418
419 //*****************************************************************************
423 //*****************************************************************************
424 struct uninitialized_fill_fn
425 {
426 template <class I, class S, class T, typename = etl::enable_if_t<!etl::is_range_v<I>>>
427 I operator()(I first, S last, const T& value) const
428 {
429 using value_type = typename etl::iterator_traits<I>::value_type;
430
431 I current = first;
432
433 #if ETL_USING_EXCEPTIONS
434 try
435 {
436 #endif
437 for (; current != last; ++current)
438 {
439 ::new (static_cast<void*>(etl::to_address(current))) value_type(value);
440 }
441
442 return current;
443 #if ETL_USING_EXCEPTIONS
444 }
445 catch (...)
446 {
447 for (; first != current; ++first)
448 {
449 etl::to_address(first)->~value_type();
450 }
451 throw;
452 }
453 #endif
454 }
455
456 template <class R, class T, typename = etl::enable_if_t<etl::is_range_v<R>>>
457 ranges::borrowed_iterator_t<R> operator()(R&& r, const T& value) const
458 {
459 return (*this)(ranges::begin(r), ranges::end(r), value);
460 }
461 };
462
463 inline constexpr uninitialized_fill_fn uninitialized_fill{};
464
465 //*****************************************************************************
469 //*****************************************************************************
470 struct uninitialized_fill_n_fn
471 {
472 template <class I, class T>
473 I operator()(I first, etl::iter_difference_t<I> n, const T& value) const
474 {
475 using value_type = typename etl::iterator_traits<I>::value_type;
476
477 I current = first;
478
479 #if ETL_USING_EXCEPTIONS
480 try
481 {
482 #endif
483 for (; n > 0; ++current, --n)
484 {
485 ::new (static_cast<void*>(etl::to_address(current))) value_type(value);
486 }
487
488 return current;
489 #if ETL_USING_EXCEPTIONS
490 }
491 catch (...)
492 {
493 for (; first != current; ++first)
494 {
495 etl::to_address(first)->~value_type();
496 }
497 throw;
498 }
499 #endif
500 }
501 };
502
503 inline constexpr uninitialized_fill_n_fn uninitialized_fill_n{};
504 } // namespace ranges
505#endif
506
507#if ETL_USING_STL && ETL_USING_CPP11
508 //*****************************************************************************
512 //*****************************************************************************
513 template <typename TInputIterator, typename TSize, typename TOutputIterator>
514 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
515 {
516 return std::uninitialized_copy_n(i_begin, n, o_begin);
517 }
518
519 //*****************************************************************************
524 //*****************************************************************************
525 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
526 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
527 {
528 count += n;
529
530 return std::uninitialized_copy_n(i_begin, n, o_begin);
531 }
532#else
533 //*****************************************************************************
537 //*****************************************************************************
538 template <typename TInputIterator, typename TSize, typename TOutputIterator>
539 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
540 {
541 return etl::uninitialized_copy(i_begin, i_begin + n, o_begin);
542 }
543
544 //*****************************************************************************
549 //*****************************************************************************
550 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
551 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
552 {
553 count += n;
554
555 return etl::uninitialized_copy(i_begin, i_begin + n, o_begin);
556 }
557#endif
558
559#if ETL_USING_CPP11
560 #if ETL_USING_STL && ETL_USING_CPP17
561 //*****************************************************************************
565 //*****************************************************************************
566 template <typename TInputIterator, typename TOutputIterator>
567 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
568 {
571 return std::uninitialized_move(i_begin, i_end, o_begin);
573 }
574
575 //*****************************************************************************
580 //*****************************************************************************
581 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
582 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
583 {
584 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
585
587 return std::uninitialized_move(i_begin, i_end, o_begin);
589 }
590 #else
591 //*****************************************************************************
595 //*****************************************************************************
596 template <typename TInputIterator, typename TOutputIterator>
597 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
598 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
599 {
600 return etl::move(i_begin, i_end, o_begin);
601 }
602
603 //*****************************************************************************
607 //*****************************************************************************
608 template <typename TInputIterator, typename TOutputIterator>
609 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
610 TOutputIterator>::type
611 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
612 {
613 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
614
615 TOutputIterator o_end = o_begin;
616
617 while (i_begin != i_end)
618 {
619 ::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
620 ++i_begin;
621 ++o_end;
622 }
623
624 return o_end;
625 }
626
627 //*****************************************************************************
632 //*****************************************************************************
633 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
634 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
635 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
636 {
637 TOutputIterator o_end = etl::move(i_begin, i_end, o_begin);
638 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
639
640 return o_end;
641 }
642
643 //*****************************************************************************
648 //*****************************************************************************
649 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
650 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
651 TOutputIterator>::type
652 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
653 {
654 TOutputIterator o_end = etl::uninitialized_move(i_begin, i_end, o_begin);
655
656 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
657
658 return o_end;
659 }
660 #endif
661#else
662 // C++03
663 //*****************************************************************************
667 //*****************************************************************************
668 template <typename TInputIterator, typename TOutputIterator>
669 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
670 {
671 // Move not supported. Defer to copy.
672 return ETL_OR_STD::uninitialized_copy(i_begin, i_end, o_begin);
673 }
674
675 //*****************************************************************************
680 //*****************************************************************************
681 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
682 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
683 {
684 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
685
686 // Move not supported. Defer to copy.
687 return ETL_OR_STD::uninitialized_copy(i_begin, i_end, o_begin);
688 }
689#endif
690
691#if ETL_USING_CPP11
692 #if ETL_USING_STL && ETL_USING_CPP17
693 //*****************************************************************************
697 //*****************************************************************************
698 template <typename TInputIterator, typename TSize, typename TOutputIterator>
699 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
700 {
701 return std::uninitialized_move(i_begin, i_begin + n, o_begin);
702 }
703
704 //*****************************************************************************
709 //*****************************************************************************
710 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
711 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
712 {
713 count += TCounter(n);
714
715 return std::uninitialized_move(i_begin, i_begin + n, o_begin);
716 }
717 #else
718 //*****************************************************************************
722 //*****************************************************************************
723 template <typename TInputIterator, typename TSize, typename TOutputIterator>
724 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
725 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
726 {
727 return etl::move(i_begin, i_begin + n, o_begin);
728 }
729
730 //*****************************************************************************
734 //*****************************************************************************
735 template <typename TInputIterator, typename TSize, typename TOutputIterator>
736 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
737 TOutputIterator>::type
738 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
739 {
740 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
741
742 TOutputIterator o_end = o_begin;
743
744 while (n-- != 0)
745 {
746 ::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
747 ++i_begin;
748 ++o_end;
749 }
750
751 return o_end;
752 }
753
754 //*****************************************************************************
759 //*****************************************************************************
760 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
761 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
762 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
763 {
764 TOutputIterator o_end = etl::move(i_begin, i_begin + n, o_begin);
765 count += TCounter(n);
766
767 return o_end;
768 }
769
770 //*****************************************************************************
775 //*****************************************************************************
776 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
777 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
778 TOutputIterator>::type
779 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
780 {
781 TOutputIterator o_end = etl::uninitialized_move(i_begin, i_begin + n, o_begin);
782
783 count += TCounter(n);
784
785 return o_end;
786 }
787 #endif
788#else
789 // C++03
790 //*****************************************************************************
794 //*****************************************************************************
795 template <typename TInputIterator, typename TSize, typename TOutputIterator>
796 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
797 {
798 // Move not supported. Defer to copy.
799 #if ETL_USING_CPP11
800 return std::uninitialized_copy_n(i_begin, n, o_begin);
801 #else
802 return etl::uninitialized_copy_n(i_begin, n, o_begin);
803 #endif
804 }
805
806 //*****************************************************************************
811 //*****************************************************************************
812 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
813 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
814 {
815 count += TCounter(n);
816
817 // Move not supported. Defer to copy.
818 #if ETL_USING_CPP11
819 return std::uninitialized_copy_n(i_begin, n, o_begin);
820 #else
821 return etl::uninitialized_copy_n(i_begin, n, o_begin);
822 #endif
823 }
824#endif
825
826#if ETL_USING_CPP17
827 namespace ranges
828 {
829 //*****************************************************************************
833 //*****************************************************************************
834 struct uninitialized_move_fn
835 {
836 template <class I, class S1, class O, class S2, typename = etl::enable_if_t<!etl::is_range_v<I>>>
837 ranges::uninitialized_move_result<I, O> operator()(I ifirst, S1 ilast, O ofirst, S2 olast) const
838 {
839 using value_type = typename etl::iterator_traits<O>::value_type;
840
841 O ofirst_original = ofirst;
842
843 #if ETL_USING_EXCEPTIONS
844 try
845 {
846 #endif
847 for (; ifirst != ilast && ofirst != olast; ++ifirst, ++ofirst)
848 {
849 ::new (static_cast<void*>(etl::to_address(ofirst))) value_type(etl::move(*ifirst));
850 }
851
852 return {etl::move(ifirst), etl::move(ofirst)};
853 #if ETL_USING_EXCEPTIONS
854 }
855 catch (...)
856 {
857 for (; ofirst_original != ofirst; ++ofirst_original)
858 {
859 etl::to_address(ofirst_original)->~value_type();
860 }
861 throw;
862 }
863 #endif
864 }
865
866 template <class IR, class OR, typename = etl::enable_if_t<etl::is_range_v<IR>>>
867 ranges::uninitialized_move_result<ranges::borrowed_iterator_t<IR>, ranges::borrowed_iterator_t<OR>> operator()(IR&& in_range,
868 OR&& out_range) const
869 {
870 return (*this)(ranges::begin(in_range), ranges::end(in_range), ranges::begin(out_range), ranges::end(out_range));
871 }
872 };
873
874 inline constexpr uninitialized_move_fn uninitialized_move{};
875
876 //*****************************************************************************
880 //*****************************************************************************
881 struct uninitialized_move_n_fn
882 {
883 template <class I, class O, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
884 ranges::uninitialized_move_n_result<I, O> operator()(I ifirst, etl::iter_difference_t<I> n, O ofirst, S olast) const
885 {
886 using value_type = typename etl::iterator_traits<O>::value_type;
887
888 O ofirst_original = ofirst;
889
890 #if ETL_USING_EXCEPTIONS
891 try
892 {
893 #endif
894 for (; n > 0 && ofirst != olast; ++ifirst, ++ofirst, --n)
895 {
896 ::new (static_cast<void*>(etl::to_address(ofirst))) value_type(etl::move(*ifirst));
897 }
898
899 return {etl::move(ifirst), etl::move(ofirst)};
900 #if ETL_USING_EXCEPTIONS
901 }
902 catch (...)
903 {
904 for (; ofirst_original != ofirst; ++ofirst_original)
905 {
906 etl::to_address(ofirst_original)->~value_type();
907 }
908 throw;
909 }
910 #endif
911 }
912 };
913
914 inline constexpr uninitialized_move_n_fn uninitialized_move_n{};
915 } // namespace ranges
916#endif
917
918#if ETL_USING_STL && ETL_USING_CPP17
919 //*****************************************************************************
923 //*****************************************************************************
924 template <typename TOutputIterator>
925 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
926 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end)
927 {
928 std::uninitialized_default_construct(o_begin, o_end);
929 }
930
931 //*****************************************************************************
936 //*****************************************************************************
937 template <typename TOutputIterator, typename TCounter>
938 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
939 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
940 {
941 count = static_cast<TCounter>(etl::distance(o_begin, o_end));
942
943 std::uninitialized_default_construct(o_begin, o_end);
944 }
945#else
946 //*****************************************************************************
950 //*****************************************************************************
951 template <typename TOutputIterator>
952 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
953 uninitialized_default_construct(TOutputIterator /*o_begin*/, TOutputIterator /*o_end*/)
954 {
955 // Do nothing
956 }
957
958 //*****************************************************************************
962 //*****************************************************************************
963 template <typename TOutputIterator>
964 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
965 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end)
966 {
967 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
968
969 while (o_begin != o_end)
970 {
971 ::new (static_cast<void*>(etl::to_address(o_begin))) value_type;
972 ++o_begin;
973 }
974 }
975
976 //*****************************************************************************
981 //*****************************************************************************
982 template <typename TOutputIterator, typename TCounter>
983 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
984 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
985 {
986 count = static_cast<TCounter>(etl::distance(o_begin, o_end));
987 }
988
989 //*****************************************************************************
994 //*****************************************************************************
995 template <typename TOutputIterator, typename TCounter>
996 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
997 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
998 {
999 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
1000
1002 }
1003#endif
1004
1005#if ETL_USING_STL && ETL_USING_CPP17
1006 //*****************************************************************************
1010 //*****************************************************************************
1011 template <typename TOutputIterator, typename TSize>
1012 TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
1013 {
1014 return std::uninitialized_default_construct_n(o_begin, n);
1015 }
1016
1017 //*****************************************************************************
1022 //*****************************************************************************
1023 template <typename TOutputIterator, typename TSize, typename TCounter>
1024 TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1025 {
1026 count += n;
1027
1028 return std::uninitialized_default_construct_n(o_begin, n);
1029 }
1030#else
1031 //*****************************************************************************
1035 //*****************************************************************************
1036 template <typename TOutputIterator, typename TSize>
1037 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
1038 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
1039 {
1040 TOutputIterator o_end = o_begin + n;
1041 return o_end;
1042 }
1043
1044 //*****************************************************************************
1048 //*****************************************************************************
1049 template <typename TOutputIterator, typename TSize>
1050 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
1051 TOutputIterator>::type
1052 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
1053 {
1054 TOutputIterator o_end = o_begin + n;
1055
1057
1058 return o_end;
1059 }
1060
1061 //*****************************************************************************
1066 //*****************************************************************************
1067 template <typename TOutputIterator, typename TSize, typename TCounter>
1068 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
1069 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1070 {
1071 TOutputIterator o_end = o_begin + n;
1072
1073 count += n;
1074
1075 return o_end;
1076 }
1077
1078 //*****************************************************************************
1083 //*****************************************************************************
1084 template <typename TOutputIterator, typename TSize, typename TCounter>
1085 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
1086 TOutputIterator>::type
1087 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1088 {
1089 TOutputIterator o_end = o_begin + n;
1090
1092
1093 count += n;
1094
1095 return o_end;
1096 }
1097#endif
1098
1099#if ETL_USING_CPP17
1100 namespace ranges
1101 {
1102 //*****************************************************************************
1106 //*****************************************************************************
1107 struct uninitialized_default_construct_fn
1108 {
1109 template <class I, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
1110 I operator()(I first, S last) const
1111 {
1112 using value_type = typename etl::iterator_traits<I>::value_type;
1113
1114 I current = first;
1115
1116 #if ETL_USING_EXCEPTIONS
1117 try
1118 {
1119 #endif
1120 for (; current != last; ++current)
1121 {
1122 ::new (static_cast<void*>(etl::to_address(current))) value_type;
1123 }
1124
1125 return current;
1126 #if ETL_USING_EXCEPTIONS
1127 }
1128 catch (...)
1129 {
1130 for (; first != current; ++first)
1131 {
1132 etl::to_address(first)->~value_type();
1133 }
1134 throw;
1135 }
1136 #endif
1137 }
1138
1139 template <class R, typename = etl::enable_if_t<etl::is_range_v<R>>>
1140 ranges::borrowed_iterator_t<R> operator()(R&& r) const
1141 {
1142 return (*this)(ranges::begin(r), ranges::end(r));
1143 }
1144 };
1145
1146 inline constexpr uninitialized_default_construct_fn uninitialized_default_construct{};
1147
1148 //*****************************************************************************
1152 //*****************************************************************************
1153 struct uninitialized_default_construct_n_fn
1154 {
1155 template <class I>
1156 I operator()(I first, etl::iter_difference_t<I> n) const
1157 {
1158 using value_type = typename etl::iterator_traits<I>::value_type;
1159
1160 I current = first;
1161
1162 #if ETL_USING_EXCEPTIONS
1163 try
1164 {
1165 #endif
1166 for (; n > 0; ++current, --n)
1167 {
1168 ::new (static_cast<void*>(etl::to_address(current))) value_type;
1169 }
1170
1171 return current;
1172 #if ETL_USING_EXCEPTIONS
1173 }
1174 catch (...)
1175 {
1176 for (; first != current; ++first)
1177 {
1178 etl::to_address(first)->~value_type();
1179 }
1180 throw;
1181 }
1182 #endif
1183 }
1184 };
1185
1186 inline constexpr uninitialized_default_construct_n_fn uninitialized_default_construct_n{};
1187 } // namespace ranges
1188#endif
1189
1190#if ETL_USING_STL && ETL_USING_CPP17
1191 //*****************************************************************************
1195 //*****************************************************************************
1196 template <typename TOutputIterator>
1197 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
1198 {
1199 std::uninitialized_value_construct(o_begin, o_end);
1200 }
1201
1202 //*****************************************************************************
1207 //*****************************************************************************
1208 template <typename TOutputIterator, typename TCounter>
1209 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
1210 {
1211 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
1212
1213 std::uninitialized_value_construct(o_begin, o_end);
1214 }
1215#else
1216 //*****************************************************************************
1220 //*****************************************************************************
1221 template <typename TOutputIterator>
1222 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1223 uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
1224 {
1225 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
1226
1227 etl::fill(o_begin, o_end, value_type());
1228 }
1229
1230 //*****************************************************************************
1234 //*****************************************************************************
1235 template <typename TOutputIterator>
1236 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1237 uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
1238 {
1239 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
1240
1241 while (o_begin != o_end)
1242 {
1243 ::new (static_cast<void*>(etl::to_address(o_begin))) value_type();
1244 ++o_begin;
1245 }
1246 }
1247
1248 //*****************************************************************************
1253 //*****************************************************************************
1254 template <typename TOutputIterator, typename TCounter>
1255 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
1256 {
1257 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
1258
1259 etl::uninitialized_value_construct(o_begin, o_end);
1260 }
1261#endif
1262
1263#if ETL_USING_STL && ETL_USING_CPP17
1264 //*****************************************************************************
1268 //*****************************************************************************
1269 template <typename TOutputIterator, typename TSize>
1270 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
1271 {
1272 return std::uninitialized_value_construct_n(o_begin, n);
1273 }
1274
1275 //*****************************************************************************
1280 //*****************************************************************************
1281 template <typename TOutputIterator, typename TSize, typename TCounter>
1282 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1283 {
1284 count += n;
1285
1286 return std::uninitialized_value_construct_n(o_begin, n);
1287 }
1288#else
1289 //*****************************************************************************
1293 //*****************************************************************************
1294 template <typename TOutputIterator, typename TSize>
1295 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
1296 {
1297 TOutputIterator o_end = o_begin + n;
1298
1299 etl::uninitialized_value_construct(o_begin, o_end);
1300
1301 return o_end;
1302 }
1303
1304 //*****************************************************************************
1309 //*****************************************************************************
1310 template <typename TOutputIterator, typename TSize, typename TCounter>
1311 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1312 {
1313 TOutputIterator o_end = o_begin + n;
1314
1315 etl::uninitialized_value_construct(o_begin, o_end);
1316
1317 count += n;
1318
1319 return o_end;
1320 }
1321#endif
1322
1323#if ETL_USING_CPP17
1324 namespace ranges
1325 {
1326 //*****************************************************************************
1330 //*****************************************************************************
1331 struct uninitialized_value_construct_fn
1332 {
1333 template <class I, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
1334 I operator()(I first, S last) const
1335 {
1336 using value_type = typename etl::iterator_traits<I>::value_type;
1337
1338 I current = first;
1339
1340 #if ETL_USING_EXCEPTIONS
1341 try
1342 {
1343 #endif
1344 for (; current != last; ++current)
1345 {
1346 ::new (static_cast<void*>(etl::to_address(current))) value_type();
1347 }
1348
1349 return current;
1350 #if ETL_USING_EXCEPTIONS
1351 }
1352 catch (...)
1353 {
1354 for (; first != current; ++first)
1355 {
1356 etl::to_address(first)->~value_type();
1357 }
1358 throw;
1359 }
1360 #endif
1361 }
1362
1363 template <class R, typename = etl::enable_if_t<etl::is_range_v<R>>>
1364 ranges::borrowed_iterator_t<R> operator()(R&& r) const
1365 {
1366 return (*this)(ranges::begin(r), ranges::end(r));
1367 }
1368 };
1369
1370 inline constexpr uninitialized_value_construct_fn uninitialized_value_construct{};
1371
1372 //*****************************************************************************
1376 //*****************************************************************************
1377 struct uninitialized_value_construct_n_fn
1378 {
1379 template <class I>
1380 I operator()(I first, etl::iter_difference_t<I> n) const
1381 {
1382 using value_type = typename etl::iterator_traits<I>::value_type;
1383
1384 I current = first;
1385
1386 #if ETL_USING_EXCEPTIONS
1387 try
1388 {
1389 #endif
1390 for (; n > 0; ++current, --n)
1391 {
1392 ::new (static_cast<void*>(etl::to_address(current))) value_type();
1393 }
1394
1395 return current;
1396 #if ETL_USING_EXCEPTIONS
1397 }
1398 catch (...)
1399 {
1400 for (; first != current; ++first)
1401 {
1402 etl::to_address(first)->~value_type();
1403 }
1404 throw;
1405 }
1406 #endif
1407 }
1408 };
1409
1410 inline constexpr uninitialized_value_construct_n_fn uninitialized_value_construct_n{};
1411 } // namespace ranges
1412#endif
1413
1414#if ETL_USING_STL && ETL_USING_CPP20
1415 //*****************************************************************************
1419 //*****************************************************************************
1420 template <typename T, typename... TArgs>
1421 ETL_CONSTEXPR20 T* construct_at(T* p, TArgs&&... args)
1422 {
1423 return std::construct_at(p, etl::forward<TArgs>(args)...);
1424 }
1425#elif ETL_USING_CPP11
1426 //*****************************************************************************
1430 //*****************************************************************************
1431 template <typename T, typename... TArgs>
1432 T* construct_at(T* p, TArgs&&... args)
1433 {
1434 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T(etl::forward<TArgs>(args)...);
1435 }
1436#else
1437 //*****************************************************************************
1441 //*****************************************************************************
1442 template <typename T>
1444 {
1445 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T();
1446 }
1447 //*****************************************************************************
1451 //*****************************************************************************
1452 template <typename T, typename TArg>
1453 T* construct_at(T* p, const TArg& arg)
1454 {
1455 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T(arg);
1456 }
1457#endif
1458
1459#if ETL_USING_CPP17
1460 namespace ranges
1461 {
1462 //*****************************************************************************
1466 //*****************************************************************************
1467 struct construct_at_fn
1468 {
1469 template <class T, class... Args>
1470 constexpr T* operator()(T* p, Args&&... args) const
1471 {
1472 return etl::construct_at(p, etl::forward<Args>(args)...);
1473 }
1474 };
1475
1476 inline constexpr construct_at_fn construct_at{};
1477 } // namespace ranges
1478#endif
1479
1480#if ETL_USING_STL && ETL_USING_CPP20
1481 //*****************************************************************************
1485 //*****************************************************************************
1486 template <typename T>
1487 ETL_CONSTEXPR20 void destroy_at(T* p)
1488 {
1489 std::destroy_at(p);
1490 }
1491
1492 //*****************************************************************************
1497 //*****************************************************************************
1498 template <typename T, typename TCounter>
1499 ETL_CONSTEXPR20 void destroy_at(T* p, TCounter& count)
1500 {
1501 --count;
1502 std::destroy_at(p);
1503 }
1504#else
1505 //*****************************************************************************
1509 //*****************************************************************************
1510 template <typename T>
1511 typename etl::enable_if<etl::is_trivially_destructible<T>::value, void>::type destroy_at(T* /*p*/)
1512 {
1513 }
1514
1515 //*****************************************************************************
1519 //*****************************************************************************
1520 template <typename T>
1521 typename etl::enable_if<!etl::is_trivially_destructible<T>::value, void>::type destroy_at(T* p)
1522 {
1523 p->~T();
1524 }
1525
1526 //*****************************************************************************
1531 //*****************************************************************************
1532 template <typename T, typename TCounter>
1533 typename etl::enable_if<etl::is_trivially_destructible<T>::value, void>::type destroy_at(T* /*p*/, TCounter& count)
1534 {
1535 --count;
1536 }
1537
1538 //*****************************************************************************
1543 //*****************************************************************************
1544 template <typename T, typename TCounter>
1545 typename etl::enable_if<!etl::is_trivially_destructible<T>::value, void>::type destroy_at(T* p, TCounter& count)
1546 {
1547 p->~T();
1548 --count;
1549 }
1550#endif
1551
1552#if ETL_USING_STL && ETL_USING_CPP17
1553 //*****************************************************************************
1557 //*****************************************************************************
1558 template <typename TIterator>
1559 void destroy(TIterator i_begin, TIterator i_end)
1560 {
1561 std::destroy(i_begin, i_end);
1562 }
1563
1564 //*****************************************************************************
1569 //*****************************************************************************
1570 template <typename TIterator, typename TCounter>
1571 void destroy(TIterator i_begin, TIterator i_end, TCounter& count)
1572 {
1573 count -= static_cast<TCounter>(etl::distance(i_begin, i_end));
1574
1575 std::destroy(i_begin, i_end);
1576 }
1577#else
1578 //*****************************************************************************
1582 //*****************************************************************************
1583 template <typename TIterator>
1584 typename etl::enable_if< etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, void>::type
1585 destroy(TIterator /*i_begin*/, TIterator /*i_end*/)
1586 {
1587 }
1588
1589 //*****************************************************************************
1593 //*****************************************************************************
1594 template <typename TIterator>
1595 typename etl::enable_if< !etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, void>::type
1596 destroy(TIterator i_begin, TIterator i_end)
1597 {
1598 while (i_begin != i_end)
1599 {
1601 ++i_begin;
1602 }
1603 }
1604
1605 //*****************************************************************************
1610 //*****************************************************************************
1611 template <typename TIterator, typename TCounter>
1612 typename etl::enable_if< etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, void>::type
1613 destroy(TIterator i_begin, TIterator i_end, TCounter& count)
1614 {
1615 count -= static_cast<TCounter>(etl::distance(i_begin, i_end));
1616 }
1617
1618 //*****************************************************************************
1623 //*****************************************************************************
1624 template <typename TIterator, typename TCounter>
1625 typename etl::enable_if< !etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, void>::type
1626 destroy(TIterator i_begin, TIterator i_end, TCounter& count)
1627 {
1628 count -= static_cast<TCounter>(etl::distance(i_begin, i_end));
1629
1630 while (i_begin != i_end)
1631 {
1633 ++i_begin;
1634 }
1635 }
1636#endif
1637
1638#if ETL_USING_STL && ETL_USING_CPP17
1639 //*****************************************************************************
1643 //*****************************************************************************
1644 template <typename TIterator, typename TSize>
1645 TIterator destroy_n(TIterator i_begin, TSize n)
1646 {
1647 return std::destroy_n(i_begin, n);
1648 }
1649
1650 //*****************************************************************************
1655 //*****************************************************************************
1656 template <typename TIterator, typename TSize, typename TCounter>
1657 TIterator destroy_n(TIterator i_begin, TSize n, TCounter& count)
1658 {
1659 count -= n;
1660
1661 return std::destroy_n(i_begin, n);
1662 }
1663#else
1664 //*****************************************************************************
1668 //*****************************************************************************
1669 template <typename TIterator, typename TSize>
1670 typename etl::enable_if< etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, TIterator>::type
1671 destroy_n(TIterator i_begin, TSize n)
1672 {
1673 return i_begin + n;
1674 }
1675
1676 //*****************************************************************************
1680 //*****************************************************************************
1681 template <typename TIterator, typename TSize>
1682 typename etl::enable_if< !etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, TIterator>::type
1683 destroy_n(TIterator i_begin, TSize n)
1684 {
1685 while (n > 0)
1686 {
1688 ++i_begin;
1689 --n;
1690 }
1691
1692 return i_begin;
1693 }
1694
1695 //*****************************************************************************
1700 //*****************************************************************************
1701 template <typename TIterator, typename TSize, typename TCounter>
1702 typename etl::enable_if< etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, TIterator>::type
1703 destroy_n(TIterator i_begin, TSize n, TCounter& count)
1704 {
1705 count -= n;
1706 return i_begin + n;
1707 }
1708
1709 //*****************************************************************************
1714 //*****************************************************************************
1715 template <typename TIterator, typename TSize, typename TCounter>
1716 typename etl::enable_if< !etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, TIterator>::type
1717 destroy_n(TIterator i_begin, TSize n, TCounter& count)
1718 {
1719 count -= n;
1720
1721 while (n > 0)
1722 {
1724 ++i_begin;
1725 --n;
1726 }
1727
1728 return i_begin;
1729 }
1730#endif
1731
1732#if ETL_USING_CPP17
1733 namespace ranges
1734 {
1735 //*****************************************************************************
1739 //*****************************************************************************
1740 struct destroy_at_fn
1741 {
1742 template <class T>
1743 constexpr void operator()(T* p) const
1744 {
1745 etl::destroy_at(p);
1746 }
1747 };
1748
1749 inline constexpr destroy_at_fn destroy_at{};
1750
1751 //*****************************************************************************
1755 //*****************************************************************************
1756 struct destroy_fn
1757 {
1758 template <class I, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
1759 I operator()(I first, S last) const
1760 {
1761 for (; first != last; ++first)
1762 {
1764 }
1765
1766 return first;
1767 }
1768
1769 template <class R, typename = etl::enable_if_t<etl::is_range_v<R>>>
1770 ranges::borrowed_iterator_t<R> operator()(R&& r) const
1771 {
1772 return (*this)(ranges::begin(r), ranges::end(r));
1773 }
1774 };
1775
1776 inline constexpr destroy_fn destroy{};
1777
1778 //*****************************************************************************
1782 //*****************************************************************************
1783 struct destroy_n_fn
1784 {
1785 template <class I>
1786 I operator()(I first, etl::iter_difference_t<I> n) const
1787 {
1788 for (; n > 0; ++first, --n)
1789 {
1791 }
1792
1793 return first;
1794 }
1795 };
1796
1797 inline constexpr destroy_n_fn destroy_n{};
1798 } // namespace ranges
1799#endif
1800
1801 //*****************************************************************************
1806 //*****************************************************************************
1807 template <typename T>
1808 struct default_delete
1809 {
1810 //*********************************
1811 ETL_CONSTEXPR default_delete() ETL_NOEXCEPT
1812 {
1813 }
1814
1815 //*********************************
1816 template <typename U>
1817 default_delete(const default_delete<U>&) ETL_NOEXCEPT
1818 {
1819 }
1820
1821 //*********************************
1822 void operator()(T* p) const ETL_NOEXCEPT
1823 {
1824 delete p;
1825 }
1826 };
1827
1828 //*****************************************************************************
1833 //*****************************************************************************
1834 template <typename T>
1835 struct default_delete<T[]>
1836 {
1837 //*********************************
1838 ETL_CONSTEXPR default_delete() ETL_NOEXCEPT
1839 {
1840 }
1841
1842 //*********************************
1843 template <typename U>
1844 default_delete(const default_delete<U>&) ETL_NOEXCEPT
1845 {
1846 }
1847
1848 //*********************************
1849 template <class U>
1850 void operator()(U* p) const
1851 {
1852 delete[] p;
1853 }
1854 };
1855
1856 //*****************************************************************************
1861 //*****************************************************************************
1862 template <typename T, typename TDeleter = etl::default_delete<T> >
1863 class unique_ptr
1864 {
1865 public:
1866
1867 typedef T element_type;
1868 typedef T* pointer;
1869 typedef T& reference;
1870
1871 //*********************************
1872 ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT
1873 : p(ETL_NULLPTR)
1874 {
1875 }
1876
1877 //*********************************
1878 ETL_CONSTEXPR explicit unique_ptr(pointer p_) ETL_NOEXCEPT
1879 : p(p_)
1880 {
1881 }
1882
1883#if ETL_USING_CPP11
1884 //*********************************
1885 unique_ptr(unique_ptr&& other) ETL_NOEXCEPT
1886 {
1887 if (&other != this)
1888 {
1889 p = other.release();
1890 deleter = etl::move(other.deleter);
1891 }
1892 }
1893#else
1894 //*********************************
1895 unique_ptr(unique_ptr& other) ETL_NOEXCEPT
1896 {
1897 if (&other != this)
1898 {
1899 p = other.release();
1900 deleter = other.deleter;
1901 }
1902 }
1903#endif
1904
1905 //*********************************
1906 unique_ptr(pointer p_, typename etl::conditional< etl::is_reference<TDeleter>::value, TDeleter,
1907 typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
1908 : p(p_)
1909 , deleter(deleter_)
1910 {
1911 }
1912
1913#if ETL_USING_CPP11
1914 //*********************************
1915 unique_ptr(pointer p_, typename etl::remove_reference<TDeleter>::type&& deleter_) ETL_NOEXCEPT
1916 : p(p_)
1917 , deleter(etl::move(deleter_))
1918 {
1919 }
1920
1921 template <typename U, typename E>
1922 unique_ptr(unique_ptr<U, E>&& u) ETL_NOEXCEPT
1923 : p(u.release())
1924 , deleter(etl::forward<E>(u.get_deleter()))
1925 {
1926 }
1927#endif
1928
1929 //*********************************
1930 ~unique_ptr()
1931 {
1932 if (p != ETL_NULLPTR)
1933 {
1934 deleter(p);
1935 }
1936 }
1937
1938 //*********************************
1939 ETL_CONSTEXPR pointer get() const ETL_NOEXCEPT
1940 {
1941 return p;
1942 }
1943
1944 //*********************************
1945 TDeleter& get_deleter() ETL_NOEXCEPT
1946 {
1947 return deleter;
1948 }
1949
1950 //*********************************
1951 const TDeleter& get_deleter() const ETL_NOEXCEPT
1952 {
1953 return deleter;
1954 }
1955
1956 //*********************************
1957 pointer release() ETL_NOEXCEPT
1958 {
1959 pointer value = p;
1960 p = ETL_NULLPTR;
1961
1962 return value;
1963 }
1964
1965 //*********************************
1966 void reset(pointer p_ = pointer()) ETL_NOEXCEPT
1967 {
1968 if (p_ == ETL_NULLPTR || p_ != p)
1969 {
1970 pointer value = p;
1971 p = p_;
1972
1973 if (value != ETL_NULLPTR)
1974 {
1975 deleter(value);
1976 }
1977 }
1978 }
1979
1980 //*********************************
1981 void swap(unique_ptr& value) ETL_NOEXCEPT
1982 {
1983 using ETL_OR_STD::swap;
1984
1985 swap(p, value.p);
1986 }
1987
1988 //*********************************
1989 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
1990 {
1991 return (p != ETL_NULLPTR);
1992 }
1993
1994 //*********************************
1995 unique_ptr& operator=(etl::nullptr_t) ETL_NOEXCEPT
1996 {
1997 if (p)
1998 {
1999 reset(ETL_NULLPTR);
2000 }
2001
2002 return *this;
2003 }
2004
2005#if ETL_USING_CPP11
2006 //*********************************
2007 unique_ptr& operator=(unique_ptr&& other) ETL_NOEXCEPT
2008 {
2009 if (&other != this)
2010 {
2011 reset(other.release());
2012 deleter = etl::move(other.deleter);
2013 }
2014
2015 return *this;
2016 }
2017#else
2018 //*********************************
2019 unique_ptr& operator=(unique_ptr& other) ETL_NOEXCEPT
2020 {
2021 if (&other != this)
2022 {
2023 reset(other.release());
2024 deleter = other.deleter;
2025 }
2026
2027 return *this;
2028 }
2029#endif
2030
2031 //*********************************
2032 ETL_CONSTEXPR reference operator*() const
2033 {
2034 return *get();
2035 }
2036
2037 //*********************************
2038 ETL_CONSTEXPR pointer operator->() const ETL_NOEXCEPT
2039 {
2040 return get();
2041 }
2042
2043 //*********************************
2044 ETL_CONSTEXPR reference operator[](size_t i) const
2045 {
2046 return p[i];
2047 }
2048
2049 private:
2050
2051 // Deleted.
2052 unique_ptr(const unique_ptr&) ETL_DELETE;
2053 unique_ptr& operator=(const unique_ptr&) ETL_DELETE;
2054
2055 pointer p;
2056 TDeleter deleter;
2057 };
2058
2059 //*****************************************************************************
2064 //*****************************************************************************
2065 template <typename T, typename TDeleter>
2066 class unique_ptr<T[], TDeleter>
2067 {
2068 public:
2069
2070 typedef T element_type;
2071 typedef T* pointer;
2072 typedef T& reference;
2073
2074 //*********************************
2075 ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT
2076 : p(ETL_NULLPTR)
2077 {
2078 }
2079
2080 //*********************************
2081 ETL_CONSTEXPR explicit unique_ptr(pointer p_) ETL_NOEXCEPT
2082 : p(p_)
2083 {
2084 }
2085
2086#if ETL_USING_CPP11
2087 //*********************************
2088 unique_ptr(unique_ptr&& other) ETL_NOEXCEPT
2089 {
2090 if (&other != this)
2091 {
2092 p = other.release();
2093 deleter = etl::move(other.deleter);
2094 }
2095 }
2096#else
2097 //*********************************
2098 unique_ptr(unique_ptr& other) ETL_NOEXCEPT
2099 {
2100 if (&other != this)
2101 {
2102 p = other.release();
2103 deleter = other.deleter;
2104 }
2105 }
2106#endif
2107
2108 //*********************************
2109 unique_ptr(pointer p_, typename etl::conditional< etl::is_reference<TDeleter>::value, TDeleter,
2110 typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
2111 : p(p_)
2112 , deleter(deleter_)
2113 {
2114 }
2115
2116#if ETL_USING_CPP11
2117 //*********************************
2118 unique_ptr(pointer p_, typename etl::remove_reference<TDeleter>::type&& deleter_) ETL_NOEXCEPT
2119 : p(p_)
2120 , deleter(etl::move(deleter_))
2121 {
2122 }
2123
2124 template <typename U, typename E>
2125 unique_ptr(unique_ptr<U, E>&& u) ETL_NOEXCEPT
2126 : p(u.release())
2127 , deleter(etl::forward<E>(u.get_deleter()))
2128 {
2129 }
2130#endif
2131
2132 //*********************************
2133 ~unique_ptr()
2134 {
2135 if (p != ETL_NULLPTR)
2136 {
2137 deleter(p);
2138 }
2139 }
2140
2141 //*********************************
2142 ETL_CONSTEXPR pointer get() const ETL_NOEXCEPT
2143 {
2144 return p;
2145 }
2146
2147 //*********************************
2148 TDeleter& get_deleter() ETL_NOEXCEPT
2149 {
2150 return deleter;
2151 }
2152
2153 //*********************************
2154 const TDeleter& get_deleter() const ETL_NOEXCEPT
2155 {
2156 return deleter;
2157 }
2158
2159 //*********************************
2160 pointer release() ETL_NOEXCEPT
2161 {
2162 pointer value = p;
2163 p = ETL_NULLPTR;
2164 return value;
2165 }
2166
2167 //*********************************
2168 void reset(pointer p_) ETL_NOEXCEPT
2169 {
2170 if (p_ != p)
2171 {
2172 pointer value = p;
2173 p = p_;
2174
2175 if (value != ETL_NULLPTR)
2176 {
2177 deleter(value);
2178 }
2179 }
2180 }
2181
2182 void reset(etl::nullptr_t = ETL_NULLPTR) ETL_NOEXCEPT
2183 {
2184 reset(pointer());
2185 }
2186
2187 //*********************************
2188 void swap(unique_ptr& v) ETL_NOEXCEPT
2189 {
2190 using ETL_OR_STD::swap;
2191
2192 swap(p, v.p);
2193 }
2194
2195 //*********************************
2196 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
2197 {
2198 return (p != ETL_NULLPTR);
2199 }
2200
2201 //*********************************
2202 unique_ptr& operator=(etl::nullptr_t) ETL_NOEXCEPT
2203 {
2204 reset(ETL_NULLPTR);
2205
2206 return *this;
2207 }
2208
2209#if ETL_USING_CPP11
2210 //*********************************
2211 unique_ptr& operator=(unique_ptr&& other) ETL_NOEXCEPT
2212 {
2213 if (&other != this)
2214 {
2215 reset(other.release());
2216 deleter = etl::move(other.deleter);
2217 }
2218
2219 return *this;
2220 }
2221#else
2222 //*********************************
2223 unique_ptr& operator=(unique_ptr& other) ETL_NOEXCEPT
2224 {
2225 if (&other != this)
2226 {
2227 reset(other.release());
2228 deleter = other.deleter;
2229 }
2230
2231 return *this;
2232 }
2233#endif
2234
2235 //*********************************
2236 ETL_CONSTEXPR reference operator*() const
2237 {
2238 return *p;
2239 }
2240
2241 //*********************************
2242 ETL_CONSTEXPR pointer operator->() const ETL_NOEXCEPT
2243 {
2244 return p;
2245 }
2246
2247 //*********************************
2248 ETL_CONSTEXPR reference operator[](size_t i) const
2249 {
2250 return p[i];
2251 }
2252
2253 private:
2254
2255 // Deleted.
2256 unique_ptr(const unique_ptr&) ETL_DELETE;
2257 unique_ptr& operator=(const unique_ptr&) ETL_DELETE;
2258
2259 pointer p;
2260 TDeleter deleter;
2261 };
2262} // namespace etl
2263
2264//*****************************************************************************
2265// Global functions for unique_ptr
2266//*****************************************************************************
2267template <typename T1, typename TD1, typename T2, typename TD2>
2268bool operator==(const etl::unique_ptr<T1, TD1>& lhs, const etl::unique_ptr<T2, TD2>& rhs)
2269{
2270 return lhs.get() == rhs.get();
2271}
2272
2273//*********************************
2274template <typename T1, typename TD1, typename T2, typename TD2>
2275bool operator<(const etl::unique_ptr<T1, TD1>& lhs, const etl::unique_ptr<T2, TD2>& rhs)
2276{
2277 return reinterpret_cast<char*>(lhs.get()) < reinterpret_cast<char*>(rhs.get());
2278}
2279
2280//*********************************
2281template <typename T1, typename TD1, typename T2, typename TD2>
2282bool operator<=(const etl::unique_ptr<T1, TD1>& lhs, const etl::unique_ptr<T2, TD2>& rhs)
2283{
2284 return !(rhs < lhs);
2285}
2286
2287//*********************************
2288template <typename T1, typename TD1, typename T2, typename TD2>
2289bool operator>(const etl::unique_ptr<T1, TD1>& lhs, const etl::unique_ptr<T2, TD2>& rhs)
2290{
2291 return (rhs < lhs);
2292}
2293
2294//*********************************
2295template <typename T1, typename TD1, typename T2, typename TD2>
2296bool operator>=(const etl::unique_ptr<T1, TD1>& lhs, const etl::unique_ptr<T2, TD2>& rhs)
2297{
2298 return !(lhs < rhs);
2299}
2300
2301namespace etl
2302{
2303 //*****************************************************************************
2306 //*****************************************************************************
2307 template <typename T>
2308 typename etl::enable_if<etl::is_trivially_constructible<T>::value, void>::type create_default_at(T* /*p*/)
2309 {
2310 }
2311
2312 //*****************************************************************************
2315 //*****************************************************************************
2316 template <typename T, typename TCounter>
2317 typename etl::enable_if<etl::is_trivially_constructible<T>::value, void>::type create_default_at(T* /*p*/, TCounter& count)
2318 {
2319 ++count;
2320 }
2321
2322 //*****************************************************************************
2325 //*****************************************************************************
2326 template <typename T>
2327 typename etl::enable_if<!etl::is_trivially_constructible<T>::value, void>::type create_default_at(T* p)
2328 {
2329 ::new (p) T;
2330 }
2331
2332 //*****************************************************************************
2335 //*****************************************************************************
2336 template <typename T, typename TCounter>
2337 typename etl::enable_if<!etl::is_trivially_constructible<T>::value, void>::type create_default_at(T* p, TCounter& count)
2338 {
2339 ::new (p) T;
2340 ++count;
2341 }
2342
2343 //*****************************************************************************
2346 //*****************************************************************************
2347 template <typename T>
2349 {
2350 ::new (p) T();
2351 }
2352
2353 //*****************************************************************************
2356 //*****************************************************************************
2357 template <typename T, typename TCounter>
2358 void create_value_at(T* p, TCounter& count)
2359 {
2360 ::new (p) T();
2361 ++count;
2362 }
2363
2364 //*****************************************************************************
2367 //*****************************************************************************
2368 template <typename T>
2369 void create_copy_at(T* p, const T& value)
2370 {
2371 ::new (p) T(value);
2372 }
2373
2374#if ETL_USING_CPP11
2375 //*****************************************************************************
2378 //*****************************************************************************
2379 template <typename T>
2380 void create_copy_at(T* p, T&& value)
2381 {
2382 ::new (p) T(etl::move(value));
2383 }
2384#endif
2385
2386 //*****************************************************************************
2389 //*****************************************************************************
2390 template <typename T, typename TCounter>
2391 void create_copy_at(T* p, const T& value, TCounter& count)
2392 {
2393 ::new (p) T(value);
2394 ++count;
2395 }
2396
2397 //*****************************************************************************
2400 //*****************************************************************************
2401 template <typename T>
2403 {
2404 ::new (p) T();
2405 return *reinterpret_cast<T*>(p);
2406 }
2407
2408 //*****************************************************************************
2411 //*****************************************************************************
2412 template <typename T, typename TCounter>
2413 T& make_default_at(T* p, TCounter& count)
2414 {
2415 ::new (p) T();
2416 ++count;
2417 return *reinterpret_cast<T*>(p);
2418 }
2419
2420 //*****************************************************************************
2423 //*****************************************************************************
2424 template <typename T>
2425 T& make_copy_at(T* p, const T& other)
2426 {
2427 ::new (p) T(other);
2428 return *reinterpret_cast<T*>(p);
2429 }
2430
2431#if ETL_USING_CPP11
2432 //*****************************************************************************
2435 //*****************************************************************************
2436 template <typename T>
2437 T& make_copy_at(T* p, T&& other)
2438 {
2439 ::new (p) T(etl::move(other));
2440 return *reinterpret_cast<T*>(p);
2441 }
2442#endif
2443
2444 //*****************************************************************************
2447 //*****************************************************************************
2448 template <typename T, typename TCounter>
2449 T& make_copy_at(T* p, const T& other, TCounter& count)
2450 {
2451 ::new (p) T(other);
2452 ++count;
2453 return *reinterpret_cast<T*>(p);
2454 }
2455
2456 //*****************************************************************************
2459 //*****************************************************************************
2460 template <typename T, typename TParameter>
2461 T& make_value_at(T* p, const TParameter& value)
2462 {
2463 ::new (p) T(value);
2464 return *reinterpret_cast<T*>(p);
2465 }
2466
2467#if ETL_USING_CPP11
2468 //*****************************************************************************
2471 //*****************************************************************************
2472 template <typename T, typename TParameter>
2473 T& make_value_at(T* p, TParameter&& value)
2474 {
2475 ::new (p) T(etl::move(value));
2476 return *reinterpret_cast<T*>(p);
2477 }
2478#endif
2479
2480 //*****************************************************************************
2483 //*****************************************************************************
2484 template <typename T, typename TParameter, typename TCounter>
2485 T& make_value_at(T* p, const TParameter& value, TCounter& count)
2486 {
2487 ::new (p) T(value);
2488 ++count;
2489 return *reinterpret_cast<T*>(p);
2490 }
2491
2492 //*****************************************************************************
2496 //*****************************************************************************
2497 template <typename T>
2499 {
2500 void create_copy_at(void* p)
2501 {
2502 new (p) T(static_cast<const T&>(*this));
2503 }
2504
2505 template <typename TCounter>
2506 void create_copy_at(void* p, TCounter& count)
2507 {
2508 new (p) T(static_cast<const T&>(*this));
2509 ++count;
2510 }
2511
2512 T& make_copy_at(void* p)
2513 {
2514 new (p) T(static_cast<const T&>(*this));
2515 return *reinterpret_cast<T*>(p);
2516 }
2517
2518 template <typename TCounter>
2519 T& make_copy_at(void* p, TCounter& count)
2520 {
2521 new (p) T(static_cast<const T&>(*this));
2522 ++count;
2523 return *reinterpret_cast<T*>(p);
2524 }
2525 };
2526
2527 //*****************************************************************************
2532 //*****************************************************************************
2533 inline void memory_clear(volatile char* p, size_t n)
2534 {
2535 while (n--)
2536 {
2537 *p++ = 0;
2538 }
2539 }
2540
2541 //*****************************************************************************
2546 //*****************************************************************************
2547 template <typename T>
2548 void memory_clear(volatile T& object)
2549 {
2550 memory_clear(reinterpret_cast<volatile char*>(&object), sizeof(T));
2551 }
2552
2553 //*****************************************************************************
2559 //*****************************************************************************
2560 template <typename T>
2561 void memory_clear_range(volatile T* begin, size_t n)
2562 {
2563 memory_clear(reinterpret_cast<volatile char*>(begin), n * sizeof(T));
2564 }
2565
2566 //*****************************************************************************
2572 //*****************************************************************************
2573 template <typename T>
2574 void memory_clear_range(volatile T* begin, volatile T* end)
2575 {
2576 const size_t n = static_cast<size_t>(etl::distance(begin, end));
2577
2579 }
2580
2581 //*****************************************************************************
2587 //*****************************************************************************
2588 inline void memory_set(volatile char* p, size_t n, char value)
2589 {
2590 while (n--)
2591 {
2592 *p++ = value;
2593 }
2594 }
2595
2596 //*****************************************************************************
2602 //*****************************************************************************
2603 template <typename T>
2604 void memory_set(volatile T& object, const char value)
2605 {
2606 memory_set(reinterpret_cast<volatile char*>(&object), sizeof(T), value);
2607 }
2608
2609 //*****************************************************************************
2616 //*****************************************************************************
2617 template <typename T>
2618 void memory_set_range(volatile T* begin, size_t n, const char value)
2619 {
2620 memory_set(reinterpret_cast<volatile char*>(begin), n * sizeof(T), value);
2621 }
2622
2623 //*****************************************************************************
2630 //*****************************************************************************
2631 template <typename T>
2632 void memory_set_range(volatile T* begin, volatile T* end, const char value)
2633 {
2634 const size_t n = static_cast<size_t>(etl::distance(begin, end));
2635
2636 memory_set_range(begin, n, value);
2637 }
2638
2639 //*****************************************************************************
2645 //*****************************************************************************
2646 template <typename T>
2648 {
2650 {
2651 memory_clear(static_cast<volatile T&>(*this));
2652 }
2653 };
2654
2655 //***************************************************************************
2659 //***************************************************************************
2660 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2662 {
2663 public:
2664
2665 static ETL_CONSTANT size_t Object_Size = VObject_Size;
2666 static ETL_CONSTANT size_t N_Objects = VN_Objects;
2667 static ETL_CONSTANT size_t Alignment = VAlignment;
2668
2670 template <typename T>
2671 operator T&()
2672 {
2673 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2674 return *reinterpret_cast<T*>(raw);
2675 }
2676
2678 template <typename T>
2679 operator const T&() const
2680 {
2681 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2682 return *reinterpret_cast<const T*>(raw);
2683 }
2684
2686 template <typename T>
2687 operator T*()
2688 {
2689 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2690 return reinterpret_cast<T*>(raw);
2691 }
2692
2694 template <typename T>
2695 operator const T*() const
2696 {
2697 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
2698 return reinterpret_cast<const T*>(raw);
2699 }
2700
2701#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
2702 alignas(VAlignment) char raw[Object_Size * N_Objects];
2703#else
2704 union
2705 {
2706 char raw[VObject_Size * VN_Objects];
2707 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment
2708 // as VAlignment.
2709 };
2710#endif
2711 };
2712
2713 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2714 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Object_Size;
2715
2716 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2717 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::N_Objects;
2718
2719 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
2720 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Alignment;
2721
2722 //***************************************************************************
2725 //***************************************************************************
2726 template <typename T, size_t VN_Objects>
2728 {
2729 public:
2730
2731 typedef T value_type;
2732 typedef T& reference;
2733 typedef const T& const_reference;
2734 typedef T* pointer;
2735 typedef const T* const_pointer;
2736 typedef T* iterator;
2737 typedef const T* const_iterator;
2738
2739 static ETL_CONSTANT size_t Object_Size = sizeof(T);
2740 static ETL_CONSTANT size_t N_Objects = VN_Objects;
2741 static ETL_CONSTANT size_t Alignment = etl::alignment_of<T>::value;
2742
2744 T& operator[](int i)
2745 {
2746 return reinterpret_cast<T*>(this->raw)[i];
2747 }
2748
2750 const T& operator[](int i) const
2751 {
2752 return reinterpret_cast<const T*>(this->raw)[i];
2753 }
2754
2756 operator T&()
2757 {
2758 return *reinterpret_cast<T*>(raw);
2759 }
2760
2762 operator const T&() const
2763 {
2764 return *reinterpret_cast<const T*>(raw);
2765 }
2766
2768 operator T*()
2769
2770 {
2771 return reinterpret_cast<T*>(raw);
2772 }
2773
2775 operator const T*() const
2776 {
2777 return reinterpret_cast<const T*>(raw);
2778 }
2779
2780 T* begin()
2781 {
2782 return reinterpret_cast<T*>(raw);
2783 }
2784
2785 const T* begin() const
2786 {
2787 return reinterpret_cast<const T*>(raw);
2788 }
2789
2790 T* end()
2791 {
2792 return reinterpret_cast<T*>(raw + (sizeof(T) * N_Objects));
2793 }
2794
2795 const T* end() const
2796 {
2797 return reinterpret_cast<const T*>(raw + (sizeof(T) * N_Objects));
2798 }
2799
2800#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
2801 alignas(Alignment) char raw[sizeof(T) * N_Objects];
2802#else
2803 union
2804 {
2805 char raw[sizeof(T) * N_Objects];
2806 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment
2807 // as Alignment.
2808 };
2809#endif
2810 };
2811
2812 template <typename T, size_t VN_Objects>
2813 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Object_Size;
2814
2815 template <typename T, size_t VN_Objects>
2816 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::N_Objects;
2817
2818 template <typename T, size_t VN_Objects>
2819 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Alignment;
2820
2821#if ETL_USING_CPP11
2822 template <typename T, size_t N_Objects>
2823 using uninitialized_buffer_of_t = typename uninitialized_buffer_of<T, N_Objects>::buffer;
2824#endif
2825
2826 //***************************************************************************
2833 //***************************************************************************
2834 template <typename T>
2835 T* mem_copy(const T* sb, const T* se, T* db) ETL_NOEXCEPT
2836 {
2837 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_copy a non trivially copyable type");
2838
2839#if ETL_USING_BUILTIN_MEMCPY
2840 __builtin_memcpy(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
2841#else
2842 ::memcpy(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
2843#endif
2844
2845 return db;
2846 }
2847
2848 //***************************************************************************
2854 //***************************************************************************
2855 template <typename T>
2856 T* mem_copy(const T* sb, size_t n, T* db) ETL_NOEXCEPT
2857 {
2858 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_copy a non trivially copyable type");
2859
2860#if ETL_USING_BUILTIN_MEMCPY
2861 __builtin_memcpy(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
2862#else
2863 ::memcpy(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
2864#endif
2865
2866 return db;
2867 }
2868
2869 //***************************************************************************
2875 //***************************************************************************
2876 template <typename T>
2877 T* mem_move(const T* sb, const T* se, T* db) ETL_NOEXCEPT
2878 {
2879 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_move a non trivially copyable type");
2880
2881#if ETL_USING_BUILTIN_MEMMOVE
2882 __builtin_memmove(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
2883#else
2884 ::memmove(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
2885#endif
2886
2887 return db;
2888 }
2889
2890 //***************************************************************************
2896 //***************************************************************************
2897 template <typename T>
2898 T* mem_move(const T* sb, size_t n, T* db) ETL_NOEXCEPT
2899 {
2900 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_move a non trivially copyable type");
2901
2902#if ETL_USING_BUILTIN_MEMMOVE
2905 __builtin_memmove(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
2907#else
2908 ::memmove(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
2909#endif
2910
2911 return db;
2912 }
2913
2914 //***************************************************************************
2925 //***************************************************************************
2926 template <typename T>
2927 ETL_NODISCARD
2928 int mem_compare(const T* sb, const T* se, const T* db) ETL_NOEXCEPT
2929 {
2930 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_compare a non trivially copyable type");
2931
2932#if ETL_USING_BUILTIN_MEMCMP
2933 return __builtin_memcmp(reinterpret_cast<const void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
2934#else
2935 return ::memcmp(reinterpret_cast<const void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
2936#endif
2937 }
2938
2939 //***************************************************************************
2950 //***************************************************************************
2951 template <typename T>
2952 ETL_NODISCARD
2953 int mem_compare(const T* sb, size_t n, const T* db) ETL_NOEXCEPT
2954 {
2955 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_compare a non trivially copyable type");
2956
2957#if ETL_USING_BUILTIN_MEMCMP
2958 return __builtin_memcmp(reinterpret_cast<const void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
2959#else
2960 return ::memcmp(reinterpret_cast<const void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
2961#endif
2962 }
2963
2964 //***************************************************************************
2970 //***************************************************************************
2971 template <typename TPointer, typename T>
2972 typename etl::enable_if<etl::is_pointer<TPointer>::value && !etl::is_const<TPointer>::value && etl::is_integral<T>::value && sizeof(T) == 1,
2973 TPointer>::type
2974 mem_set(TPointer db, const TPointer de, T value) ETL_NOEXCEPT
2975 {
2976 ETL_STATIC_ASSERT(etl::is_trivially_copyable< typename etl::iterator_traits<TPointer>::value_type>::value,
2977 "Cannot mem_set a non trivially copyable type");
2978
2979#if ETL_USING_BUILTIN_MEMSET
2980 __builtin_memset(reinterpret_cast<void*>(db), static_cast<char>(value),
2981 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(de - db));
2982#else
2983 ::memset(reinterpret_cast<void*>(db), static_cast<char>(value),
2984 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(de - db));
2985#endif
2986
2987 return db;
2988 }
2989
2990 //***************************************************************************
2996 //***************************************************************************
2997 template <typename TPointer, typename T>
2998 typename etl::enable_if<etl::is_pointer<TPointer>::value && !etl::is_const<TPointer>::value && etl::is_integral<T>::value && sizeof(T) == 1,
2999 TPointer>::type
3000 mem_set(TPointer db, size_t n, T value) ETL_NOEXCEPT
3001 {
3002 ETL_STATIC_ASSERT(etl::is_trivially_copyable< typename etl::iterator_traits<TPointer>::value_type>::value,
3003 "Cannot mem_set a non trivially copyable type");
3004
3005#if ETL_USING_BUILTIN_MEMSET
3006 __builtin_memset(reinterpret_cast<void*>(db), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3007#else
3008 ::memset(reinterpret_cast<void*>(db), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3009#endif
3010
3011 return db;
3012 }
3013
3014 //***************************************************************************
3020 //***************************************************************************
3021 template <typename TPointer, typename T>
3022 ETL_NODISCARD
3023 typename etl::enable_if< etl::is_pointer<TPointer>::value && !etl::is_const<typename etl::remove_pointer<TPointer>::type>::value
3024 && etl::is_integral<T>::value && sizeof(T) == 1,
3025 char*>::type mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
3026 {
3027#if ETL_USING_BUILTIN_MEMCHR
3028 void* result = __builtin_memchr(reinterpret_cast<void*>(sb), static_cast<char>(value),
3029 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
3030
3031 return (result == 0U) ? reinterpret_cast<char*>(se) : reinterpret_cast<char*>(result);
3032#else
3033 void* result = ::memchr(reinterpret_cast<void*>(sb), static_cast<char>(value),
3034 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
3035
3036 return (result == 0U) ? reinterpret_cast<char*>(se) : reinterpret_cast<char*>(result);
3037#endif
3038 }
3039
3040 //***************************************************************************
3046 //***************************************************************************
3047 template <typename TPointer, typename T>
3048 ETL_NODISCARD
3049 typename etl::enable_if< etl::is_pointer<TPointer>::value && etl::is_const<typename etl::remove_pointer<TPointer>::type>::value
3050 && etl::is_integral<T>::value && sizeof(T) == 1,
3051 const char*>::type mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
3052 {
3053#if ETL_USING_BUILTIN_MEMCHR
3054 const void* result = __builtin_memchr(reinterpret_cast<const void*>(sb), static_cast<char>(value),
3055 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
3056
3057 return (result == 0U) ? reinterpret_cast<const char*>(se) : reinterpret_cast<const char*>(result);
3058#else
3059 const void* result = ::memchr(reinterpret_cast<const void*>(sb), static_cast<char>(value),
3060 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
3061
3062 return (result == 0U) ? reinterpret_cast<const char*>(se) : reinterpret_cast<const char*>(result);
3063#endif
3064 }
3065
3066 //***************************************************************************
3072 //***************************************************************************
3073 template <typename TPointer, typename T>
3074 ETL_NODISCARD
3075 typename etl::enable_if< etl::is_pointer<TPointer>::value && !etl::is_const<typename etl::remove_pointer<TPointer>::type>::value
3076 && etl::is_integral<T>::value && sizeof(T) == 1,
3077 char*>::type mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
3078 {
3079#if ETL_USING_BUILTIN_MEMCHR
3080 void* result =
3081 __builtin_memchr(reinterpret_cast<void*>(sb), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3082
3083 return (result == 0U) ? reinterpret_cast<char*>(sb + n) : reinterpret_cast<char*>(result);
3084#else
3085 void* result = ::memchr(reinterpret_cast<void*>(sb), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3086
3087 return (result == 0U) ? reinterpret_cast<char*>(sb + n) : reinterpret_cast<char*>(result);
3088#endif
3089 }
3090
3091 //***************************************************************************
3097 //***************************************************************************
3098 template <typename TPointer, typename T>
3099 ETL_NODISCARD
3100 typename etl::enable_if< etl::is_pointer<TPointer>::value && etl::is_const<typename etl::remove_pointer<TPointer>::type>::value
3101 && etl::is_integral<T>::value && sizeof(T) == 1,
3102 const char*>::type mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
3103 {
3104#if ETL_USING_BUILTIN_MEMCHR
3105 const void* result =
3106 __builtin_memchr(reinterpret_cast<const void*>(sb), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3107
3108 return (result == 0U) ? reinterpret_cast<const char*>(sb + n) : reinterpret_cast<const char*>(result);
3109#else
3110 const void* result =
3111 ::memchr(reinterpret_cast<const void*>(sb), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3112
3113 return (result == 0U) ? reinterpret_cast<const char*>(sb + n) : reinterpret_cast<const char*>(result);
3114#endif
3115 }
3116
3117#if ETL_USING_CPP11
3118 //*****************************************************************************
3120 //*****************************************************************************
3121 template <typename TObject>
3122 TObject& construct_object_at(void* p, TObject&& other)
3123 {
3124 #if ETL_IS_DEBUG_BUILD
3125 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
3126 #endif
3127
3128 return *etl::construct_at(reinterpret_cast<typename etl::remove_reference<TObject>::type*>(p), etl::forward<TObject>(other));
3129 }
3130
3131 //*****************************************************************************
3133 //*****************************************************************************
3134 template <typename TObject, typename... TArgs>
3135 TObject& construct_object_at(void* p, TArgs&&... args)
3136 {
3137 #if ETL_IS_DEBUG_BUILD
3139 #endif
3140
3141 return *etl::construct_at(reinterpret_cast<TObject*>(p), etl::forward<TArgs>(args)...);
3142 }
3143#else
3144 //*****************************************************************************
3146 //*****************************************************************************
3147 template <typename TObject>
3148 TObject& construct_object_at(void* p)
3149 {
3150 #if ETL_IS_DEBUG_BUILD
3152 #endif
3153
3154 return *etl::construct_at(reinterpret_cast<TObject*>(p));
3155 }
3156
3157 //*****************************************************************************
3159 //*****************************************************************************
3160 template <typename TObject>
3161 TObject& construct_object_at(void* p, const TObject& other)
3162 {
3163 #if ETL_IS_DEBUG_BUILD
3165 #endif
3166
3167 return *etl::construct_at(reinterpret_cast<TObject*>(p), other);
3168 }
3169
3170 //*****************************************************************************
3172 //*****************************************************************************
3173 template <typename TObject, typename TArg>
3174 TObject& construct_object_at(void* p, const TArg& arg)
3175 {
3176 #if ETL_IS_DEBUG_BUILD
3178 #endif
3179
3180 return *etl::construct_at(reinterpret_cast<TObject*>(p), arg);
3181 }
3182#endif
3183
3184 //*****************************************************************************
3186 //*****************************************************************************
3187 template <typename TObject>
3188 TObject& get_object_at(void* p)
3189 {
3190#if ETL_IS_DEBUG_BUILD
3192#endif
3193
3194 return *reinterpret_cast<TObject*>(p);
3195 }
3196
3197 //*****************************************************************************
3199 //*****************************************************************************
3200 template <typename TObject>
3201 const TObject& get_object_at(const void* p)
3202 {
3203#if ETL_IS_DEBUG_BUILD
3205#endif
3206
3207 return *reinterpret_cast<const TObject*>(p);
3208 }
3209
3210 //*****************************************************************************
3213 //*****************************************************************************
3214 template <typename TObject>
3215 void destroy_object_at(void* p)
3216 {
3217#if ETL_IS_DEBUG_BUILD
3219#endif
3220
3221 TObject& v = get_object_at<TObject>(p);
3222 v.~TObject();
3223 }
3224} // namespace etl
3225
3226#endif
Memory misalignment exception.
Definition alignment.h:66
Definition nullptr.h:42
T & operator[](int i)
Index operator.
Definition memory.h:2744
const T & operator[](int i) const
Index operator.
Definition memory.h:2750
Definition memory.h:2662
Definition memory.h:2728
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
Definition memory.h:1864
TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T &value)
Definition memory.h:86
etl::enable_if< etl::is_trivially_constructible< typenameetl::iterator_traits< TOutputIterator >::value_type >::value, void >::type uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
Definition memory.h:1223
void memory_set_range(volatile T *begin, size_t n, const char value)
Definition memory.h:2618
TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
Definition memory.h:1295
etl::enable_if< etl::is_trivially_constructible< T >::value, void >::type create_default_at(T *)
Definition memory.h:2308
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:1038
T * construct_at(T *p)
Definition memory.h:1443
void create_copy_at(T *p, const T &value)
Definition memory.h:2369
void create_value_at(T *p)
Definition memory.h:2348
T & make_value_at(T *p, const TParameter &value)
Definition memory.h:2461
etl::enable_if< etl::is_trivially_destructible< typenameetl::iterator_traits< TIterator >::value_type >::value, void >::type destroy(TIterator, TIterator)
Definition memory.h:1585
etl::enable_if< etl::is_trivially_destructible< T >::value, void >::type destroy_at(T *)
Definition memory.h:1511
void memory_clear_range(volatile T *begin, size_t n)
Definition memory.h:2561
void memory_set(volatile char *p, size_t n, char value)
Definition memory.h:2588
TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
Definition memory.h:796
TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
Definition memory.h:539
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:1671
T & make_default_at(T *p)
Definition memory.h:2402
TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
Definition memory.h:669
T & make_copy_at(T *p, const T &other)
Definition memory.h:2425
void memory_clear(volatile char *p, size_t n)
Definition memory.h:2533
TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
Definition memory.h:239
etl::enable_if< etl::is_trivially_constructible< typenameetl::iterator_traits< TOutputIterator >::value_type >::value, void >::type uninitialized_default_construct(TOutputIterator, TOutputIterator)
Definition memory.h:953
TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T &value)
Definition memory.h:212
Definition memory.h:2499
Definition memory.h:2648
bitset_ext
Definition absolute.h:40
T * mem_move(const T *sb, const T *se, T *db) ETL_NOEXCEPT
Definition memory.h:2877
ETL_NODISCARD int mem_compare(const T *sb, const T *se, const T *db) ETL_NOEXCEPT
Definition memory.h:2928
void destroy_object_at(void *p)
Definition memory.h:3215
etl::enable_if< etl::is_pointer< TPointer >::value &&!etl::is_const< TPointer >::value &&etl::is_integral< T >::value &&sizeof(T)==1, TPointer >::type mem_set(TPointer db, const TPointer de, T value) ETL_NOEXCEPT
Definition memory.h:2974
TObject & construct_object_at(void *p)
Default construct the container at 'p'.
Definition memory.h:3148
bool is_aligned(const void *p, size_t required_alignment)
Check that 'p' has 'required_alignment'.
Definition alignment.h:91
ETL_NODISCARD etl::enable_if< etl::is_pointer< TPointer >::value &&!etl::is_const< typenameetl::remove_pointer< TPointer >::type >::value &&etl::is_integral< T >::value &&sizeof(T)==1, char * >::type mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
Definition memory.h:3025
ETL_CONSTEXPR T * to_address(T *p) ETL_NOEXCEPT
Definition memory.h:62
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:967
T * mem_copy(const T *sb, const T *se, T *db) ETL_NOEXCEPT
Definition memory.h:2835
TObject & get_object_at(void *p)
Get the container at 'p'.
Definition memory.h:3188
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition iterator.h:997
is_const
Definition type_traits.h:213