X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fstructure%2FSGSharedPtr.hxx;h=081d5eb943b1bcb43cf89661228b4477ea94a7ab;hb=10375086ed794770fcb97591ec19c60c0fcdaff1;hp=d0f899bd6682945396e8e1b01cc038c05e8b5607;hpb=dcb95d131bc6aef1abe25d1f415e309f06e52436;p=simgear.git diff --git a/simgear/structure/SGSharedPtr.hxx b/simgear/structure/SGSharedPtr.hxx index d0f899bd..081d5eb9 100644 --- a/simgear/structure/SGSharedPtr.hxx +++ b/simgear/structure/SGSharedPtr.hxx @@ -1,6 +1,6 @@ /* -*-c++-*- * - * Copyright (C) 2005-2006 Mathias Froehlich + * Copyright (C) 2005-2012 Mathias Froehlich * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -37,31 +37,36 @@ /// to zero and consequently the objects will never be destroyed. /// Always try to use directed graphs where the references away from the /// top node are made with SGSharedPtr's and the back references are done with -/// ordinary pointers. +/// ordinary pointers or SGWeakPtr's. /// There is a very good description of OpenSceneGraphs ref_ptr which is /// pretty much the same than this one at /// http://dburns.dhs.org/OSG/Articles/RefPointers/RefPointers.html +template +class SGWeakPtr; + template class SGSharedPtr { public: + typedef T element_type; + SGSharedPtr(void) : _ptr(0) {} SGSharedPtr(T* ptr) : _ptr(ptr) { get(_ptr); } - SGSharedPtr(const SGSharedPtr& p) : _ptr(p.ptr()) + SGSharedPtr(const SGSharedPtr& p) : _ptr(p.get()) { get(_ptr); } template - SGSharedPtr(const SGSharedPtr& p) : _ptr(p.ptr()) + SGSharedPtr(const SGSharedPtr& p) : _ptr(p.get()) { get(_ptr); } ~SGSharedPtr(void) { put(); } SGSharedPtr& operator=(const SGSharedPtr& p) - { assign(p.ptr()); return *this; } + { assign(p.get()); return *this; } template SGSharedPtr& operator=(const SGSharedPtr& p) - { assign(p.ptr()); return *this; } + { assign(p.get()); return *this; } template SGSharedPtr& operator=(U* p) { assign(p); return *this; } @@ -74,26 +79,95 @@ public: { return _ptr; } T* ptr(void) const { return _ptr; } + T* get(void) const + { return _ptr; } + T* release() + { T* tmp = _ptr; _ptr = 0; T::put(tmp); return tmp; } bool isShared(void) const - { return SGReferenced::shared(_ptr); } + { return T::shared(_ptr); } unsigned getNumRefs(void) const - { return SGReferenced::count(_ptr); } + { return T::count(_ptr); } bool valid(void) const - { return _ptr; } + { return _ptr != (T*)0; } + + void clear() + { put(); } + void swap(SGSharedPtr& sharedPtr) + { T* tmp = _ptr; _ptr = sharedPtr._ptr; sharedPtr._ptr = tmp; } private: void assign(T* p) { get(p); put(); _ptr = p; } + void assignNonRef(T* p) + { put(); _ptr = p; } void get(const T* p) const - { SGReferenced::get(p); } + { T::get(p); } void put(void) - { if (!SGReferenced::put(_ptr)) { delete _ptr; _ptr = 0; } } + { if (!T::put(_ptr)) delete _ptr; _ptr = 0; } // The reference itself. T* _ptr; + + template + friend class SGWeakPtr; }; +/** + * Support for boost::mem_fn + */ +template +T* get_pointer(SGSharedPtr const & p) +{ + return p.ptr(); +} + +/** + * static_cast for SGSharedPtr + */ +template +SGSharedPtr static_pointer_cast(SGSharedPtr const & r) +{ + return SGSharedPtr( static_cast(r.get()) ); +} + +/** + * Compare two SGSharedPtr objects for equality. + * + * @note Only pointer values are compared, not the actual objects they are + * pointing at. + */ +template +bool operator==(const SGSharedPtr& lhs, const SGSharedPtr& rhs) +{ + return lhs.get() == rhs.get(); +} + +/** + * Compare two SGSharedPtr objects for equality. + * + * @note Only pointer values are compared, not the actual objects they are + * pointing at. + */ +template +bool operator!=(const SGSharedPtr& lhs, const SGSharedPtr& rhs) +{ + return lhs.get() != rhs.get(); +} + +/** + * Compare two SGSharedPtr objects for weak ordering. + * + * @note Only pointer values are compared, not the actual objects they are + * pointing at. + * @note This allows using SGSharedPtr as key in associative containers like for + * example std::map and std::set. + */ +template +bool operator<(const SGSharedPtr& lhs, const SGSharedPtr& rhs) +{ + return lhs.get() < rhs.get(); +} #endif