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 <string.h>
46
47#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
48 #include <memory>
49#endif
50
53
54namespace etl
55{
56 //*****************************************************************************
59 //*****************************************************************************
60 template <typename T>
61 ETL_CONSTEXPR T* to_address(T* p) ETL_NOEXCEPT
62 {
63 return p;
64 }
65
66 //*****************************************************************************
70 //*****************************************************************************
71 template <typename Iterator>
72 ETL_CONSTEXPR typename Iterator::pointer to_address(const Iterator& itr) ETL_NOEXCEPT
73 {
74 return etl::to_address(itr.operator->());
75 }
76
77#if ETL_USING_STL && ETL_USING_CPP17 && defined(__cpp_lib_launder)
78 using std::launder;
79#else
80 //*****************************************************************************
87 //*****************************************************************************
88 template <typename T>
89 ETL_NODISCARD ETL_CONSTEXPR17 T* launder(T* p) ETL_NOEXCEPT
90 {
91 #if ETL_USING_CPP11
92 // etl::is_function is only defined for C++11 and later.
93 ETL_STATIC_ASSERT(!etl::is_function<T>::value, "etl::launder argument must not be a function type");
94 #endif
95 ETL_STATIC_ASSERT(!etl::is_void<T>::value, "etl::launder argument must not be a void type");
96
97 #if defined(__has_builtin) && !defined(ETL_COMPILER_MICROSOFT)
98 #if __has_builtin(__builtin_launder)
99 return __builtin_launder(p);
100 #else
101 return p;
102 #endif
103 #elif ETL_USING_GCC_COMPILER && (ETL_COMPILER_FULL_VERSION >= 70000)
104 // GCC 7, 8 and 9 provide __builtin_launder but not __has_builtin.
105 return __builtin_launder(p);
106 #else
107 return p;
108 #endif
109 }
110#endif
111
112#if ETL_USING_STL && ETL_USING_CPP23 && defined(__cpp_lib_start_lifetime_as)
113 using std::start_lifetime_as;
114 using std::start_lifetime_as_array;
115#else
116 namespace private_memory
117 {
118 //*************************************************************************
121 //*************************************************************************
122 template <typename T>
123 ETL_NODISCARD
124 inline T* start_lifetime_as_impl(void* p, size_t n) ETL_NOEXCEPT
125 {
126 if (n == 0U)
127 {
128 // No objects are created, so there is nothing to launder.
129 // Return the original pointer to preserve pointer identity.
130 return static_cast<T*>(p);
131 }
132
133 #if ETL_USING_BUILTIN_MEMMOVE
134 void* const q = __builtin_memmove(p, p, sizeof(T) * n);
135 #else
136 void* const q = ::memmove(p, p, sizeof(T) * n);
137 #endif
138
139 return etl::launder(static_cast<T*>(q));
140 }
141 } // namespace private_memory
142
143 //*****************************************************************************
149 //*****************************************************************************
150 template <typename T>
151 ETL_NODISCARD
152 T* start_lifetime_as(void* p) ETL_NOEXCEPT
153 {
154 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "T must be trivially copyable");
156 }
157
158 template <typename T>
159 ETL_NODISCARD
160 const T* start_lifetime_as(const void* p) ETL_NOEXCEPT
161 {
162 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "T must be trivially copyable");
163 return etl::private_memory::start_lifetime_as_impl<const T>(const_cast<void*>(p), 1U);
164 }
165
166 template <typename T>
167 ETL_NODISCARD
168 volatile T* start_lifetime_as(volatile void* p) ETL_NOEXCEPT
169 {
170 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "T must be trivially copyable");
171 return etl::private_memory::start_lifetime_as_impl<volatile T>(const_cast<void*>(p), 1U);
172 }
173
174 template <typename T>
175 ETL_NODISCARD
176 const volatile T* start_lifetime_as(const volatile void* p) ETL_NOEXCEPT
177 {
178 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "T must be trivially copyable");
179 return etl::private_memory::start_lifetime_as_impl<const volatile T>(const_cast<void*>(p), 1U);
180 }
181
182 //*****************************************************************************
189 //*****************************************************************************
190 template <typename T>
191 ETL_NODISCARD
192 T* start_lifetime_as_array(void* p, size_t n) ETL_NOEXCEPT
193 {
194 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "T must be trivially copyable");
196 }
197
198 template <typename T>
199 ETL_NODISCARD
200 const T* start_lifetime_as_array(const void* p, size_t n) ETL_NOEXCEPT
201 {
202 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "T must be trivially copyable");
203 return etl::private_memory::start_lifetime_as_impl<const T>(const_cast<void*>(p), n);
204 }
205
206 template <typename T>
207 ETL_NODISCARD
208 volatile T* start_lifetime_as_array(volatile void* p, size_t n) ETL_NOEXCEPT
209 {
210 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "T must be trivially copyable");
211 return etl::private_memory::start_lifetime_as_impl<volatile T>(const_cast<void*>(p), n);
212 }
213
214 template <typename T>
215 ETL_NODISCARD
216 const volatile T* start_lifetime_as_array(const volatile void* p, size_t n) ETL_NOEXCEPT
217 {
218 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "T must be trivially copyable");
219 return etl::private_memory::start_lifetime_as_impl<const volatile T>(const_cast<void*>(p), n);
220 }
221#endif
222
223#if ETL_USING_STL && ETL_USING_CPP11
224 using std::pointer_traits;
225#else
226 #if ETL_USING_CPP11
227 namespace private_memory
228 {
229 //*************************************************************************
234 //*************************************************************************
235 template <typename T>
236 struct pointer_traits_template;
237
238 template <template <typename, typename...> class Pointer, typename Element, typename... Args>
239 struct pointer_traits_template<Pointer<Element, Args...> >
240 {
241 typedef Element type;
242
243 template <typename U>
244 struct rebind
245 {
246 typedef Pointer<U, Args...> type;
247 };
248 };
249
250 //*************************************************************************
253 //*************************************************************************
254 template <typename T, typename = void>
255 struct pointer_traits_element_type
256 {
257 typedef typename pointer_traits_template<T>::type type;
258 };
259
260 template <typename T>
261 struct pointer_traits_element_type<T, etl::void_t<typename T::element_type> >
262 {
263 typedef typename T::element_type type;
264 };
265 } // namespace private_memory
266 #endif
267
268 //*****************************************************************************
273 //*****************************************************************************
274 template <typename T>
276 {
277 typedef T pointer;
278 #if ETL_USING_CPP11
279 typedef typename private_memory::pointer_traits_element_type<T>::type element_type;
280 #else
281 typedef typename T::element_type element_type;
282 #endif
283 typedef ptrdiff_t difference_type;
284
285 #if ETL_USING_CPP11
286 template <typename U>
287 using rebind = typename private_memory::pointer_traits_template<T>::template rebind<U>::type;
288 #endif
289
290 ETL_NODISCARD
291 static ETL_CONSTEXPR pointer pointer_to(element_type& r) ETL_NOEXCEPT
292 {
293 return T::pointer_to(r);
294 }
295 };
296
297 //*****************************************************************************
301 //*****************************************************************************
302 template <typename T>
303 struct pointer_traits<T*>
304 {
305 typedef T* pointer;
306 typedef T element_type;
307 typedef ptrdiff_t difference_type;
308
309 #if ETL_USING_CPP11
310 template <typename U>
311 using rebind = U*;
312 #endif
313
314 ETL_NODISCARD
315 static ETL_CONSTEXPR pointer pointer_to(element_type& r) ETL_NOEXCEPT
316 {
317 return etl::addressof(r);
318 }
319 };
320#endif
321
322#if ETL_USING_STL && ETL_USING_CPP11
323 using std::align;
324#else
325 //*****************************************************************************
333 //*****************************************************************************
334 inline void* align(size_t alignment, size_t size, void*& ptr, size_t& space) ETL_NOEXCEPT
335 {
336 const uintptr_t p = reinterpret_cast<uintptr_t>(ptr);
337 const uintptr_t aligned = (p + (alignment - 1U)) & ~(static_cast<uintptr_t>(alignment) - 1U);
338 const size_t padding = static_cast<size_t>(aligned - p);
339
340 if ((padding > space) || (size > (space - padding)))
341 {
342 return ETL_NULLPTR;
343 }
344
345 space -= padding;
346 ptr = reinterpret_cast<void*>(aligned);
347
348 return ptr;
349 }
350#endif
351
352#if ETL_USING_STL && ETL_USING_CPP20 && defined(__cpp_lib_assume_aligned)
353 using std::assume_aligned;
354#else
355 //*****************************************************************************
361 //*****************************************************************************
362 template <size_t N, typename T>
363 ETL_NODISCARD ETL_CONSTEXPR T* assume_aligned(T* ptr) ETL_NOEXCEPT
364 {
365 #if defined(__has_builtin) && !defined(ETL_COMPILER_MICROSOFT)
366 #if __has_builtin(__builtin_assume_aligned)
367 return static_cast<T*>(__builtin_assume_aligned(ptr, N));
368 #else
369 return ptr;
370 #endif
371 #else
372 return ptr;
373 #endif
374 }
375#endif
376
377#if ETL_USING_STL && ETL_USING_CPP26 && defined(__cpp_lib_is_sufficiently_aligned)
378 using std::is_sufficiently_aligned;
379#else
380 //*****************************************************************************
385 //*****************************************************************************
386 template <size_t Alignment, typename T>
387 ETL_NODISCARD
388 bool is_sufficiently_aligned(T* ptr) ETL_NOEXCEPT
389 {
390 return (reinterpret_cast<uintptr_t>(ptr) % Alignment) == 0U;
391 }
392#endif
393
394#if ETL_USING_STL
395 //*****************************************************************************
400 //*****************************************************************************
401 template <typename TOutputIterator, typename T>
402 TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
403 {
404 std::uninitialized_fill(o_begin, o_end, value);
405
406 return o_end;
407 }
408
409 //*****************************************************************************
414 //*****************************************************************************
415 template <typename TOutputIterator, typename T, typename TCounter>
416 TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
417 {
418 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
419
420 std::uninitialized_fill(o_begin, o_end, value);
421
422 return o_end;
423 }
424#else
425 //*****************************************************************************
429 //*****************************************************************************
430 template <typename TOutputIterator, typename T>
431 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
432 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
433 {
434 etl::fill(o_begin, o_end, value);
435
436 return o_end;
437 }
438
439 //*****************************************************************************
443 //*****************************************************************************
444 template <typename TOutputIterator, typename T>
445 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
446 TOutputIterator>::type
447 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value)
448 {
449 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
450
451 while (o_begin != o_end)
452 {
453 ::new (static_cast<void*>(etl::to_address(o_begin))) value_type(value);
454 ++o_begin;
455 }
456
457 return o_end;
458 }
459
460 //*****************************************************************************
465 //*****************************************************************************
466 template <typename TOutputIterator, typename T, typename TCounter>
467 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
468 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
469 {
470 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
471
472 etl::fill(o_begin, o_end, value);
473
474 return o_end;
475 }
476
477 //*****************************************************************************
482 //*****************************************************************************
483 template <typename TOutputIterator, typename T, typename TCounter>
484 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
485 TOutputIterator>::type
486 uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T& value, TCounter& count)
487 {
488 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
489
490 etl::uninitialized_fill(o_begin, o_end, value);
491
492 return o_end;
493 }
494#endif
495
496#if ETL_USING_STL && ETL_USING_CPP11
497 //*****************************************************************************
501 //*****************************************************************************
502 template <typename TOutputIterator, typename TSize, typename T>
503 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value)
504 {
505 return std::uninitialized_fill_n(o_begin, n, value);
506 }
507
508 //*****************************************************************************
513 //*****************************************************************************
514 template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
515 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count)
516 {
517 count += n;
518
519 return std::uninitialized_fill_n(o_begin, n, value);
520 }
521#else
522 //*****************************************************************************
526 //*****************************************************************************
527 template <typename TOutputIterator, typename TSize, typename T>
528 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value)
529 {
530 return etl::uninitialized_fill(o_begin, o_begin + n, value);
531 }
532
533 //*****************************************************************************
538 //*****************************************************************************
539 template <typename TOutputIterator, typename TSize, typename T, typename TCounter>
540 TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count)
541 {
542 count += n;
543
544 return etl::uninitialized_fill(o_begin, o_begin + n, value);
545 }
546#endif
547
548#if ETL_USING_STL
549 //*****************************************************************************
553 //*****************************************************************************
554 template <typename TInputIterator, typename TOutputIterator>
555 TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
556 {
557 return std::uninitialized_copy(i_begin, i_end, o_begin);
558 }
559
560 //*****************************************************************************
565 //*****************************************************************************
566 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
567 TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
568 {
569 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
570
571 return std::uninitialized_copy(i_begin, i_end, o_begin);
572 }
573#else
574 //*****************************************************************************
578 //*****************************************************************************
579 template <typename TInputIterator, typename TOutputIterator>
580 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
581 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
582 {
583 return etl::copy(i_begin, i_end, o_begin);
584 }
585
586 //*****************************************************************************
590 //*****************************************************************************
591 template <typename TInputIterator, typename TOutputIterator>
592 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
593 TOutputIterator>::type
594 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
595 {
596 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
597
598 TOutputIterator o_end = o_begin;
599
600 while (i_begin != i_end)
601 {
602 ::new (static_cast<void*>(etl::to_address(o_end))) value_type(*i_begin);
603 ++i_begin;
604 ++o_end;
605 }
606
607 return o_end;
608 }
609
610 //*****************************************************************************
615 //*****************************************************************************
616 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
617 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
618 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
619 {
620 TOutputIterator o_end = etl::copy(i_begin, i_end, o_begin);
621 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
622
623 return o_end;
624 }
625
626 //*****************************************************************************
631 //*****************************************************************************
632 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
633 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
634 TOutputIterator>::type
635 uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
636 {
637 TOutputIterator o_end = etl::uninitialized_copy(i_begin, i_end, o_begin);
638
639 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
640
641 return o_end;
642 }
643#endif
644
645#if ETL_USING_CPP17
646 namespace ranges
647 {
648 //*****************************************************************************
652 //*****************************************************************************
653 struct uninitialized_copy_fn
654 {
655 template <class I, class S1, class O, class S2, typename = etl::enable_if_t<!etl::is_range_v<I>>>
656 ranges::uninitialized_copy_result<I, O> operator()(I ifirst, S1 ilast, O ofirst, S2 olast) const
657 {
658 using value_type = typename etl::iterator_traits<O>::value_type;
659
660 O ofirst_original = ofirst;
661
662 #if ETL_USING_EXCEPTIONS
663 try
664 {
665 #endif
666 for (; ifirst != ilast && ofirst != olast; ++ifirst, ++ofirst)
667 {
668 ::new (static_cast<void*>(etl::to_address(ofirst))) value_type(*ifirst);
669 }
670
671 return {etl::move(ifirst), etl::move(ofirst)};
672 #if ETL_USING_EXCEPTIONS
673 }
674 catch (...)
675 {
676 for (; ofirst_original != ofirst; ++ofirst_original)
677 {
678 etl::to_address(ofirst_original)->~value_type();
679 }
680 throw;
681 }
682 #endif
683 }
684
685 template <class IR, class OR, typename = etl::enable_if_t<etl::is_range_v<IR>>>
686 ranges::uninitialized_copy_result<ranges::borrowed_iterator_t<IR>, ranges::borrowed_iterator_t<OR>> operator()(IR&& in_range,
687 OR&& out_range) const
688 {
689 return (*this)(ranges::begin(in_range), ranges::end(in_range), ranges::begin(out_range), ranges::end(out_range));
690 }
691 };
692
693 inline constexpr uninitialized_copy_fn uninitialized_copy{};
694
695 //*****************************************************************************
699 //*****************************************************************************
700 struct uninitialized_copy_n_fn
701 {
702 template <class I, class O, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
703 ranges::uninitialized_copy_n_result<I, O> operator()(I ifirst, etl::iter_difference_t<I> n, O ofirst, S olast) const
704 {
705 using value_type = typename etl::iterator_traits<O>::value_type;
706
707 O ofirst_original = ofirst;
708
709 #if ETL_USING_EXCEPTIONS
710 try
711 {
712 #endif
713 for (; n > 0 && ofirst != olast; ++ifirst, ++ofirst, --n)
714 {
715 ::new (static_cast<void*>(etl::to_address(ofirst))) value_type(*ifirst);
716 }
717
718 return {etl::move(ifirst), etl::move(ofirst)};
719 #if ETL_USING_EXCEPTIONS
720 }
721 catch (...)
722 {
723 for (; ofirst_original != ofirst; ++ofirst_original)
724 {
725 etl::to_address(ofirst_original)->~value_type();
726 }
727 throw;
728 }
729 #endif
730 }
731 };
732
733 inline constexpr uninitialized_copy_n_fn uninitialized_copy_n{};
734
735 //*****************************************************************************
739 //*****************************************************************************
740 struct uninitialized_fill_fn
741 {
742 template <class I, class S, class T, typename = etl::enable_if_t<!etl::is_range_v<I>>>
743 I operator()(I first, S last, const T& value) const
744 {
745 using value_type = typename etl::iterator_traits<I>::value_type;
746
747 I current = first;
748
749 #if ETL_USING_EXCEPTIONS
750 try
751 {
752 #endif
753 for (; current != last; ++current)
754 {
755 ::new (static_cast<void*>(etl::to_address(current))) value_type(value);
756 }
757
758 return current;
759 #if ETL_USING_EXCEPTIONS
760 }
761 catch (...)
762 {
763 for (; first != current; ++first)
764 {
765 etl::to_address(first)->~value_type();
766 }
767 throw;
768 }
769 #endif
770 }
771
772 template <class R, class T, typename = etl::enable_if_t<etl::is_range_v<R>>>
773 ranges::borrowed_iterator_t<R> operator()(R&& r, const T& value) const
774 {
775 return (*this)(ranges::begin(r), ranges::end(r), value);
776 }
777 };
778
779 inline constexpr uninitialized_fill_fn uninitialized_fill{};
780
781 //*****************************************************************************
785 //*****************************************************************************
786 struct uninitialized_fill_n_fn
787 {
788 template <class I, class T>
789 I operator()(I first, etl::iter_difference_t<I> n, const T& value) const
790 {
791 using value_type = typename etl::iterator_traits<I>::value_type;
792
793 I current = first;
794
795 #if ETL_USING_EXCEPTIONS
796 try
797 {
798 #endif
799 for (; n > 0; ++current, --n)
800 {
801 ::new (static_cast<void*>(etl::to_address(current))) value_type(value);
802 }
803
804 return current;
805 #if ETL_USING_EXCEPTIONS
806 }
807 catch (...)
808 {
809 for (; first != current; ++first)
810 {
811 etl::to_address(first)->~value_type();
812 }
813 throw;
814 }
815 #endif
816 }
817 };
818
819 inline constexpr uninitialized_fill_n_fn uninitialized_fill_n{};
820 } // namespace ranges
821#endif
822
823#if ETL_USING_STL && ETL_USING_CPP11
824 //*****************************************************************************
828 //*****************************************************************************
829 template <typename TInputIterator, typename TSize, typename TOutputIterator>
830 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
831 {
832 return std::uninitialized_copy_n(i_begin, n, o_begin);
833 }
834
835 //*****************************************************************************
840 //*****************************************************************************
841 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
842 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
843 {
844 count += n;
845
846 return std::uninitialized_copy_n(i_begin, n, o_begin);
847 }
848#else
849 //*****************************************************************************
853 //*****************************************************************************
854 template <typename TInputIterator, typename TSize, typename TOutputIterator>
855 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
856 {
857 return etl::uninitialized_copy(i_begin, i_begin + n, o_begin);
858 }
859
860 //*****************************************************************************
865 //*****************************************************************************
866 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
867 TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
868 {
869 count += n;
870
871 return etl::uninitialized_copy(i_begin, i_begin + n, o_begin);
872 }
873#endif
874
875#if ETL_USING_CPP11
876 #if ETL_USING_STL && ETL_USING_CPP17
877 //*****************************************************************************
881 //*****************************************************************************
882 template <typename TInputIterator, typename TOutputIterator>
883 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
884 {
887 return std::uninitialized_move(i_begin, i_end, o_begin);
889 }
890
891 //*****************************************************************************
896 //*****************************************************************************
897 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
898 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
899 {
900 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
901
903 return std::uninitialized_move(i_begin, i_end, o_begin);
905 }
906 #else
907 //*****************************************************************************
911 //*****************************************************************************
912 template <typename TInputIterator, typename TOutputIterator>
913 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
914 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
915 {
916 return etl::move(i_begin, i_end, o_begin);
917 }
918
919 //*****************************************************************************
923 //*****************************************************************************
924 template <typename TInputIterator, typename TOutputIterator>
925 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
926 TOutputIterator>::type
927 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
928 {
929 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
930
931 TOutputIterator o_end = o_begin;
932
933 while (i_begin != i_end)
934 {
935 ::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
936 ++i_begin;
937 ++o_end;
938 }
939
940 return o_end;
941 }
942
943 //*****************************************************************************
948 //*****************************************************************************
949 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
950 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
951 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
952 {
953 TOutputIterator o_end = etl::move(i_begin, i_end, o_begin);
954 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
955
956 return o_end;
957 }
958
959 //*****************************************************************************
964 //*****************************************************************************
965 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
966 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
967 TOutputIterator>::type
968 uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
969 {
970 TOutputIterator o_end = etl::uninitialized_move(i_begin, i_end, o_begin);
971
972 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
973
974 return o_end;
975 }
976 #endif
977#else
978 // C++03
979 //*****************************************************************************
983 //*****************************************************************************
984 template <typename TInputIterator, typename TOutputIterator>
985 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
986 {
987 // Move not supported. Defer to copy.
988 return ETL_OR_STD::uninitialized_copy(i_begin, i_end, o_begin);
989 }
990
991 //*****************************************************************************
996 //*****************************************************************************
997 template <typename TInputIterator, typename TOutputIterator, typename TCounter>
998 TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin, TCounter& count)
999 {
1000 count += static_cast<TCounter>(etl::distance(i_begin, i_end));
1001
1002 // Move not supported. Defer to copy.
1003 return ETL_OR_STD::uninitialized_copy(i_begin, i_end, o_begin);
1004 }
1005#endif
1006
1007#if ETL_USING_CPP11
1008 #if ETL_USING_STL && ETL_USING_CPP17
1009 //*****************************************************************************
1013 //*****************************************************************************
1014 template <typename TInputIterator, typename TSize, typename TOutputIterator>
1015 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
1016 {
1017 return std::uninitialized_move(i_begin, i_begin + n, o_begin);
1018 }
1019
1020 //*****************************************************************************
1025 //*****************************************************************************
1026 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
1027 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
1028 {
1029 count += TCounter(n);
1030
1031 return std::uninitialized_move(i_begin, i_begin + n, o_begin);
1032 }
1033 #else
1034 //*****************************************************************************
1038 //*****************************************************************************
1039 template <typename TInputIterator, typename TSize, typename TOutputIterator>
1040 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
1041 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
1042 {
1043 return etl::move(i_begin, i_begin + n, o_begin);
1044 }
1045
1046 //*****************************************************************************
1050 //*****************************************************************************
1051 template <typename TInputIterator, typename TSize, typename TOutputIterator>
1052 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
1053 TOutputIterator>::type
1054 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
1055 {
1056 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
1057
1058 TOutputIterator o_end = o_begin;
1059
1060 while (n-- != 0)
1061 {
1062 ::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
1063 ++i_begin;
1064 ++o_end;
1065 }
1066
1067 return o_end;
1068 }
1069
1070 //*****************************************************************************
1075 //*****************************************************************************
1076 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
1077 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
1078 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
1079 {
1080 TOutputIterator o_end = etl::move(i_begin, i_begin + n, o_begin);
1081 count += TCounter(n);
1082
1083 return o_end;
1084 }
1085
1086 //*****************************************************************************
1091 //*****************************************************************************
1092 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
1093 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
1094 TOutputIterator>::type
1095 uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
1096 {
1097 TOutputIterator o_end = etl::uninitialized_move(i_begin, i_begin + n, o_begin);
1098
1099 count += TCounter(n);
1100
1101 return o_end;
1102 }
1103 #endif
1104#else
1105 // C++03
1106 //*****************************************************************************
1110 //*****************************************************************************
1111 template <typename TInputIterator, typename TSize, typename TOutputIterator>
1112 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
1113 {
1114 // Move not supported. Defer to copy.
1115 return etl::uninitialized_copy_n(i_begin, n, o_begin);
1116 }
1117
1118 //*****************************************************************************
1123 //*****************************************************************************
1124 template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TCounter>
1125 TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count)
1126 {
1127 count += TCounter(n);
1128
1129 // Move not supported. Defer to copy.
1130 return etl::uninitialized_copy_n(i_begin, n, o_begin);
1131 }
1132#endif
1133
1134#if ETL_USING_CPP17
1135 namespace ranges
1136 {
1137 //*****************************************************************************
1141 //*****************************************************************************
1142 struct uninitialized_move_fn
1143 {
1144 template <class I, class S1, class O, class S2, typename = etl::enable_if_t<!etl::is_range_v<I>>>
1145 ranges::uninitialized_move_result<I, O> operator()(I ifirst, S1 ilast, O ofirst, S2 olast) const
1146 {
1147 using value_type = typename etl::iterator_traits<O>::value_type;
1148
1149 O ofirst_original = ofirst;
1150
1151 #if ETL_USING_EXCEPTIONS
1152 try
1153 {
1154 #endif
1155 for (; ifirst != ilast && ofirst != olast; ++ifirst, ++ofirst)
1156 {
1157 ::new (static_cast<void*>(etl::to_address(ofirst))) value_type(etl::move(*ifirst));
1158 }
1159
1160 return {etl::move(ifirst), etl::move(ofirst)};
1161 #if ETL_USING_EXCEPTIONS
1162 }
1163 catch (...)
1164 {
1165 for (; ofirst_original != ofirst; ++ofirst_original)
1166 {
1167 etl::to_address(ofirst_original)->~value_type();
1168 }
1169 throw;
1170 }
1171 #endif
1172 }
1173
1174 template <class IR, class OR, typename = etl::enable_if_t<etl::is_range_v<IR>>>
1175 ranges::uninitialized_move_result<ranges::borrowed_iterator_t<IR>, ranges::borrowed_iterator_t<OR>> operator()(IR&& in_range,
1176 OR&& out_range) const
1177 {
1178 return (*this)(ranges::begin(in_range), ranges::end(in_range), ranges::begin(out_range), ranges::end(out_range));
1179 }
1180 };
1181
1182 inline constexpr uninitialized_move_fn uninitialized_move{};
1183
1184 //*****************************************************************************
1188 //*****************************************************************************
1189 struct uninitialized_move_n_fn
1190 {
1191 template <class I, class O, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
1192 ranges::uninitialized_move_n_result<I, O> operator()(I ifirst, etl::iter_difference_t<I> n, O ofirst, S olast) const
1193 {
1194 using value_type = typename etl::iterator_traits<O>::value_type;
1195
1196 O ofirst_original = ofirst;
1197
1198 #if ETL_USING_EXCEPTIONS
1199 try
1200 {
1201 #endif
1202 for (; n > 0 && ofirst != olast; ++ifirst, ++ofirst, --n)
1203 {
1204 ::new (static_cast<void*>(etl::to_address(ofirst))) value_type(etl::move(*ifirst));
1205 }
1206
1207 return {etl::move(ifirst), etl::move(ofirst)};
1208 #if ETL_USING_EXCEPTIONS
1209 }
1210 catch (...)
1211 {
1212 for (; ofirst_original != ofirst; ++ofirst_original)
1213 {
1214 etl::to_address(ofirst_original)->~value_type();
1215 }
1216 throw;
1217 }
1218 #endif
1219 }
1220 };
1221
1222 inline constexpr uninitialized_move_n_fn uninitialized_move_n{};
1223 } // namespace ranges
1224#endif
1225
1226#if ETL_USING_STL && ETL_USING_CPP17
1227 //*****************************************************************************
1231 //*****************************************************************************
1232 template <typename TOutputIterator>
1233 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1234 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end)
1235 {
1236 std::uninitialized_default_construct(o_begin, o_end);
1237 }
1238
1239 //*****************************************************************************
1244 //*****************************************************************************
1245 template <typename TOutputIterator, typename TCounter>
1246 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1247 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
1248 {
1249 count = static_cast<TCounter>(etl::distance(o_begin, o_end));
1250
1251 std::uninitialized_default_construct(o_begin, o_end);
1252 }
1253#else
1254 //*****************************************************************************
1258 //*****************************************************************************
1259 template <typename TOutputIterator>
1260 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1261 uninitialized_default_construct(TOutputIterator /*o_begin*/, TOutputIterator /*o_end*/)
1262 {
1263 // Do nothing
1264 }
1265
1266 //*****************************************************************************
1270 //*****************************************************************************
1271 template <typename TOutputIterator>
1272 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1273 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end)
1274 {
1275 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
1276
1277 while (o_begin != o_end)
1278 {
1279 ::new (static_cast<void*>(etl::to_address(o_begin))) value_type;
1280 ++o_begin;
1281 }
1282 }
1283
1284 //*****************************************************************************
1289 //*****************************************************************************
1290 template <typename TOutputIterator, typename TCounter>
1291 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1292 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
1293 {
1294 count = static_cast<TCounter>(etl::distance(o_begin, o_end));
1295 }
1296
1297 //*****************************************************************************
1302 //*****************************************************************************
1303 template <typename TOutputIterator, typename TCounter>
1304 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1305 uninitialized_default_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
1306 {
1307 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
1308
1310 }
1311#endif
1312
1313#if ETL_USING_STL && ETL_USING_CPP17
1314 //*****************************************************************************
1318 //*****************************************************************************
1319 template <typename TOutputIterator, typename TSize>
1320 TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
1321 {
1322 return std::uninitialized_default_construct_n(o_begin, n);
1323 }
1324
1325 //*****************************************************************************
1330 //*****************************************************************************
1331 template <typename TOutputIterator, typename TSize, typename TCounter>
1332 TOutputIterator uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1333 {
1334 count += n;
1335
1336 return std::uninitialized_default_construct_n(o_begin, n);
1337 }
1338#else
1339 //*****************************************************************************
1343 //*****************************************************************************
1344 template <typename TOutputIterator, typename TSize>
1345 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
1346 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
1347 {
1348 TOutputIterator o_end = o_begin + n;
1349 return o_end;
1350 }
1351
1352 //*****************************************************************************
1356 //*****************************************************************************
1357 template <typename TOutputIterator, typename TSize>
1358 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
1359 TOutputIterator>::type
1360 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n)
1361 {
1362 TOutputIterator o_end = o_begin + n;
1363
1365
1366 return o_end;
1367 }
1368
1369 //*****************************************************************************
1374 //*****************************************************************************
1375 template <typename TOutputIterator, typename TSize, typename TCounter>
1376 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, TOutputIterator>::type
1377 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1378 {
1379 TOutputIterator o_end = o_begin + n;
1380
1381 count += n;
1382
1383 return o_end;
1384 }
1385
1386 //*****************************************************************************
1391 //*****************************************************************************
1392 template <typename TOutputIterator, typename TSize, typename TCounter>
1393 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value,
1394 TOutputIterator>::type
1395 uninitialized_default_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1396 {
1397 TOutputIterator o_end = o_begin + n;
1398
1400
1401 count += n;
1402
1403 return o_end;
1404 }
1405#endif
1406
1407#if ETL_USING_CPP17
1408 namespace ranges
1409 {
1410 //*****************************************************************************
1414 //*****************************************************************************
1415 struct uninitialized_default_construct_fn
1416 {
1417 template <class I, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
1418 I operator()(I first, S last) const
1419 {
1420 using value_type = typename etl::iterator_traits<I>::value_type;
1421
1422 I current = first;
1423
1424 #if ETL_USING_EXCEPTIONS
1425 try
1426 {
1427 #endif
1428 for (; current != last; ++current)
1429 {
1430 ::new (static_cast<void*>(etl::to_address(current))) value_type;
1431 }
1432
1433 return current;
1434 #if ETL_USING_EXCEPTIONS
1435 }
1436 catch (...)
1437 {
1438 for (; first != current; ++first)
1439 {
1440 etl::to_address(first)->~value_type();
1441 }
1442 throw;
1443 }
1444 #endif
1445 }
1446
1447 template <class R, typename = etl::enable_if_t<etl::is_range_v<R>>>
1448 ranges::borrowed_iterator_t<R> operator()(R&& r) const
1449 {
1450 return (*this)(ranges::begin(r), ranges::end(r));
1451 }
1452 };
1453
1454 inline constexpr uninitialized_default_construct_fn uninitialized_default_construct{};
1455
1456 //*****************************************************************************
1460 //*****************************************************************************
1461 struct uninitialized_default_construct_n_fn
1462 {
1463 template <class I>
1464 I operator()(I first, etl::iter_difference_t<I> n) const
1465 {
1466 using value_type = typename etl::iterator_traits<I>::value_type;
1467
1468 I current = first;
1469
1470 #if ETL_USING_EXCEPTIONS
1471 try
1472 {
1473 #endif
1474 for (; n > 0; ++current, --n)
1475 {
1476 ::new (static_cast<void*>(etl::to_address(current))) value_type;
1477 }
1478
1479 return current;
1480 #if ETL_USING_EXCEPTIONS
1481 }
1482 catch (...)
1483 {
1484 for (; first != current; ++first)
1485 {
1486 etl::to_address(first)->~value_type();
1487 }
1488 throw;
1489 }
1490 #endif
1491 }
1492 };
1493
1494 inline constexpr uninitialized_default_construct_n_fn uninitialized_default_construct_n{};
1495 } // namespace ranges
1496#endif
1497
1498#if ETL_USING_STL && ETL_USING_CPP17
1499 //*****************************************************************************
1503 //*****************************************************************************
1504 template <typename TOutputIterator>
1505 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
1506 {
1507 std::uninitialized_value_construct(o_begin, o_end);
1508 }
1509
1510 //*****************************************************************************
1515 //*****************************************************************************
1516 template <typename TOutputIterator, typename TCounter>
1517 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
1518 {
1519 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
1520
1521 std::uninitialized_value_construct(o_begin, o_end);
1522 }
1523#else
1524 //*****************************************************************************
1528 //*****************************************************************************
1529 template <typename TOutputIterator>
1530 typename etl::enable_if< etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1531 uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
1532 {
1533 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
1534
1535 etl::fill(o_begin, o_end, value_type());
1536 }
1537
1538 //*****************************************************************************
1542 //*****************************************************************************
1543 template <typename TOutputIterator>
1544 typename etl::enable_if< !etl::is_trivially_constructible< typename etl::iterator_traits<TOutputIterator>::value_type>::value, void>::type
1545 uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end)
1546 {
1547 typedef typename etl::iterator_traits<TOutputIterator>::value_type value_type;
1548
1549 while (o_begin != o_end)
1550 {
1551 ::new (static_cast<void*>(etl::to_address(o_begin))) value_type();
1552 ++o_begin;
1553 }
1554 }
1555
1556 //*****************************************************************************
1561 //*****************************************************************************
1562 template <typename TOutputIterator, typename TCounter>
1563 void uninitialized_value_construct(TOutputIterator o_begin, TOutputIterator o_end, TCounter& count)
1564 {
1565 count += static_cast<TCounter>(etl::distance(o_begin, o_end));
1566
1567 etl::uninitialized_value_construct(o_begin, o_end);
1568 }
1569#endif
1570
1571#if ETL_USING_STL && ETL_USING_CPP17
1572 //*****************************************************************************
1576 //*****************************************************************************
1577 template <typename TOutputIterator, typename TSize>
1578 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
1579 {
1580 return std::uninitialized_value_construct_n(o_begin, n);
1581 }
1582
1583 //*****************************************************************************
1588 //*****************************************************************************
1589 template <typename TOutputIterator, typename TSize, typename TCounter>
1590 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1591 {
1592 count += n;
1593
1594 return std::uninitialized_value_construct_n(o_begin, n);
1595 }
1596#else
1597 //*****************************************************************************
1601 //*****************************************************************************
1602 template <typename TOutputIterator, typename TSize>
1603 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
1604 {
1605 TOutputIterator o_end = o_begin + n;
1606
1607 etl::uninitialized_value_construct(o_begin, o_end);
1608
1609 return o_end;
1610 }
1611
1612 //*****************************************************************************
1617 //*****************************************************************************
1618 template <typename TOutputIterator, typename TSize, typename TCounter>
1619 TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n, TCounter& count)
1620 {
1621 TOutputIterator o_end = o_begin + n;
1622
1623 etl::uninitialized_value_construct(o_begin, o_end);
1624
1625 count += n;
1626
1627 return o_end;
1628 }
1629#endif
1630
1631#if ETL_USING_CPP17
1632 namespace ranges
1633 {
1634 //*****************************************************************************
1638 //*****************************************************************************
1639 struct uninitialized_value_construct_fn
1640 {
1641 template <class I, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
1642 I operator()(I first, S last) const
1643 {
1644 using value_type = typename etl::iterator_traits<I>::value_type;
1645
1646 I current = first;
1647
1648 #if ETL_USING_EXCEPTIONS
1649 try
1650 {
1651 #endif
1652 for (; current != last; ++current)
1653 {
1654 ::new (static_cast<void*>(etl::to_address(current))) value_type();
1655 }
1656
1657 return current;
1658 #if ETL_USING_EXCEPTIONS
1659 }
1660 catch (...)
1661 {
1662 for (; first != current; ++first)
1663 {
1664 etl::to_address(first)->~value_type();
1665 }
1666 throw;
1667 }
1668 #endif
1669 }
1670
1671 template <class R, typename = etl::enable_if_t<etl::is_range_v<R>>>
1672 ranges::borrowed_iterator_t<R> operator()(R&& r) const
1673 {
1674 return (*this)(ranges::begin(r), ranges::end(r));
1675 }
1676 };
1677
1678 inline constexpr uninitialized_value_construct_fn uninitialized_value_construct{};
1679
1680 //*****************************************************************************
1684 //*****************************************************************************
1685 struct uninitialized_value_construct_n_fn
1686 {
1687 template <class I>
1688 I operator()(I first, etl::iter_difference_t<I> n) const
1689 {
1690 using value_type = typename etl::iterator_traits<I>::value_type;
1691
1692 I current = first;
1693
1694 #if ETL_USING_EXCEPTIONS
1695 try
1696 {
1697 #endif
1698 for (; n > 0; ++current, --n)
1699 {
1700 ::new (static_cast<void*>(etl::to_address(current))) value_type();
1701 }
1702
1703 return current;
1704 #if ETL_USING_EXCEPTIONS
1705 }
1706 catch (...)
1707 {
1708 for (; first != current; ++first)
1709 {
1710 etl::to_address(first)->~value_type();
1711 }
1712 throw;
1713 }
1714 #endif
1715 }
1716 };
1717
1718 inline constexpr uninitialized_value_construct_n_fn uninitialized_value_construct_n{};
1719 } // namespace ranges
1720#endif
1721
1722#if ETL_USING_STL && ETL_USING_CPP20
1723 //*****************************************************************************
1727 //*****************************************************************************
1728 template <typename T, typename... TArgs>
1729 ETL_CONSTEXPR20 T* construct_at(T* p, TArgs&&... args)
1730 {
1731 return std::construct_at(p, etl::forward<TArgs>(args)...);
1732 }
1733#elif ETL_USING_CPP11
1734 //*****************************************************************************
1738 //*****************************************************************************
1739 template <typename T, typename... TArgs>
1740 T* construct_at(T* p, TArgs&&... args)
1741 {
1742 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T(etl::forward<TArgs>(args)...);
1743 }
1744#else
1745 //*****************************************************************************
1749 //*****************************************************************************
1750 template <typename T>
1752 {
1753 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T();
1754 }
1755 //*****************************************************************************
1759 //*****************************************************************************
1760 template <typename T, typename TArg>
1761 T* construct_at(T* p, const TArg& arg)
1762 {
1763 return ::new (const_cast<void*>(static_cast<const volatile void*>(p))) T(arg);
1764 }
1765#endif
1766
1767#if ETL_USING_CPP17
1768 namespace ranges
1769 {
1770 //*****************************************************************************
1774 //*****************************************************************************
1775 struct construct_at_fn
1776 {
1777 template <class T, class... Args>
1778 constexpr T* operator()(T* p, Args&&... args) const
1779 {
1780 return etl::construct_at(p, etl::forward<Args>(args)...);
1781 }
1782 };
1783
1784 inline constexpr construct_at_fn construct_at{};
1785 } // namespace ranges
1786#endif
1787
1788#if ETL_USING_STL && ETL_USING_CPP20
1789 //*****************************************************************************
1793 //*****************************************************************************
1794 template <typename T>
1795 ETL_CONSTEXPR20 void destroy_at(T* p)
1796 {
1797 std::destroy_at(p);
1798 }
1799
1800 //*****************************************************************************
1805 //*****************************************************************************
1806 template <typename T, typename TCounter>
1807 ETL_CONSTEXPR20 void destroy_at(T* p, TCounter& count)
1808 {
1809 --count;
1810 std::destroy_at(p);
1811 }
1812#else
1813 //*****************************************************************************
1817 //*****************************************************************************
1818 template <typename T>
1819 typename etl::enable_if<etl::is_trivially_destructible<T>::value, void>::type destroy_at(T* /*p*/)
1820 {
1821 }
1822
1823 //*****************************************************************************
1827 //*****************************************************************************
1828 template <typename T>
1829 typename etl::enable_if<!etl::is_trivially_destructible<T>::value, void>::type destroy_at(T* p)
1830 {
1831 p->~T();
1832 }
1833
1834 //*****************************************************************************
1839 //*****************************************************************************
1840 template <typename T, typename TCounter>
1841 typename etl::enable_if<etl::is_trivially_destructible<T>::value, void>::type destroy_at(T* /*p*/, TCounter& count)
1842 {
1843 --count;
1844 }
1845
1846 //*****************************************************************************
1851 //*****************************************************************************
1852 template <typename T, typename TCounter>
1853 typename etl::enable_if<!etl::is_trivially_destructible<T>::value, void>::type destroy_at(T* p, TCounter& count)
1854 {
1855 p->~T();
1856 --count;
1857 }
1858#endif
1859
1860#if ETL_USING_STL && ETL_USING_CPP17
1861 //*****************************************************************************
1865 //*****************************************************************************
1866 template <typename TIterator>
1867 void destroy(TIterator i_begin, TIterator i_end)
1868 {
1869 std::destroy(i_begin, i_end);
1870 }
1871
1872 //*****************************************************************************
1877 //*****************************************************************************
1878 template <typename TIterator, typename TCounter>
1879 void destroy(TIterator i_begin, TIterator i_end, TCounter& count)
1880 {
1881 count -= static_cast<TCounter>(etl::distance(i_begin, i_end));
1882
1883 std::destroy(i_begin, i_end);
1884 }
1885#else
1886 //*****************************************************************************
1890 //*****************************************************************************
1891 template <typename TIterator>
1892 typename etl::enable_if< etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, void>::type
1893 destroy(TIterator /*i_begin*/, TIterator /*i_end*/)
1894 {
1895 }
1896
1897 //*****************************************************************************
1901 //*****************************************************************************
1902 template <typename TIterator>
1903 typename etl::enable_if< !etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, void>::type
1904 destroy(TIterator i_begin, TIterator i_end)
1905 {
1906 while (i_begin != i_end)
1907 {
1909 ++i_begin;
1910 }
1911 }
1912
1913 //*****************************************************************************
1918 //*****************************************************************************
1919 template <typename TIterator, typename TCounter>
1920 typename etl::enable_if< etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, void>::type
1921 destroy(TIterator i_begin, TIterator i_end, TCounter& count)
1922 {
1923 count -= static_cast<TCounter>(etl::distance(i_begin, i_end));
1924 }
1925
1926 //*****************************************************************************
1931 //*****************************************************************************
1932 template <typename TIterator, typename TCounter>
1933 typename etl::enable_if< !etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, void>::type
1934 destroy(TIterator i_begin, TIterator i_end, TCounter& count)
1935 {
1936 count -= static_cast<TCounter>(etl::distance(i_begin, i_end));
1937
1938 while (i_begin != i_end)
1939 {
1941 ++i_begin;
1942 }
1943 }
1944#endif
1945
1946#if ETL_USING_STL && ETL_USING_CPP17
1947 //*****************************************************************************
1951 //*****************************************************************************
1952 template <typename TIterator, typename TSize>
1953 TIterator destroy_n(TIterator i_begin, TSize n)
1954 {
1955 return std::destroy_n(i_begin, n);
1956 }
1957
1958 //*****************************************************************************
1963 //*****************************************************************************
1964 template <typename TIterator, typename TSize, typename TCounter>
1965 TIterator destroy_n(TIterator i_begin, TSize n, TCounter& count)
1966 {
1967 count -= n;
1968
1969 return std::destroy_n(i_begin, n);
1970 }
1971#else
1972 //*****************************************************************************
1976 //*****************************************************************************
1977 template <typename TIterator, typename TSize>
1978 typename etl::enable_if< etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, TIterator>::type
1979 destroy_n(TIterator i_begin, TSize n)
1980 {
1981 return i_begin + n;
1982 }
1983
1984 //*****************************************************************************
1988 //*****************************************************************************
1989 template <typename TIterator, typename TSize>
1990 typename etl::enable_if< !etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, TIterator>::type
1991 destroy_n(TIterator i_begin, TSize n)
1992 {
1993 while (n > 0)
1994 {
1996 ++i_begin;
1997 --n;
1998 }
1999
2000 return i_begin;
2001 }
2002
2003 //*****************************************************************************
2008 //*****************************************************************************
2009 template <typename TIterator, typename TSize, typename TCounter>
2010 typename etl::enable_if< etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, TIterator>::type
2011 destroy_n(TIterator i_begin, TSize n, TCounter& count)
2012 {
2013 count -= n;
2014 return i_begin + n;
2015 }
2016
2017 //*****************************************************************************
2022 //*****************************************************************************
2023 template <typename TIterator, typename TSize, typename TCounter>
2024 typename etl::enable_if< !etl::is_trivially_destructible< typename etl::iterator_traits<TIterator>::value_type>::value, TIterator>::type
2025 destroy_n(TIterator i_begin, TSize n, TCounter& count)
2026 {
2027 count -= n;
2028
2029 while (n > 0)
2030 {
2032 ++i_begin;
2033 --n;
2034 }
2035
2036 return i_begin;
2037 }
2038#endif
2039
2040#if ETL_USING_CPP17
2041 namespace ranges
2042 {
2043 //*****************************************************************************
2047 //*****************************************************************************
2048 struct destroy_at_fn
2049 {
2050 template <class T>
2051 constexpr void operator()(T* p) const
2052 {
2053 etl::destroy_at(p);
2054 }
2055 };
2056
2057 inline constexpr destroy_at_fn destroy_at{};
2058
2059 //*****************************************************************************
2063 //*****************************************************************************
2064 struct destroy_fn
2065 {
2066 template <class I, class S, typename = etl::enable_if_t<!etl::is_range_v<I>>>
2067 I operator()(I first, S last) const
2068 {
2069 for (; first != last; ++first)
2070 {
2072 }
2073
2074 return first;
2075 }
2076
2077 template <class R, typename = etl::enable_if_t<etl::is_range_v<R>>>
2078 ranges::borrowed_iterator_t<R> operator()(R&& r) const
2079 {
2080 return (*this)(ranges::begin(r), ranges::end(r));
2081 }
2082 };
2083
2084 inline constexpr destroy_fn destroy{};
2085
2086 //*****************************************************************************
2090 //*****************************************************************************
2091 struct destroy_n_fn
2092 {
2093 template <class I>
2094 I operator()(I first, etl::iter_difference_t<I> n) const
2095 {
2096 for (; n > 0; ++first, --n)
2097 {
2099 }
2100
2101 return first;
2102 }
2103 };
2104
2105 inline constexpr destroy_n_fn destroy_n{};
2106 } // namespace ranges
2107#endif
2108
2109#if ETL_USING_CPP11
2110 //*****************************************************************************
2117 //*****************************************************************************
2118 template <typename T>
2119 typename etl::enable_if<etl::is_trivially_relocatable<T>::value && !etl::is_const<T>::value, T*>::type trivially_relocate(T* first, T* last,
2120 T* result)
2121 {
2122 if (first == result)
2123 {
2124 return last;
2125 }
2126
2127 const size_t count = static_cast<size_t>(last - first);
2128
2129 if (count > 0)
2130 {
2131 // Use memmove to handle overlapping ranges
2132 ::memmove(static_cast<void*>(result), static_cast<const void*>(first), count * sizeof(T));
2133 }
2134
2135 return result + count;
2136 }
2137
2138 //*****************************************************************************
2146 //*****************************************************************************
2147 template <typename T>
2148 typename etl::enable_if<etl::is_trivially_relocatable<T>::value, T*>::type relocate_impl(T* first, T* last, T* result)
2149 {
2150 return etl::trivially_relocate(first, last, result);
2151 }
2152
2153 //*****************************************************************************
2157 //*****************************************************************************
2158 template <typename T>
2159 typename etl::enable_if<!etl::is_trivially_relocatable<T>::value, T*>::type relocate_impl(T* first, T* last, T* result)
2160 {
2161 const ptrdiff_t count = last - first;
2162
2163 // Check if ranges overlap and handle accordingly
2164 if (result < first || result >= last)
2165 {
2166 // No overlap or destination is after source - iterate forward
2167 T* src = first;
2168 T* dst = result;
2169 while (src != last)
2170 {
2171 ::new (static_cast<void*>(dst)) T(etl::move(*src));
2172 src->~T();
2173 ++src;
2174 ++dst;
2175 }
2176 }
2177 else
2178 {
2179 // Destination overlaps with source from below - iterate backward
2180 T* src = last;
2181 T* dst = result + count;
2182 while (src != first)
2183 {
2184 --src;
2185 --dst;
2186 ::new (static_cast<void*>(dst)) T(etl::move(*src));
2187 src->~T();
2188 }
2189 }
2190
2191 return result + count;
2192 }
2193
2194 //*****************************************************************************
2204 //*****************************************************************************
2205 template <typename T>
2206 typename etl::enable_if<etl::is_nothrow_relocatable<T>::value && !etl::is_const<T>::value, T*>::type relocate(T* first, T* last, T* result)
2207 {
2208 // Handle trivial relocation case
2209 if (first == result || first == last)
2210 {
2211 return (first == result) ? last : result;
2212 }
2213
2214 // SFINAE on etl::is_trivially_relocatable<T> selects the correct overload
2215 // so that etl::trivially_relocate is only instantiated when valid.
2216 return relocate_impl(first, last, result);
2217 }
2218#endif
2219
2220 //*****************************************************************************
2225 //*****************************************************************************
2226 template <typename T>
2227 struct default_delete
2228 {
2229 //*********************************
2230 ETL_CONSTEXPR default_delete() ETL_NOEXCEPT
2231 {
2232 }
2233
2234 //*********************************
2235 template <typename U>
2236 ETL_CONSTEXPR default_delete(const default_delete<U>&) ETL_NOEXCEPT
2237 {
2238 }
2239
2240 //*********************************
2241 void operator()(T* p) const ETL_NOEXCEPT
2242 {
2243 delete p;
2244 }
2245 };
2246
2247 //*****************************************************************************
2252 //*****************************************************************************
2253 template <typename T>
2254 struct default_delete<T[]>
2255 {
2256 //*********************************
2257 ETL_CONSTEXPR default_delete() ETL_NOEXCEPT
2258 {
2259 }
2260
2261 //*********************************
2262 template <typename U>
2263 ETL_CONSTEXPR default_delete(const default_delete<U>&) ETL_NOEXCEPT
2264 {
2265 }
2266
2267 //*********************************
2268 template <class U>
2269 void operator()(U* p) const
2270 {
2271 delete[] p;
2272 }
2273 };
2274
2275 //*****************************************************************************
2280 //*****************************************************************************
2281 template <typename T, typename TDeleter = etl::default_delete<T> >
2282 class unique_ptr
2283 {
2284 public:
2285
2286 typedef T element_type;
2287 typedef T* pointer;
2288 typedef T& reference;
2289
2290 //*********************************
2291 ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT
2292 : p(ETL_NULLPTR)
2293 {
2294 }
2295
2296 //*********************************
2297 ETL_CONSTEXPR explicit unique_ptr(pointer p_) ETL_NOEXCEPT
2298 : p(p_)
2299 {
2300 }
2301
2302#if ETL_USING_CPP11
2303 //*********************************
2304 unique_ptr(unique_ptr&& other) ETL_NOEXCEPT
2305 {
2306 if (&other != this)
2307 {
2308 p = other.release();
2309 deleter = etl::move(other.deleter);
2310 }
2311 }
2312#else
2313 //*********************************
2314 unique_ptr(unique_ptr& other) ETL_NOEXCEPT
2315 {
2316 if (&other != this)
2317 {
2318 p = other.release();
2319 deleter = other.deleter;
2320 }
2321 }
2322#endif
2323
2324 //*********************************
2325 unique_ptr(pointer p_, typename etl::conditional< etl::is_reference<TDeleter>::value, TDeleter,
2326 typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
2327 : p(p_)
2328 , deleter(deleter_)
2329 {
2330 }
2331
2332#if ETL_USING_CPP11
2333 //*********************************
2334 unique_ptr(pointer p_, typename etl::remove_reference<TDeleter>::type&& deleter_) ETL_NOEXCEPT
2335 : p(p_)
2336 , deleter(etl::move(deleter_))
2337 {
2338 }
2339
2340 template <typename U, typename E>
2341 unique_ptr(unique_ptr<U, E>&& u) ETL_NOEXCEPT
2342 : p(u.release())
2343 , deleter(etl::forward<E>(u.get_deleter()))
2344 {
2345 }
2346#endif
2347
2348 //*********************************
2349 ~unique_ptr()
2350 {
2351 if (p != ETL_NULLPTR)
2352 {
2353 deleter(p);
2354 }
2355 }
2356
2357 //*********************************
2358 ETL_CONSTEXPR pointer get() const ETL_NOEXCEPT
2359 {
2360 return p;
2361 }
2362
2363 //*********************************
2364 TDeleter& get_deleter() ETL_NOEXCEPT
2365 {
2366 return deleter;
2367 }
2368
2369 //*********************************
2370 const TDeleter& get_deleter() const ETL_NOEXCEPT
2371 {
2372 return deleter;
2373 }
2374
2375 //*********************************
2376 pointer release() ETL_NOEXCEPT
2377 {
2378 pointer value = p;
2379 p = ETL_NULLPTR;
2380
2381 return value;
2382 }
2383
2384 //*********************************
2385 void reset(pointer p_ = pointer()) ETL_NOEXCEPT
2386 {
2387 if (p_ == ETL_NULLPTR || p_ != p)
2388 {
2389 pointer value = p;
2390 p = p_;
2391
2392 if (value != ETL_NULLPTR)
2393 {
2394 deleter(value);
2395 }
2396 }
2397 }
2398
2399 //*********************************
2400 void swap(unique_ptr& value) ETL_NOEXCEPT
2401 {
2402 using ETL_OR_STD::swap;
2403
2404 swap(p, value.p);
2405 swap(deleter, value.deleter);
2406 }
2407
2408 //*********************************
2409 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
2410 {
2411 return (p != ETL_NULLPTR);
2412 }
2413
2414 //*********************************
2415 unique_ptr& operator=(etl::nullptr_t) ETL_NOEXCEPT
2416 {
2417 if (p)
2418 {
2419 reset(ETL_NULLPTR);
2420 }
2421
2422 return *this;
2423 }
2424
2425#if ETL_USING_CPP11
2426 //*********************************
2427 unique_ptr& operator=(unique_ptr&& other) ETL_NOEXCEPT
2428 {
2429 if (&other != this)
2430 {
2431 reset(other.release());
2432 deleter = etl::move(other.deleter);
2433 }
2434
2435 return *this;
2436 }
2437#else
2438 //*********************************
2439 unique_ptr& operator=(unique_ptr& other) ETL_NOEXCEPT
2440 {
2441 if (&other != this)
2442 {
2443 reset(other.release());
2444 deleter = other.deleter;
2445 }
2446
2447 return *this;
2448 }
2449#endif
2450
2451 //*********************************
2452 ETL_CONSTEXPR reference operator*() const
2453 {
2454 return *get();
2455 }
2456
2457 //*********************************
2458 ETL_CONSTEXPR pointer operator->() const ETL_NOEXCEPT
2459 {
2460 return get();
2461 }
2462
2463 //*********************************
2464 ETL_CONSTEXPR reference operator[](size_t i) const
2465 {
2466 return p[i];
2467 }
2468
2469 private:
2470
2471 // Deleted.
2472 unique_ptr(const unique_ptr&) ETL_DELETE;
2473 unique_ptr& operator=(const unique_ptr&) ETL_DELETE;
2474
2475 pointer p;
2476 TDeleter deleter;
2477 };
2478
2479 //*****************************************************************************
2484 //*****************************************************************************
2485 template <typename T, typename TDeleter>
2486 class unique_ptr<T[], TDeleter>
2487 {
2488 public:
2489
2490 typedef T element_type;
2491 typedef T* pointer;
2492 typedef T& reference;
2493
2494 //*********************************
2495 ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT
2496 : p(ETL_NULLPTR)
2497 {
2498 }
2499
2500 //*********************************
2501 ETL_CONSTEXPR explicit unique_ptr(pointer p_) ETL_NOEXCEPT
2502 : p(p_)
2503 {
2504 }
2505
2506#if ETL_USING_CPP11
2507 //*********************************
2508 unique_ptr(unique_ptr&& other) ETL_NOEXCEPT
2509 {
2510 if (&other != this)
2511 {
2512 p = other.release();
2513 deleter = etl::move(other.deleter);
2514 }
2515 }
2516#else
2517 //*********************************
2518 unique_ptr(unique_ptr& other) ETL_NOEXCEPT
2519 {
2520 if (&other != this)
2521 {
2522 p = other.release();
2523 deleter = other.deleter;
2524 }
2525 }
2526#endif
2527
2528 //*********************************
2529 unique_ptr(pointer p_, typename etl::conditional< etl::is_reference<TDeleter>::value, TDeleter,
2530 typename etl::add_lvalue_reference<const TDeleter>::type>::type deleter_) ETL_NOEXCEPT
2531 : p(p_)
2532 , deleter(deleter_)
2533 {
2534 }
2535
2536#if ETL_USING_CPP11
2537 //*********************************
2538 unique_ptr(pointer p_, typename etl::remove_reference<TDeleter>::type&& deleter_) ETL_NOEXCEPT
2539 : p(p_)
2540 , deleter(etl::move(deleter_))
2541 {
2542 }
2543
2544 template <typename U, typename E>
2545 unique_ptr(unique_ptr<U, E>&& u) ETL_NOEXCEPT
2546 : p(u.release())
2547 , deleter(etl::forward<E>(u.get_deleter()))
2548 {
2549 }
2550#endif
2551
2552 //*********************************
2553 ~unique_ptr()
2554 {
2555 if (p != ETL_NULLPTR)
2556 {
2557 deleter(p);
2558 }
2559 }
2560
2561 //*********************************
2562 ETL_CONSTEXPR pointer get() const ETL_NOEXCEPT
2563 {
2564 return p;
2565 }
2566
2567 //*********************************
2568 TDeleter& get_deleter() ETL_NOEXCEPT
2569 {
2570 return deleter;
2571 }
2572
2573 //*********************************
2574 const TDeleter& get_deleter() const ETL_NOEXCEPT
2575 {
2576 return deleter;
2577 }
2578
2579 //*********************************
2580 pointer release() ETL_NOEXCEPT
2581 {
2582 pointer value = p;
2583 p = ETL_NULLPTR;
2584 return value;
2585 }
2586
2587 //*********************************
2588 void reset(pointer p_) ETL_NOEXCEPT
2589 {
2590 if (p_ != p)
2591 {
2592 pointer value = p;
2593 p = p_;
2594
2595 if (value != ETL_NULLPTR)
2596 {
2597 deleter(value);
2598 }
2599 }
2600 }
2601
2602 void reset(etl::nullptr_t = ETL_NULLPTR) ETL_NOEXCEPT
2603 {
2604 reset(pointer());
2605 }
2606
2607 //*********************************
2608 void swap(unique_ptr& v) ETL_NOEXCEPT
2609 {
2610 using ETL_OR_STD::swap;
2611
2612 swap(p, v.p);
2613 swap(deleter, v.deleter);
2614 }
2615
2616 //*********************************
2617 ETL_CONSTEXPR operator bool() const ETL_NOEXCEPT
2618 {
2619 return (p != ETL_NULLPTR);
2620 }
2621
2622 //*********************************
2623 unique_ptr& operator=(etl::nullptr_t) ETL_NOEXCEPT
2624 {
2625 reset(ETL_NULLPTR);
2626
2627 return *this;
2628 }
2629
2630#if ETL_USING_CPP11
2631 //*********************************
2632 unique_ptr& operator=(unique_ptr&& other) ETL_NOEXCEPT
2633 {
2634 if (&other != this)
2635 {
2636 reset(other.release());
2637 deleter = etl::move(other.deleter);
2638 }
2639
2640 return *this;
2641 }
2642#else
2643 //*********************************
2644 unique_ptr& operator=(unique_ptr& other) ETL_NOEXCEPT
2645 {
2646 if (&other != this)
2647 {
2648 reset(other.release());
2649 deleter = other.deleter;
2650 }
2651
2652 return *this;
2653 }
2654#endif
2655
2656 //*********************************
2657 ETL_CONSTEXPR reference operator*() const
2658 {
2659 return *p;
2660 }
2661
2662 //*********************************
2663 ETL_CONSTEXPR pointer operator->() const ETL_NOEXCEPT
2664 {
2665 return p;
2666 }
2667
2668 //*********************************
2669 ETL_CONSTEXPR reference operator[](size_t i) const
2670 {
2671 return p[i];
2672 }
2673
2674 private:
2675
2676 // Deleted.
2677 unique_ptr(const unique_ptr&) ETL_DELETE;
2678 unique_ptr& operator=(const unique_ptr&) ETL_DELETE;
2679
2680 pointer p;
2681 TDeleter deleter;
2682 };
2683
2684 //*****************************************************************************
2685 // Comparison operators for unique_ptr
2686 //*****************************************************************************
2687 template <typename T1, typename TD1, typename T2, typename TD2>
2689 {
2690 return lhs.get() == rhs.get();
2691 }
2692
2693 //*********************************
2694 template <typename T1, typename TD1, typename T2, typename TD2>
2696 {
2697 return reinterpret_cast<char*>(lhs.get()) < reinterpret_cast<char*>(rhs.get());
2698 }
2699
2700 //*********************************
2701 template <typename T1, typename TD1, typename T2, typename TD2>
2702 bool operator<=(const etl::unique_ptr<T1, TD1>& lhs, const etl::unique_ptr<T2, TD2>& rhs)
2703 {
2704 return !(rhs < lhs);
2705 }
2706
2707 //*********************************
2708 template <typename T1, typename TD1, typename T2, typename TD2>
2709 bool operator>(const etl::unique_ptr<T1, TD1>& lhs, const etl::unique_ptr<T2, TD2>& rhs)
2710 {
2711 return (rhs < lhs);
2712 }
2713
2714 //*********************************
2715 template <typename T1, typename TD1, typename T2, typename TD2>
2716 bool operator>=(const etl::unique_ptr<T1, TD1>& lhs, const etl::unique_ptr<T2, TD2>& rhs)
2717 {
2718 return !(lhs < rhs);
2719 }
2720 //*****************************************************************************
2723 //*****************************************************************************
2724 template <typename T>
2725 typename etl::enable_if<etl::is_trivially_constructible<T>::value, void>::type create_default_at(T* /*p*/)
2726 {
2727 }
2728
2729 //*****************************************************************************
2732 //*****************************************************************************
2733 template <typename T, typename TCounter>
2734 typename etl::enable_if<etl::is_trivially_constructible<T>::value, void>::type create_default_at(T* /*p*/, TCounter& count)
2735 {
2736 ++count;
2737 }
2738
2739 //*****************************************************************************
2742 //*****************************************************************************
2743 template <typename T>
2744 typename etl::enable_if<!etl::is_trivially_constructible<T>::value, void>::type create_default_at(T* p)
2745 {
2746 ::new (p) T;
2747 }
2748
2749 //*****************************************************************************
2752 //*****************************************************************************
2753 template <typename T, typename TCounter>
2754 typename etl::enable_if<!etl::is_trivially_constructible<T>::value, void>::type create_default_at(T* p, TCounter& count)
2755 {
2756 ::new (p) T;
2757 ++count;
2758 }
2759
2760 //*****************************************************************************
2763 //*****************************************************************************
2764 template <typename T>
2766 {
2767 ::new (p) T();
2768 }
2769
2770 //*****************************************************************************
2773 //*****************************************************************************
2774 template <typename T, typename TCounter>
2775 void create_value_at(T* p, TCounter& count)
2776 {
2777 ::new (p) T();
2778 ++count;
2779 }
2780
2781 //*****************************************************************************
2784 //*****************************************************************************
2785 template <typename T>
2786 void create_copy_at(T* p, const T& value)
2787 {
2788 ::new (p) T(value);
2789 }
2790
2791#if ETL_USING_CPP11
2792 //*****************************************************************************
2795 //*****************************************************************************
2796 template <typename T>
2797 void create_copy_at(T* p, T&& value)
2798 {
2799 ::new (p) T(etl::move(value));
2800 }
2801#endif
2802
2803 //*****************************************************************************
2806 //*****************************************************************************
2807 template <typename T, typename TCounter>
2808 void create_copy_at(T* p, const T& value, TCounter& count)
2809 {
2810 ::new (p) T(value);
2811 ++count;
2812 }
2813
2814 //*****************************************************************************
2817 //*****************************************************************************
2818 template <typename T>
2820 {
2821 ::new (p) T();
2822 return *reinterpret_cast<T*>(p);
2823 }
2824
2825 //*****************************************************************************
2828 //*****************************************************************************
2829 template <typename T, typename TCounter>
2830 T& make_default_at(T* p, TCounter& count)
2831 {
2832 ::new (p) T();
2833 ++count;
2834 return *reinterpret_cast<T*>(p);
2835 }
2836
2837 //*****************************************************************************
2840 //*****************************************************************************
2841 template <typename T>
2842 T& make_copy_at(T* p, const T& other)
2843 {
2844 ::new (p) T(other);
2845 return *reinterpret_cast<T*>(p);
2846 }
2847
2848#if ETL_USING_CPP11
2849 //*****************************************************************************
2852 //*****************************************************************************
2853 template <typename T>
2854 T& make_copy_at(T* p, T&& other)
2855 {
2856 ::new (p) T(etl::move(other));
2857 return *reinterpret_cast<T*>(p);
2858 }
2859#endif
2860
2861 //*****************************************************************************
2864 //*****************************************************************************
2865 template <typename T, typename TCounter>
2866 T& make_copy_at(T* p, const T& other, TCounter& count)
2867 {
2868 ::new (p) T(other);
2869 ++count;
2870 return *reinterpret_cast<T*>(p);
2871 }
2872
2873 //*****************************************************************************
2876 //*****************************************************************************
2877 template <typename T, typename TParameter>
2878 T& make_value_at(T* p, const TParameter& value)
2879 {
2880 ::new (p) T(value);
2881 return *reinterpret_cast<T*>(p);
2882 }
2883
2884#if ETL_USING_CPP11
2885 //*****************************************************************************
2888 //*****************************************************************************
2889 template <typename T, typename TParameter>
2890 T& make_value_at(T* p, TParameter&& value)
2891 {
2892 ::new (p) T(etl::move(value));
2893 return *reinterpret_cast<T*>(p);
2894 }
2895#endif
2896
2897 //*****************************************************************************
2900 //*****************************************************************************
2901 template <typename T, typename TParameter, typename TCounter>
2902 T& make_value_at(T* p, const TParameter& value, TCounter& count)
2903 {
2904 ::new (p) T(value);
2905 ++count;
2906 return *reinterpret_cast<T*>(p);
2907 }
2908
2909 //*****************************************************************************
2913 //*****************************************************************************
2914 template <typename T>
2916 {
2917 void create_copy_at(void* p)
2918 {
2919 new (p) T(static_cast<const T&>(*this));
2920 }
2921
2922 template <typename TCounter>
2923 void create_copy_at(void* p, TCounter& count)
2924 {
2925 new (p) T(static_cast<const T&>(*this));
2926 ++count;
2927 }
2928
2929 T& make_copy_at(void* p)
2930 {
2931 new (p) T(static_cast<const T&>(*this));
2932 return *reinterpret_cast<T*>(p);
2933 }
2934
2935 template <typename TCounter>
2936 T& make_copy_at(void* p, TCounter& count)
2937 {
2938 new (p) T(static_cast<const T&>(*this));
2939 ++count;
2940 return *reinterpret_cast<T*>(p);
2941 }
2942 };
2943
2944 //*****************************************************************************
2949 //*****************************************************************************
2950 inline void memory_clear(volatile char* p, size_t n)
2951 {
2952 while (n--)
2953 {
2954 *p++ = 0;
2955 }
2956
2957 // Prevent the compiler from optimising away the volatile stores
2958 // as dead stores (observed with GCC -O3 in C++23 mode).
2959#if defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_CLANG)
2960 __asm__ __volatile__("" : : : "memory");
2961#elif defined(ETL_COMPILER_MICROSOFT)
2962 _ReadWriteBarrier();
2963#endif
2964 }
2965
2966 //*****************************************************************************
2971 //*****************************************************************************
2972 template <typename T>
2973 void memory_clear(volatile T& object)
2974 {
2975 memory_clear(reinterpret_cast<volatile char*>(&object), sizeof(T));
2976 }
2977
2978 //*****************************************************************************
2984 //*****************************************************************************
2985 template <typename T>
2986 void memory_clear_range(volatile T* begin, size_t n)
2987 {
2988 memory_clear(reinterpret_cast<volatile char*>(begin), n * sizeof(T));
2989 }
2990
2991 //*****************************************************************************
2997 //*****************************************************************************
2998 template <typename T>
2999 void memory_clear_range(volatile T* begin, volatile T* end)
3000 {
3001 const size_t n = static_cast<size_t>(etl::distance(begin, end));
3002
3004 }
3005
3006 //*****************************************************************************
3012 //*****************************************************************************
3013 inline void memory_set(volatile char* p, size_t n, char value)
3014 {
3015 while (n--)
3016 {
3017 *p++ = value;
3018 }
3019 }
3020
3021 //*****************************************************************************
3027 //*****************************************************************************
3028 template <typename T>
3029 void memory_set(volatile T& object, const char value)
3030 {
3031 memory_set(reinterpret_cast<volatile char*>(&object), sizeof(T), value);
3032 }
3033
3034 //*****************************************************************************
3041 //*****************************************************************************
3042 template <typename T>
3043 void memory_set_range(volatile T* begin, size_t n, const char value)
3044 {
3045 memory_set(reinterpret_cast<volatile char*>(begin), n * sizeof(T), value);
3046 }
3047
3048 //*****************************************************************************
3055 //*****************************************************************************
3056 template <typename T>
3057 void memory_set_range(volatile T* begin, volatile T* end, const char value)
3058 {
3059 const size_t n = static_cast<size_t>(etl::distance(begin, end));
3060
3061 memory_set_range(begin, n, value);
3062 }
3063
3064 //*****************************************************************************
3070 //*****************************************************************************
3071 template <typename T>
3073 {
3075 {
3076 memory_clear(static_cast<volatile T&>(*this));
3077 }
3078 };
3079
3080 //***************************************************************************
3084 //***************************************************************************
3085 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
3087 {
3088 public:
3089
3090 static ETL_CONSTANT size_t Object_Size = VObject_Size;
3091 static ETL_CONSTANT size_t N_Objects = VN_Objects;
3092 static ETL_CONSTANT size_t Alignment = VAlignment;
3093
3095 template <typename T>
3096 operator T&()
3097 {
3098 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
3099 return *reinterpret_cast<T*>(raw);
3100 }
3101
3103 template <typename T>
3104 operator const T&() const
3105 {
3106 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
3107 return *reinterpret_cast<const T*>(raw);
3108 }
3109
3111 template <typename T>
3112 operator T*()
3113 {
3114 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
3115 return reinterpret_cast<T*>(raw);
3116 }
3117
3119 template <typename T>
3120 operator const T*() const
3121 {
3122 ETL_STATIC_ASSERT((etl::is_same<T*, void*>::value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
3123 return reinterpret_cast<const T*>(raw);
3124 }
3125
3126#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
3127 alignas(VAlignment) char raw[Object_Size * N_Objects];
3128#else
3129 union
3130 {
3131 char raw[VObject_Size * VN_Objects];
3132 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment
3133 // as VAlignment.
3134 };
3135#endif
3136 };
3137
3138 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
3139 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Object_Size;
3140
3141 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
3142 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::N_Objects;
3143
3144 template <size_t VObject_Size, size_t VN_Objects, size_t VAlignment>
3145 ETL_CONSTANT size_t uninitialized_buffer<VObject_Size, VN_Objects, VAlignment>::Alignment;
3146
3147 //***************************************************************************
3150 //***************************************************************************
3151 template <typename T, size_t VN_Objects>
3153 {
3154 public:
3155
3156 typedef T value_type;
3157 typedef T& reference;
3158 typedef const T& const_reference;
3159 typedef T* pointer;
3160 typedef const T* const_pointer;
3161 typedef T* iterator;
3162 typedef const T* const_iterator;
3163
3164 static ETL_CONSTANT size_t Object_Size = sizeof(T);
3165 static ETL_CONSTANT size_t N_Objects = VN_Objects;
3166 static ETL_CONSTANT size_t Alignment = etl::alignment_of<T>::value;
3167
3169 T& operator[](int i)
3170 {
3171 return reinterpret_cast<T*>(this->raw)[i];
3172 }
3173
3175 const T& operator[](int i) const
3176 {
3177 return reinterpret_cast<const T*>(this->raw)[i];
3178 }
3179
3181 operator T&()
3182 {
3183 return *reinterpret_cast<T*>(raw);
3184 }
3185
3187 operator const T&() const
3188 {
3189 return *reinterpret_cast<const T*>(raw);
3190 }
3191
3193 operator T*()
3194
3195 {
3196 return reinterpret_cast<T*>(raw);
3197 }
3198
3200 operator const T*() const
3201 {
3202 return reinterpret_cast<const T*>(raw);
3203 }
3204
3205 T* begin()
3206 {
3207 return reinterpret_cast<T*>(raw);
3208 }
3209
3210 const T* begin() const
3211 {
3212 return reinterpret_cast<const T*>(raw);
3213 }
3214
3215 T* end()
3216 {
3217 return reinterpret_cast<T*>(raw + (sizeof(T) * N_Objects));
3218 }
3219
3220 const T* end() const
3221 {
3222 return reinterpret_cast<const T*>(raw + (sizeof(T) * N_Objects));
3223 }
3224
3225#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) && !defined(ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION)
3226 alignas(Alignment) char raw[sizeof(T) * N_Objects];
3227#else
3228 union
3229 {
3230 char raw[sizeof(T) * N_Objects];
3231 typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment
3232 // as Alignment.
3233 };
3234#endif
3235 };
3236
3237 template <typename T, size_t VN_Objects>
3238 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Object_Size;
3239
3240 template <typename T, size_t VN_Objects>
3241 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::N_Objects;
3242
3243 template <typename T, size_t VN_Objects>
3244 ETL_CONSTANT size_t uninitialized_buffer_of<T, VN_Objects>::Alignment;
3245
3246#if ETL_USING_CPP11
3247 template <typename T, size_t N_Objects>
3248 using uninitialized_buffer_of_t = typename uninitialized_buffer_of<T, N_Objects>::buffer;
3249#endif
3250
3251 //***************************************************************************
3258 //***************************************************************************
3259 template <typename T>
3260 T* mem_copy(const T* sb, const T* se, T* db) ETL_NOEXCEPT
3261 {
3262 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_copy a non trivially copyable type");
3263
3264#if ETL_USING_BUILTIN_MEMCPY
3265 __builtin_memcpy(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
3266#else
3267 ::memcpy(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
3268#endif
3269
3270 return db;
3271 }
3272
3273 //***************************************************************************
3279 //***************************************************************************
3280 template <typename T>
3281 T* mem_copy(const T* sb, size_t n, T* db) ETL_NOEXCEPT
3282 {
3283 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_copy a non trivially copyable type");
3284
3285#if ETL_USING_BUILTIN_MEMCPY
3286 __builtin_memcpy(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
3287#else
3288 ::memcpy(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
3289#endif
3290
3291 return db;
3292 }
3293
3294 //***************************************************************************
3300 //***************************************************************************
3301 template <typename T>
3302 T* mem_move(const T* sb, const T* se, T* db) ETL_NOEXCEPT
3303 {
3304 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_move a non trivially copyable type");
3305
3306#if ETL_USING_BUILTIN_MEMMOVE
3307 __builtin_memmove(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
3308#else
3309 ::memmove(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
3310#endif
3311
3312 return db;
3313 }
3314
3315 //***************************************************************************
3321 //***************************************************************************
3322 template <typename T>
3323 T* mem_move(const T* sb, size_t n, T* db) ETL_NOEXCEPT
3324 {
3325 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_move a non trivially copyable type");
3326
3327#if ETL_USING_BUILTIN_MEMMOVE
3330 __builtin_memmove(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
3332#else
3333 ::memmove(reinterpret_cast<void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
3334#endif
3335
3336 return db;
3337 }
3338
3339 //***************************************************************************
3350 //***************************************************************************
3351 template <typename T>
3352 ETL_NODISCARD
3353 int mem_compare(const T* sb, const T* se, const T* db) ETL_NOEXCEPT
3354 {
3355 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_compare a non trivially copyable type");
3356
3357#if ETL_USING_BUILTIN_MEMCMP
3358 return __builtin_memcmp(reinterpret_cast<const void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
3359#else
3360 return ::memcmp(reinterpret_cast<const void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * static_cast<size_t>(se - sb));
3361#endif
3362 }
3363
3364 //***************************************************************************
3375 //***************************************************************************
3376 template <typename T>
3377 ETL_NODISCARD
3378 int mem_compare(const T* sb, size_t n, const T* db) ETL_NOEXCEPT
3379 {
3380 ETL_STATIC_ASSERT(etl::is_trivially_copyable<T>::value, "Cannot mem_compare a non trivially copyable type");
3381
3382#if ETL_USING_BUILTIN_MEMCMP
3383 return __builtin_memcmp(reinterpret_cast<const void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
3384#else
3385 return ::memcmp(reinterpret_cast<const void*>(db), reinterpret_cast<const void*>(sb), sizeof(T) * n);
3386#endif
3387 }
3388
3389 //***************************************************************************
3395 //***************************************************************************
3396 template <typename TPointer, typename T>
3397 typename etl::enable_if<etl::is_pointer<TPointer>::value && !etl::is_const<TPointer>::value && etl::is_integral<T>::value && sizeof(T) == 1,
3398 TPointer>::type
3399 mem_set(TPointer db, const TPointer de, T value) ETL_NOEXCEPT
3400 {
3401 ETL_STATIC_ASSERT(etl::is_trivially_copyable< typename etl::iterator_traits<TPointer>::value_type>::value,
3402 "Cannot mem_set a non trivially copyable type");
3403
3404#if ETL_USING_BUILTIN_MEMSET
3405 __builtin_memset(reinterpret_cast<void*>(db), static_cast<char>(value),
3406 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(de - db));
3407#else
3408 ::memset(reinterpret_cast<void*>(db), static_cast<char>(value),
3409 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(de - db));
3410#endif
3411
3412 return db;
3413 }
3414
3415 //***************************************************************************
3421 //***************************************************************************
3422 template <typename TPointer, typename T>
3423 typename etl::enable_if<etl::is_pointer<TPointer>::value && !etl::is_const<TPointer>::value && etl::is_integral<T>::value && sizeof(T) == 1,
3424 TPointer>::type
3425 mem_set(TPointer db, size_t n, T value) ETL_NOEXCEPT
3426 {
3427 ETL_STATIC_ASSERT(etl::is_trivially_copyable< typename etl::iterator_traits<TPointer>::value_type>::value,
3428 "Cannot mem_set a non trivially copyable type");
3429
3430#if ETL_USING_BUILTIN_MEMSET
3431 __builtin_memset(reinterpret_cast<void*>(db), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3432#else
3433 ::memset(reinterpret_cast<void*>(db), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3434#endif
3435
3436 return db;
3437 }
3438
3439 //***************************************************************************
3445 //***************************************************************************
3446 template <typename TPointer, typename T>
3447 ETL_NODISCARD
3448 typename etl::enable_if< etl::is_pointer<TPointer>::value && !etl::is_const<typename etl::remove_pointer<TPointer>::type>::value
3449 && etl::is_integral<T>::value && sizeof(T) == 1,
3450 char*>::type mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
3451 {
3452#if ETL_USING_BUILTIN_MEMCHR
3453 void* result = __builtin_memchr(reinterpret_cast<void*>(sb), static_cast<char>(value),
3454 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
3455
3456 return (result == 0U) ? reinterpret_cast<char*>(se) : reinterpret_cast<char*>(result);
3457#else
3458 void* result = ::memchr(reinterpret_cast<void*>(sb), static_cast<char>(value),
3459 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
3460
3461 return (result == 0U) ? reinterpret_cast<char*>(se) : reinterpret_cast<char*>(result);
3462#endif
3463 }
3464
3465 //***************************************************************************
3471 //***************************************************************************
3472 template <typename TPointer, typename T>
3473 ETL_NODISCARD
3474 typename etl::enable_if< etl::is_pointer<TPointer>::value && etl::is_const<typename etl::remove_pointer<TPointer>::type>::value
3475 && etl::is_integral<T>::value && sizeof(T) == 1,
3476 const char*>::type mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT
3477 {
3478#if ETL_USING_BUILTIN_MEMCHR
3479 const void* result = __builtin_memchr(reinterpret_cast<const void*>(sb), static_cast<char>(value),
3480 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
3481
3482 return (result == 0U) ? reinterpret_cast<const char*>(se) : reinterpret_cast<const char*>(result);
3483#else
3484 const void* result = ::memchr(reinterpret_cast<const void*>(sb), static_cast<char>(value),
3485 sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
3486
3487 return (result == 0U) ? reinterpret_cast<const char*>(se) : reinterpret_cast<const char*>(result);
3488#endif
3489 }
3490
3491 //***************************************************************************
3497 //***************************************************************************
3498 template <typename TPointer, typename T>
3499 ETL_NODISCARD
3500 typename etl::enable_if< etl::is_pointer<TPointer>::value && !etl::is_const<typename etl::remove_pointer<TPointer>::type>::value
3501 && etl::is_integral<T>::value && sizeof(T) == 1,
3502 char*>::type mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
3503 {
3504#if ETL_USING_BUILTIN_MEMCHR
3505 void* result =
3506 __builtin_memchr(reinterpret_cast<void*>(sb), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3507
3508 return (result == 0U) ? reinterpret_cast<char*>(sb + n) : reinterpret_cast<char*>(result);
3509#else
3510 void* result = ::memchr(reinterpret_cast<void*>(sb), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3511
3512 return (result == 0U) ? reinterpret_cast<char*>(sb + n) : reinterpret_cast<char*>(result);
3513#endif
3514 }
3515
3516 //***************************************************************************
3522 //***************************************************************************
3523 template <typename TPointer, typename T>
3524 ETL_NODISCARD
3525 typename etl::enable_if< etl::is_pointer<TPointer>::value && etl::is_const<typename etl::remove_pointer<TPointer>::type>::value
3526 && etl::is_integral<T>::value && sizeof(T) == 1,
3527 const char*>::type mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT
3528 {
3529#if ETL_USING_BUILTIN_MEMCHR
3530 const void* result =
3531 __builtin_memchr(reinterpret_cast<const void*>(sb), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3532
3533 return (result == 0U) ? reinterpret_cast<const char*>(sb + n) : reinterpret_cast<const char*>(result);
3534#else
3535 const void* result =
3536 ::memchr(reinterpret_cast<const void*>(sb), static_cast<char>(value), sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
3537
3538 return (result == 0U) ? reinterpret_cast<const char*>(sb + n) : reinterpret_cast<const char*>(result);
3539#endif
3540 }
3541
3542#if ETL_USING_CPP11
3543 //*****************************************************************************
3545 //*****************************************************************************
3546 template <typename TObject>
3547 TObject& construct_object_at(void* p, TObject&& other)
3548 {
3549 #if ETL_IS_DEBUG_BUILD
3550 ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
3551 #endif
3552
3553 return *etl::construct_at(reinterpret_cast<typename etl::remove_reference<TObject>::type*>(p), etl::forward<TObject>(other));
3554 }
3555
3556 //*****************************************************************************
3558 //*****************************************************************************
3559 template <typename TObject, typename... TArgs>
3560 TObject& construct_object_at(void* p, TArgs&&... args)
3561 {
3562 #if ETL_IS_DEBUG_BUILD
3564 #endif
3565
3566 return *etl::construct_at(reinterpret_cast<TObject*>(p), etl::forward<TArgs>(args)...);
3567 }
3568#else
3569 //*****************************************************************************
3571 //*****************************************************************************
3572 template <typename TObject>
3573 TObject& construct_object_at(void* p)
3574 {
3575 #if ETL_IS_DEBUG_BUILD
3577 #endif
3578
3579 return *etl::construct_at(reinterpret_cast<TObject*>(p));
3580 }
3581
3582 //*****************************************************************************
3584 //*****************************************************************************
3585 template <typename TObject>
3586 TObject& construct_object_at(void* p, const TObject& other)
3587 {
3588 #if ETL_IS_DEBUG_BUILD
3590 #endif
3591
3592 return *etl::construct_at(reinterpret_cast<TObject*>(p), other);
3593 }
3594
3595 //*****************************************************************************
3597 //*****************************************************************************
3598 template <typename TObject, typename TArg>
3599 TObject& construct_object_at(void* p, const TArg& arg)
3600 {
3601 #if ETL_IS_DEBUG_BUILD
3603 #endif
3604
3605 return *etl::construct_at(reinterpret_cast<TObject*>(p), arg);
3606 }
3607#endif
3608
3609 //*****************************************************************************
3611 //*****************************************************************************
3612 template <typename TObject>
3613 TObject& get_object_at(void* p)
3614 {
3615#if ETL_IS_DEBUG_BUILD
3617#endif
3618
3619 return *reinterpret_cast<TObject*>(p);
3620 }
3621
3622 //*****************************************************************************
3624 //*****************************************************************************
3625 template <typename TObject>
3626 const TObject& get_object_at(const void* p)
3627 {
3628#if ETL_IS_DEBUG_BUILD
3630#endif
3631
3632 return *reinterpret_cast<const TObject*>(p);
3633 }
3634
3635 //*****************************************************************************
3638 //*****************************************************************************
3639 template <typename TObject>
3640 void destroy_object_at(void* p)
3641 {
3642#if ETL_IS_DEBUG_BUILD
3644#endif
3645
3646 TObject& v = get_object_at<TObject>(p);
3647 v.~TObject();
3648 }
3649} // namespace etl
3650
3651#endif
Memory misalignment exception.
Definition alignment.h:66
Definition nullptr.h:42
T & operator[](int i)
Index operator.
Definition memory.h:3169
const T & operator[](int i) const
Index operator.
Definition memory.h:3175
Definition memory.h:3087
Definition memory.h:3153
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
Definition memory.h:2283
TOutputIterator uninitialized_fill(TOutputIterator o_begin, TOutputIterator o_end, const T &value)
Definition memory.h:402
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:1531
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
void memory_set_range(volatile T *begin, size_t n, const char value)
Definition memory.h:3043
TOutputIterator uninitialized_value_construct_n(TOutputIterator o_begin, TSize n)
Definition memory.h:1603
ETL_NODISCARD T * start_lifetime_as(void *p) ETL_NOEXCEPT
Definition memory.h:152
etl::enable_if< etl::is_trivially_constructible< T >::value, void >::type create_default_at(T *)
Definition memory.h:2725
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:1346
T * construct_at(T *p)
Definition memory.h:1751
void create_copy_at(T *p, const T &value)
Definition memory.h:2786
void create_value_at(T *p)
Definition memory.h:2765
T & make_value_at(T *p, const TParameter &value)
Definition memory.h:2878
etl::enable_if< etl::is_trivially_destructible< typenameetl::iterator_traits< TIterator >::value_type >::value, void >::type destroy(TIterator, TIterator)
Definition memory.h:1893
etl::enable_if< etl::is_trivially_destructible< T >::value, void >::type destroy_at(T *)
Definition memory.h:1819
void memory_clear_range(volatile T *begin, size_t n)
Definition memory.h:2986
void memory_set(volatile char *p, size_t n, char value)
Definition memory.h:3013
TOutputIterator uninitialized_move_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
Definition memory.h:1112
TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin)
Definition memory.h:855
ETL_NODISCARD T * start_lifetime_as_array(void *p, size_t n) ETL_NOEXCEPT
Definition memory.h:192
ETL_NODISCARD ETL_CONSTEXPR T * assume_aligned(T *ptr) ETL_NOEXCEPT
Definition memory.h:363
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:1979
T & make_default_at(T *p)
Definition memory.h:2819
TOutputIterator uninitialized_move(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
Definition memory.h:985
T & make_copy_at(T *p, const T &other)
Definition memory.h:2842
void * align(size_t alignment, size_t size, void *&ptr, size_t &space) ETL_NOEXCEPT
Definition memory.h:334
void memory_clear(volatile char *p, size_t n)
Definition memory.h:2950
TOutputIterator uninitialized_copy(TInputIterator i_begin, TInputIterator i_end, TOutputIterator o_begin)
Definition memory.h:555
ETL_NODISCARD ETL_CONSTEXPR17 T * launder(T *p) ETL_NOEXCEPT
Definition memory.h:89
etl::enable_if< etl::is_trivially_constructible< typenameetl::iterator_traits< TOutputIterator >::value_type >::value, void >::type uninitialized_default_construct(TOutputIterator, TOutputIterator)
Definition memory.h:1261
TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T &value)
Definition memory.h:528
ETL_NODISCARD bool is_sufficiently_aligned(T *ptr) ETL_NOEXCEPT
Definition memory.h:388
Definition memory.h:2916
Definition memory.h:276
Definition memory.h:3073
ETL_NODISCARD T * start_lifetime_as_impl(void *p, size_t n) ETL_NOEXCEPT
Definition memory.h:124
Definition absolute.h:40
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1078
T * mem_move(const T *sb, const T *se, T *db) ETL_NOEXCEPT
Definition memory.h:3302
ETL_NODISCARD int mem_compare(const T *sb, const T *se, const T *db) ETL_NOEXCEPT
Definition memory.h:3353
void destroy_object_at(void *p)
Definition memory.h:3640
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:3399
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1130
TObject & construct_object_at(void *p)
Default construct the container at 'p'.
Definition memory.h:3573
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1144
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:3450
ETL_CONSTEXPR T * to_address(T *p) ETL_NOEXCEPT
Definition memory.h:61
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1434
TContainer::iterator end(TContainer &container)
Definition iterator.h:1166
T * mem_copy(const T *sb, const T *se, T *db) ETL_NOEXCEPT
Definition memory.h:3260
TContainer::iterator begin(TContainer &container)
Definition iterator.h:1136
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1103
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1117
TObject & get_object_at(void *p)
Get the container at 'p'.
Definition memory.h:3613
is_const
Definition type_traits.h:213