3 #include "../exception/exceptions.h"
\r
7 #include <type_traits>
\r
11 template<typename T>
\r
14 template <typename> friend class safe_ptr;
\r
16 typedef T element_type;
\r
18 safe_ptr() : impl_(std::make_shared<T>()){static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");}
\r
20 safe_ptr(const safe_ptr<T>& other) : impl_(other.impl_){}
\r
22 template<typename Y>
\r
23 safe_ptr(const safe_ptr<Y>& other, typename std::enable_if<std::is_convertible<Y*, T*>::value, void*>::type = 0) : impl_(other.impl_){}
\r
25 template<typename Y>
\r
26 safe_ptr(const Y& impl, typename std::enable_if<std::is_convertible<typename std::add_pointer<Y>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)
\r
27 : impl_(std::make_shared<Y>(impl)) {}
\r
29 template<typename Y>
\r
30 safe_ptr(Y&& impl, typename std::enable_if<std::is_convertible<typename std::add_pointer<Y>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)
\r
31 : impl_(std::make_shared<Y>(std::forward<Y>(impl))) {}
\r
33 template<typename Y>
\r
34 typename std::enable_if<std::is_convertible<Y*, T*>::value, safe_ptr<T>&>::type
\r
35 operator=(const safe_ptr<Y>& other)
\r
37 safe_ptr<T> temp(other);
\r
42 template <typename Y>
\r
43 typename std::enable_if<std::is_convertible<typename std::add_pointer<Y>::type, typename std::add_pointer<T>::type>::value, safe_ptr<T>&>::type
\r
46 safe_ptr<T> temp(std::forward<T>(impl));
\r
51 T& operator*() const { return *impl_.get();}
\r
53 T* operator->() const { return impl_.get();}
\r
55 T* get() const { return impl_.get();}
\r
57 bool unique() const { return impl_.unique();}
\r
59 long use_count() const { return impl_.use_count();}
\r
61 void swap(safe_ptr& other) { impl_.swap(other.impl_); }
\r
63 std::shared_ptr<T> get_shared() const { return impl_; }
\r
65 static safe_ptr<T> from_shared(const std::shared_ptr<T>& impl) { return safe_ptr<T>(impl); }
\r
69 template<typename Y>
\r
70 safe_ptr(const std::shared_ptr<Y>& impl, typename std::enable_if<std::is_convertible<Y*, T*>::value, void*>::type = 0) : impl_(impl)
\r
73 BOOST_THROW_EXCEPTION(null_argument() << msg_info("impl"));
\r
76 std::shared_ptr<T> impl_;
\r
79 template<class T, class U>
\r
80 bool operator==(safe_ptr<T> const & a, safe_ptr<U> const & b)
\r
82 return a.get() == b.get();
\r
85 template<class T, class U>
\r
86 bool operator!=(safe_ptr<T> const & a, safe_ptr<U> const & b)
\r
88 return a.get() != b.get();
\r
91 template<class T, class U>
\r
92 bool operator<(safe_ptr<T> const & a, safe_ptr<U> const & b)
\r
94 return a.get() < b.get();
\r
97 template<class T> void swap(safe_ptr<T> & a, safe_ptr<T> & b)
\r
102 template<class T> T* get_pointer(safe_ptr<T> const & p)
\r
107 template<typename T>
\r
108 safe_ptr<T> make_safe()
\r
110 static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");
\r
111 return safe_ptr<T>();
\r
114 template<typename T, typename P0>
\r
115 safe_ptr<T> make_safe(P0&& p0)
\r
117 static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");
\r
118 return safe_ptr<T>(T(std::forward<P0>(p0)));
\r
121 template<typename T, typename P0, typename P1>
\r
122 safe_ptr<T> make_safe(P0&& p0, P1&& p1)
\r
124 static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");
\r
125 return safe_ptr<T>(T(std::forward<P0>(p0), std::forward<P1>(p1)));
\r
128 template<typename T, typename P0, typename P1, typename P2>
\r
129 safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2)
\r
131 static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");
\r
132 return safe_ptr<T>(T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));
\r