Ookii.CommandLine for C++  1.0.0
owned_or_borrowed_ptr.h
Go to the documentation of this file.
1 #ifndef OOKII_OWNED_OR_BORROWED_PTR_H_
4 #define OOKII_OWNED_OR_BORROWED_PTR_H_
5 
6 #pragma once
7 
8 #include <algorithm>
9 
10 namespace ookii
11 {
26  template<typename T>
28  {
29  public:
31  using element_type = T;
33  using pointer = T*;
35  using reference = std::add_lvalue_reference_t<T>;
36 
39  owned_or_borrowed_ptr() noexcept = default;
40 
43  owned_or_borrowed_ptr(std::nullptr_t) noexcept {}
44 
51  owned_or_borrowed_ptr(pointer ptr, bool owned = true) noexcept
52  : _ptr{ptr},
53  _owned{owned}
54  {
55  }
56 
59  {
60  reset();
61  }
62 
64 
68  : _ptr{other.release()},
69  _owned{other.is_owned()}
70  {
71  }
72 
76  template<typename T2, typename = std::enable_if_t<std::is_convertible_v<T2*, pointer>>>
78  : _ptr{other.release()},
79  _owned{other.is_owned()}
80  {
81  }
82 
83  owned_or_borrowed_ptr &operator=(const owned_or_borrowed_ptr &) = delete;
84 
88  {
89  if (this != std::addressof(other))
90  {
91  reset(other.release(), other.is_owned());
92  }
93 
94  return *this;
95  }
96 
100  template<typename T2, typename = std::enable_if_t<std::is_convertible_v<T2*, pointer>>>
102  {
103  if (this != std::addressof(other))
104  {
105  reset(other.release(), other.is_owned());
106  }
107 
108  return *this;
109  }
110 
112  owned_or_borrowed_ptr &operator=(std::nullptr_t) noexcept
113  {
114  reset();
115  return *this;
116  }
117 
120  explicit operator bool() const noexcept
121  {
122  return _ptr != nullptr;
123  }
124 
127  void swap(owned_or_borrowed_ptr &other) noexcept
128  {
129  std::swap(_ptr, other._ptr);
130  std::swap(_owned, other._owned);
131  }
132 
134  pointer get() const noexcept
135  {
136  return _ptr;
137  }
138 
148  bool is_owned() const noexcept
149  {
150  return _owned;
151  }
152 
158  reference operator*() const noexcept
159  {
160  return *get();
161  }
162 
164  pointer operator->() const noexcept
165  {
166  return get();
167  }
168 
176  void reset(pointer ptr = nullptr, bool owned = true) noexcept
177  {
178  if (_owned && _ptr != nullptr)
179  delete _ptr;
180 
181  _ptr = ptr;
182  _owned = owned;
183  }
184 
188  void reset(std::nullptr_t) noexcept
189  {
190  reset();
191  }
192 
199  pointer release() noexcept
200  {
201  return std::exchange(_ptr, nullptr);
202  }
203 
206  {
207  return {_ptr, false};
208  }
209 
210  private:
211  pointer _ptr{};
212  bool _owned{};
213  };
214 
218  template<typename T>
220  {
221  left.swap(right);
222  }
223 
230  template<typename T, typename... Args>
231  [[nodiscard]] auto make_owned_ptr(Args&&... args)
232  {
233  return owned_or_borrowed_ptr<T>(new T{std::forward<Args>(args)...});
234  }
235 }
236 
237 #endif
Smart pointer that may or may not own the contained pointer.
Definition: owned_or_borrowed_ptr.h:28
owned_or_borrowed_ptr & operator=(owned_or_borrowed_ptr< T2 > &&other) noexcept
Move assignment operator from a different owned_or_borrowed_ptr if the pointer types can be implicitl...
Definition: owned_or_borrowed_ptr.h:101
owned_or_borrowed_ptr & operator=(std::nullptr_t) noexcept
Assigns a NULL value to this instance.
Definition: owned_or_borrowed_ptr.h:112
owned_or_borrowed_ptr & operator=(owned_or_borrowed_ptr &&other) noexcept
Move assignment operator.
Definition: owned_or_borrowed_ptr.h:87
bool is_owned() const noexcept
Gets a value that indicates whether the contained pointer is owned.
Definition: owned_or_borrowed_ptr.h:148
pointer operator->() const noexcept
Member access operator.
Definition: owned_or_borrowed_ptr.h:164
void reset(pointer ptr=nullptr, bool owned=true) noexcept
Resets this instance with a new pointer value.
Definition: owned_or_borrowed_ptr.h:176
owned_or_borrowed_ptr(owned_or_borrowed_ptr< T2 > &&other) noexcept
Move constructor from a different owned_or_borrowed_ptr if the pointer types can be implicitly conver...
Definition: owned_or_borrowed_ptr.h:77
void swap(owned_or_borrowed_ptr &other) noexcept
Swaps this owned_or_borrowed_ptr with another.
Definition: owned_or_borrowed_ptr.h:127
~owned_or_borrowed_ptr()
Deletes the contained pointer if it is not NULL and if it's owned.
Definition: owned_or_borrowed_ptr.h:58
owned_or_borrowed_ptr(pointer ptr, bool owned=true) noexcept
Initializes a new instance of the owned_or_borrowed_ptr class, which contains the specified pointer.
Definition: owned_or_borrowed_ptr.h:51
reference operator*() const noexcept
Dererences the contained pointer.
Definition: owned_or_borrowed_ptr.h:158
pointer release() noexcept
Releases the contained pointer without deleting it, even if it was owned.
Definition: owned_or_borrowed_ptr.h:199
T element_type
The type of object referred to by the pointer.
Definition: owned_or_borrowed_ptr.h:31
T * pointer
A pointer to T.
Definition: owned_or_borrowed_ptr.h:33
owned_or_borrowed_ptr() noexcept=default
Initializes a new instance of the owned_or_borrowed_ptr class, which does not contain any pointer.
owned_or_borrowed_ptr(owned_or_borrowed_ptr &&other) noexcept
Move constructor.
Definition: owned_or_borrowed_ptr.h:67
std::add_lvalue_reference_t< T > reference
A reference to T.
Definition: owned_or_borrowed_ptr.h:35
pointer get() const noexcept
Gets the contained pointer.
Definition: owned_or_borrowed_ptr.h:134
void reset(std::nullptr_t) noexcept
Resets this instance with a NULL pointer value.
Definition: owned_or_borrowed_ptr.h:188
owned_or_borrowed_ptr as_borrowed() const noexcept
Creates a borrowed pointer that refers to the same pointer as this instance.
Definition: owned_or_borrowed_ptr.h:205
Namespace containing the core Ookii.CommandLine.Cpp types.
Definition: command_line_argument.h:16
auto make_owned_ptr(Args &&... args)
Creates a new instance of the owned_or_borrowed_ptr that owns the contained pointer,...
Definition: owned_or_borrowed_ptr.h:231
void swap(owned_or_borrowed_ptr< T > &left, owned_or_borrowed_ptr< T > &right) noexcept
Swaps two owned_or_borrowed_ptr instances.
Definition: owned_or_borrowed_ptr.h:219