Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Changed the implementation of SharedPtr again. I decided to represent the inheritance of the underlying object pointers by using inheritance in the SharedPtr itself (with SharedChildPtr : public SharedPtr). The previous solution led to ambiguity in functions that are overloaded for different types of SharedPtr (for example createExecutor).

  • Property svn:eol-style set to native
File size: 6.1 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#include <cassert>
35
36namespace orxonox
37{
38    class SharedPtrDestroyer
39    {
40        public:
41            virtual void destroy() = 0;
42    };
43
44    template <class T>
45    class SharedPtrDestroyerImpl : public SharedPtrDestroyer
46    {
47        public:
48            SharedPtrDestroyerImpl(T* pointer) : pointer_(pointer) {}
49
50            void destroy()
51            {
52//                COUT(0) << "delete " << this->pointer_ << std::endl;
53                delete this->pointer_;
54            }
55
56        private:
57            T* pointer_;
58    };
59
60    template <class T>
61    class SharedPtr
62    {
63        template <class O>
64        friend class SharedPtr;
65
66        public:
67            inline SharedPtr() : pointer_(0), counter_(0), destroyer_(0)
68            {
69//                COUT(0) << "SharedPtr (1): " << this->pointer_ << std::endl;
70            }
71
72            inline SharedPtr(T* pointer) : pointer_(pointer), counter_(0), destroyer_(0)
73            {
74//                COUT(0) << "SharedPtr (2): " << this->pointer_ << std::endl;
75                if (this->pointer_)
76                {
77                    this->counter_ = new int(1);
78                    this->destroyer_ = new SharedPtrDestroyerImpl<T>(this->pointer_);
79                }
80            }
81
82            inline SharedPtr(const SharedPtr& other) : pointer_(other.pointer_), counter_(other.counter_), destroyer_(other.destroyer_)
83            {
84//                COUT(0) << "SharedPtr (3): " << this->pointer_ << std::endl;
85                if (this->pointer_)
86                    ++(*this->counter_);
87            }
88
89            template <class O>
90            inline SharedPtr(const SharedPtr<O>& other) : pointer_(other.pointer_), counter_(other.counter_), destroyer_(other.destroyer_)
91            {
92//                COUT(0) << "SharedPtr (4): " << this->pointer_ << std::endl;
93                if (this->pointer_)
94                    ++(*this->counter_);
95            }
96
97            inline ~SharedPtr()
98            {
99//                COUT(0) << "~SharedPtr: " << this->pointer_ << std::endl;
100                if (this->pointer_)
101                {
102                    --(*this->counter_);
103
104                    if (*this->counter_ == 0)
105                    {
106                        this->destroyer_->destroy();
107                        delete this->destroyer_;
108                        delete this->counter_;
109                    }
110                }
111            }
112
113            inline const SharedPtr& operator=(const SharedPtr& other)
114            {
115//                COUT(0) << "SharedPtr= (1)" << std::endl;
116                SharedPtr(other).swap(*this);
117                return *this;
118            }
119
120            template <class O>
121            inline const SharedPtr& operator=(const SharedPtr<O>& other)
122            {
123//                COUT(0) << "SharedPtr= (2)" << std::endl;
124                SharedPtr(other).swap(*this);
125                return *this;
126            }
127
128            template <class O>
129            inline SharedPtr<O> cast() const
130            {
131                O* temp = static_cast<O*>(this->pointer_); // temp value for prettier compiler error in case of an invalid static_cast
132                return SharedPtr<O>(temp, this->counter_, this->destroyer_);
133            }
134
135            inline T* operator->() const
136            {
137                assert(this->pointer_ != 0);
138                return this->pointer_;
139            }
140
141            inline T& operator*() const
142            {
143                assert(this->pointer_ != 0);
144                return *this->pointer_;
145            }
146
147            inline operator bool() const
148            {
149                return (this->pointer_ != 0);
150            }
151
152            inline void swap(SharedPtr& other)
153            {
154                std::swap(this->pointer_, other.pointer_);
155                std::swap(this->counter_, other.counter_);
156                std::swap(this->destroyer_, other.destroyer_);
157            }
158
159        private:
160            inline SharedPtr(T* pointer, int* counter, SharedPtrDestroyer* destroyer) : pointer_(pointer), counter_(counter), destroyer_(destroyer)
161            {
162//                COUT(0) << "SharedPtr (5): " << this->pointer_ << std::endl;
163                if (this->pointer_)
164                    ++(*this->counter_);
165            }
166
167            T* pointer_;
168            int* counter_;
169            SharedPtrDestroyer* destroyer_;
170    };
171
172    template <class T, class Parent>
173    class SharedChildPtr : public Parent
174    {
175        public:
176            inline SharedChildPtr() : Parent() {}
177            inline SharedChildPtr(T* pointer) : Parent(pointer) {}
178//            inline SharedChildPtr(const SharedChildPtr& other) : Parent(other) {}
179//            template <class O>
180//            inline SharedChildPtr(const SharedChildPtr<O, T>& other) : Parent(other) {}
181            inline SharedChildPtr(const SharedPtr<T>& other) : Parent(other) {}
182
183//            inline const SharedChildPtr& operator=(const SharedChildPtr& other) { Parent::operator=(other); return *this; }
184
185            inline T* operator->() const { return static_cast<T*>(Parent::operator->()); }
186            inline T& operator*() const { return *static_cast<T*>(Parent::operator->()); }
187    };
188
189}
190
191#endif /* _SharedPtr_H__ */
Note: See TracBrowser for help on using the repository browser.