Berserk
Ref.hpp
Go to the documentation of this file.
1 /**********************************************************************************/
2 /* This file is part of Berserk Engine project */
3 /* https://github.com/EgorOrachyov/Berserk */
4 /**********************************************************************************/
5 /* MIT License */
6 /* */
7 /* Copyright (c) 2018 - 2021 Egor Orachyov */
8 /* */
9 /* Permission is hereby granted, free of charge, to any person obtaining a copy */
10 /* of this software and associated documentation files (the "Software"), to deal */
11 /* in the Software without restriction, including without limitation the rights */
12 /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
13 /* copies of the Software, and to permit persons to whom the Software is */
14 /* furnished to do so, subject to the following conditions: */
15 /* */
16 /* The above copyright notice and this permission notice shall be included in all */
17 /* copies or substantial portions of the Software. */
18 /* */
19 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
20 /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
21 /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
22 /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
23 /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
24 /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
25 /* SOFTWARE. */
26 /**********************************************************************************/
27 
28 #ifndef BERSERK_REF_HPP
29 #define BERSERK_REF_HPP
30 
32 
34 
45 template<typename T>
46 class Ref {
47 public:
48  Ref() = default;
49 
50  explicit Ref(T *object) {
51  if (object)
52  mObject = AddRef(object);
53  }
54 
55  Ref(const Ref &other) {
56  if (other.mObject)
57  mObject = AddRef(other.mObject);
58  }
59 
60  Ref(Ref &&other) noexcept {
61  mObject = other.mObject;
62  other.mObject = nullptr;
63  }
64 
65  ~Ref() {
66  Unref(mObject);
67  mObject = nullptr;
68  }
69 
70  Ref<T> &operator=(const Ref &other) {
71  if (this != &other)
72  this->Reset(SafeAddRef(other.Get()));
73  return *this;
74  }
75 
76  Ref<T> &operator=(Ref &&other) noexcept {
77  if (this != &other)
78  this->Reset(other.Release());
79  return *this;
80  }
81 
82  bool operator==(const Ref &other) const {
83  return mObject == other.mObject;
84  }
85 
86  bool operator!=(const Ref &other) const {
87  return mObject != other.mObject;
88  }
89 
90  [[nodiscard]] bool IsNull() const {
91  return mObject == nullptr;
92  }
93 
94  [[nodiscard]] bool IsNotNull() const {
95  return mObject;
96  }
97 
98  T *operator->() const {
99  assert(mObject);
100  return mObject;
101  }
102 
103  T &operator*() const {
104  assert(mObject);
105  return *mObject;
106  }
107 
108  explicit operator bool() const {
109  return mObject != nullptr;
110  }
111 
112  void Reset(T *ptr = nullptr) {
113  T *old = mObject;
114  mObject = ptr;
115  Unref(old);
116  }
117 
119  [[nodiscard]] bool IsUnique() const {
120  return mObject ? mObject->IsUnique() : false;
121  }
122 
123  T *Release() {
124  T *ptr = mObject;
125  mObject = nullptr;
126  return ptr;
127  }
128 
129  [[nodiscard]] T *Get() const {
130  return mObject;
131  }
132 
133  template<typename G>
134  [[nodiscard]] bool Is() const {
135  return !mObject || dynamic_cast<G *>(mObject);
136  }
137 
138  template<class G>
139  [[nodiscard]] Ref<G> As() const {
140  return Ref<G>(mObject);
141  }
142 
143  template<class G>
144  [[nodiscard]] Ref<G> Cast() const {
145  return Ref<G>(dynamic_cast<G *>(mObject));
146  }
147 
148  template<class G>
149  [[nodiscard]] Ref<G> ForceCast() const {
150  return Ref<G>((G *) mObject);
151  }
152 
153 private:
154  T *mObject = nullptr;
155 };
156 
162 
163 #endif//BERSERK_REF_HPP
#define BRK_NS_END
Definition: Config.hpp:48
Automates reference counting and behaves as shared smart pointer.
Definition: Ref.hpp:46
T * Get() const
Definition: Ref.hpp:129
bool Is() const
Definition: Ref.hpp:134
T * operator->() const
Definition: Ref.hpp:98
bool IsNotNull() const
Definition: Ref.hpp:94
bool IsUnique() const
Definition: Ref.hpp:119
Ref< T > & operator=(const Ref &other)
Definition: Ref.hpp:70
bool operator==(const Ref &other) const
Definition: Ref.hpp:82
bool IsNull() const
Definition: Ref.hpp:90
Ref< G > Cast() const
Definition: Ref.hpp:144
~Ref()
Definition: Ref.hpp:65
T * Release()
Definition: Ref.hpp:123
Ref< G > ForceCast() const
Definition: Ref.hpp:149
Ref< G > As() const
Definition: Ref.hpp:139
Ref(T *object)
Definition: Ref.hpp:50
Ref< T > & operator=(Ref &&other) noexcept
Definition: Ref.hpp:76
void Reset(T *ptr=nullptr)
Definition: Ref.hpp:112
Ref(const Ref &other)
Definition: Ref.hpp:55
Ref(Ref &&other) noexcept
Definition: Ref.hpp:60
bool operator!=(const Ref &other) const
Definition: Ref.hpp:86
Ref()=default
T & operator*() const
Definition: Ref.hpp:103
Definition: GLDevice.cpp:46