root/library/bdm/shared_ptr.h @ 477

Revision 477, 4.2 kB (checked in by mido, 15 years ago)

panove, vite, jak jsem peclivej na upravu kodu.. snad se vam bude libit:) konfigurace je v souboru /system/astylerc

Line 
1/*!
2  \file
3  \brief BDM's own smart pointer.
4  \author Vaclav Barta.
5
6  -----------------------------------
7  BDM++ - C++ library for Bayesian Decision Making under Uncertainty
8
9  Using IT++ for numerical operations
10  -----------------------------------
11*/
12
13#ifndef shared_ptr_h
14#define shared_ptr_h
15
16#include <limits.h>
17#include <algorithm>
18#include <stdexcept>
19#include <string>
20#include "itpp_ext.h"
21
22namespace bdm {
23
24//! A naive implementation of roughly a subset of the std::tr1:shared_ptr spec (really just roughly - it ignores memory exceptions, for example; also note I didn't read the spec).
25// The standard template would naturally be preferable, _if_ it was
26// included in the standard libraries of all supported compilers - but
27// that's exactly what remains to be seen...
28template <typename T>
29class shared_ptr {
30        template<class U> friend class shared_ptr;
31
32private:
33        T *payload;
34        unsigned *refCnt;
35
36public:
37        //! Creates an empty shared_ptr - one that doesn't point anywhere.
38        shared_ptr() :
39                        payload ( 0 ),
40                        refCnt ( 0 ) {
41        }
42
43        //! Constructs a shared_ptr that owns the pointer p (unless p is
44        //! null, in which case this constructor creates an empty
45        //! shared_ptr).
46        shared_ptr ( T *p ) :
47                        payload ( p ),
48                        refCnt ( p ? new unsigned ( 1 ) : 0 ) {
49        }
50
51        //! If other is empty, constructs an empty shared_ptr; otherwise,
52        //! constructs a shared_ptr that shares ownership with other.
53        shared_ptr ( const shared_ptr<T> &other ) :
54                        payload ( other.payload ),
55                        refCnt ( other.refCnt ) {
56                add_ref();
57        }
58
59        //! If other is empty, constructs an empty shared_ptr; otherwise,
60        //! constructs a shared_ptr that shares ownership with other.
61        template<typename U>
62        shared_ptr ( const shared_ptr<U> &other ) :
63                        payload ( other.payload ),
64                        refCnt ( other.refCnt ) {
65                add_ref();
66        }
67
68        ~shared_ptr() {
69                del_ref();
70        }
71
72        shared_ptr &operator= ( const shared_ptr &other ) {
73                other.add_ref();
74                del_ref();
75
76                payload = other.payload;
77                refCnt = other.refCnt;
78
79                return *this;
80        }
81
82        //! Returns the stored pointer (which remains owned by this
83        //! instance).
84        T *get() {
85                return payload;
86        }
87
88        //! Returns the stored pointer (which remains owned by this
89        //! instance). This method may only be called when the stored
90        //! pointer isn't NULL.
91        T *operator->() {
92                it_assert_debug ( payload, "dereferencing NULL" );
93                return payload;
94        }
95
96        //! Returns a reference to the object pointed to by the stored
97        //! pointer. This method may only be called when the stored pointer
98        //! isn't NULL.
99        T &operator*() {
100                it_assert_debug ( payload, "dereferencing NULL" );
101                return *payload;
102        }
103
104        //! Returns the stored pointer (which remains owned by this
105        //! instance).
106        const T* get() const {
107                return payload;
108        }
109
110        //! Returns the stored pointer (which remains owned by this
111        //! instance). This method may only be called when the stored
112        //! pointer isn't NULL.
113        const T *operator->() const {
114                it_assert_debug ( payload, "dereferencing NULL" );
115                return payload;
116        }
117
118        //! Returns a reference to the object pointed to by the stored
119        //! pointer. This method may only be called when the stored pointer
120        //! isn't NULL.
121        const T &operator*() const {
122                it_assert_debug ( payload, "dereferencing NULL" );
123                return *payload;
124        }
125
126        bool unique() const {
127                return refCnt && ( *refCnt == 1 );
128        }
129
130        long use_count() const {
131                return refCnt ? *refCnt : 0;
132        }
133
134        operator bool() const {
135                return payload;
136        }
137
138        void swap ( shared_ptr &other ) {
139                std::swap ( payload, other.payload );
140                std::swap ( refCnt, other.refCnt );
141        }
142
143private:
144        void add_ref() const {
145                if ( refCnt ) {
146                        if ( *refCnt == UINT_MAX ) {
147                                throw std::overflow_error (
148                                    std::string ( "Shared pointer has too many references." ) );
149                        }
150
151                        ++*refCnt;
152                }
153        }
154
155        void del_ref() {
156                if ( refCnt ) {
157                        if ( ! ( --*refCnt ) ) {
158                                delete payload;
159                                delete refCnt;
160                        }
161                }
162        }
163};
164
165template<typename T, typename U>
166bool operator== ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
167        return a.get() == b.get();
168}
169
170template<typename T, typename U>
171bool operator!= ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
172        return a.get() != b.get();
173}
174
175template<typename T, typename U>
176bool operator< ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
177        return a.get() < b.get();
178}
179
180}
181
182#endif
Note: See TracBrowser for help on using the browser.