1
+
2
+ namespace std {
3
+ namespace detail {
4
+ template <typename T>
5
+ class compressed_pair_element {
6
+ T element;
7
+
8
+ public:
9
+ compressed_pair_element () = default ;
10
+ compressed_pair_element (const T& t) : element(t) {}
11
+
12
+ T& get () { return element; }
13
+
14
+ const T& get () const { return element; }
15
+ };
16
+
17
+ template <typename T, typename U>
18
+ struct compressed_pair : private compressed_pair_element <T>, private compressed_pair_element<U> {
19
+ compressed_pair () = default ;
20
+ compressed_pair (T& t) : compressed_pair_element<T>(t), compressed_pair_element<U>() {}
21
+ compressed_pair (const compressed_pair&) = delete ;
22
+ compressed_pair (compressed_pair<T, U>&&) noexcept = default ;
23
+
24
+ T& first () { return static_cast <compressed_pair_element<T>&>(*this ).get (); }
25
+ U& second () { return static_cast <compressed_pair_element<U>&>(*this ).get (); }
26
+
27
+ const T& first () const { return static_cast <const compressed_pair_element<T>&>(*this ).get (); }
28
+ const U& second () const { return static_cast <const compressed_pair_element<U>&>(*this ).get (); }
29
+ };
30
+ }
31
+
32
+ template <class T >
33
+ struct default_delete {
34
+ void operator ()(T* ptr) const { delete ptr; }
35
+ };
36
+
37
+ template <class T >
38
+ struct default_delete <T[]> {
39
+ template <class U >
40
+ void operator ()(U* ptr) const { delete[] ptr; }
41
+ };
42
+
43
+ template <class T , class Deleter = default_delete<T> >
44
+ class unique_ptr {
45
+ private:
46
+ detail::compressed_pair<T*, Deleter> data;
47
+ public:
48
+ constexpr unique_ptr () noexcept {}
49
+ explicit unique_ptr (T* ptr) noexcept : data(ptr) {}
50
+ unique_ptr (const unique_ptr& ptr) = delete ;
51
+ unique_ptr (unique_ptr&& ptr) noexcept = default ;
52
+
53
+ unique_ptr& operator =(unique_ptr&& ptr) noexcept = default ;
54
+
55
+ T& operator *() const { return *get (); }
56
+ T* operator ->() const noexcept { return get (); }
57
+
58
+ T* get () const noexcept { return data.first (); }
59
+
60
+ ~unique_ptr () {
61
+ Deleter& d = data.second ();
62
+ d (data.first ());
63
+ }
64
+ };
65
+
66
+ template <typename T, class ... Args> unique_ptr<T> make_unique (Args&&... args) {
67
+ return unique_ptr<T>(new T (args...)); // std::forward calls elided for simplicity.
68
+ }
69
+
70
+ class ctrl_block {
71
+ unsigned uses;
72
+
73
+ public:
74
+ ctrl_block () : uses(1 ) {}
75
+
76
+ void inc () { ++uses; }
77
+ bool dec () { return --uses == 0 ; }
78
+
79
+ virtual void destroy () = 0;
80
+ virtual ~ctrl_block () {}
81
+ };
82
+
83
+ template <typename T, class Deleter = default_delete<T> >
84
+ struct ctrl_block_impl : public ctrl_block {
85
+ T* ptr;
86
+ Deleter d;
87
+
88
+ ctrl_block_impl (T* ptr, Deleter d) : ptr(ptr), d(d) {}
89
+ virtual void destroy () override { d (ptr); }
90
+ };
91
+
92
+ template <class T >
93
+ class shared_ptr {
94
+ private:
95
+ ctrl_block* ctrl;
96
+ T* ptr;
97
+
98
+ void dec () {
99
+ if (ctrl->dec ()) {
100
+ ctrl->destroy ();
101
+ delete ctrl;
102
+ }
103
+ }
104
+
105
+ void inc () {
106
+ ctrl->inc ();
107
+ }
108
+
109
+ public:
110
+ constexpr shared_ptr () noexcept = default;
111
+ shared_ptr (T* ptr) : ctrl(new ctrl_block_impl<T>(ptr, default_delete<T>())) {}
112
+ shared_ptr (const shared_ptr& s) noexcept : ptr(s.ptr), ctrl(s.ctrl) {
113
+ inc ();
114
+ }
115
+ shared_ptr (shared_ptr&& s) noexcept = default ;
116
+
117
+ T* operator ->() const { return ptr; }
118
+
119
+ T& operator *() const { return *ptr; }
120
+
121
+ ~shared_ptr () { dec (); }
122
+ };
123
+
124
+ template <typename T, class ... Args> shared_ptr<T> make_shared (Args&&... args) {
125
+ return shared_ptr<T>(new T (args...)); // std::forward calls elided for simplicity.
126
+ }
127
+ }
0 commit comments