Mountain  1.0.0
Simple C++ 2D Game Framework
pointer.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <format>
4 #include <ostream>
5 #include <sstream>
6 #include <utility>
7 
8 #include "Mountain/core.hpp"
9 #include "Mountain/utils/reference_counter.hpp"
10 
13 
14 namespace Mountain
15 {
59  template <typename T>
60  class Pointer final
61  {
62  public:
64  using Type = T;
65 
67  template <typename... Args>
68  static Pointer New(Args&&... args);
69 
71  static Pointer New();
72 
74  Pointer() = default;
75 
77  Pointer(const Pointer& other, bool_t strongReference = false);
78 
80  Pointer(Pointer&& other) noexcept;
81 
82  // ReSharper disable once CppNonExplicitConvertingConstructor
84  Pointer(nullptr_t);
85 
89  template <typename U>
90  explicit Pointer(const Pointer<U>& other, bool_t strongReference = false);
91 
93  template <typename U>
94  explicit Pointer(Pointer<U>& other, bool_t strongReference = false);
95 
97  template <typename U>
98  explicit Pointer(Pointer<U>&& other) noexcept;
99 
101  ~Pointer();
102 
104  [[nodiscard]]
106 
110  [[nodiscard]]
111  const T* Get() const;
112 
116  [[nodiscard]]
117  T* Get();
118 
120  [[nodiscard]]
121  bool_t IsValid() const;
122 
124  void ToStrongReference();
125 
127  void ToWeakReference();
128 
130  [[nodiscard]]
131  const ReferenceCounter<T>* GetReferenceCounter() const;
132 
134  [[nodiscard]]
135  bool_t GetIsStrongReference() const;
136 
142  void Reset();
143 
145  Pointer& operator=(const Pointer& other);
146 
148  Pointer& operator=(Pointer&& other) noexcept;
149 
151  Pointer& operator=(nullptr_t);
152 
154  template <typename U>
155  Pointer& operator=(const Pointer<U>& other);
156 
158  template <typename U>
159  Pointer& operator=(Pointer<U>&& other) noexcept;
160 
162  [[nodiscard]]
163  explicit operator const T*() const;
164 
166  [[nodiscard]]
167  explicit operator T*();
168 
169  // ReSharper disable once CppNonExplicitConversionOperator
171  [[nodiscard]]
172  operator bool_t() const;
173 
175  [[nodiscard]]
176  T& operator*();
177 
179  [[nodiscard]]
180  const T& operator*() const;
181 
183  [[nodiscard]]
184  T* operator->();
185 
187  [[nodiscard]]
188  const T* operator->() const;
189 
190  private:
191  ReferenceCounter<T>* m_ReferenceCounter = nullptr;
192 
193  bool_t m_IsStrongReference = false;
194 
195  explicit Pointer(ReferenceCounter<T>*&& referenceCounter, bool_t strongReference);
196 
197  void SetReferenceCounter(ReferenceCounter<T>* newReferenceCounter);
198 
199  void CheckReferenceCounterValid();
200  };
201 }
202 
203 #include "Mountain/utils/pointer.inl"
204 
206 template <typename T>
207 struct std::formatter<Mountain::Pointer<T>> // NOLINT(cert-dcl58-cpp)
208 {
210  template <class ParseContext>
211  constexpr typename ParseContext::iterator parse(ParseContext& ctx)
212  {
213  auto it = ctx.begin();
214  if (it == ctx.end())
215  return it;
216 
217  if (*it != '}')
218  throw std::format_error("Invalid format args for Mountain::Pointer");
219 
220  return it;
221  }
222 
223  // ReSharper disable once CppMemberFunctionMayBeStatic
225  template <class FormatContext>
226  typename FormatContext::iterator format(const Mountain::Pointer<T>& pointer, FormatContext& ctx) const
227  {
228  std::ostringstream out;
229 
230  out << "0x" << static_cast<const T*>(pointer);
231 
232  return std::ranges::copy(std::move(out).str(), ctx.out()).out;
233  }
234 };
235 
237 template<typename T>
238 struct std::hash<Mountain::Pointer<T>> // NOLINT(cert-dcl58-cpp)
239 {
241  std::size_t operator()(const Mountain::Pointer<T>& p) const noexcept
242  {
243  const std::size_t h1 = std::hash<decltype(p.GetReferenceCounter())>{}(const_cast<decltype(p.GetReferenceCounter())>(p.GetReferenceCounter()));
244  const std::size_t h2 = std::hash<bool_t>{}(p.GetIsStrongReference());
245  return h1 ^ (h2 << 1);
246  }
247 };
T * operator->()
Dereferences this Pointer, which gives a reference to the underlying Type.
void ToStrongReference()
Converts this Pointer to a strong reference.
static Pointer New()
Creates a Pointer with a default-initialized value.
std::size_t operator()(const Mountain::Pointer< T > &p) const noexcept
Hashes the given Mountain::Pointer.
Definition: pointer.hpp:241
T & operator*()
Dereferences this Pointer, which gives a reference to the underlying Type.
Pointer CreateStrongReference() const
Creates a new strong reference to this pointer.
Pointer & operator=(const Pointer &other)
Sets this Pointer to the values of other.
Custom Mountain smart pointer. Represents both a std::shared_ptr and a std::weak_ptr.
const ReferenceCounter< T > * GetReferenceCounter() const
Returns the underlying ReferenceCounter.
void Reset()
Resets this Pointer to a nullptr.
FormatContext::iterator format(const Mountain::Pointer< T > &pointer, FormatContext &ctx) const
Formats a string using the given instance of Mountain::Pointer, according to the given options in the...
Definition: pointer.hpp:226
bool_t IsValid() const
Returns whether this Pointer is nullptr.
constexpr ParseContext::iterator parse(ParseContext &ctx)
Parses the input formatting options.
Definition: pointer.hpp:211
const T * Get() const
Gets the underlying raw pointer.
Pointer()=default
Creates an empty Pointer without a reference counter and pointing to nullptr.
Encapsulates a GPU shader.
Definition: shader.hpp:27
bool_t GetIsStrongReference() const
Returns whether this Pointer is holding a strong reference.
void ToWeakReference()
Converts this Pointer to a weak reference.
~Pointer()
Destroys this Pointer, deallocating any memory if this is the last strong reference.
Contains all declarations of the Mountain Framework.
Definition: audio.hpp:22