Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/util/SharedPtr.h @ 7264

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

Added new utility SmallObjectAllocator.
Merged counter and destroyer in SharedPtr and allocate them with SmallObjectAllocator

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