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