source: trunk/src/core/RpPtr.h @ 1036

Last change on this file since 1036 was 1031, checked in by gah, 16 years ago

more 1.1 fixes

File size: 3.2 KB
Line 
1/*
2 * ======================================================================
3 *  Rappture::Ptr<type>
4 *
5 *  AUTHOR:  Michael McLennan, Purdue University
6 *  Copyright (c) 2004-2006  Purdue Research Foundation
7 * ----------------------------------------------------------------------
8 *  See the file "license.terms" for information on usage and
9 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10 * ======================================================================
11 */
12#ifndef RAPPTURE_PTR_H
13#define RAPPTURE_PTR_H
14
15#include <assert.h>
16#include <stddef.h>
17
18namespace Rappture {
19
20/**
21 *  This is the core of a smart pointer, built to keep a reference
22 *  count and do most of the work, so the template class can be lean
23 *  and mean.
24 */
25class PtrCore {
26public:
27    explicit PtrCore(void* ptr=NULL);
28    ~PtrCore();
29
30    void* pointer() const;
31    void attach();
32    void* detach();
33
34private:
35    // copying the core is not allowed
36    PtrCore(const PtrCore& pc) { assert(0); }
37    PtrCore& operator=(const PtrCore& pc) { assert(0); return *this; }
38
39    void *_ptr;
40    int _refcount;
41};
42
43/**
44 *  This is a smart pointer with reference counting.  Once one of
45 *  these pointers is constructed with an object of the underlying
46 *  type, that object becomes property of the pointer.  Other
47 *  pointers can point to the same object.  When all such pointers
48 *  have been destroyed, the underlying object goes away.
49 */
50template <class Type>
51class Ptr {
52public:
53    explicit Ptr(Type* ptr=NULL);
54    Ptr(const Ptr& ptr);
55    Ptr& operator=(Type* ptr);
56    Ptr& operator=(const Ptr& ptr);
57    ~Ptr();
58
59    int isNull() const;
60    Type* operator->() const;
61    Type* pointer() const;
62    Type& operator*() const;
63    void clear();
64
65private:
66    PtrCore *_pc;
67};
68
69template <class Type>
70Ptr<Type>::Ptr(Type* ptr)
71  : _pc(NULL)
72{
73    if (ptr) {
74        _pc = new PtrCore(ptr);
75    }
76}
77
78template <class Type>
79Ptr<Type>::Ptr(const Ptr<Type>& ptr)
80  : _pc(NULL)
81{
82    if (ptr._pc) {
83        ptr._pc->attach();
84        _pc = ptr._pc;
85    }
86}
87
88template <class Type>
89Ptr<Type>::~Ptr()
90{
91    clear();
92}
93
94template <class Type>
95Ptr<Type>&
96Ptr<Type>::operator=(Type* ptr)
97{
98    clear();
99    _pc = new PtrCore(ptr);
100    return *this;
101}
102
103template <class Type>
104Ptr<Type>&
105Ptr<Type>::operator=(const Ptr<Type>& ptr)
106{
107    if (ptr._pc) {
108        ptr._pc->attach();
109    }
110    clear();
111    _pc = ptr._pc;
112    return *this;
113}
114
115template <class Type>
116int
117Ptr<Type>::isNull() const
118{
119    if (_pc) {
120        return (_pc->pointer() == NULL);
121    }
122    return 1;
123}
124
125template <class Type>
126Type*
127Ptr<Type>::operator->() const
128{
129    if (_pc) {
130        return static_cast<Type*>(_pc->pointer());
131    }
132    return NULL;
133}
134
135template <class Type>
136Type*
137Ptr<Type>::pointer() const
138{
139    if (_pc) {
140        return (Type*)_pc->pointer();
141    }
142    return NULL;
143}
144
145template <class Type>
146Type&
147Ptr<Type>::operator*() const
148{
149    assert(_pc != NULL);
150    return *(Type*)_pc->pointer();
151}
152
153template <class Type>
154void
155Ptr<Type>::clear()
156{
157    if (_pc) {
158        Type* ptr = (Type*)_pc->detach();
159        if (ptr) {
160            // If we get back a pointer, then it is fully detached.
161            // Clean it up.
162            delete ptr;
163            delete _pc;
164        }
165        _pc = NULL;
166    }
167}
168
169} // namespace Rappture
170
171#endif // RAPPTURE_PTR_H
Note: See TracBrowser for help on using the repository browser.