rgc.H 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. * */
  13. //RGC: simple reference counting based garbage collection framework
  14. #ifndef __RGC_H
  15. #define __RGC_H
  16. #include <cstddef>
  17. #include <utility>
  18. #include <stdlib.h>
  19. namespace RGC
  20. {
  21. typedef volatile int atomic_t;
  22. #define atomic_read(v) v
  23. #define atomic_set(v,i) v = i
  24. #define atomic_add(i,v) v += i
  25. #define atomic_sub(i,v) v -= i
  26. #define atomic_sub_and_test(i,v) (v -= i) == 0
  27. #define atomic_inc(v) v++
  28. #define atomic_dec(v) v--
  29. #define atomic_dec_and_test(v) --v == 0
  30. #define atomic_inc_and_test(v) ++v == 0
  31. #define atomic_add_negative(i,v) (v += i) < 0
  32. //static int objs=0;
  33. class Allocator;
  34. class Object
  35. {
  36. public:
  37. Allocator* allocator;
  38. atomic_t refCount; //reference counter
  39. Object() {
  40. allocator = NULL;
  41. refCount = 1;
  42. /*objs++;
  43. cout << objs << " objects" << endl;*/
  44. }
  45. Object(const Object& other) {
  46. refCount = 1;
  47. }
  48. virtual ~Object() {
  49. /*objs--;
  50. cout << objs << " objects" << endl;*/
  51. }
  52. inline void retain(int n=1) {
  53. atomic_add(n,refCount);
  54. }
  55. inline void destruct();
  56. inline bool release(int n=1) { //returns whether or not destruction occurred
  57. atomic_sub(n,refCount);
  58. if (refCount <= 0) {
  59. destruct();
  60. return true;
  61. }
  62. return false;
  63. }
  64. /*Object& operator=(const Object& other)
  65. {
  66. //refCount = 1;
  67. return *this;
  68. }*/
  69. };
  70. class Allocator: public virtual Object
  71. {
  72. public:
  73. virtual void* alloc(int s)=0;
  74. virtual void dealloc(void* obj)=0;
  75. template<class T>
  76. void del(T* obj) {
  77. obj->~T();
  78. dealloc(obj);
  79. }
  80. };
  81. class DefaultAllocator: public Allocator
  82. {
  83. void* alloc(int s) override final {
  84. return malloc(s);
  85. }
  86. void dealloc(void* obj) override final {
  87. return free(obj);
  88. }
  89. };
  90. static DefaultAllocator defaultAllocator;
  91. void Object::destruct() {
  92. if(allocator==NULL) delete this;
  93. else allocator->del(this);
  94. }
  95. //template<class T> struct Ref;
  96. template<class T> struct Ref
  97. {
  98. T* obj;
  99. inline Ref() :
  100. obj(NULL) {
  101. }
  102. //inline Ref(const Ref<T>& other);
  103. inline Ref(T* obj) :
  104. obj(obj) {
  105. if (obj != NULL) obj->retain();
  106. }
  107. inline Ref(T& obj) :
  108. obj(&obj) {
  109. if (&obj != NULL) obj.retain();
  110. }
  111. /*template<class ... ARGS> inline Ref(ARGS&& ... args)
  112. :obj(new T(std::forward<ARGS>(args)...))
  113. {
  114. }*/
  115. inline ~Ref() {
  116. if (this->obj != NULL) this->obj->release();
  117. }
  118. Ref(const Ref<T>& other) :
  119. obj(other.obj) {
  120. if (obj != NULL) obj->retain();
  121. }
  122. T* operator=(T* obj) {
  123. if (this->obj != NULL) this->obj->release();
  124. this->obj = obj;
  125. if (obj != NULL) obj->retain();
  126. return obj;
  127. }
  128. T* operator=(T& obj) {
  129. return operator=(*obj);
  130. }
  131. Ref& operator=(const Ref& other) {
  132. if (this->obj != NULL) this->obj->release();
  133. this->obj = other.obj;
  134. if (obj != NULL) obj->retain();
  135. return *this;
  136. }
  137. inline T* operator()() const {
  138. return obj;
  139. }
  140. inline T& operator*() const {
  141. return *obj;
  142. }
  143. inline T* operator->() const {
  144. return obj;
  145. }
  146. inline T* get() const {
  147. return obj;
  148. }
  149. template<class A> Ref<A> staticCast() {
  150. return Ref<A>(static_cast<A*>(obj));
  151. }
  152. template<class A> Ref<A> dynamicCast() {
  153. return Ref<A>(dynamic_cast<A*>(obj));
  154. }
  155. template<class A> Ref<A> reinterpretCast() {
  156. return Ref<A>(reinterpret_cast<A*>(obj));
  157. }
  158. };
  159. //creates a new instance, but disowns it
  160. template<class T, class ... ARGS> inline T* newObj(ARGS&&... args)
  161. {
  162. T* tmp = new T(std::forward<ARGS>(args)...);
  163. tmp->refCount--;
  164. return tmp;
  165. }
  166. /*template<class T> struct Ref
  167. {
  168. T* obj;
  169. template<class ... ARGS> inline Ref(ARGS&& ... args)
  170. :obj(new T(std::forward<ARGS>(args)...))
  171. {
  172. }
  173. Ref(const Property<T>& prop):obj(prop.obj)
  174. {
  175. obj->retain();
  176. }
  177. ~Ref()
  178. {
  179. obj->release();
  180. }
  181. inline T* operator()() const
  182. {
  183. return obj;
  184. }
  185. inline T* operator->() const
  186. {
  187. return obj;
  188. }
  189. inline T& operator*() const
  190. {
  191. return *obj;
  192. }
  193. inline T* get() const
  194. {
  195. return obj;
  196. }
  197. };*/
  198. //callback mechanism similar to .NET events
  199. /*template<class funcType> class Event
  200. {
  201. public:
  202. vector<funcType> callbacks;
  203. void operator()() {
  204. for(int i=0;i<callbacks.size();i++)
  205. callbacks[i]();
  206. }
  207. void operator+=(const funcType& cb) {
  208. callbacks.push_back(cb);
  209. }
  210. };*/
  211. }
  212. #endif