X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=common%2Futility%2Fsafe_ptr.h;h=9eeb923a4a32bace6c1f4cf165e60e18ce9b8457;hb=852dacfae88898d42e79817b761f3e309a53153d;hp=9c75e3d475cb5f7c35b0962f4997ea4c724c5c58;hpb=7e5091cff2b2c2197f91eb5adb0edafdfa564069;p=casparcg diff --git a/common/utility/safe_ptr.h b/common/utility/safe_ptr.h index 9c75e3d47..9eeb923a4 100644 --- a/common/utility/safe_ptr.h +++ b/common/utility/safe_ptr.h @@ -1,10 +1,8 @@ #pragma once -#include "../exception/exceptions.h" - #include -#include #include +#include namespace caspar { @@ -15,48 +13,69 @@ class safe_ptr public: typedef T element_type; - safe_ptr() : impl_(std::make_shared()){static_assert(!std::is_abstract::value, "Cannot construct abstract class.");} + safe_ptr() : impl_(std::make_shared()){} safe_ptr(const safe_ptr& other) : impl_(other.impl_){} - safe_ptr(safe_ptr&& other) : impl_(other.impl_) {} // Move doesn't move. - template - safe_ptr(const safe_ptr& other, typename std::enable_if::value, void*>::type = 0) : impl_(other.impl_){} + template + safe_ptr(const safe_ptr& other, typename std::enable_if::value, void*>::type = 0) : impl_(other.impl_){} - template - safe_ptr(const Y& impl, typename std::enable_if::type, typename std::add_pointer::type>::value, void>::type* = 0) - : impl_(std::make_shared(impl)) {} + template + safe_ptr(const U& impl, typename std::enable_if::type, typename std::add_pointer::type>::value, void>::type* = 0) + : impl_(std::make_shared(impl)) {} - template - safe_ptr(Y&& impl, typename std::enable_if::type, typename std::add_pointer::type>::value, void>::type* = 0) - : impl_(std::make_shared(std::forward(impl))) {} + template + safe_ptr(const U& impl, D dtor, typename std::enable_if::type, typename std::add_pointer::type>::value, void>::type* = 0) + : impl_(new U(impl), dtor) {} + + template + safe_ptr(U&& impl, typename std::enable_if::type, typename std::add_pointer::type>::value, void>::type* = 0) + : impl_(std::make_shared(std::forward(impl))) {} + + template + safe_ptr(U&& impl, D dtor, typename std::enable_if::type, typename std::add_pointer::type>::value, void>::type* = 0) + : impl_(new U(std::forward(impl)), dtor) {} - template - explicit safe_ptr(const std::shared_ptr& impl, typename std::enable_if::value, void*>::type = 0) : impl_(impl) + template + explicit safe_ptr(const std::shared_ptr& impl, typename std::enable_if::value, void*>::type = 0) : impl_(impl) { if(!impl_) - BOOST_THROW_EXCEPTION(null_argument() << msg_info("impl")); + throw std::invalid_argument("impl"); } - template - explicit safe_ptr(std::shared_ptr&& impl, typename std::enable_if::value, void*>::type = 0) : impl_(std::move(impl)) + template + explicit safe_ptr(std::shared_ptr&& impl, typename std::enable_if::value, void*>::type = 0) : impl_(std::move(impl)) + { + if(!impl_) + throw std::invalid_argument("impl"); + } + + template + explicit safe_ptr(U* impl, typename std::enable_if::value, void*>::type = 0) : impl_(impl) + { + if(!impl_) + throw std::invalid_argument("impl"); + } + + template + explicit safe_ptr(U* impl, D dtor, typename std::enable_if::value, void*>::type = 0) : impl_(impl, dtor) { if(!impl_) - BOOST_THROW_EXCEPTION(null_argument() << msg_info("impl")); + throw std::invalid_argument("impl"); } - template - typename std::enable_if::value, safe_ptr&>::type - operator=(const safe_ptr& other) + template + typename std::enable_if::value, safe_ptr&>::type + operator=(const safe_ptr& other) { safe_ptr temp(other); temp.swap(*this); return *this; } - template - typename std::enable_if::type, typename std::add_pointer::type>::value, safe_ptr&>::type - operator=(Y&& impl) + template + typename std::enable_if::type, typename std::add_pointer::type>::value, safe_ptr&>::type + operator=(U&& impl) { safe_ptr temp(std::forward(impl)); temp.swap(*this); @@ -75,66 +94,129 @@ public: void swap(safe_ptr& other) { impl_.swap(other.impl_); } - std::shared_ptr get_shared() const { return impl_; } + operator std::shared_ptr() const { return impl_;} + + template + bool owner_before(const safe_ptr& ptr){ return impl_.owner_before(ptr.impl_); } + + template + bool owner_before(const std::shared_ptr& ptr){ return impl_.owner_before(ptr); } + + template + D* get_deleter(safe_ptr const& ptr) { return impl_.get_deleter(); } private: std::shared_ptr impl_; }; template -bool operator==(safe_ptr const & a, safe_ptr const & b) +bool operator==(const safe_ptr& a, const safe_ptr& b) { return a.get() == b.get(); } template -bool operator!=(safe_ptr const & a, safe_ptr const & b) +bool operator!=(const safe_ptr& a, const safe_ptr& b) { return a.get() != b.get(); } template -bool operator<(safe_ptr const & a, safe_ptr const & b) +bool operator<(const safe_ptr& a, const safe_ptr& b) { return a.get() < b.get(); } -template void swap(safe_ptr & a, safe_ptr & b) +template +bool operator>(const safe_ptr& a, const safe_ptr& b) +{ + return a.get() > b.get(); +} + +template +bool operator>=(const safe_ptr& a, const safe_ptr& b) +{ + return a.get() >= b.get(); +} + +template +bool operator<=(const safe_ptr& a, const safe_ptr& b) +{ + return a.get() <= b.get(); +} + +template +std::basic_ostream& operator<<(std::basic_ostream& out, const safe_ptr& p) +{ + return out << p.get(); +} + +template +void swap(safe_ptr& a, safe_ptr& b) { a.swap(b); } -template T* get_pointer(safe_ptr const & p) +template +T* get_pointer(safe_ptr const& p) { return p.get(); } +template +safe_ptr static_pointer_cast(const safe_ptr& p) +{ + return safe_ptr(std::static_pointer_cast(std::shared_ptr(p))); +} + +template +safe_ptr const_pointer_cast(const safe_ptr& p) +{ + return safe_ptr(std::const_pointer_cast(std::shared_ptr(p))); +} + +template +safe_ptr dynamic_pointer_cast(const safe_ptr& p) +{ + auto temp = std::dynamic_pointer_cast(std::shared_ptr(p)); + if(!temp) + throw std::bad_cast(); + return safe_ptr(temp); +} + template safe_ptr make_safe() { - static_assert(!std::is_abstract::value, "Cannot construct abstract class."); return safe_ptr(); } template safe_ptr make_safe(P0&& p0) { - static_assert(!std::is_abstract::value, "Cannot construct abstract class."); return safe_ptr(std::make_shared(std::forward(p0))); } template safe_ptr make_safe(P0&& p0, P1&& p1) { - static_assert(!std::is_abstract::value, "Cannot construct abstract class."); return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1))); } template safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2) { - static_assert(!std::is_abstract::value, "Cannot construct abstract class."); return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2))); } +template +safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3) +{ + return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3))); +} + +template +safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&&) +{ + return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4))); +} } \ No newline at end of file