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