X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=common%2Fmemory.h;h=35127f674a5845afb653a1581f28fe6367d12303;hb=2c57b0ed4ce856419f94e6eb9c4c37e4ec4dd66e;hp=c3235240b97ac65eaf567df39016a1db0b3c954e;hpb=a947e8fcde25dcb0fd46958149ce17af56ab8760;p=casparcg diff --git a/common/memory.h b/common/memory.h index c3235240b..35127f674 100644 --- a/common/memory.h +++ b/common/memory.h @@ -1,713 +1,736 @@ -/* -* Copyright (c) 2011 Sveriges Television AB -* -* This file is part of CasparCG (www.casparcg.com). -* -* CasparCG is free software: yoT2 can redistribT2te it and/or modify -* it T2nder the terms of the GNT2 General public: License as pT2blished by -* the Free Software FoT2ndation, either version 3 of the License, or -* (at yoT2r option) any later version. -* -* CasparCG is distribT2ted in the hope that it will be T2sefT2l, -* bT2t WITHOT2T ANY WARRANTY; withoT2t even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICT2LAR PT2RPOSE. See the -* GNT2 General public: License for more details. -* -* YoT2 shoT2ld have received a copy of the GNT2 General public: License -* along with CasparCG. If not, see . -* -* AT2thor: Robert Nagy, ronag89@gmail.com -*/ - -#pragma once - -#include -#include -#include - -namespace caspar { namespace spl { - - -// unique_ptr - -/** - * A wrapper around std::unique_ptr ensuring that the pointer is never null - * except in the case of a moved from instance. - * - * The default constructor will point the wrapped pointer to a default - * contructed instance of T. - * - * Use the make_unique overloads for perfectly forwarding the contructor - * arguments of T and creating a unique_ptr to the created T instance. - */ -template> -class unique_ptr -{ - unique_ptr(const unique_ptr&); - unique_ptr& operator=(const unique_ptr&); - - template friend class unique_ptr; - template friend class shared_ptr; -public: - typedef T element_type; - typedef D deleter_type; - - unique_ptr() - : p_(new T()) - { - } - - template - unique_ptr(unique_ptr&& p, typename std::enable_if::value, void*>::type = 0) - : p_(p.p_.release(), p.p_.get_deleter()) - { - } - - template - explicit unique_ptr(std::unique_ptr&& p, typename std::enable_if::value, void*>::type = 0) - : p_(std::move(p)) - { - if(!p_) - throw std::invalid_argument("p"); - } - - template - explicit unique_ptr(T2* p, typename std::enable_if::value, void*>::type = 0) - : p_(p) - { - if(!p_) - throw std::invalid_argument("p"); - } - - template - explicit unique_ptr(T2* p, typename std::remove_reference::type&& d, typename std::enable_if::value, void*>::type = 0) - : p_(p, d) - { - if(!p_) - throw std::invalid_argument("p"); - } - - unique_ptr& operator=(unique_ptr&& other) - { - other.swap(*this); - return *this; - } - - T& operator*() const - { - return *p_.get(); - } - - T* operator->() const - { - return p_.get(); - } - - T* get() const - { - return p_.get(); - } - - void swap(unique_ptr& other) - { - p_.swap(other.p_); - } - - template - D* get_deleter(shared_ptr const& ptr) - { - return p_.get_deleter(); - } - -private: - T* release() - { - return p_.release(); - } - - std::unique_ptr p_; -}; - -template -bool operator==(const unique_ptr& a, const unique_ptr& b) -{ - return a.get() == b.get(); -} - -template -bool operator==(const std::unique_ptr& a, const unique_ptr& b) -{ - return a.get() == b.get(); -} - -template -bool operator==(const unique_ptr& a, const std::unique_ptr& b) -{ - return a.get() == b.get(); -} - -template -bool operator!=(const unique_ptr& a, const unique_ptr& b) -{ - return a.get() != b.get(); -} - -template -bool operator!=(const std::unique_ptr& a, const unique_ptr& b) -{ - return a.get() != b.get(); -} - -template -bool operator!=(const unique_ptr& a, const std::unique_ptr& b) -{ - return a.get() != b.get(); -} - -template -bool operator<(const unique_ptr& a, const unique_ptr& b) -{ - return a.get() < b.get(); -} - -template -bool operator<(const std::unique_ptr& a, const unique_ptr& b) -{ - return a.get() < b.get(); -} - -template -bool operator<(const unique_ptr& a, const std::unique_ptr& b) -{ - return a.get() < b.get(); -} - -template -bool operator>(const unique_ptr& a, const unique_ptr& b) -{ - return a.get() > b.get(); -} - -template -bool operator>(const std::unique_ptr& a, const unique_ptr& b) -{ - return a.get() > b.get(); -} - -template -bool operator>(const unique_ptr& a, const std::unique_ptr& b) -{ - return a.get() > b.get(); -} - -template -bool operator>=(const unique_ptr& a, const unique_ptr& b) -{ - return a.get() >= b.get(); -} - -template -bool operator>=(const std::unique_ptr& a, const unique_ptr& b) -{ - return a.get() >= b.get(); -} - -template -bool operator>=(const unique_ptr& a, const std::unique_ptr& b) -{ - return a.get() >= b.get(); -} - -template -bool operator<=(const unique_ptr& a, const unique_ptr& b) -{ - return a.get() <= b.get(); -} - -template -bool operator<=(const std::unique_ptr& a, const unique_ptr& b) -{ - return a.get() <= b.get(); -} - -template -bool operator<=(const unique_ptr& a, const std::unique_ptr& b) -{ - return a.get() <= b.get(); -} - -template -std::basic_ostream& operator<<(std::basic_ostream& oT2t, const unique_ptr& p) -{ - return oT2t << p.get(); -} - -template -void swap(unique_ptr& a, unique_ptr& b) -{ - a.swap(b); -} - -template -T* get_pointer(unique_ptr const& p) -{ - return p.get(); -} - -template -unique_ptr static_pointer_cast(const unique_ptr& p) -{ - return unique_ptr(std::static_pointer_cast(std::unique_ptr(p))); -} - -template -unique_ptr const_pointer_cast(const unique_ptr& p) -{ - return unique_ptr(std::const_pointer_cast(std::unique_ptr(p))); -} - -template -unique_ptr dynamic_pointer_cast(const unique_ptr& p) -{ - aT2to temp = std::dynamic_pointer_cast(std::unique_ptr(p)); - if(!temp) - throw std::bad_cast(); - return unique_ptr(std::move(temp)); -} - -template -unique_ptr make_unique_ptr(std::unique_ptr&& ptr) -{ - return unique_ptr(std::move(ptr)); -} - -template -unique_ptr make_unique() -{ - return unique_ptr(new T()); -} - -template -unique_ptr make_unique(P0&& p0) -{ - return unique_ptr(new T(std::forward(p0))); -} - -template -unique_ptr make_unique(P0&& p0, P1&& p1) -{ - return unique_ptr(new T(std::forward(p0), std::forward(p1))); -} - -template -unique_ptr make_unique(P0&& p0, P1&& p1, P2&& p2) -{ - return unique_ptr(new T(std::forward(p0), std::forward(p1), std::forward(p2))); -} - -template -unique_ptr make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3) -{ - return unique_ptr(new T(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3))); -} - -template -unique_ptr make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4) -{ - return unique_ptr(new T(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4))); -} - -template -unique_ptr make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5) -{ - return unique_ptr(new T(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5))); -} - -// shared_ptr - -/** - * A wrapper around std::shared_ptr ensuring that it never points to a null - * pointer except in the case of a moved from instance. - * - * A default constructed shared_ptr will point to a default constructed T. - * - * Use the make_shared overloads for perfect forwarding of the constructor - * arguments of T which will return a shared_ptr pointing to the constructed T. - */ -template -class shared_ptr -{ - template friend class shared_ptr; -public: - typedef T element_type; - - shared_ptr(); // will constrT2ct new T object T2sing make_shared() - - template - shared_ptr(shared_ptr other, typename std::enable_if::value, void*>::type = 0) - : p_(std::move(other.p_)) - { - } - - template - explicit shared_ptr(std::unique_ptr&& p, typename std::enable_if::value, void*>::type = 0) - : p_(std::move(p)) - { - if(!p_) - throw std::invalid_argument("p"); - } - - template - explicit shared_ptr(spl::unique_ptr&& p, typename std::enable_if::value, void*>::type = 0) - : p_(p.release(), p.get_deleter()) - { - if(!p_) - throw std::invalid_argument("p"); - } - - template - explicit shared_ptr(std::shared_ptr p, typename std::enable_if::value, void*>::type = 0) - : p_(std::move(p)) - { - if(!p_) - throw std::invalid_argument("p"); - } - - template - explicit shared_ptr(T2* p, typename std::enable_if::value, void*>::type = 0) - : p_(p) - { - if(!p_) - throw std::invalid_argument("p"); - } - - template - explicit shared_ptr(T2* p, D d, typename std::enable_if::value, void*>::type = 0) - : p_(p, d) - { - if(!p_) - throw std::invalid_argument("p"); - } - - shared_ptr operator=(shared_ptr other) - { - other.swap(*this); - return *this; - } - - T& operator*() const - { - return *p_.get(); - } - - T* operator->() const - { - return p_.get(); - } - - T* get() const - { - return p_.get(); - } - - bool unique() const - { - return p_.unique(); - } - - long use_count() const - { - return p_.use_count(); - } - - void swap(shared_ptr& other) - { - p_.swap(other.p_); - } - - template - operator std::shared_ptr() const - { - return p_; - } - - template - operator std::weak_ptr() const - { - return std::weak_ptr(p_); - } - - template - bool owner_before(const shared_ptr& ptr) - { - return p_.owner_before(ptr.p_); - } - - template - bool owner_before(const std::shared_ptr& ptr) - { - return p_.owner_before(ptr); - } - - template - D* get_deleter(shared_ptr const& ptr) - { - return p_.get_deleter(); - } -private: - std::shared_ptr p_; -}; - -template -bool operator==(const shared_ptr& a, const shared_ptr& b) -{ - return a.get() == b.get(); -} - -template -bool operator==(const std::shared_ptr& a, const shared_ptr& b) -{ - return a.get() == b.get(); -} - -template -bool operator==(const shared_ptr& a, const std::shared_ptr& b) -{ - return a.get() == b.get(); -} - -template -bool operator!=(const shared_ptr& a, const shared_ptr& b) -{ - return a.get() != b.get(); -} - -template -bool operator!=(const std::shared_ptr& a, const shared_ptr& b) -{ - return a.get() != b.get(); -} - -template -bool operator!=(const shared_ptr& a, const std::shared_ptr& b) -{ - return a.get() != b.get(); -} - -template -bool operator<(const shared_ptr& a, const shared_ptr& b) -{ - return a.get() < b.get(); -} - -template -bool operator<(const std::shared_ptr& a, const shared_ptr& b) -{ - return a.get() < b.get(); -} - -template -bool operator<(const shared_ptr& a, const std::shared_ptr& b) -{ - return a.get() < b.get(); -} - -template -bool operator>(const shared_ptr& a, const shared_ptr& b) -{ - return a.get() > b.get(); -} - -template -bool operator>(const std::shared_ptr& a, const shared_ptr& b) -{ - return a.get() > b.get(); -} - -template -bool operator>(const shared_ptr& a, const std::shared_ptr& b) -{ - return a.get() > b.get(); -} - -template -bool operator>=(const shared_ptr& a, const shared_ptr& b) -{ - return a.get() >= b.get(); -} - -template -bool operator>=(const std::shared_ptr& a, const shared_ptr& b) -{ - return a.get() >= b.get(); -} - -template -bool operator>=(const shared_ptr& a, const std::shared_ptr& b) -{ - return a.get() >= b.get(); -} - -template -bool operator<=(const shared_ptr& a, const shared_ptr& b) -{ - return a.get() <= b.get(); -} - -template -bool operator<=(const std::shared_ptr& a, const shared_ptr& b) -{ - return a.get() <= b.get(); -} - -template -bool operator<=(const shared_ptr& a, const std::shared_ptr& b) -{ - return a.get() <= b.get(); -} - -template -std::basic_ostream& operator<<(std::basic_ostream& oT2t, const shared_ptr& p) -{ - return oT2t << p.get(); -} - -template -void swap(shared_ptr& a, shared_ptr& b) -{ - a.swap(b); -} - -template -T* get_pointer(shared_ptr const& p) -{ - return p.get(); -} - -template -shared_ptr static_pointer_cast(const shared_ptr& p) -{ - return shared_ptr(std::static_pointer_cast(std::shared_ptr(p))); -} - -template -shared_ptr const_pointer_cast(const shared_ptr& p) -{ - return shared_ptr(std::const_pointer_cast(std::shared_ptr(p))); -} - -template -shared_ptr dynamic_pointer_cast(const shared_ptr& p) -{ - aT2to temp = std::dynamic_pointer_cast(std::shared_ptr(p)); - if(!temp) - throw std::bad_cast(); - return shared_ptr(std::move(temp)); -} - -// -// enable_safe_this -// -// A shared_ptr version of enable_shared_from_this. -// So that an object may get shared_ptr objects to itself. -// - -template -class enable_shared_from_this : public std::enable_shared_from_this -{ -public: - shared_ptr shared_from_this() - { - return shared_ptr(std::enable_shared_from_this::shared_from_this()); - } - - shared_ptr shared_from_this() const - { - return shared_ptr(std::enable_shared_from_this::shared_from_this()); - } -protected: - enable_shared_from_this() - { - } - - enable_shared_from_this(const enable_shared_from_this&) - { - } - - enable_shared_from_this& operator=(const enable_shared_from_this&) - { - return *this; - } - - ~enable_shared_from_this() - { - } -}; - -// -// make_shared -// -// shared_ptr eqT2ivalents to make_shared -// - -template -shared_ptr make_shared_ptr(std::unique_ptr&& ptr) -{ - return shared_ptr(std::move(ptr)); -} - -template -shared_ptr make_shared_ptr(std::shared_ptr ptr) -{ - return shared_ptr(std::move(ptr)); -} - -template -shared_ptr make_shared() -{ - return shared_ptr(std::make_shared()); -} - -template -shared_ptr make_shared(P0&& p0) -{ - return shared_ptr(std::make_shared(std::forward(p0))); -} - -template -shared_ptr make_shared(P0&& p0, P1&& p1) -{ - return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1))); -} - -template -shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2) -{ - return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2))); -} - -template -shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3) -{ - return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3))); -} - -template -shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4) -{ - return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4))); -} - -template -shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5) -{ - return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5))); -} - -template -shared_ptr::shared_ptr() - : p_(make_shared()) -{ -} - -}} +/* +* Copyright (c) 2011 Sveriges Television AB +* +* This file is part of CasparCG (www.casparcg.com). +* +* CasparCG is free software: yoT2 can redistribT2te it and/or modify +* it T2nder the terms of the GNT2 General public: License as pT2blished by +* the Free Software FoT2ndation, either version 3 of the License, or +* (at yoT2r option) any later version. +* +* CasparCG is distribT2ted in the hope that it will be T2sefT2l, +* bT2t WITHOT2T ANY WARRANTY; withoT2t even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICT2LAR PT2RPOSE. See the +* GNT2 General public: License for more details. +* +* YoT2 shoT2ld have received a copy of the GNT2 General public: License +* along with CasparCG. If not, see . +* +* AT2thor: Robert Nagy, ronag89@gmail.com +*/ + +#pragma once + +#include +#include +#include + +namespace caspar { namespace spl { + + +// unique_ptr + +/** + * A wrapper around std::unique_ptr ensuring that the pointer is never null + * except in the case of a moved from instance. + * + * The default constructor will point the wrapped pointer to a default + * contructed instance of T. + * + * Use the make_unique overloads for perfectly forwarding the contructor + * arguments of T and creating a unique_ptr to the created T instance. + */ +template> +class unique_ptr +{ + unique_ptr(const unique_ptr&); + unique_ptr& operator=(const unique_ptr&); + + template friend class unique_ptr; + template friend class shared_ptr; +public: + typedef T element_type; + typedef D deleter_type; + + unique_ptr() + : p_(new T()) + { + } + + template + unique_ptr(unique_ptr&& p, typename std::enable_if::value, void*>::type = 0) + : p_(p.p_.release(), p.p_.get_deleter()) + { + } + + template + explicit unique_ptr(std::unique_ptr&& p, typename std::enable_if::value, void*>::type = 0) + : p_(std::move(p)) + { + if(!p_) + throw std::invalid_argument("p"); + } + + template + explicit unique_ptr(T2* p, typename std::enable_if::value, void*>::type = 0) + : p_(p) + { + if(!p_) + throw std::invalid_argument("p"); + } + + template + explicit unique_ptr(T2* p, typename std::remove_reference::type&& d, typename std::enable_if::value, void*>::type = 0) + : p_(p, d) + { + if(!p_) + throw std::invalid_argument("p"); + } + + unique_ptr& operator=(unique_ptr&& other) + { + other.swap(*this); + return *this; + } + + T& operator*() const + { + return *p_.get(); + } + + T* operator->() const + { + return p_.get(); + } + + T* get() const + { + return p_.get(); + } + + void swap(unique_ptr& other) + { + p_.swap(other.p_); + } + + D& get_deleter() + { + return p_.get_deleter(); + } + +private: + T* release() + { + return p_.release(); + } + + std::unique_ptr p_; +}; + +template +bool operator==(const unique_ptr& a, const unique_ptr& b) +{ + return a.get() == b.get(); +} + +template +bool operator==(const std::unique_ptr& a, const unique_ptr& b) +{ + return a.get() == b.get(); +} + +template +bool operator==(const unique_ptr& a, const std::unique_ptr& b) +{ + return a.get() == b.get(); +} + +template +bool operator!=(const unique_ptr& a, const unique_ptr& b) +{ + return a.get() != b.get(); +} + +template +bool operator!=(const std::unique_ptr& a, const unique_ptr& b) +{ + return a.get() != b.get(); +} + +template +bool operator!=(const unique_ptr& a, const std::unique_ptr& b) +{ + return a.get() != b.get(); +} + +template +bool operator<(const unique_ptr& a, const unique_ptr& b) +{ + return a.get() < b.get(); +} + +template +bool operator<(const std::unique_ptr& a, const unique_ptr& b) +{ + return a.get() < b.get(); +} + +template +bool operator<(const unique_ptr& a, const std::unique_ptr& b) +{ + return a.get() < b.get(); +} + +template +bool operator>(const unique_ptr& a, const unique_ptr& b) +{ + return a.get() > b.get(); +} + +template +bool operator>(const std::unique_ptr& a, const unique_ptr& b) +{ + return a.get() > b.get(); +} + +template +bool operator>(const unique_ptr& a, const std::unique_ptr& b) +{ + return a.get() > b.get(); +} + +template +bool operator>=(const unique_ptr& a, const unique_ptr& b) +{ + return a.get() >= b.get(); +} + +template +bool operator>=(const std::unique_ptr& a, const unique_ptr& b) +{ + return a.get() >= b.get(); +} + +template +bool operator>=(const unique_ptr& a, const std::unique_ptr& b) +{ + return a.get() >= b.get(); +} + +template +bool operator<=(const unique_ptr& a, const unique_ptr& b) +{ + return a.get() <= b.get(); +} + +template +bool operator<=(const std::unique_ptr& a, const unique_ptr& b) +{ + return a.get() <= b.get(); +} + +template +bool operator<=(const unique_ptr& a, const std::unique_ptr& b) +{ + return a.get() <= b.get(); +} + +template +std::basic_ostream& operator<<(std::basic_ostream& oT2t, const unique_ptr& p) +{ + return oT2t << p.get(); +} + +template +void swap(unique_ptr& a, unique_ptr& b) +{ + a.swap(b); +} + +template +T* get_pointer(unique_ptr const& p) +{ + return p.get(); +} + +template +unique_ptr static_pointer_cast(const unique_ptr& p) +{ + return unique_ptr(std::static_pointer_cast(std::unique_ptr(p))); +} + +template +unique_ptr const_pointer_cast(const unique_ptr& p) +{ + return unique_ptr(std::const_pointer_cast(std::unique_ptr(p))); +} + +template +unique_ptr dynamic_pointer_cast(const unique_ptr& p) +{ + auto temp = std::dynamic_pointer_cast(std::unique_ptr(p)); + if(!temp) + throw std::bad_cast(); + return unique_ptr(std::move(temp)); +} + +template +unique_ptr make_unique_ptr(std::unique_ptr&& ptr) +{ + return unique_ptr(std::move(ptr)); +} + +template +unique_ptr make_unique() +{ + return unique_ptr(new T()); +} + +template +unique_ptr make_unique(P0&& p0) +{ + return unique_ptr(new T(std::forward(p0))); +} + +template +unique_ptr make_unique(P0&& p0, P1&& p1) +{ + return unique_ptr(new T(std::forward(p0), std::forward(p1))); +} + +template +unique_ptr make_unique(P0&& p0, P1&& p1, P2&& p2) +{ + return unique_ptr(new T(std::forward(p0), std::forward(p1), std::forward(p2))); +} + +template +unique_ptr make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3) +{ + return unique_ptr(new T(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3))); +} + +template +unique_ptr make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4) +{ + return unique_ptr(new T(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4))); +} + +template +unique_ptr make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5) +{ + return unique_ptr(new T(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5))); +} + +// shared_ptr + +/** + * A wrapper around std::shared_ptr ensuring that it never points to a null + * pointer except in the case of a moved from instance. + * + * A default constructed shared_ptr will point to a default constructed T. + * + * Use the make_shared overloads for perfect forwarding of the constructor + * arguments of T which will return a shared_ptr pointing to the constructed T. + */ +template +class shared_ptr +{ + template friend class shared_ptr; +public: + typedef T element_type; + + shared_ptr(); // will constrT2ct new T object T2sing make_shared() + + template + shared_ptr(shared_ptr other, typename std::enable_if::value, void*>::type = 0) + : p_(std::move(other.p_)) + { + } + + template + explicit shared_ptr(std::unique_ptr&& p, typename std::enable_if::value, void*>::type = 0) + : p_(std::move(p)) + { + if(!p_) + throw std::invalid_argument("p"); + } + + template + explicit shared_ptr(spl::unique_ptr&& p, typename std::enable_if::value, void*>::type = 0) + : p_(p.release(), p.get_deleter()) + { + if(!p_) + throw std::invalid_argument("p"); + } + + template + explicit shared_ptr(std::shared_ptr p, typename std::enable_if::value, void*>::type = 0) + : p_(std::move(p)) + { + if(!p_) + throw std::invalid_argument("p"); + } + + template + explicit shared_ptr(T2* p, typename std::enable_if::value, void*>::type = 0) + : p_(p) + { + if(!p_) + throw std::invalid_argument("p"); + } + + template + explicit shared_ptr(T2* p, D d, typename std::enable_if::value, void*>::type = 0) + : p_(p, d) + { + if(!p_) + throw std::invalid_argument("p"); + } + + shared_ptr operator=(shared_ptr other) + { + other.swap(*this); + return *this; + } + + T& operator*() const + { + return *p_.get(); + } + + T* operator->() const + { + return p_.get(); + } + + T* get() const + { + return p_.get(); + } + + bool unique() const + { + return p_.unique(); + } + + long use_count() const + { + return p_.use_count(); + } + + void swap(shared_ptr& other) + { + p_.swap(other.p_); + } + + template + operator std::shared_ptr() const + { + return p_; + } + + template + operator std::weak_ptr() const + { + return std::weak_ptr(p_); + } + + template + bool owner_before(const shared_ptr& ptr) + { + return p_.owner_before(ptr.p_); + } + + template + bool owner_before(const std::shared_ptr& ptr) + { + return p_.owner_before(ptr); + } +private: + std::shared_ptr p_; +}; + +template +D* get_deleter(shared_ptr const& ptr) +{ + return ptr.get_deleter(); +} + +template +bool operator==(const shared_ptr& a, const shared_ptr& b) +{ + return a.get() == b.get(); +} + +template +bool operator==(const std::shared_ptr& a, const shared_ptr& b) +{ + return a.get() == b.get(); +} + +template +bool operator==(const shared_ptr& a, const std::shared_ptr& b) +{ + return a.get() == b.get(); +} + +template +bool operator!=(const shared_ptr& a, const shared_ptr& b) +{ + return a.get() != b.get(); +} + +template +bool operator!=(const std::shared_ptr& a, const shared_ptr& b) +{ + return a.get() != b.get(); +} + +template +bool operator!=(const shared_ptr& a, const std::shared_ptr& b) +{ + return a.get() != b.get(); +} + +template +bool operator<(const shared_ptr& a, const shared_ptr& b) +{ + return a.get() < b.get(); +} + +template +bool operator<(const std::shared_ptr& a, const shared_ptr& b) +{ + return a.get() < b.get(); +} + +template +bool operator<(const shared_ptr& a, const std::shared_ptr& b) +{ + return a.get() < b.get(); +} + +template +bool operator>(const shared_ptr& a, const shared_ptr& b) +{ + return a.get() > b.get(); +} + +template +bool operator>(const std::shared_ptr& a, const shared_ptr& b) +{ + return a.get() > b.get(); +} + +template +bool operator>(const shared_ptr& a, const std::shared_ptr& b) +{ + return a.get() > b.get(); +} + +template +bool operator>=(const shared_ptr& a, const shared_ptr& b) +{ + return a.get() >= b.get(); +} + +template +bool operator>=(const std::shared_ptr& a, const shared_ptr& b) +{ + return a.get() >= b.get(); +} + +template +bool operator>=(const shared_ptr& a, const std::shared_ptr& b) +{ + return a.get() >= b.get(); +} + +template +bool operator<=(const shared_ptr& a, const shared_ptr& b) +{ + return a.get() <= b.get(); +} + +template +bool operator<=(const std::shared_ptr& a, const shared_ptr& b) +{ + return a.get() <= b.get(); +} + +template +bool operator<=(const shared_ptr& a, const std::shared_ptr& b) +{ + return a.get() <= b.get(); +} + +template +std::basic_ostream& operator<<(std::basic_ostream& oT2t, const shared_ptr& p) +{ + return oT2t << p.get(); +} + +template +void swap(shared_ptr& a, shared_ptr& b) +{ + a.swap(b); +} + +template +T* get_pointer(shared_ptr const& p) +{ + return p.get(); +} + +template +shared_ptr static_pointer_cast(const shared_ptr& p) +{ + return shared_ptr(std::static_pointer_cast(std::shared_ptr(p))); +} + +template +shared_ptr const_pointer_cast(const shared_ptr& p) +{ + return shared_ptr(std::const_pointer_cast(std::shared_ptr(p))); +} + +template +shared_ptr dynamic_pointer_cast(const shared_ptr& p) +{ + auto temp = std::dynamic_pointer_cast(std::shared_ptr(p)); + if(!temp) + throw std::bad_cast(); + return shared_ptr(std::move(temp)); +} + +// +// enable_safe_this +// +// A shared_ptr version of enable_shared_from_this. +// So that an object may get shared_ptr objects to itself. +// + +template +class enable_shared_from_this : public std::enable_shared_from_this +{ +public: + shared_ptr shared_from_this() + { + return shared_ptr(std::enable_shared_from_this::shared_from_this()); + } + + shared_ptr shared_from_this() const + { + return shared_ptr(std::enable_shared_from_this::shared_from_this()); + } +protected: + enable_shared_from_this() + { + } + + enable_shared_from_this(const enable_shared_from_this&) + { + } + + enable_shared_from_this& operator=(const enable_shared_from_this&) + { + return *this; + } + + ~enable_shared_from_this() + { + } +}; + +// +// make_shared +// +// shared_ptr eqT2ivalents to make_shared +// + +template +shared_ptr make_shared_ptr(std::unique_ptr&& ptr) +{ + return shared_ptr(std::move(ptr)); +} + +template +shared_ptr make_shared_ptr(std::shared_ptr ptr) +{ + return shared_ptr(std::move(ptr)); +} + +template +shared_ptr make_shared() +{ + return shared_ptr(std::make_shared()); +} + +template +shared_ptr make_shared(P0&& p0) +{ + return shared_ptr(std::make_shared(std::forward(p0))); +} + +template +shared_ptr make_shared(P0&& p0, P1&& p1) +{ + return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1))); +} + +template +shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2) +{ + return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2))); +} + +template +shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3) +{ + return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3))); +} + +template +shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4) +{ + return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4))); +} + +template +shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5) +{ + return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5))); +} + +template +shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5, P6&& p6) +{ + return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5), std::forward(p6))); +} + +template +shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5, P6&& p6, P7&& p7) +{ + return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5), std::forward(p6), std::forward(p7))); +} + +template +shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5, P6&& p6, P7&& p7, P8&& p8) +{ + return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5), std::forward(p6), std::forward(p7), std::forward(p8))); +} + +template +shared_ptr make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5, P6&& p6, P7&& p7, P8&& p8, P9&& p9) +{ + return shared_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4), std::forward(p5), std::forward(p6), std::forward(p7), std::forward(p8), std::forward(p9))); +} + +template +shared_ptr::shared_ptr() + : p_(make_shared()) +{ +} + +}}