X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fstructure%2FSGSharedPtr.hxx;h=3afcfc9103bf69d6eff446c039899d74f07c1362;hb=9da0031039bb534011591ce3bd6fede21030c345;hp=479c197294247e96dbf90c46639863cabbadeb04;hpb=e179bda57aee4c342df3168737b7dad0b6a3a8f7;p=simgear.git diff --git a/simgear/structure/SGSharedPtr.hxx b/simgear/structure/SGSharedPtr.hxx index 479c1972..3afcfc91 100644 --- a/simgear/structure/SGSharedPtr.hxx +++ b/simgear/structure/SGSharedPtr.hxx @@ -1,33 +1,36 @@ -/* -*-c++-*- - * - * 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ +///@file +/// Pointer proxy doing reference counting. +// +// Copyright (C) 2005-2012 Mathias Froehlich +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef SGSharedPtr_HXX #define SGSharedPtr_HXX #include "SGReferenced.hxx" +#include + +template +class SGWeakPtr; /// This class is a pointer proxy doing reference counting on the object /// it is pointing to. /// The SGSharedPtr class handles reference counting and possible /// destruction if no nore references are in use automatically. -/// Classes derived from @SGReferenced can be handled with SGSharedPtr. +/// Classes derived from SGReferenced can be handled with SGSharedPtr. /// Once you have a SGSharedPtr available you can use it just like /// a usual pointer with the exception that you don't need to delete it. /// Such a reference is initialized by zero if not initialized with a @@ -42,9 +45,6 @@ /// pretty much the same than this one at /// http://dburns.dhs.org/OSG/Articles/RefPointers/RefPointers.html -template -class SGWeakPtr; - template class SGSharedPtr { public: @@ -59,17 +59,20 @@ public: template SGSharedPtr(const SGSharedPtr& p) : _ptr(p.get()) { get(_ptr); } + template + explicit SGSharedPtr(const SGWeakPtr& p): _ptr(0) + { reset(p.lock().get()); } ~SGSharedPtr(void) - { put(); } + { reset(); } SGSharedPtr& operator=(const SGSharedPtr& p) - { assign(p.get()); return *this; } + { reset(p.get()); return *this; } template SGSharedPtr& operator=(const SGSharedPtr& p) - { assign(p.get()); return *this; } + { reset(p.get()); return *this; } template SGSharedPtr& operator=(U* p) - { assign(p); return *this; } + { reset(p); return *this; } T* operator->(void) const { return _ptr; } @@ -83,6 +86,10 @@ public: { return _ptr; } T* release() { T* tmp = _ptr; _ptr = 0; T::put(tmp); return tmp; } + void reset() + { if (!T::put(_ptr)) delete _ptr; _ptr = 0; } + void reset(T* p) + { SGSharedPtr(p).swap(*this); } bool isShared(void) const { return T::shared(_ptr); } @@ -93,20 +100,16 @@ public: { return _ptr != (T*)0; } void clear() - { put(); } - void swap(SGSharedPtr& sharedPtr) - { T* tmp = _ptr; _ptr = sharedPtr._ptr; sharedPtr._ptr = tmp; } + { reset(); } + void swap(SGSharedPtr& other) + { std::swap(_ptr, other._ptr); } private: - void assign(T* p) - { get(p); put(); _ptr = p; } void assignNonRef(T* p) - { put(); _ptr = p; } + { reset(); _ptr = p; } void get(const T* p) const { T::get(p); } - void put(void) - { if (!T::put(_ptr)) delete _ptr; _ptr = 0; } // The reference itself. T* _ptr; @@ -132,4 +135,42 @@ 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