tenno 0.1.0
Loading...
Searching...
No Matches
memory.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// Author: Giovanni Santini
3// Mail: giovanni.santini@proton.me
4// Github: @San7o
5
6#pragma once
7
8#include <tenno/mutex.hpp>
9#include <tenno/types.hpp>
10#include <tenno/utility.hpp>
11#include <type_traits>
12
13namespace tenno
14{
15
16/*
17// Example of a custom allocator
18template <class T>
19struct custom_allocator
20{
21 using value_type = T;
22 custom_allocator() noexcept;
23 template <class U> custom_allocator (const custom_allocator<U>&) noexcept;
24 T* allocate (tenno::size n);
25 void deallocate (T* p, tenno::size n);
26 constexpr bool operator== (const custom_allocator&) const noexcept;
27 constexpr bool operator!= (const custom_allocator&) const noexcept;
28};
29*/
30
31template <class T> struct allocator
32{
33 using value_type = T;
34 using pointer = T *;
35 using const_pointer = const T *;
36 using reference = T &;
37 using const_referemce = const T &;
39
40 allocator() noexcept = default;
41 template <class U> allocator(const allocator<U> &) noexcept
42 {
43 }
44
46 {
47 return (T *) ::operator new(n * sizeof(T));
48 }
49
50 void deallocate(T *p, tenno::size n)
51 {
52 ::operator delete(p, n * sizeof(T));
53 }
54
55 constexpr bool operator==(const allocator &) const noexcept
56 {
57 return true;
58 }
59
60 constexpr bool operator!=(const allocator &) const noexcept
61 {
62 return false;
63 }
64};
65
66template <typename T> struct default_delete
67{
68 default_delete() noexcept = default;
69 void operator()(T *ptr) const noexcept
70 {
71 delete ptr;
72 }
73 template <typename U> void operator()(U *ptr) const noexcept
74 {
75 delete ptr;
76 }
77};
78
79template <class T> class weak_ptr;
80
86template <class T, class Deleter = tenno::default_delete<T>,
87 class Alloc = tenno::allocator<T>>
89{
90public:
94 using element_type = T;
95
97 {
99 Alloc allocator;
100 Deleter deleter;
104 control_block() = default;
106 {
107 this->deleter(this->object);
108 if (this->num_weak_ptrs == 0)
109 this->allocator.deallocate(
110 (T *) this, sizeof(control_block) / sizeof(T)
111 + (sizeof(control_block) % sizeof(T) != 0 ? 1 : 0));
112 }
113 };
114
116 friend class tenno::weak_ptr<T>;
117 template <class Y, class... Args>
118 friend typename std::enable_if<!std::is_array<Y>::value, shared_ptr<Y>>::type
119 make_shared(Args &&...args) noexcept;
120 template <class Y> friend shared_ptr<Y> make_shared() noexcept;
121 template <class Y>
122 friend typename std::enable_if<std::is_array<Y>::value, shared_ptr<Y>>::type
123 make_shared(tenno::size n) noexcept;
124
128 shared_ptr() noexcept : _element(nullptr), _control_block(nullptr)
129 {
130 }
131
138 {
140 sizeof(control_block) / sizeof(T)
141 + (sizeof(control_block) % sizeof(T) != 0 ? 1 : 0));
142 cb->object = ptr;
143 cb->num_ptrs = 1;
144 cb->num_weak_ptrs = 0;
145 cb->allocator = tenno::allocator<T>();
146 cb->deleter = tenno::default_delete<T>();
147 cb->cb_mutex = tenno::mutex();
148 this->_element = cb->object;
149 this->_control_block = cb;
150 }
151
158 shared_ptr(T *ptr, Deleter deleter)
159 {
161 sizeof(control_block) / sizeof(T)
162 + (sizeof(control_block) % sizeof(T) != 0 ? 1 : 0));
163 cb->object = ptr;
164 cb->num_ptrs = 1;
165 cb->num_weak_ptrs = 0;
166 cb->allocator = tenno::allocator<T>();
167 cb->deleter = deleter;
168 cb->cb_mutex = tenno::mutex();
169 this->_element = cb->object;
170 this->_control_block = cb;
171 }
172
180 shared_ptr(T *ptr, Deleter deleter, Alloc alloc)
181 {
182 control_block *cb = (control_block *) alloc.allocate(
183 sizeof(control_block) / sizeof(T)
184 + (sizeof(control_block) % sizeof(T) != 0 ? 1 : 0));
185 cb->object = ptr;
186 cb->num_ptrs = 1;
187 cb->num_weak_ptrs = 0;
188 cb->allocator = alloc;
189 cb->deleter = deleter;
190 cb->cb_mutex = tenno::mutex();
191 this->_element = cb->object;
192 this->_control_block = cb;
193 }
194
200 shared_ptr(const shared_ptr &other) noexcept
201 : _element(other._element), _control_block(other._control_block)
202 {
203 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
204 this->_control_block->num_ptrs++;
205 }
206
212 shared_ptr(shared_ptr &&other) noexcept
213 : _element(other._element), _control_block(other._control_block)
214 {
215 other._element = nullptr;
216 other._control_block = nullptr;
217 }
218
223 {
224 if (!this->_control_block)
225 return;
226
227 {
228 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
229 this->_control_block->num_ptrs--;
230 }
231 if (this->_control_block->num_ptrs == 0)
232 {
233 this->_control_block->deallocate();
234 }
235 }
236
243 shared_ptr &operator=(shared_ptr &&other) noexcept
244 {
245 if (this == &other)
246 return *this;
247
248 this->_element = other._element;
249 this->_control_block = other._control_block;
250 return *this;
251 }
252
259 shared_ptr &operator=(const shared_ptr &other) noexcept
260 {
261 if (this == &other)
262 return *this;
263
264 if (this->_control_block)
265 {
266 {
267 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
268 this->_control_block->num_ptrs--;
269 }
270 if (this->_control_block->num_ptrs == 0)
271 {
272 this->_control_block->deallocate();
273 }
274 }
275
276 this->_element = other._element;
277 this->_control_block = other._control_block;
278 other._control_block->num_ptrs++;
279 return *this;
280 }
281
285 void reset() noexcept
286 {
287 if (!this->_control_block)
288 return;
289
290 {
291 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
292 this->_control_block->num_ptrs--;
293 }
294 if (this->_control_block->num_ptrs == 0)
295 {
296 this->_control_block->deallocate();
297 }
298
299 this->_element = nullptr;
300 this->_control_block = nullptr;
301 }
302
309 void reset(T *ptr) noexcept
310 {
311 if (!this->_control_block)
312 return;
313
314 {
315 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
316 this->_control_block->num_ptrs--;
317 }
318 if (this->_control_block->num_ptrs == 0)
319 {
320 this->_control_block->deallocate();
321 }
322
324 sizeof(control_block) / sizeof(T)
325 + (sizeof(control_block) % sizeof(T) != 0 ? 1 : 0));
326 cb->object = ptr;
327 cb->num_ptrs = 1;
328 cb->num_weak_ptrs = 0;
329 cb->allocator = tenno::allocator<T>();
330 cb->deleter = tenno::default_delete<T>();
331 cb->cb_mutex = tenno::mutex();
332 this->_element = cb->object;
333 this->_control_block = cb;
334 }
335
343 void reset(T *ptr, Deleter deleter) noexcept
344 {
345 if (!this->_control_block)
346 return;
347
348 {
349 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
350 this->_control_block->num_ptrs--;
351 }
352 if (this->_control_block->num_ptrs == 0)
353 {
354 this->_control_block->deallocate();
355 }
356
358 sizeof(control_block) / sizeof(T)
359 + (sizeof(control_block) % sizeof(T) != 0 ? 1 : 0));
360 cb->object = ptr;
361 cb->num_ptrs = 1;
362 cb->num_weak_ptrs = 0;
363 cb->allocator = tenno::allocator<T>();
364 cb->deleter = deleter;
365 cb->cb_mutex = tenno::mutex();
366 this->_element = cb->object;
367 this->_control_block = cb;
368 }
369
378 void reset(T *ptr, Deleter deleter, Alloc alloc) noexcept
379 {
380 if (!this->_control_block)
381 return;
382
383 {
384 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
385 this->_control_block->num_ptrs--;
386 }
387 if (this->_control_block->num_ptrs == 0)
388 {
389 this->_control_block->deallocate();
390 }
391
392 control_block *cb = (control_block *) alloc.allocate(
393 sizeof(control_block) / sizeof(T)
394 + (sizeof(control_block) % sizeof(T) != 0 ? 1 : 0));
395 cb->object = ptr;
396 cb->num_ptrs = 1;
397 cb->num_weak_ptrs = 0;
398 cb->allocator = alloc;
399 cb->deleter = deleter;
400 cb->cb_mutex = tenno::mutex();
401 this->_element = cb->object;
402 this->_control_block = cb;
403 }
404
410 void swap(shared_ptr &other) noexcept
411 {
412 T *tmp_element = this->_element;
413 control_block *tmp_control_block = this->_control_block;
414
415 this->_element = other._element;
416 this->_control_block = other._control_block;
417
418 other._element = tmp_element;
419 other._control_block = tmp_control_block;
420 }
421
427 T *get() const noexcept
428 {
429 return this->_element;
430 }
431
437 T &operator*() const noexcept
438 {
439 return *this->_element;
440 }
441
447 T *operator->() const noexcept
448 {
449 return this->_element;
450 }
451
458 auto &operator[](tenno::size index) const noexcept
459 {
460 return (*this->_element)[index];
461 }
462
468 long use_count() const noexcept
469 {
470 if (!this->_control_block)
471 return 0;
472 return this->_control_block->num_ptrs;
473 }
474
481 explicit operator bool() const noexcept
482 {
483 return this->_element != nullptr;
484 }
485
493 bool owner_before(const shared_ptr &other) const noexcept
494 {
495 return *this->_element < *other._element;
496 }
497
506 bool owner_equal(const shared_ptr &other) const noexcept
507 {
508 if (!this->_element && !other._element)
509 return true;
510 if (!this->_element || !other._element)
511 return false;
512 return *this->_element == *other._element;
513 }
514
515 // TODO:
516 // - owner_hash (c++26)
517
518#ifndef TENNO_DEBUG
519private:
520#endif
521 T *_element;
522 control_block *_control_block;
523};
524
530template <typename T> class weak_ptr
531{
532public:
536 using element_type = T;
537
541 constexpr weak_ptr() noexcept
542 {
543 this->_control_block = nullptr;
544 this->_ptr = nullptr;
545 }
546
552 weak_ptr(const weak_ptr &r) noexcept
553 {
554 if (!r._control_block)
555 {
556 this->_control_block = nullptr;
557 this->_ptr = nullptr;
558 return;
559 }
560 this->_control_block = r._control_block;
561 this->_ptr = r._ptr;
562 this->_control_block->num_weak_ptrs++;
563 }
564
570 weak_ptr(weak_ptr &&r) noexcept
571 {
572 if (!r._control_block)
573 {
574 this->_control_block = nullptr;
575 this->_ptr = nullptr;
576 return;
577 }
578 this->_control_block = r._control_block;
579 this->_ptr = r._ptr;
580 r._control_block = nullptr;
581 r._ptr = nullptr;
582 }
583
590 {
591 if (!r._control_block)
592 {
593 this->_control_block = nullptr;
594 this->_ptr = nullptr;
595 return;
596 }
597 tenno::lock_guard<tenno::mutex> lock(r._control_block->cb_mutex);
598 this->_ptr = r._element;
599 this->_control_block = r._control_block;
600 this->_control_block->num_weak_ptrs++;
601 }
602
607 {
608 if (this->_control_block)
609 {
610 {
611 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
612 this->_control_block->num_weak_ptrs--;
613 }
614 if (this->_control_block->num_ptrs == 0
615 && this->_control_block->num_weak_ptrs == 0)
616 this->_control_block->deallocate();
617 }
618 }
619
626 weak_ptr &operator=(const weak_ptr &r) noexcept
627 {
628 if (this->_control_block)
629 {
630 {
631 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
632 this->_control_block->num_weak_ptrs--;
633 }
634 if (this->_control_block->num_ptrs == 0
635 && this->_control_block->num_weak_ptrs == 0)
636 this->_control_block->deallocate();
637 }
638 if (!r._control_block)
639 {
640 this->_control_block = nullptr;
641 this->_ptr = nullptr;
642 return *this;
643 }
644 tenno::lock_guard<tenno::mutex> lock(r._control_block->cb_mutex);
645 this->_control_block = r._control_block;
646 this->_ptr = r._ptr;
647 this->_control_block->num_weak_ptrs++;
648 return *this;
649 }
650
657 weak_ptr &operator=(const shared_ptr<T> &r) noexcept
658 {
659 if (this->_control_block)
660 {
661 {
662 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
663 this->_control_block->num_weak_ptrs--;
664 }
665 if (this->_control_block->num_ptrs == 0
666 && this->_control_block->num_weak_ptrs == 0)
667 this->_control_block->deallocate();
668 }
669 if (!r._control_block)
670 {
671 this->_control_block = nullptr;
672 this->_ptr = nullptr;
673 return *this;
674 }
675 tenno::lock_guard<tenno::mutex> lock(r._control_block->cb_mutex);
676 this->_ptr = r._element;
677 this->_control_block = r._control_block;
678 this->_control_block->num_weak_ptrs++;
679 return *this;
680 }
681
689 {
690 if (this->_control_block)
691 {
692 {
693 tenno::lock_guard<tenno::mutex> lock(this->_control_block->cb_mutex);
694 this->_control_block->num_weak_ptrs--;
695 }
696 if (this->_control_block->num_ptrs == 0
697 && this->_control_block->num_weak_ptrs == 0)
698 this->_control_block->deallocate();
699 }
700 if (!r._control_block)
701 {
702 this->_control_block = nullptr;
703 this->_ptr = nullptr;
704 return *this;
705 }
706 this->_control_block = r._control_block;
707 this->_ptr = r._ptr;
708 r._control_block = nullptr;
709 r._ptr = nullptr;
710 return *this;
711 }
712
716 void reset() noexcept
717 {
718 if (this->_control_block)
719 this->_control_block->num_weak_ptrs--;
720 this->_control_block = nullptr;
721 this->_ptr = nullptr;
722 }
723
729 void swap(weak_ptr &r) noexcept
730 {
731 auto cb_tmp = this->_control_block;
732 auto ptr_tmp = this->_ptr;
733 this->_control_block = r._control_block;
734 this->_ptr = r._ptr;
735 r._control_block = cb_tmp;
736 r._ptr = ptr_tmp;
737 }
738
744 long use_count() const noexcept
745 {
746 if (this->_control_block)
747 return this->_control_block->num_ptrs;
748 return 0;
749 }
750
757 bool expired() const noexcept
758 {
759 if (!this->_control_block)
760 return true;
761 return this->_control_block->num_ptrs == 0;
762 }
763
769 tenno::shared_ptr<T> lock() const noexcept
770 {
771 if (this->_control_block->num_ptrs == 0)
772 return tenno::shared_ptr<T>();
773 auto sp = tenno::shared_ptr<T>();
774 sp._element = this->_ptr;
775 sp._control_block = this->_control_block;
776 sp._control_block->num_ptrs++;
777 return sp;
778 }
779
787 template <class Y> bool owner_before(const weak_ptr<Y> &other) const noexcept
788 {
789 if (this->_ptr && !other._ptr)
790 return true;
791 if (!this->_ptr && other._ptr)
792 return false;
793 if (!this->_ptr || !other._ptr)
794 return false;
795 return *this->_ptr < *other._ptr;
796 }
797
805 template <class Y>
806 bool owner_before(const tenno::shared_ptr<Y> &other) const noexcept
807 {
808 return *this->_ptr < *other._element;
809 }
810
818 template <class Y>
819 bool owner_equal(const tenno::shared_ptr<Y> &other) const noexcept
820 {
821 if (!this->_ptr && !other._element)
822 return true;
823 if (!this->_ptr || !other._element)
824 return false;
825 return *this->_ptr == *other._element;
826 }
827
828 // TODO
829 /*
830 tenno::size_t owner_hash() const noexcept
831 {
832 return std::hash<element_type>()(this->_ptr);
833 }
834 */
835
836private:
837 element_type *_ptr;
838 typename tenno::shared_ptr<T>::control_block *_control_block;
839};
840
846template <class T, class Deleter = tenno::default_delete<T>> class unique_ptr
847{
848public:
849 using pointer = T *;
850 using element_type = T;
851 using deleter_type = Deleter;
852
856 constexpr unique_ptr() : _value(nullptr)
857 {
858 }
859
865 constexpr unique_ptr(T *ptr, Deleter deleter = tenno::default_delete<T>())
866 : _value(ptr), _deleter(deleter)
867 {
868 }
869
870 constexpr unique_ptr(const unique_ptr &other) = delete;
876 constexpr unique_ptr(unique_ptr &&other) noexcept
877 {
878 this->reset(other.release());
879 this->_deleter = other.get_deleter();
880 }
881
885#if __cplusplus >= 202002L // C++20
886 constexpr
887#endif
889 {
890 if (this->_value != nullptr)
891 this->_deleter(this->_value);
892 }
893
894 constexpr unique_ptr &operator=(const unique_ptr &other) = delete;
901 constexpr unique_ptr &operator=(unique_ptr &&other) noexcept
902 {
903 this->reset(other.release());
904 this->_deleter = other.get_deleter();
905 return *this;
906 }
907
913 constexpr pointer release() noexcept
914 {
915 if (!this->_value)
916 return nullptr;
917
918 pointer ptr = _value;
919 this->_value = nullptr;
920 return ptr;
921 }
922
928 constexpr void reset(pointer ptr = pointer()) noexcept
929 {
930 if (this->_value)
931 this->_deleter(this->_value);
932 this->_value = ptr;
933 }
934
940 void swap(unique_ptr &other) noexcept
941 {
942 T tmp_val = *other.get();
943 Deleter del_tmp = other.get_deleter();
944 *other.get() = *this->get();
945 other.get_deleter() = this->get_deleter();
946 *this->_value = tmp_val;
947 this->_deleter = del_tmp;
948 }
949
955 constexpr pointer get() const noexcept
956 {
957 return this->_value;
958 }
959
966 {
967 return this->_deleter;
968 }
969
974 explicit operator bool() const noexcept
975 {
976 return this->_value != nullptr;
977 }
978
983 T &operator*() noexcept
984 {
985 return *this->_value;
986 }
987
992 T &operator->() noexcept
993 {
994 return this->_value;
995 }
996
997private:
998 pointer _value = nullptr;
999 deleter_type _deleter;
1000};
1001
1015template <class T, class... Args>
1016typename std::enable_if<!std::is_array<T>::value, shared_ptr<T>>::type
1017make_shared(Args &&...args) noexcept
1018{
1019 using cb_t = typename tenno::shared_ptr<T>::control_block;
1021 T *t = new T(args...);
1022 cb_t *cb = (cb_t *) tenno::allocator<T>().allocate(
1023 sizeof(cb_t) / sizeof(T) + (sizeof(cb_t) % sizeof(T) != 0 ? 1 : 0));
1024 cb->object = t;
1025 cb->num_ptrs = 1;
1026 cb->num_weak_ptrs = 0;
1027 cb->allocator = tenno::allocator<T>();
1028 cb->deleter = tenno::default_delete<T>();
1029 cb->cb_mutex = tenno::mutex();
1030 sp._element = t;
1031 sp._control_block = cb;
1032 return tenno::move(sp);
1033}
1034
1035template <class T>
1036typename std::enable_if<std::is_array<T>::value, shared_ptr<T>>::type
1038{
1039 using cb_t = typename tenno::shared_ptr<T>::control_block;
1041 T *t = new T[n];
1042 cb_t *cb = (cb_t *) tenno::allocator<T>().allocate(
1043 sizeof(cb_t) / sizeof(T) + (sizeof(cb_t) % sizeof(T) != 0 ? 1 : 0));
1044 cb->object = t;
1045 cb->num_ptrs = 1;
1046 cb->num_weak_ptrs = 0;
1047 cb->allocator = tenno::allocator<T>();
1048 cb->deleter = tenno::default_delete<T>();
1049 cb->cb_mutex = tenno::mutex();
1050 sp._element = t;
1051 sp._control_block = cb;
1052 return tenno::move(sp);
1053}
1054
1061template <class T> shared_ptr<T> make_shared() noexcept
1062{
1063 using cb_t = typename tenno::shared_ptr<T>::control_block;
1065 T *t = new T();
1066 cb_t *cb = (cb_t *) tenno::allocator<T>().allocate(
1067 sizeof(cb_t) / sizeof(T) + (sizeof(cb_t) % sizeof(T) != 0 ? 1 : 0));
1068 cb->object = t;
1069 cb->num_ptrs = 1;
1070 cb->num_weak_ptrs = 0;
1071 cb->allocator = tenno::allocator<T>();
1072 cb->deleter = tenno::default_delete<T>();
1073 cb->cb_mutex = tenno::mutex();
1074 sp._element = t;
1075 sp._control_block = cb;
1076 return tenno::move(sp);
1077}
1078
1089template <class T, class Alloc, class... Args>
1090// typename std::enable_if<!std::is_array<T>::value, shared_ptr<T>>::type
1092 Args &&...args) noexcept
1093{
1094 T *t = alloc.allocate(1);
1095 *t = T(args...);
1096 return tenno::shared_ptr<T>(t);
1097}
1098
1107template <class T, class Alloc>
1108shared_ptr<T> allocate_shared(Alloc &alloc) noexcept
1109{
1110 T *t = alloc.allocate(1);
1111 *t = T();
1112 return tenno::shared_ptr<T>(t);
1113}
1114
1115/*
1116template <class T, class Alloc>
1117typename std::enable_if<std::is_array<T>::value, shared_ptr<T>>::type
1118allocate_shared(Alloc &alloc, tenno::size n) noexcept
1119{
1120 using elem = std::remove_all_extents<T>::type;
1121
1122 T *t = (T*) alloc.allocate(n);
1123 auto *cb =
1124 new tenno::shared_ptr<T, tenno::default_delete<elem>>::control_block();
1125 cb->object = t;
1126 cb->num_ptrs = 1;
1127 cb->num_weak_ptrs = 0;
1128 cb->allocator = alloc;
1129 cb->deleter = tenno::default_delete<elem>();
1130 cb->cb_mutex = tenno::mutex();
1131
1132 auto sp = tenno::shared_ptr<T, tenno::default_delete<elem>>();
1133 sp._element = t;
1134 sp._control_block = cb;
1135 return tenno::move(sp);
1136}
1137*/
1138
1148template <class T, class... Args>
1149constexpr unique_ptr<T> make_unique(Args &&...args)
1150{
1151 T *t = new T(args...);
1152 return tenno::unique_ptr<T>(t);
1153}
1154
1155} // namespace tenno
A simple lock guard implementation.
Definition mutex.hpp:126
A simple mutex implementation.
Definition mutex.hpp:15
A shared pointer.
Definition memory.hpp:89
shared_ptr(T *ptr)
Construct a new shared pointer object.
Definition memory.hpp:137
friend std::enable_if<!std::is_array< Y >::value, shared_ptr< Y > >::type make_shared(Args &&...args) noexcept
Create a shared pointer with the given arguments.
Definition memory.hpp:1017
void reset(T *ptr, Deleter deleter, Alloc alloc) noexcept
Reset the shared pointer to point to the object managed by the control block cb.
Definition memory.hpp:378
shared_ptr(T *ptr, Deleter deleter)
Construct a new shared pointer object.
Definition memory.hpp:158
void reset(T *ptr, Deleter deleter) noexcept
Reset the shared pointer to point to the object managed by the control block cb.
Definition memory.hpp:343
bool owner_before(const shared_ptr &other) const noexcept
Stored value ordering.
Definition memory.hpp:493
shared_ptr & operator=(shared_ptr &&other) noexcept
Move assignment operator.
Definition memory.hpp:243
shared_ptr(shared_ptr &&other) noexcept
Move constructor.
Definition memory.hpp:212
void swap(shared_ptr &other) noexcept
Swap the shared pointer with another shared pointer.
Definition memory.hpp:410
shared_ptr(const shared_ptr &other) noexcept
Copy constructor.
Definition memory.hpp:200
~shared_ptr()
Destructor.
Definition memory.hpp:222
T element_type
The type of the object to point to.
Definition memory.hpp:94
shared_ptr & operator=(const shared_ptr &other) noexcept
Copy assignment operator.
Definition memory.hpp:259
long use_count() const noexcept
Get the number of shared pointers pointing to the object.
Definition memory.hpp:468
shared_ptr(T *ptr, Deleter deleter, Alloc alloc)
Construct a new shared pointer object.
Definition memory.hpp:180
T & operator*() const noexcept
Dereference operator.
Definition memory.hpp:437
auto & operator[](tenno::size index) const noexcept
Array access operator.
Definition memory.hpp:458
void reset(T *ptr) noexcept
Reset the shared pointer to point to the object managed by the control block cb.
Definition memory.hpp:309
void reset() noexcept
Reset the shared pointer.
Definition memory.hpp:285
bool owner_equal(const shared_ptr &other) const noexcept
Stored value equality.
Definition memory.hpp:506
T * operator->() const noexcept
Member access operator.
Definition memory.hpp:447
friend control_block
Definition memory.hpp:115
T * get() const noexcept
Get the object pointed to by the shared pointer.
Definition memory.hpp:427
A shared pointer.
Definition memory.hpp:847
T & operator->() noexcept
Dereference operator.
Definition memory.hpp:992
constexpr unique_ptr & operator=(unique_ptr &&other) noexcept
Move the other unique_ptr object into this one.
Definition memory.hpp:901
Deleter deleter_type
Definition memory.hpp:851
constexpr unique_ptr(T *ptr, Deleter deleter=tenno::default_delete< T >())
Construct a new unique_ptr object with the given pointer.
Definition memory.hpp:865
deleter_type & get_deleter()
Get the deleter of the object.
Definition memory.hpp:965
constexpr unique_ptr(const unique_ptr &other)=delete
T & operator*() noexcept
Dereference operator.
Definition memory.hpp:983
constexpr pointer release() noexcept
Release the pointer from the unique_ptr object.
Definition memory.hpp:913
constexpr unique_ptr & operator=(const unique_ptr &other)=delete
~unique_ptr()
Destroy the unique_ptr object.
Definition memory.hpp:888
constexpr unique_ptr(unique_ptr &&other) noexcept
Construct a new unique_ptr object by moving the other object.
Definition memory.hpp:876
constexpr unique_ptr()
Construct a new empty unique_ptr object.
Definition memory.hpp:856
constexpr void reset(pointer ptr=pointer()) noexcept
Reset the pointer to the given value.
Definition memory.hpp:928
void swap(unique_ptr &other) noexcept
Swap the unique_ptr object with the other one.
Definition memory.hpp:940
constexpr pointer get() const noexcept
Get the pointer to the object.
Definition memory.hpp:955
A weak pointer.
Definition memory.hpp:531
void reset() noexcept
Reset the weak pointer.
Definition memory.hpp:716
bool owner_before(const weak_ptr< Y > &other) const noexcept
Stored value ordering.
Definition memory.hpp:787
long use_count() const noexcept
Get the number of shared pointers pointing to the object.
Definition memory.hpp:744
bool expired() const noexcept
Check if the weak pointer is empty.
Definition memory.hpp:757
tenno::shared_ptr< T > lock() const noexcept
Lock the weak pointer.
Definition memory.hpp:769
constexpr weak_ptr() noexcept
Default constructor.
Definition memory.hpp:541
weak_ptr & operator=(const weak_ptr &r) noexcept
Copy assignment operator.
Definition memory.hpp:626
bool owner_before(const tenno::shared_ptr< Y > &other) const noexcept
Stored value ordering.
Definition memory.hpp:806
void swap(weak_ptr &r) noexcept
Swap the weak pointer with another weak pointer.
Definition memory.hpp:729
weak_ptr(const weak_ptr &r) noexcept
Copy constructor.
Definition memory.hpp:552
weak_ptr(const tenno::shared_ptr< T > &r) noexcept
Construct a new weak pointer object.
Definition memory.hpp:589
weak_ptr & operator=(const shared_ptr< T > &r) noexcept
Move assignment operator.
Definition memory.hpp:657
T element_type
The type of the object to point to.
Definition memory.hpp:536
~weak_ptr()
Destructor.
Definition memory.hpp:606
weak_ptr(weak_ptr &&r) noexcept
Move constructor.
Definition memory.hpp:570
weak_ptr & operator=(weak_ptr &&r) noexcept
Move assignment operator.
Definition memory.hpp:688
bool owner_equal(const tenno::shared_ptr< Y > &other) const noexcept
Stored value equality.
Definition memory.hpp:819
constexpr unique_ptr< T > make_unique(Args &&...args)
Create a unique pointer with the given arguments.
Definition memory.hpp:1149
tenno::shared_ptr< T > allocate_shared(Alloc &alloc, Args &&...args) noexcept
Create a shared pointer with the given arguments and allocator.
Definition memory.hpp:1091
size_t size
Definition types.hpp:13
shared_ptr< T > make_shared() noexcept
Default initialize a shared pointer.
Definition memory.hpp:1061
constexpr std::remove_reference_t< T > && move(T &&t) noexcept
Move a value from one location to another.
Definition utility.hpp:21
T * allocate(tenno::size n)
Definition memory.hpp:45
tenno::size size_type
Definition memory.hpp:38
void deallocate(T *p, tenno::size n)
Definition memory.hpp:50
const T * const_pointer
Definition memory.hpp:35
constexpr bool operator==(const allocator &) const noexcept
Definition memory.hpp:55
allocator() noexcept=default
constexpr bool operator!=(const allocator &) const noexcept
Definition memory.hpp:60
const T & const_referemce
Definition memory.hpp:37
default_delete() noexcept=default
void operator()(U *ptr) const noexcept
Definition memory.hpp:73