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 explicit safe_ptr(const std::shared_ptr<U>& p, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
46 throw std::invalid_argument("p");
\r
49 template<typename U>
\r
50 explicit safe_ptr(std::shared_ptr<U>&& p, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
54 throw std::invalid_argument("p");
\r
57 template<typename U>
\r
58 explicit safe_ptr(U* p, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
62 throw std::invalid_argument("p");
\r
65 template<typename U, typename D>
\r
66 explicit safe_ptr(U* p, D d, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0)
\r
70 throw std::invalid_argument("p");
\r
73 template<typename U>
\r
74 typename std::enable_if<std::is_convertible<U*, T*>::value, safe_ptr&>::type
\r
75 operator=(const safe_ptr<U>& other)
\r
77 safe_ptr(other).swap(*this);
\r
81 template<typename U>
\r
82 typename std::enable_if<std::is_convertible<U*, T*>::value, safe_ptr&>::type
\r
83 operator=(safe_ptr<U>&& other)
\r
85 safe_ptr<T>(std::move(other)).swap(*this);
\r
89 T& operator*() const
\r
94 T* operator->() const
\r
104 bool unique() const
\r
106 return p_.unique();
\r
109 long use_count() const
\r
111 return p_.use_count();
\r
114 void swap(safe_ptr& other)
\r
116 p_.swap(other.p_);
\r
119 operator std::shared_ptr<T>() const
\r
124 operator std::weak_ptr<T>() const
\r
126 return std::weak_ptr<T>(p_);
\r
130 bool owner_before(const safe_ptr& ptr)
\r
132 return p_.owner_before(ptr.p_);
\r
136 bool owner_before(const std::shared_ptr<U>& ptr)
\r
138 return p_.owner_before(ptr);
\r
141 template<class D, class U>
\r
142 D* get_deleter(safe_ptr<U> const& ptr)
\r
144 return p_.get_deleter();
\r
148 std::shared_ptr<T> p_;
\r
151 template<class T, class U>
\r
152 bool operator==(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
154 return a.get() == b.get();
\r
157 template<class T, class U>
\r
158 bool operator==(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
160 return a.get() == b.get();
\r
163 template<class T, class U>
\r
164 bool operator==(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
166 return a.get() == b.get();
\r
169 template<class T, class U>
\r
170 bool operator!=(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
172 return a.get() != b.get();
\r
175 template<class T, class U>
\r
176 bool operator!=(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
178 return a.get() != b.get();
\r
181 template<class T, class U>
\r
182 bool operator!=(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
184 return a.get() != b.get();
\r
187 template<class T, class U>
\r
188 bool operator<(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
190 return a.get() < b.get();
\r
193 template<class T, class U>
\r
194 bool operator<(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
196 return a.get() < b.get();
\r
199 template<class T, class U>
\r
200 bool operator<(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
202 return a.get() < b.get();
\r
205 template<class T, class U>
\r
206 bool operator>(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
208 return a.get() > b.get();
\r
211 template<class T, class U>
\r
212 bool operator>(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
214 return a.get() > b.get();
\r
217 template<class T, class U>
\r
218 bool operator>(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
220 return a.get() > b.get();
\r
223 template<class T, class U>
\r
224 bool operator>=(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
226 return a.get() >= b.get();
\r
229 template<class T, class U>
\r
230 bool operator>=(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
232 return a.get() >= b.get();
\r
235 template<class T, class U>
\r
236 bool operator>=(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
238 return a.get() >= b.get();
\r
241 template<class T, class U>
\r
242 bool operator<=(const safe_ptr<T>& a, const safe_ptr<U>& b)
\r
244 return a.get() <= b.get();
\r
247 template<class T, class U>
\r
248 bool operator<=(const std::shared_ptr<T>& a, const safe_ptr<U>& b)
\r
250 return a.get() <= b.get();
\r
253 template<class T, class U>
\r
254 bool operator<=(const safe_ptr<T>& a, const std::shared_ptr<U>& b)
\r
256 return a.get() <= b.get();
\r
259 template<class E, class T, class U>
\r
260 std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& out, const safe_ptr<U>& p)
\r
262 return out << p.get();
\r
266 void swap(safe_ptr<T>& a, safe_ptr<T>& b)
\r
272 T* get_pointer(safe_ptr<T> const& p)
\r
277 template <class T, class U>
\r
278 safe_ptr<T> static_pointer_cast(const safe_ptr<U>& p)
\r
280 return safe_ptr<T>(std::static_pointer_cast<T>(std::shared_ptr<U>(p)));
\r
283 template <class T, class U>
\r
284 safe_ptr<T> const_pointer_cast(const safe_ptr<U>& p)
\r
286 return safe_ptr<T>(std::const_pointer_cast<T>(std::shared_ptr<U>(p)));
\r
289 template <class T, class U>
\r
290 safe_ptr<T> dynamic_pointer_cast(const safe_ptr<U>& p)
\r
292 auto temp = std::dynamic_pointer_cast<T>(std::shared_ptr<U>(p));
\r
294 throw std::bad_cast();
\r
295 return safe_ptr<T>(std::move(temp));
\r
299 // enable_safe_this
\r
301 // A safe_ptr version of enable_shared_from_this.
\r
302 // So that an object may get safe_ptr objects to itself.
\r
306 class enable_safe_from_this : public std::enable_shared_from_this<T>
\r
309 safe_ptr<T> safe_from_this()
\r
311 return safe_ptr<T>(this->shared_from_this());
\r
314 safe_ptr<T const> safe_from_this() const
\r
316 return safe_ptr<T const>(this->shared_from_this());
\r
319 enable_safe_from_this()
\r
323 enable_safe_from_this(const enable_safe_from_this&)
\r
327 enable_safe_from_this& operator=(const enable_safe_from_this&)
\r
332 ~enable_safe_from_this ()
\r
340 // safe_ptr equivalents to make_shared
\r
343 template<typename T>
\r
344 safe_ptr<T> make_safe_ptr(const std::shared_ptr<T>& ptr)
\r
346 return safe_ptr<T>(ptr);
\r
349 template<typename T>
\r
350 safe_ptr<T> make_safe_ptr(std::shared_ptr<T>&& ptr)
\r
352 return safe_ptr<T>(ptr);
\r
355 template<typename T>
\r
356 safe_ptr<T> make_safe()
\r
358 return safe_ptr<T>(std::make_shared<T>());
\r
361 template<typename T, typename P0>
\r
362 safe_ptr<T> make_safe(P0&& p0)
\r
364 return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0)));
\r
367 template<typename T, typename P0, typename P1>
\r
368 safe_ptr<T> make_safe(P0&& p0, P1&& p1)
\r
370 return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1)));
\r
373 template<typename T, typename P0, typename P1, typename P2>
\r
374 safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2)
\r
376 return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));
\r
379 template<typename T, typename P0, typename P1, typename P2, typename P3>
\r
380 safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3)
\r
382 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
385 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4>
\r
386 safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4)
\r
388 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
391 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
\r
392 safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5)
\r
394 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
397 template<typename T>
\r
398 safe_ptr<T>::safe_ptr()
\r
399 : p_(make_safe<T>())
\r