source: tags/20121012/src/core/RpPtr.h @ 3825

Last change on this file since 3825 was 3177, checked in by mmc, 12 years ago

Updated all of the copyright notices to reference the transfer to
the new HUBzero Foundation, LLC.

File size: 3.2 KB
Line 
1/*
2 * ======================================================================
3 *  Rappture::Ptr<type>
4 *
5 *  AUTHOR:  Michael McLennan, Purdue University
6 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
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.