root/OpenSceneGraph/trunk/include/osg/ref_ptr

Revision 13041, 4.6 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_REF_PTR
15#define OSG_REF_PTR 1
16
17#include <osg/Config>
18
19namespace osg {
20
21template<typename T> class observer_ptr;
22
23/** Smart pointer for handling referenced counted objects.*/
24template<class T>
25class ref_ptr
26{
27    public:
28        typedef T element_type;
29
30        ref_ptr() : _ptr(0) {}
31        ref_ptr(T* ptr) : _ptr(ptr) { if (_ptr) _ptr->ref(); }
32        ref_ptr(const ref_ptr& rp) : _ptr(rp._ptr) { if (_ptr) _ptr->ref(); }
33        template<class Other> ref_ptr(const ref_ptr<Other>& rp) : _ptr(rp._ptr) { if (_ptr) _ptr->ref(); }
34        ref_ptr(observer_ptr<T>& optr) : _ptr(0) { optr.lock(*this); }
35        ~ref_ptr() { if (_ptr) _ptr->unref();  _ptr = 0; }
36
37        ref_ptr& operator = (const ref_ptr& rp)
38        {
39            assign(rp);
40            return *this;
41        }
42
43        template<class Other> ref_ptr& operator = (const ref_ptr<Other>& rp)
44        {
45            assign(rp);
46            return *this;
47        }
48
49        inline ref_ptr& operator = (T* ptr)
50        {
51            if (_ptr==ptr) return *this;
52            T* tmp_ptr = _ptr;
53            _ptr = ptr;
54            if (_ptr) _ptr->ref();
55            // unref second to prevent any deletion of any object which might
56            // be referenced by the other object. i.e rp is child of the
57            // original _ptr.
58            if (tmp_ptr) tmp_ptr->unref();
59            return *this;
60        }
61
62#ifdef OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION
63        // implicit output conversion
64        operator T*() const { return _ptr; }
65#else
66        // comparison operators for ref_ptr.
67        bool operator == (const ref_ptr& rp) const { return (_ptr==rp._ptr); }
68        bool operator == (const T* ptr) const { return (_ptr==ptr); }
69        friend bool operator == (const T* ptr, const ref_ptr& rp) { return (ptr==rp._ptr); }
70
71        bool operator != (const ref_ptr& rp) const { return (_ptr!=rp._ptr); }
72        bool operator != (const T* ptr) const { return (_ptr!=ptr); }
73        friend bool operator != (const T* ptr, const ref_ptr& rp) { return (ptr!=rp._ptr); }
74
75        bool operator < (const ref_ptr& rp) const { return (_ptr<rp._ptr); }
76
77
78    // follows is an implmentation of the "safe bool idiom", details can be found at:
79    //   http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool
80    //   http://lists.boost.org/Archives/boost/2003/09/52856.php
81
82    private:
83        typedef T* ref_ptr::*unspecified_bool_type;
84
85    public:
86        // safe bool conversion
87        operator unspecified_bool_type() const { return valid()? &ref_ptr::_ptr : 0; }
88#endif
89
90        T& operator*() const { return *_ptr; }
91        T* operator->() const { return _ptr; }
92        T* get() const { return _ptr; }
93
94        bool operator!() const   { return _ptr==0; } // not required
95        bool valid() const       { return _ptr!=0; }
96
97        T* release() { T* tmp=_ptr; if (_ptr) _ptr->unref_nodelete(); _ptr=0; return tmp; }
98
99        void swap(ref_ptr& rp) { T* tmp=_ptr; _ptr=rp._ptr; rp._ptr=tmp; }
100
101    private:
102
103        template<class Other> void assign(const ref_ptr<Other>& rp)
104        {
105            if (_ptr==rp._ptr) return;
106            T* tmp_ptr = _ptr;
107            _ptr = rp._ptr;
108            if (_ptr) _ptr->ref();
109            // unref second to prevent any deletion of any object which might
110            // be referenced by the other object. i.e rp is child of the
111            // original _ptr.
112            if (tmp_ptr) tmp_ptr->unref();
113        }
114
115        template<class Other> friend class ref_ptr;
116
117        T* _ptr;
118};
119
120
121template<class T> inline
122void swap(ref_ptr<T>& rp1, ref_ptr<T>& rp2) { rp1.swap(rp2); }
123
124template<class T> inline
125T* get_pointer(const ref_ptr<T>& rp) { return rp.get(); }
126
127template<class T, class Y> inline
128ref_ptr<T> static_pointer_cast(const ref_ptr<Y>& rp) { return static_cast<T*>(rp.get()); }
129
130template<class T, class Y> inline
131ref_ptr<T> dynamic_pointer_cast(const ref_ptr<Y>& rp) { return dynamic_cast<T*>(rp.get()); }
132
133template<class T, class Y> inline
134ref_ptr<T> const_pointer_cast(const ref_ptr<Y>& rp) { return const_cast<T*>(rp.get()); }
135
136}
137
138#endif
Note: See TracBrowser for help on using the browser.