root/library/bdm/shared_ptr.h @ 536

Revision 536, 5.5 kB (checked in by smidl, 15 years ago)

removal of unused functions _e() and samplecond(,) and added documentation lines

Line 
1/*!
2  \file
3  \brief BDM's own smart pointers.
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/*! \brief A naive implementation of roughly a subset of the std::tr1:shared_ptr spec
25
26  Really just roughly - it ignores memory
27  exceptions, for example; also note I didn't read the spec.
28
29  The standard template would naturally be preferable, _if_ it was
30  included in the standard libraries of all supported compilers - but
31  as of 2009, that's still a problem...
32*/
33template <typename T>
34class shared_ptr {
35        template<class U> friend class shared_ptr;
36
37private:
38        T *payload;
39        unsigned *refCnt;
40
41public:
42        //! Creates an empty shared_ptr - one that doesn't point anywhere.
43        shared_ptr() :
44                        payload ( 0 ),
45                        refCnt ( 0 ) {
46        }
47
48        /*!
49          Constructs a shared_ptr that owns the pointer p (unless p
50          is NULL, in which case this constructor creates an empty
51          shared_ptr). When p isn't null, it must have been alllocated
52          by new!
53        */
54        shared_ptr ( T *p ) :
55                        payload ( p ),
56                        refCnt ( p ? new unsigned ( 1 ) : 0 ) {
57        }
58
59        //! If other is empty, constructs an empty shared_ptr; otherwise,
60        //! constructs a shared_ptr that shares ownership with other.
61        shared_ptr ( const shared_ptr<T> &other ) :
62                        payload ( other.payload ),
63                        refCnt ( other.refCnt ) {
64                add_ref();
65        }
66
67        //! If other is empty, constructs an empty shared_ptr; otherwise,
68        //! constructs a shared_ptr that shares ownership with other.
69        template<typename U>
70        shared_ptr ( const shared_ptr<U> &other ) :
71                        payload ( other.payload ),
72                        refCnt ( other.refCnt ) {
73                add_ref();
74        }
75
76        ~shared_ptr() {
77                del_ref();
78        }
79
80        shared_ptr<T> &operator= ( const shared_ptr<T> &other ) {
81                other.add_ref();
82                del_ref();
83
84                payload = other.payload;
85                refCnt = other.refCnt;
86
87                return *this;
88        }
89
90        //! Returns the stored pointer (which remains owned by this
91        //! instance).
92        T *get() {
93                return payload;
94        }
95
96        //! Returns the stored pointer (which remains owned by this
97        //! instance). This method may only be called when the stored
98        //! pointer isn't NULL.
99        T *operator->() {
100                it_assert_debug ( payload, "dereferencing NULL" );
101                return payload;
102        }
103
104        //! Returns a reference to the object pointed to by the stored
105        //! pointer. This method may only be called when the stored pointer
106        //! isn't NULL.
107        T &operator*() {
108                it_assert_debug ( payload, "dereferencing NULL" );
109                return *payload;
110        }
111
112        //! Returns the stored pointer (which remains owned by this
113        //! instance).
114        const T* get() const {
115                return payload;
116        }
117
118        //! Returns the stored pointer (which remains owned by this
119        //! instance). This method may only be called when the stored
120        //! pointer isn't NULL.
121        const T *operator->() const {
122                it_assert_debug ( payload, "dereferencing NULL" );
123                return payload;
124        }
125
126        //! Returns a reference to the object pointed to by the stored
127        //! pointer. This method may only be called when the stored pointer
128        //! isn't NULL.
129        const T &operator*() const {
130                it_assert_debug ( payload, "dereferencing NULL" );
131                return *payload;
132        }
133
134        bool unique() const {
135                return refCnt && ( *refCnt == 1 );
136        }
137
138        long use_count() const {
139                return refCnt ? *refCnt : 0;
140        }
141
142        operator bool() const {
143                return payload;
144        }
145
146        void swap ( shared_ptr &other ) {
147                std::swap ( payload, other.payload );
148                std::swap ( refCnt, other.refCnt );
149        }
150
151private:
152        void add_ref() const {
153                if ( refCnt ) {
154                        if ( *refCnt == UINT_MAX ) {
155                                throw std::overflow_error (
156                                    std::string ( "Shared pointer has too many references." ) );
157                        }
158
159                        ++*refCnt;
160                }
161        }
162
163        void del_ref() {
164                if ( refCnt ) {
165                        if ( ! ( --*refCnt ) ) {
166                                delete payload;
167                                delete refCnt;
168                        }
169                }
170        }
171};
172
173//! Compare shared pointers
174template<typename T, typename U>
175bool operator== ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
176        return a.get() == b.get();
177}
178
179//! Compare shared pointers
180template<typename T, typename U>
181bool operator!= ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
182        return a.get() != b.get();
183}
184
185//! Compare shared pointers
186template<typename T, typename U>
187bool operator< ( shared_ptr<T> const &a, shared_ptr<U> const &b ) {
188        return a.get() < b.get();
189}
190
191/*! \brief A wrapper of shared_ptr which is never empty.
192
193  T must have a default constructor.
194
195  Note that shared_ptr's destructor isn't virtual - don't call delete
196  on pointers to instances of this class.
197 */
198template <typename T>
199class object_ptr : public shared_ptr<T>
200{
201public:
202        /*!
203          \brief Default constructor
204
205          Calls T's default constructor.
206        */
207        object_ptr() : shared_ptr<T> ( new T() ) { }
208
209        /*!
210          \brief Upcast from shared_ptr<T> to object_ptr<T>
211
212          \param b The shared pointer, which must not be empty.
213        */
214        object_ptr ( const shared_ptr<T> &b ) : shared_ptr<T> ( b ) {
215                it_assert_debug ( this->get(), "object_ptr cannot be empty" );
216        }
217
218        /*!
219          Constructs an object_ptr that owns the pointer p. p must
220          have been alllocated by new!
221        */
222        object_ptr ( T *p ) : shared_ptr<T> ( p ) {
223                it_assert_debug ( p, "object_ptr cannot be empty" );
224        }
225
226        object_ptr<T> &operator= ( const object_ptr<T> &other ) {
227                shared_ptr<T>::operator= ( other );
228                return *this;
229        }
230};
231
232#define SHAREDPTR(class_name) typedef bdm::object_ptr< class_name > class_name##_ptr
233
234#define SHAREDPTR2(template_class_name, template_parameter_name) typedef bdm::object_ptr< template_class_name < template_parameter_name > > template_class_name##_##template_parameter_name##_ptr
235
236}
237
238#endif
Note: See TracBrowser for help on using the browser.