Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/SharedPtr.h @ 7196

Last change on this file since 7196 was 7196, checked in by landauf, 14 years ago

Changed implementation of SharedPtr, it's now non-intrusive and uses an allocated counter instead. Hence it's possible to create an instance of SharedPtr<T> even if T is only known from a forward declaration. Also changed some parts of the code to reflect the inheritance of the underlying object pointers without using inheritance in the SharedPtr itself.

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#ifndef _SharedPtr_H__
30#define _SharedPtr_H__
31
32#include "CorePrereqs.h"
33#include <algorithm>
34
35namespace orxonox
36{
37    class SharedPtrDestroyer
38    {
39        public:
40            virtual void destroy() = 0;
41    };
42
43    template <class T>
44    class SharedPtrDestroyerImpl : public SharedPtrDestroyer
45    {
46        public:
47            SharedPtrDestroyerImpl(T* pointer) : pointer_(pointer) {}
48
49            void destroy()
50            {
51//                COUT(0) << "delete " << this->pointer_ << std::endl;
52                delete this->pointer_;
53            }
54
55        private:
56            T* pointer_;
57    };
58
59    template <class T>
60    class SharedPtr
61    {
62        template <class O>
63        friend class SharedPtr;
64
65        public:
66            inline SharedPtr() : pointer_(0), counter_(0), destroyer_(0)
67            {
68//                COUT(0) << "SharedPtr (1): " << this->pointer_ << std::endl;
69            }
70
71            inline SharedPtr(T* pointer) : pointer_(pointer), counter_(0), destroyer_(0)
72            {
73//                COUT(0) << "SharedPtr (2): " << this->pointer_ << std::endl;
74                if (this->pointer_)
75                {
76                    this->counter_ = new int(1);
77                    this->destroyer_ = new SharedPtrDestroyerImpl<T>(this->pointer_);
78                }
79            }
80
81            inline SharedPtr(const SharedPtr& other) : pointer_(other.pointer_), counter_(other.counter_), destroyer_(other.destroyer_)
82            {
83//                COUT(0) << "SharedPtr (3): " << this->pointer_ << std::endl;
84                if (this->pointer_)
85                    ++(*this->counter_);
86            }
87
88            template <class O>
89            inline SharedPtr(const SharedPtr<O>& other) : pointer_(other.pointer_), counter_(other.counter_), destroyer_(other.destroyer_)
90            {
91//                COUT(0) << "SharedPtr (4): " << this->pointer_ << std::endl;
92                if (this->pointer_)
93                    ++(*this->counter_);
94            }
95
96            inline ~SharedPtr()
97            {
98//                COUT(0) << "~SharedPtr: " << this->pointer_ << std::endl;
99                if (this->pointer_)
100                {
101                    --(*this->counter_);
102
103                    if (*this->counter_ == 0)
104                    {
105                        this->destroyer_->destroy();
106                        delete this->destroyer_;
107                        delete this->counter_;
108                    }
109                }
110            }
111
112            inline const SharedPtr& operator=(const SharedPtr& other)
113            {
114//                COUT(0) << "SharedPtr= (1)" << std::endl;
115                SharedPtr(other).swap(*this);
116                return *this;
117            }
118
119            template <class O>
120            inline const SharedPtr& operator=(const SharedPtr<O>& other)
121            {
122//                COUT(0) << "SharedPtr= (2)" << std::endl;
123                SharedPtr(other).swap(*this);
124                return *this;
125            }
126
127            template <class O>
128            inline SharedPtr<O> cast() const
129            {
130                O* temp = static_cast<O*>(this->pointer_); // temp value for prettier compiler error in case of an invalid static_cast
131                return SharedPtr<O>(temp, this->counter_, this->destroyer_);
132            }
133
134            inline T* operator->() const
135            {
136                assert(this->pointer_ != 0);
137                return this->pointer_;
138            }
139
140            inline T& operator*() const
141            {
142                assert(this->pointer_ != 0);
143                return *this->pointer_;
144            }
145
146            inline operator bool() const
147            {
148                return (this->pointer_ != 0);
149            }
150
151            inline void swap(SharedPtr& other)
152            {
153                std::swap(this->pointer_, other.pointer_);
154                std::swap(this->counter_, other.counter_);
155                std::swap(this->destroyer_, other.destroyer_);
156            }
157
158        private:
159            inline SharedPtr(T* pointer, int* counter, SharedPtrDestroyer* destroyer) : pointer_(pointer), counter_(counter), destroyer_(destroyer)
160            {
161//                COUT(0) << "SharedPtr (5): " << this->pointer_ << std::endl;
162                if (this->pointer_)
163                    ++(*this->counter_);
164            }
165
166            T* pointer_;
167            int* counter_;
168            SharedPtrDestroyer* destroyer_;
169    };
170/*
171    template <class T, class Parent>
172    class SharedChildPtr : public SharedPtr<Parent>
173    {
174        public:
175            inline SharedChildPtr() : SharedPtr<Parent>() {}
176            inline SharedChildPtr(T* pointer) : SharedPtr<Parent>(pointer) {}
177            inline SharedChildPtr(const SharedChildPtr& other) : SharedPtr<Parent>(other) {}
178            inline const SharedChildPtr& operator=(const SharedChildPtr& other) { SharedPtr<Parent>::operator=(other); return *this; }
179            inline T* operator->() const { return static_cast<T*>(SharedPtr<Parent>::operator->()); }
180            inline T& operator*() const { return *static_cast<T*>(SharedPtr<Parent>::operator->()); }
181    };
182*/
183}
184
185#endif /* _SharedPtr_H__ */
Note: See TracBrowser for help on using the repository browser.