mn_unique_ptr.hpp
Go to the documentation of this file.
1 /*
2 *This file is part of the Mini Thread Library (https://github.com/RoseLeBlood/MiniThread ).
3 *Copyright (c) 2018 Amber-Sophia Schroeck
4 *
5 *The Mini Thread Library is free software; you can redistribute it and/or modify
6 *it under the terms of the GNU Lesser General Public License as published by
7 *the Free Software Foundation, version 3, or (at your option) any later version.
8 
9 *The Mini Thread Library is distributed in the hope that it will be useful, but
10 *WITHOUT ANY WARRANTY; without even the implied warranty of
11 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 *General Public License for more details.
13 *
14 *You should have received a copy of the GNU Lesser General Public
15 *License along with the Mini Thread Library; if not, see
16 *<https://www.gnu.org/licenses/>.
17 */
18 #ifndef __MINILIB_UNIQUE_PTR_H__
19 #define __MINILIB_UNIQUE_PTR_H__
20 
21 #include "../mn_config.hpp"
22 
23 #include "../mn_copyable.hpp"
24 #include "../mn_deleter.hpp"
25 #include "../mn_functional.hpp"
26 
27 #include "../utils/mn_utils.hpp"
28 
29 
30 namespace mn {
31  namespace pointer {
38  template <typename T, class TAllocator = memory::default_allocator,
39  class TDeleter = memory::default_delete<T, TAllocator> >
40  class basic_unique_ptr : public mn::only_move_tag<void> {
41  public:
42  using value_type = T;
43  using pointer = T*;
44  using const_pointer = const T*;
45  using reference = T&;
46  using const_reference = const T&;
47  using deleter_type = TDeleter;
48  using allotor_type = TAllocator;
49 
51 
55  constexpr basic_unique_ptr() noexcept
56  : m_ptr(nullptr), m_refDeleter(deleter_type()) { }
57 
61  constexpr basic_unique_ptr(nullptr_t) noexcept
62  : m_ptr(nullptr), m_refDeleter(deleter_type()) { }
63 
67  explicit basic_unique_ptr(pointer pPointer) noexcept
68  : m_ptr(pPointer), m_refDeleter(deleter_type()) { }
69 
76  basic_unique_ptr(pointer pPointer, deleter_type& deleter) noexcept
77  : m_ptr(pPointer), m_refDeleter(deleter) { }
78 
85  basic_unique_ptr(pointer pPointer, const deleter_type& deleter) noexcept
86  : m_ptr(pPointer), m_refDeleter(deleter) { }
87 
93  basic_unique_ptr(pointer pPointer, deleter_type&& deleter) noexcept
94  : m_ptr(std::move(pPointer)), m_refDeleter(std::move(deleter)) { }
95 
100  : m_ptr(other.release()), m_refDeleter(mn::forward<deleter_type>(other.get_deleter()) ) { }
101 
105  template<typename U, class UAllocator = memory::default_allocator,
106  class UDeleter = memory::default_delete<U, UAllocator>>
108  : m_ptr(other.release()), m_refDeleter(mn::forward<deleter_type>(other.get_deleter()) ) { }
109 
113  ~basic_unique_ptr() noexcept {
114  //deleter_type _deleter = m_mPair.second();
115 
116  if (m_ptr != nullptr) get_deleter()(m_ptr);
117  m_ptr = nullptr;
118  }
119 
120 
126  self_type& operator=(self_type&& other) noexcept {
127  reset(other.release());
128  m_refDeleter = mn::forward<deleter_type>(other.get_deleter());
129  return *this;
130  }
131 
137  template<typename U, class UAllocator = memory::default_allocator,
138  class UDeleter = memory::default_delete<U, UAllocator>>
140  reset(other.release());
141  m_refDeleter = mn::forward<deleter_type>(other.get_deleter());
142  return *this;
143  }
144 
149  pointer release() noexcept {
150  pointer _ptr = get();
151  m_ptr = pointer();
152  return *this;
153  }
154 
158  void reset(pointer pPtr) noexcept {
159  mn::swap(m_ptr, pPtr);
160  if (pPtr != pointer())
161  get_deleter()(pPtr);
162  }
166  void swap(self_type& other) noexcept {
167  mn::swap(m_ptr, other.m_ptr);
168  mn::swap(m_refDeleter, other.m_refDeleter);
169  }
174  pointer get() const noexcept {
175  return m_ptr;
176  }
177 
182  deleter_type& get_deleter() noexcept {
183  return m_refDeleter;
184  }
189  const deleter_type& get_deleter() const noexcept {
190  return m_refDeleter;
191  }
192 
193 
198  return *m_ptr;
199  }
203  pointer operator->() const noexcept {
204  return m_ptr;
205  }
210  explicit operator bool() const noexcept {
211  return m_ptr == nullptr ? false : true;
212  }
213  private:
216  };
217 
224  template <typename T, class TAllocator, class TDeleter >
225  class basic_unique_ptr<T[], TAllocator, TDeleter> : public mn::only_move_tag<void> {
226  public:
227  using value_type = T;
228  using pointer = T*;
229  using const_pointer = const T*;
230  using reference = T&;
231  using const_reference = const T&;
232  using deleter_type = TDeleter;
233  using allotor_type = TAllocator;
234 
236 
240  constexpr basic_unique_ptr() noexcept
241  : m_ptr(nullptr), m_refDeleter(deleter_type()) { }
242 
246  constexpr basic_unique_ptr(nullptr_t) noexcept
247  : m_ptr(nullptr), m_refDeleter(deleter_type()) { }
248 
252  explicit basic_unique_ptr(pointer pPointer) noexcept
253  : m_ptr(pPointer), m_refDeleter(deleter_type()) { }
254 
261  basic_unique_ptr(pointer pPointer, deleter_type& deleter) noexcept
262  : m_ptr(pPointer), m_refDeleter(deleter) { }
263 
270  basic_unique_ptr(pointer pPointer, const deleter_type& deleter) noexcept
271  : m_ptr(pPointer), m_refDeleter(deleter) { }
272 
278  basic_unique_ptr(pointer pPointer, deleter_type&& deleter) noexcept
279  : m_ptr(std::move(pPointer)), m_refDeleter(std::move(deleter)) { }
280 
285  : m_ptr(other.release()), m_refDeleter(mn::forward<deleter_type>(other.get_deleter()) ) { }
286 
290  template<typename U, class UAllocator = memory::default_allocator,
291  class UDeleter = memory::default_delete<U, UAllocator>>
293  : m_ptr(other.release()), m_refDeleter(mn::forward<deleter_type>(other.get_deleter()) ) { }
294 
295  template<typename U>
296  explicit basic_unique_ptr(U* p) noexcept = delete;
300  ~basic_unique_ptr() noexcept {
301  //deleter_type _deleter = m_mPair.second();
302 
303  if (m_ptr != nullptr) get_deleter()(m_ptr);
304  m_ptr = nullptr;
305  }
306 
307 
313  self_type& operator=(self_type&& other) noexcept {
314  reset(other.release());
315  m_refDeleter = mn::forward<deleter_type>(other.get_deleter());
316  return *this;
317  }
318 
324  template<typename U, class UAllocator = memory::default_allocator,
325  class UDeleter = memory::default_delete<U, UAllocator>>
327  reset(other.release());
328  m_refDeleter = mn::forward<deleter_type>(other.get_deleter());
329  return *this;
330  }
331 
336  pointer release() noexcept {
337  pointer _ptr = get();
338  m_ptr = pointer();
339  return *this;
340  }
341 
345  void reset(pointer pPtr) noexcept {
346  mn::swap(m_ptr, pPtr);
347  if (pPtr != pointer())
348  get_deleter()(pPtr);
349  }
353  void swap(self_type& other) noexcept {
354  mn::swap(m_ptr, other.m_ptr);
355  mn::swap(m_refDeleter, other.m_refDeleter);
356  }
357 
362  pointer get() const noexcept {
363  return m_ptr;
364  }
365 
370  deleter_type& get_deleter() noexcept {
371  return m_refDeleter;
372  }
377  const deleter_type& get_deleter() const noexcept {
378  return m_refDeleter;
379  }
380 
385  return *m_ptr;
386  }
390  pointer operator->() const noexcept {
391  return m_ptr;
392  }
393 
397  reference operator[] (size_t pos) const {
398  assert(m_ptr != nullptr);
399  return m_ptr[pos];
400  }
405  explicit operator bool() const noexcept {
406  return m_ptr == nullptr ? false : true;
407  }
408 
409  // Disable construction from convertible pointer types.
410  template<typename U>
411  basic_unique_ptr(U*, const deleter_type) = delete;
412 
413  // Disable construction from convertible pointer types.
414  template<typename U>
416  private:
419  };
420 
421  template<typename T, class TA, class TD>
423  a.swap(b);
424  }
425 
426  template<typename T, class TA, class TD>
428  return a.get() == b.get();
429  }
430 
431 
432  template<typename T, class TA, class TD>
434  return a.get() != b.get();
435  }
436 
437  template<typename T, class TA, class TD>
439  using pointer = typename basic_unique_ptr<T, TA, TD>::pointer;
440  return mn::less<pointer>(a.get(), b.get());
441  }
442  template<typename T, class TA, class TD>
444  using pointer = typename basic_unique_ptr<T, TA, TD>::pointer;
445  return mn::greater<pointer>(a.get(), b.get());
446  }
447 
448  template<typename T, class TA, class TD>
450  return a.get() <= b.get();
451  }
452 
453  template<typename T, class TA, class TD>
455  return a.get() >= b.get();
456  }
457 
458 
459  template<typename T, typename... TArgs>
460  inline basic_unique_ptr<T> make_unique(TArgs&&... args) {
461  return basic_unique_ptr<T>(new T(mn::forward<TArgs>(args)...));
462  }
463 
464  template<typename T>
465  inline basic_unique_ptr<T[]> make_unique(size_t siNums) {
466  return basic_unique_ptr<T>(new T[siNums]() );
467  }
468 
469  template<typename T, typename... TArgs>
470  inline basic_unique_ptr<T[]> make_unique(TArgs&&...) = delete;
471 
472  template<typename T,
473  class TAllocator = memory::default_allocator,
474  class TDeleter = memory::default_delete<T, TAllocator>>
476  }
477 }
478 
479 #endif // __MINILIB_UNIQUE_PTR_H__
A Simple template for a deleter.
Definition: mn_basic_deleter.hpp:37
Not copyable.
Definition: mn_copyable.hpp:50
basic_unique_ptr(self_type &&other)
Move constructor.
Definition: mn_unique_ptr.hpp:284
basic_unique_ptr(pointer pPointer, deleter_type &deleter) noexcept
Takes ownership of a pointer.
Definition: mn_unique_ptr.hpp:261
~basic_unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
Definition: mn_unique_ptr.hpp:300
deleter_type & m_refDeleter
Definition: mn_unique_ptr.hpp:418
pointer m_ptr
Definition: mn_unique_ptr.hpp:417
self_type & operator=(basic_unique_ptr< U, UAllocator, UDeleter > &&other) noexcept
Move assignment operator.
Definition: mn_unique_ptr.hpp:326
reference operator*() const
Return the stored pointer as reference.
Definition: mn_unique_ptr.hpp:384
pointer operator->() const noexcept
Return the stored pointer.
Definition: mn_unique_ptr.hpp:390
pointer release() noexcept
Release ownership of any stored pointer.
Definition: mn_unique_ptr.hpp:336
T & reference
Definition: mn_unique_ptr.hpp:230
const deleter_type & get_deleter() const noexcept
Get a reference to the stored deleter.
Definition: mn_unique_ptr.hpp:377
const T & const_reference
Definition: mn_unique_ptr.hpp:231
self_type & operator=(self_type &&other) noexcept
Move assignment operator.
Definition: mn_unique_ptr.hpp:313
basic_unique_ptr(pointer pPointer) noexcept
Takes ownership of a pointer.
Definition: mn_unique_ptr.hpp:252
TAllocator allotor_type
Definition: mn_unique_ptr.hpp:233
basic_unique_ptr(pointer pPointer, deleter_type &&deleter) noexcept
Takes ownership of a pointer.
Definition: mn_unique_ptr.hpp:278
deleter_type & get_deleter() noexcept
Get a reference to the stored deleter.
Definition: mn_unique_ptr.hpp:370
constexpr basic_unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
Definition: mn_unique_ptr.hpp:246
void swap(self_type &other) noexcept
Exchange the pointer and deleter with another object.
Definition: mn_unique_ptr.hpp:353
constexpr basic_unique_ptr() noexcept
Constructor a basic_unique_ptr that owns nothing.
Definition: mn_unique_ptr.hpp:240
basic_unique_ptr(pointer pPointer, const deleter_type &deleter) noexcept
Takes ownership of a pointer.
Definition: mn_unique_ptr.hpp:270
void reset(pointer pPtr) noexcept
Replace the stored pointer.
Definition: mn_unique_ptr.hpp:345
TDeleter deleter_type
Definition: mn_unique_ptr.hpp:232
basic_unique_ptr(basic_unique_ptr< U, UAllocator, UDeleter > &&other) noexcept
Converting constructor from another type.
Definition: mn_unique_ptr.hpp:292
pointer get() const noexcept
Get the stored pointer.
Definition: mn_unique_ptr.hpp:362
const T * const_pointer
Definition: mn_unique_ptr.hpp:229
A simple unique_ptr, for a single object.
Definition: mn_unique_ptr.hpp:40
pointer m_ptr
Definition: mn_unique_ptr.hpp:214
self_type & operator=(basic_unique_ptr< U, UAllocator, UDeleter > &&other) noexcept
Move assignment operator.
Definition: mn_unique_ptr.hpp:139
pointer release() noexcept
Release ownership of any stored pointer.
Definition: mn_unique_ptr.hpp:149
TAllocator allotor_type
Definition: mn_unique_ptr.hpp:48
basic_unique_ptr(self_type &&other)
Move constructor.
Definition: mn_unique_ptr.hpp:99
const deleter_type & get_deleter() const noexcept
Get a reference to the stored deleter.
Definition: mn_unique_ptr.hpp:189
const T & const_reference
Definition: mn_unique_ptr.hpp:46
basic_unique_ptr(basic_unique_ptr< U, UAllocator, UDeleter > &&other) noexcept
Converting constructor from another type.
Definition: mn_unique_ptr.hpp:107
reference operator*() const
Return the stored pointer as reference.
Definition: mn_unique_ptr.hpp:197
TDeleter deleter_type
Definition: mn_unique_ptr.hpp:47
void swap(self_type &other) noexcept
Exchange the pointer and deleter with another object.
Definition: mn_unique_ptr.hpp:166
void reset(pointer pPtr) noexcept
Replace the stored pointer.
Definition: mn_unique_ptr.hpp:158
basic_unique_ptr(pointer pPointer, deleter_type &&deleter) noexcept
Takes ownership of a pointer.
Definition: mn_unique_ptr.hpp:93
pointer operator->() const noexcept
Return the stored pointer.
Definition: mn_unique_ptr.hpp:203
constexpr basic_unique_ptr() noexcept
Constructor a basic_unique_ptr that owns nothing.
Definition: mn_unique_ptr.hpp:55
deleter_type & m_refDeleter
Definition: mn_unique_ptr.hpp:215
self_type & operator=(self_type &&other) noexcept
Move assignment operator.
Definition: mn_unique_ptr.hpp:126
T * pointer
Definition: mn_unique_ptr.hpp:43
basic_unique_ptr(pointer pPointer, deleter_type &deleter) noexcept
Takes ownership of a pointer.
Definition: mn_unique_ptr.hpp:76
T & reference
Definition: mn_unique_ptr.hpp:45
constexpr basic_unique_ptr(nullptr_t) noexcept
Creates a unique_ptr that owns nothing.
Definition: mn_unique_ptr.hpp:61
basic_unique_ptr(pointer pPointer, const deleter_type &deleter) noexcept
Takes ownership of a pointer.
Definition: mn_unique_ptr.hpp:85
pointer get() const noexcept
Get the stored pointer.
Definition: mn_unique_ptr.hpp:174
T value_type
Definition: mn_unique_ptr.hpp:42
basic_unique_ptr(pointer pPointer) noexcept
Takes ownership of a pointer.
Definition: mn_unique_ptr.hpp:67
deleter_type & get_deleter() noexcept
Get a reference to the stored deleter.
Definition: mn_unique_ptr.hpp:182
~basic_unique_ptr() noexcept
Destructor, invokes the deleter if the stored pointer is not null.
Definition: mn_unique_ptr.hpp:113
const T * const_pointer
Definition: mn_unique_ptr.hpp:44
struct mn::memory::detail::ptr_difference T
Definition: mn_atomic_singleton.hpp:38
malloc_allocator< basic_allocator_filter > default_allocator
Definition: mn_default_allocator.hpp:30
bool operator!=(const basic_linked_ptr< T > &a, const basic_linked_ptr< U > &b)
Compares two basic_linked_ptr objects for inequality.
Definition: mn_linked_ptr.hpp:239
bool operator==(const basic_linked_ptr< T > &a, const basic_linked_ptr< U > &b)
Compares two basic_linked_ptr objects for equality. Equality is defined as being true when the pointe...
Definition: mn_linked_ptr.hpp:231
bool operator>=(basic_unique_ptr< T, TA, TD > &a, basic_unique_ptr< T, TA, TD > &b)
Definition: mn_unique_ptr.hpp:454
basic_unique_ptr< T > make_unique(TArgs &&... args)
Definition: mn_unique_ptr.hpp:460
void swap(basic_auto_ptr< T > &a, basic_auto_ptr< T > &b)
Definition: mn_auto_ptr.hpp:188
bool operator<(basic_unique_ptr< T, TA, TD > &a, basic_unique_ptr< T, TA, TD > &b)
Definition: mn_unique_ptr.hpp:438
bool operator>(basic_unique_ptr< T, TA, TD > &a, basic_unique_ptr< T, TA, TD > &b)
Definition: mn_unique_ptr.hpp:443
bool operator<=(basic_unique_ptr< T, TA, TD > &a, basic_unique_ptr< T, TA, TD > &b)
Definition: mn_unique_ptr.hpp:449
Definition: mn_allocator_typetraits.hpp:25
void swap(TAssignable &a, TAssignable &b)
Definition: mn_algorithm.hpp:312
decltype(nullptr) nullptr_t
Definition: mn_def.hpp:45
void move(const T *src, const T *last, T *dest)
Definition: mn_algorithm.hpp:100
T && forward(remove_reference_t< T > &t)
Definition: mn_functional.hpp:74
Definition: mn_utils.hpp:181
Definition: mn_utils.hpp:175