source: trunk/src2/core/Ptr.h @ 621

Last change on this file since 621 was 621, checked in by dkearney, 17 years ago

updates to RpBuffer? for syntax and more exact logic
syntax update to Ptr.h

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 "rappture2.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); }
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 _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.