public:\r
typedef T element_type;\r
\r
- safe_ptr() : impl_(std::make_shared<T>()){static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");} \r
+ safe_ptr() : impl_(std::make_shared<T>()){} \r
\r
safe_ptr(const safe_ptr<T>& other) : impl_(other.impl_){}\r
\r
- template<typename Y>\r
- safe_ptr(const safe_ptr<Y>& other, typename std::enable_if<std::is_convertible<Y*, T*>::value, void*>::type = 0) : impl_(other.impl_){}\r
+ template<typename U>\r
+ safe_ptr(const safe_ptr<U>& other, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0) : impl_(other.impl_){}\r
\r
- template<typename Y> \r
- 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
- : impl_(std::make_shared<Y>(impl)) {}\r
+ template<typename U> \r
+ safe_ptr(const U& impl, typename std::enable_if<std::is_convertible<typename std::add_pointer<U>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)\r
+ : impl_(std::make_shared<U>(impl)) {}\r
\r
- template<typename Y, typename D> \r
- safe_ptr(const Y& impl, D dtor, typename std::enable_if<std::is_convertible<typename std::add_pointer<Y>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)\r
- : impl_(new Y(impl), dtor) {}\r
+ template<typename U, typename D> \r
+ safe_ptr(const U& impl, D dtor, typename std::enable_if<std::is_convertible<typename std::add_pointer<U>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)\r
+ : impl_(new U(impl), dtor) {}\r
\r
- template<typename Y> \r
- 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
- : impl_(std::make_shared<Y>(std::forward<Y>(impl))) {}\r
+ template<typename U> \r
+ safe_ptr(U&& impl, typename std::enable_if<std::is_convertible<typename std::add_pointer<U>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)\r
+ : impl_(std::make_shared<U>(std::forward<U>(impl))) {}\r
\r
- template<typename Y, typename D> \r
- safe_ptr(Y&& impl, D dtor, typename std::enable_if<std::is_convertible<typename std::add_pointer<Y>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)\r
- : impl_(new Y(std::forward<Y>(impl)), dtor) {}\r
+ template<typename U, typename D> \r
+ safe_ptr(U&& impl, D dtor, typename std::enable_if<std::is_convertible<typename std::add_pointer<U>::type, typename std::add_pointer<T>::type>::value, void>::type* = 0)\r
+ : impl_(new U(std::forward<U>(impl)), dtor) {}\r
\r
- template<typename Y> \r
- explicit safe_ptr(const std::shared_ptr<Y>& impl, typename std::enable_if<std::is_convertible<Y*, T*>::value, void*>::type = 0) : impl_(impl)\r
+ template<typename U> \r
+ explicit safe_ptr(const std::shared_ptr<U>& impl, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0) : impl_(impl)\r
{\r
if(!impl_)\r
throw std::invalid_argument("impl");\r
}\r
\r
- template<typename Y> \r
- explicit safe_ptr(std::shared_ptr<Y>&& impl, typename std::enable_if<std::is_convertible<Y*, T*>::value, void*>::type = 0) : impl_(std::move(impl))\r
+ template<typename U> \r
+ explicit safe_ptr(std::shared_ptr<U>&& impl, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0) : impl_(std::move(impl))\r
{\r
if(!impl_)\r
throw std::invalid_argument("impl");\r
}\r
\r
- template<typename Y> \r
- explicit safe_ptr(Y* impl, typename std::enable_if<std::is_convertible<Y*, T*>::value, void*>::type = 0) : impl_(impl)\r
+ template<typename U> \r
+ explicit safe_ptr(U* impl, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0) : impl_(impl)\r
{\r
if(!impl_)\r
throw std::invalid_argument("impl");\r
}\r
\r
- template<typename Y, typename D> \r
- explicit safe_ptr(Y* impl, D dtor, typename std::enable_if<std::is_convertible<Y*, T*>::value, void*>::type = 0) : impl_(impl, dtor)\r
+ template<typename U, typename D> \r
+ explicit safe_ptr(U* impl, D dtor, typename std::enable_if<std::is_convertible<U*, T*>::value, void*>::type = 0) : impl_(impl, dtor)\r
{\r
if(!impl_)\r
throw std::invalid_argument("impl");\r
}\r
\r
- template<typename Y>\r
- typename std::enable_if<std::is_convertible<Y*, T*>::value, safe_ptr<T>&>::type\r
- operator=(const safe_ptr<Y>& other)\r
+ template<typename U>\r
+ typename std::enable_if<std::is_convertible<U*, T*>::value, safe_ptr<T>&>::type\r
+ operator=(const safe_ptr<U>& other)\r
{\r
safe_ptr<T> temp(other);\r
temp.swap(*this);\r
return *this;\r
}\r
\r
- template <typename Y>\r
- 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
- operator=(Y&& impl)\r
+ template <typename U>\r
+ typename std::enable_if<std::is_convertible<typename std::add_pointer<U>::type, typename std::add_pointer<T>::type>::value, safe_ptr<T>&>::type\r
+ operator=(U&& impl)\r
{\r
safe_ptr<T> temp(std::forward<T>(impl));\r
temp.swap(*this);\r
\r
void swap(safe_ptr& other) { impl_.swap(other.impl_); } \r
\r
- std::shared_ptr<T> get_shared() const { return impl_; }\r
+ operator std::shared_ptr<T>() const { return impl_;}\r
+\r
+ template<class U>\r
+ bool owner_before(const safe_ptr<T>& ptr){ return impl_.owner_before(ptr.impl_); }\r
+\r
+ template<class U>\r
+ bool owner_before(const std::shared_ptr<U>& ptr){ return impl_.owner_before(ptr); }\r
+ \r
+ template<class D, class U> \r
+ D* get_deleter(safe_ptr<U> const& ptr) { return impl_.get_deleter(); }\r
\r
private: \r
std::shared_ptr<T> impl_;\r
};\r
\r
template<class T, class U>\r
-bool operator==(safe_ptr<T> const & a, safe_ptr<U> const & b)\r
+bool operator==(const safe_ptr<T>& a, const safe_ptr<U>& b)\r
{\r
return a.get() == b.get();\r
}\r
\r
template<class T, class U>\r
-bool operator!=(safe_ptr<T> const & a, safe_ptr<U> const & b)\r
+bool operator!=(const safe_ptr<T>& a, const safe_ptr<U>& b)\r
{\r
return a.get() != b.get();\r
}\r
\r
template<class T, class U>\r
-bool operator<(safe_ptr<T> const & a, safe_ptr<U> const & b)\r
+bool operator<(const safe_ptr<T>& a, const safe_ptr<U>& b)\r
{\r
return a.get() < b.get();\r
}\r
\r
-template<class T> void swap(safe_ptr<T> & a, safe_ptr<T> & b)\r
+template<class T, class U>\r
+bool operator>(const safe_ptr<T>& a, const safe_ptr<U>& b)\r
+{\r
+ return a.get() > b.get();\r
+}\r
+\r
+template<class T, class U>\r
+bool operator>=(const safe_ptr<T>& a, const safe_ptr<U>& b)\r
+{\r
+ return a.get() >= b.get();\r
+}\r
+\r
+template<class T, class U>\r
+bool operator<=(const safe_ptr<T>& a, const safe_ptr<U>& b)\r
+{\r
+ return a.get() <= b.get();\r
+}\r
+\r
+template<class E, class T, class U>\r
+std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& out, const safe_ptr<U>& p)\r
+{\r
+ return out << p.get();\r
+}\r
+\r
+template<class T> \r
+void swap(safe_ptr<T>& a, safe_ptr<T>& b)\r
{\r
a.swap(b);\r
}\r
\r
-template<class T> T* get_pointer(safe_ptr<T> const & p)\r
+template<class T> \r
+T* get_pointer(safe_ptr<T> const& p)\r
{\r
return p.get();\r
}\r
\r
+template <class T, class U>\r
+safe_ptr<T> static_pointer_cast(const safe_ptr<U>& p)\r
+{\r
+ return safe_ptr<T>(std::static_pointer_cast<T>(std::shared_ptr<U>(p)));\r
+}\r
+\r
+template <class T, class U>\r
+safe_ptr<T> const_pointer_cast(const safe_ptr<U>& p)\r
+{\r
+ return safe_ptr<T>(std::const_pointer_cast<T>(std::shared_ptr<U>(p)));\r
+}\r
+\r
+template <class T, class U>\r
+safe_ptr<T> dynamic_pointer_cast(const safe_ptr<U>& p)\r
+{\r
+ auto temp = std::dynamic_pointer_cast<T>(std::shared_ptr<U>(p));\r
+ if(!temp)\r
+ throw std::bad_cast();\r
+ return safe_ptr<T>(temp);\r
+}\r
+\r
template<typename T>\r
safe_ptr<T> make_safe()\r
{\r
- static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");\r
return safe_ptr<T>();\r
}\r
\r
template<typename T, typename P0>\r
safe_ptr<T> make_safe(P0&& p0)\r
{\r
- static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");\r
return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0)));\r
}\r
\r
template<typename T, typename P0, typename P1>\r
safe_ptr<T> make_safe(P0&& p0, P1&& p1)\r
{\r
- static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");\r
return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1)));\r
}\r
\r
template<typename T, typename P0, typename P1, typename P2>\r
safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2)\r
{\r
- static_assert(!std::is_abstract<T>::value, "Cannot construct abstract class.");\r
return safe_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));\r
}\r
\r
+template<typename T, typename P0, typename P1, typename P2, typename P3>\r
+safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3)\r
+{\r
+ 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
+}\r
+\r
+template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4>\r
+safe_ptr<T> make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&&)\r
+{\r
+ 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<P3>(p4)));\r
+}\r
}
\ No newline at end of file