i6engine  1.0
sharedPtr.h
Go to the documentation of this file.
1 /*
2  * i6engine
3  * Copyright (2016) Daniel Bonrath, Michael Baer, All rights reserved.
4  *
5  * This file is part of i6engine; i6engine is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
25 #ifndef __I6ENGINE_UTILS_SHAREDPTR_H__
26 #define __I6ENGINE_UTILS_SHAREDPTR_H__
27 
28 #include <atomic>
29 #include <list>
30 #include <memory>
31 #include <mutex>
32 #include <new>
33 
34 namespace i6e {
35 namespace utils {
36 
40  template<typename T>
42  T * ptr;
43 
44  sharedPtrWrapper(T * p) : ptr(p) {
45  }
47  };
48 
49  template<typename T, typename U>
50  class sharedPtr;
51 
52  template<typename T, typename Base>
53  class weakPtr;
54 
55  template<typename T1, typename T2, typename U>
57 
58  template<typename T, typename U, typename... Args>
59  sharedPtr<T, U> make_shared(Args && ...);
60 
67  template<typename T, typename U>
68  class sharedPtr {
69  template<typename T1, typename T2, typename U1>
71  template<typename T1, typename U2, typename... Args>
72  friend sharedPtr<T1, U2> make_shared(Args && ...);
73  friend class weakPtr<T, U>;
74  template<typename V, typename W>
75  friend class sharedPtr;
76  template<typename V, typename W>
77  friend class weakPtr;
78  friend struct sharedPtrWrapper<T>;
79 
80  public:
84  sharedPtr() : _sharedPtrWrapper(nullptr), _ptr(nullptr) {
85  }
86 
90  explicit sharedPtr(T * ptr) : _sharedPtrWrapper(nullptr), _ptr(ptr) {
91  _sharedPtrWrapper = std::make_shared<sharedPtrWrapper<U>>(ptr);
92  }
93 
97  sharedPtr(const sharedPtr & other) : _sharedPtrWrapper(other._sharedPtrWrapper), _ptr(other._ptr) {
98  }
99 
103  sharedPtr(sharedPtr && other) : _sharedPtrWrapper(other._sharedPtrWrapper), _ptr(other._ptr) {
104  other._sharedPtrWrapper = nullptr;
105  other._ptr = nullptr;
106  }
107 
111  template<typename V>
112  sharedPtr(const sharedPtr<V, U> & other) : _sharedPtrWrapper(other._sharedPtrWrapper), _ptr(other._ptr) {
113  }
114 
119  }
120 
124  const sharedPtr & operator=(const sharedPtr & other) {
125  if (*this == other) {
126  return *this;
127  }
128  _sharedPtrWrapper = other._sharedPtrWrapper;
129  _ptr = other._ptr;
130 
131  return *this;
132  }
133 
137  const sharedPtr & operator=(sharedPtr && other) {
138  if (*this == other) {
139  return *this;
140  }
141  _sharedPtrWrapper = other._sharedPtrWrapper;
142  _ptr = other._ptr;
143  other._sharedPtrWrapper = nullptr;
144  other._ptr = nullptr;
145 
146  return *this;
147  }
148 
152  template<typename V>
153  const sharedPtr & operator=(const sharedPtr<V, U> & other) {
154  if (*this == other) {
155  return *this;
156  }
157  _sharedPtrWrapper = other._sharedPtrWrapper;
158  _ptr = other._ptr;
159 
160  return *this;
161  }
162 
166  T * operator->() const {
167  return _ptr;
168  }
169 
173  bool operator==(const sharedPtr & other) const {
174  return _ptr == other._ptr;
175  }
176 
180  bool operator==(const T * other) const {
181  return _ptr == other;
182  }
183 
184  friend bool operator==(const T * other, const sharedPtr & self) {
185  return self == other;
186  }
187 
188  bool operator!=(const sharedPtr & other) const {
189  return !(*this == other);
190  }
191 
192  friend bool operator!=(const T * other, const sharedPtr & self) {
193  return self != other;
194  }
195 
196  bool operator!=(const T * other) const {
197  return !(*this == other);
198  }
199 
203  static void clear() {
204  std::lock_guard<std::mutex> lg(sharedPtr<U, U>::clearListLock);
205  for (U * ptr : sharedPtr<U, U>::clearList) {
206  delete ptr;
207  }
208  sharedPtr<U, U>::clearList.clear();
209  }
210 
214  T * get() const {
215  return _ptr;
216  }
217 
218  private:
219  std::shared_ptr<sharedPtrWrapper<U>> _sharedPtrWrapper;
220  T * _ptr;
221 
225  sharedPtr(T * ptr, std::shared_ptr<sharedPtrWrapper<U>> sC) : _sharedPtrWrapper(sC), _ptr(ptr) {
226  }
227 
228  static std::mutex clearListLock;
229  static std::list<U *> clearList;
230  };
231 
232  template<typename T, typename U> std::mutex sharedPtr<T, U>::clearListLock;
233  template<typename T, typename U> std::list<U *> sharedPtr<T, U>::clearList;
234 
235  template<typename T>
237  std::lock_guard<std::mutex> lg(sharedPtr<T, T>::clearListLock);
238  sharedPtr<T, T>::clearList.push_back(reinterpret_cast<T *>(ptr));
239  }
240 
244  template<typename T1, typename T2, typename U>
246  T1 * t1 = dynamic_cast<T1 *>(base._ptr);
247  if (t1 != nullptr) {
248  return sharedPtr<T1, U>(t1, base._sharedPtrWrapper);
249  } else {
250  return sharedPtr<T1, U>();
251  }
252  }
253 
257  template<typename T, typename U, typename... Args>
258  sharedPtr<T, U> make_shared(Args && ... args) {
259  /*char * memory = static_cast<char *>(::operator new(sizeof(T) + sizeof(sharedPtrWrapper)));
260  T * ptr = new(memory) T(args...);
261  sharedPtrWrapper * sC = new(memory + sizeof(T)) sharedPtrWrapper();*/
262  T * ptr = new T(args...);
263  std::shared_ptr<sharedPtrWrapper<U>> sC = std::make_shared<sharedPtrWrapper<U>>(ptr);
264  return sharedPtr<T, U>(ptr, sC);
265  }
266 
271  template<class T, class U> T * get_pointer(const sharedPtr<T, U> & p) {
272  return p.get();
273  }
274 
275 } /* namespace utils */
276 } /* namespace i6e */
277 
278 #endif /* __I6ENGINE_UTILS_SHAREDPTR_H__ */
279 
friend sharedPtr< T1, U2 > make_shared(Args &&...)
T * operator->() const
-> operator returning stored pointer
Definition: sharedPtr.h:166
bool operator!=(const T *other) const
Definition: sharedPtr.h:196
sharedPtr(T *ptr)
normal constructor taking pointer to object to be stored
Definition: sharedPtr.h:90
const sharedPtr & operator=(const sharedPtr &other)
assignment operator
Definition: sharedPtr.h:124
A weak pointer observing a sharedPtr.
Definition: sharedPtr.h:53
friend bool operator!=(const T *other, const sharedPtr &self)
Definition: sharedPtr.h:192
struct handling threadsafe destruction of the wrapped pointer
Definition: sharedPtr.h:41
~sharedPtr()
destructor, adding pointer of object to clearList if last reference was deleted
Definition: sharedPtr.h:118
const sharedPtr & operator=(const sharedPtr< V, U > &other)
upcast, derived => base
Definition: sharedPtr.h:153
const sharedPtr & operator=(sharedPtr &&other)
move assignment operator
Definition: sharedPtr.h:137
friend sharedPtr< T1, U1 > dynamic_pointer_cast(const sharedPtr< T2, U1 > &)
T * get_pointer(const sharedPtr< T, U > &p)
gets pointer of a shared pointer necessary for luabind and boost::python
Definition: sharedPtr.h:271
static void clear()
deletes all pointers in clearList
Definition: sharedPtr.h:203
A shared pointer counting references and adds objects being not referenced any more to an internal li...
Definition: sharedPtr.h:50
sharedPtr(const sharedPtr< V, U > &other)
upcast derived => base
Definition: sharedPtr.h:112
sharedPtr< T1, U > dynamic_pointer_cast(const sharedPtr< T2, U > &)
casts a sharedPtr of dynamic type T2 to dynamic type T1
Definition: sharedPtr.h:245
T * get() const
returns the contained pointer
Definition: sharedPtr.h:214
sharedPtr< T, U > make_shared(Args &&...)
sharedPtr()
default constructor creating a sharedPtr containing a nullptr
Definition: sharedPtr.h:84
bool operator==(const sharedPtr &other) const
comparison between two shared pointer
Definition: sharedPtr.h:173
bool operator==(const T *other) const
comparison between shared and normal pointer
Definition: sharedPtr.h:180
sharedPtr(sharedPtr &&other)
move constructor
Definition: sharedPtr.h:103
friend bool operator==(const T *other, const sharedPtr &self)
Definition: sharedPtr.h:184
sharedPtr(const sharedPtr &other)
copy constructor sharing reference and incrementing refCounter
Definition: sharedPtr.h:97
bool operator!=(const sharedPtr &other) const
Definition: sharedPtr.h:188