5 #include <type_traits>
\r
10 template<typename T>
\r
13 template <typename> friend class safe_ptr;
\r
15 typedef T element_type;
\r
17 safe_ptr(); // will construct new T object using make_safe<T>()
\r
19 safe_ptr(const safe_ptr& other)
\r
24 template<typename U>
\r
25 safe_ptr(const safe_ptr<U>& other, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
30 safe_ptr(safe_ptr&& other)
\r
35 template<typename U>
\r
36 safe_ptr(safe_ptr<U>&& other, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
41 template<typename U>
\r
42 safe_ptr(U&& v, typename std::enable_if<std::is_convertible<U*, T*>::value, void>::type* = 0)
\r
43 : p_(std::make_shared<U>(std::forward<U>(v)))
\r
47 template<typename U, typename D>
\r
48 safe_ptr(U&& v, D d, typename std::enable_if<std::is_convertible<U*, T*>::value, void>::type* = 0)
\r
49 : p_(new U(std::forward<U>(v)), d)
\r
53 template<typename U>
\r
54 explicit safe_ptr(const std::shared_ptr<U>& p, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
58 throw std::invalid_argument("p");
\r
61 template<typename U>
\r
62 explicit safe_ptr(std::shared_ptr<U>&& p, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
66 throw std::invalid_argument("p");
\r
69 template<typename U>
\r
70 explicit safe_ptr(U* p, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
74 throw std::invalid_argument("p");
\r
77 template<typename U, typename D>
\r
78 explicit safe_ptr(U* p, D d, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
82 throw std::invalid_argument("p");
\r
85 template<typename U>
\r
86 typename std::enable_if<std::is_convertible<U*, T*>::value, safe_ptr&>::type
\r
87 operator=(const safe_ptr<U>& other)
\r
89 safe_ptr(other).swap(*this);
\r
93 template<typename U>
\r
94 typename std::enable_if<std::is_convertible<U*, T*>::value, safe_ptr&>::type
\r
95 operator=(safe_ptr<U>&& other)
\r
97 safe_ptr<T>(std::move(other)).swap(*this);
\r
101 template <typename U>
\r
102 typename std::enable_if<std::is_convertible<U*, T*>::value, safe_ptr&>::type
\r
105 safe_ptr(std::forward<U>(v)).swap(*this);
\r
109 T& operator*() const
\r
114 T* operator->() const
\r
124 bool unique() const
\r
126 return p_.unique();
\r
129 long use_count() const
\r
131 return p_.use_count();
\r
134 void swap(safe_ptr& other)
\r
136 p_.swap(other.p_);
\r
139 operator std::shared_ptr<T>() const
\r
144 operator std::weak_ptr<T>() const
\r
146 return std::weak_ptr<T>(p_);
\r
150 bool owner_before(const safe_ptr& ptr)
\r
152 return p_.owner_before(ptr.p_);
\r
156 bool owner_before(const std::shared_ptr<U>& ptr)
\r
158 return p_.owner_before(ptr);
\r
161 template<class D, class U>
\r
162 D* get_deleter(safe_ptr<U> const& ptr)
\r
164 return p_.get_deleter();
\r
168 std::shared_ptr<T> p_;
\r
171 template<class T, class U>
\r
172 bool operator==(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
174 return a.get() == b.get();
\r
177 template<class T, class U>
\r
178 bool operator==(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
180 return a.get() == b.get();
\r
183 template<class T, class U>
\r
184 bool operator==(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
186 return a.get() == b.get();
\r
189 template<class T, class U>
\r
190 bool operator!=(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
192 return a.get() != b.get();
\r
195 template<class T, class U>
\r
196 bool operator!=(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
198 return a.get() != b.get();
\r
201 template<class T, class U>
\r
202 bool operator!=(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
204 return a.get() != b.get();
\r
207 template<class T, class U>
\r
208 bool operator<(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
210 return a.get() < b.get();
\r
213 template<class T, class U>
\r
214 bool operator<(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
216 return a.get() < b.get();
\r
219 template<class T, class U>
\r
220 bool operator<(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
222 return a.get() < b.get();
\r
225 template<class T, class U>
\r
226 bool operator>(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
228 return a.get() > b.get();
\r
231 template<class T, class U>
\r
232 bool operator>(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
234 return a.get() > b.get();
\r
237 template<class T, class U>
\r
238 bool operator>(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
240 return a.get() > b.get();
\r
243 template<class T, class U>
\r
244 bool operator>=(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
246 return a.get() >= b.get();
\r
249 template<class T, class U>
\r
250 bool operator>=(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
252 return a.get() >= b.get();
\r
255 template<class T, class U>
\r
256 bool operator>=(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
258 return a.get() >= b.get();
\r
261 template<class T, class U>
\r
262 bool operator<=(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
264 return a.get() <= b.get();
\r
267 template<class T, class U>
\r
268 bool operator<=(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
270 return a.get() <= b.get();
\r
273 template<class T, class U>
\r
274 bool operator<=(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
276 return a.get() <= b.get();
\r
279 template<class E, class T, class U>
\r
280 std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& out, const safe_ptr<U>& p)
\r
282 return out << p.get();
\r
286 void swap(safe_ptr<T>& a, safe_ptr<T>& b)
\r
292 T* get_pointer(safe_ptr<T> const& p)
\r
297 template <class T, class U>
\r
298 safe_ptr<T> static_pointer_cast(const safe_ptr<U>& p)
\r
300 return safe_ptr<T>(std::static_pointer_cast<T>(std::shared_ptr<U>(p)));
\r
303 template <class T, class U>
\r
304 safe_ptr<T> const_pointer_cast(const safe_ptr<U>& p)
\r
306 return safe_ptr<T>(std::const_pointer_cast<T>(std::shared_ptr<U>(p)));
\r
309 template <class T, class U>
\r
310 safe_ptr<T> dynamic_pointer_cast(const safe_ptr<U>& p)
\r
312 auto temp = std::dynamic_pointer_cast<T>(std::shared_ptr<U>(p));
\r
314 throw std::bad_cast();
\r
315 return safe_ptr<T>(std::move(temp));
\r
319 // enable_safe_this
\r
321 // A safe_ptr version of enable_shared_from_this.
\r
322 // So that an object may get safe_ptr objects to itself.
\r
326 class enable_safe_from_this : public std::enable_shared_from_this<T>
\r
329 safe_ptr<T> safe_from_this()
\r
331 return safe_ptr<T>(this->shared_from_this());
\r
334 safe_ptr<T const> safe_from_this() const
\r
336 return safe_ptr<T const>(this->shared_from_this());
\r
339 enable_safe_from_this()
\r
343 enable_safe_from_this(const enable_safe_from_this&)
\r
347 enable_safe_from_this& operator=(const enable_safe_from_this&)
\r
352 ~enable_safe_from_this ()
\r
360 // safe_ptr equivalents to make_shared
\r
363 template<typename T>
\r
364 safe_ptr<T> make_safe_ptr(const std::shared_ptr<T>& ptr)
\r
366 return safe_ptr<T>(ptr);
\r
369 template<typename T>
\r
370 safe_ptr<T> make_safe_ptr(std::shared_ptr<T>&& ptr)
\r
372 return safe_ptr<T>(ptr);
\r
375 template<typename T>
\r
376 safe_ptr<T> make_safe()
\r
378 return safe_ptr<T>(std::make_shared<T>());
\r
381 template<typename T, typename P0>
\r
382 safe_ptr<T> make_safe(P0&& p0)
\r
384 return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0)));
\r
387 template<typename T, typename P0, typename P1>
\r
388 safe_ptr<T> make_safe(P0&& p0, P1&& p1)
\r
390 return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1)));
\r
393 template<typename T, typename P0, typename P1, typename P2>
\r
394 safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2)
\r
396 return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));
\r
399 template<typename T, typename P0, typename P1, typename P2, typename P3>
\r
400 safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3)
\r
402 return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3)));
\r
405 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4>
\r
406 safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4)
\r
408 return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4)));
\r
411 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
\r
412 safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5)
\r
414 return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4), std::forward<P5>(p5)));
\r
417 template<typename T>
\r
418 safe_ptr<T>::safe_ptr()
\r
419 : p_(make_safe<T>())
\r