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

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

Massive changes: New directory/file layout

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