Berserk
RefCnt.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_REFCNT_HPP
29 #define BERSERK_REFCNT_HPP
30 
31 #include <core/Config.hpp>
32 
33 #include <atomic>
34 #include <cassert>
35 
37 
52 class RefCnt {
53 public:
54  virtual ~RefCnt() {
55 #ifdef BERSERK_DEBUG
56  assert(mRefs.load() == 0);
57  mRefs.store(0);
58 #endif
59  }
60 
61  bool IsUnique() const {
62  return GetRefs() <= 1;
63  }
64 
65  std::int32_t GetRefs() const {
66  return mRefs.load(std::memory_order_relaxed);
67  }
68 
69  std::int32_t AddRef() const {
70  assert(GetRefs() >= 0);
71  return mRefs.fetch_add(1);
72  }
73 
74  std::int32_t RelRef() const {
75  assert(GetRefs() > 0);
76  auto refs = mRefs.fetch_sub(1);
77 
78  if (refs == 1) {
79  // Was last reference
80  // Destroy object and release memory
81  Destroy();
82  }
83 
84  return refs;
85  }
86 
87 protected:
88  virtual void Destroy() const {
89  // Use default delete to destroy object
90  // and free used memory
91  delete this;
92  }
93 
94 private:
95  // This type of object after creation always has no references
96  mutable std::atomic_int32_t mRefs{0};
97 };
98 
106 template<typename T>
107 static inline T *AddRef(T *object) {
108  assert(object);
109  object->AddRef();
110  return object;
111 }
112 
120 template<typename T>
121 static inline T *SafeAddRef(T *object) {
122  if (object)
123  object->AddRef();
124  return object;
125 }
126 
133 template<typename T>
134 static inline void Unref(T *object) {
135  if (object)
136  object->RelRef();
137 }
138 
144 
145 #endif//BERSERK_REFCNT_HPP
#define BRK_NS_END
Definition: Config.hpp:48
Reference counted base object.
Definition: RefCnt.hpp:52
virtual ~RefCnt()
Definition: RefCnt.hpp:54
std::int32_t RelRef() const
Definition: RefCnt.hpp:74
std::int32_t GetRefs() const
Definition: RefCnt.hpp:65
bool IsUnique() const
Definition: RefCnt.hpp:61
std::int32_t AddRef() const
Definition: RefCnt.hpp:69
virtual void Destroy() const
Definition: RefCnt.hpp:88
Definition: GLDevice.cpp:46