vrshoot

view libs/assimp/boost/shared_ptr.hpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
2 #ifndef INCLUDED_AI_BOOST_SHARED_PTR
3 #define INCLUDED_AI_BOOST_SHARED_PTR
5 #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
7 // ------------------------------
8 // Internal stub
9 namespace boost {
10 namespace detail {
11 class controller {
12 public:
14 controller()
15 : cnt(1)
16 {}
18 public:
20 template <typename T>
21 controller* decref(T* pt) {
22 if (--cnt <= 0) {
23 delete this;
24 delete pt;
25 }
26 return NULL;
27 }
29 controller* incref() {
30 ++cnt;
31 return this;
32 }
34 long get() const {
35 return cnt;
36 }
38 private:
39 long cnt;
40 };
42 struct empty {};
44 template <typename DEST, typename SRC>
45 struct is_convertible_stub {
47 struct yes {char s[1];};
48 struct no {char s[2];};
50 static yes foo(DEST*);
51 static no foo(...);
53 enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};
54 };
56 template <bool> struct enable_if {};
57 template <> struct enable_if<true> {
58 typedef empty result;
59 };
61 template <typename DEST, typename SRC>
62 struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
63 };
64 }
66 // ------------------------------
67 // Small replacement for boost::shared_ptr, not threadsafe because no
68 // atomic reference counter is in use.
69 // ------------------------------
70 template <class T>
71 class shared_ptr
72 {
73 template <typename TT> friend class shared_ptr;
75 template<class TT, class U> friend shared_ptr<TT> static_pointer_cast (shared_ptr<U> ptr);
76 template<class TT, class U> friend shared_ptr<TT> dynamic_pointer_cast (shared_ptr<U> ptr);
77 template<class TT, class U> friend shared_ptr<TT> const_pointer_cast (shared_ptr<U> ptr);
79 template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
80 template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
81 template<class TT> friend bool operator< (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
83 public:
85 typedef T element_type;
87 public:
89 // provide a default constructor
90 shared_ptr()
91 : ptr()
92 , ctr(NULL)
93 {
94 }
96 // construction from an existing object of type T
97 explicit shared_ptr(T* ptr)
98 : ptr(ptr)
99 , ctr(ptr ? new detail::controller() : NULL)
100 {
101 }
103 shared_ptr(const shared_ptr& r)
104 : ptr(r.ptr)
105 , ctr(r.ctr ? r.ctr->incref() : NULL)
106 {
107 }
109 template <typename Y>
110 shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
111 : ptr(r.ptr)
112 , ctr(r.ctr ? r.ctr->incref() : NULL)
113 {
114 }
116 // automatic destruction of the wrapped object when all
117 // references are freed.
118 ~shared_ptr() {
119 if (ctr) {
120 ctr = ctr->decref(ptr);
121 }
122 }
124 shared_ptr& operator=(const shared_ptr& r) {
125 if (this == &r) {
126 return *this;
127 }
128 if (ctr) {
129 ctr->decref(ptr);
130 }
131 ptr = r.ptr;
132 ctr = ptr?r.ctr->incref():NULL;
133 return *this;
134 }
136 template <typename Y>
137 shared_ptr& operator=(const shared_ptr<Y>& r) {
138 if (this == &r) {
139 return *this;
140 }
141 if (ctr) {
142 ctr->decref(ptr);
143 }
144 ptr = r.ptr;
145 ctr = ptr?r.ctr->incref():NULL;
146 return *this;
147 }
149 // pointer access
150 inline operator T*() const {
151 return ptr;
152 }
154 inline T* operator-> () const {
155 return ptr;
156 }
158 // standard semantics
159 inline T* get() {
160 return ptr;
161 }
163 inline const T* get() const {
164 return ptr;
165 }
167 inline operator bool () const {
168 return ptr != NULL;
169 }
171 inline bool unique() const {
172 return use_count() == 1;
173 }
175 inline long use_count() const {
176 return ctr->get();
177 }
179 inline void reset (T* t = 0) {
180 if (ctr) {
181 ctr->decref(ptr);
182 }
183 ptr = t;
184 ctr = ptr?new detail::controller():NULL;
185 }
187 void swap(shared_ptr & b) {
188 std::swap(ptr, b.ptr);
189 std::swap(ctr, b.ctr);
190 }
192 private:
195 // for use by the various xxx_pointer_cast helper templates
196 explicit shared_ptr(T* ptr, detail::controller* ctr)
197 : ptr(ptr)
198 , ctr(ctr->incref())
199 {
200 }
202 private:
204 // encapsulated object pointer
205 T* ptr;
207 // control block
208 detail::controller* ctr;
209 };
211 template<class T>
212 inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
213 {
214 a.swap(b);
215 }
217 template<class T>
218 bool operator== (const shared_ptr<T>& a, const shared_ptr<T>& b) {
219 return a.ptr == b.ptr;
220 }
221 template<class T>
222 bool operator!= (const shared_ptr<T>& a, const shared_ptr<T>& b) {
223 return a.ptr != b.ptr;
224 }
226 template<class T>
227 bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) {
228 return a.ptr < b.ptr;
229 }
232 template<class T, class U>
233 inline shared_ptr<T> static_pointer_cast( shared_ptr<U> ptr)
234 {
235 return shared_ptr<T>(static_cast<T*>(ptr.ptr),ptr.ctr);
236 }
238 template<class T, class U>
239 inline shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> ptr)
240 {
241 return shared_ptr<T>(dynamic_cast<T*>(ptr.ptr),ptr.ctr);
242 }
244 template<class T, class U>
245 inline shared_ptr<T> const_pointer_cast( shared_ptr<U> ptr)
246 {
247 return shared_ptr<T>(const_cast<T*>(ptr.ptr),ptr.ctr);
248 }
252 } // end of namespace boost
254 #else
255 # error "shared_ptr.h was already included"
256 #endif
257 #endif // INCLUDED_AI_BOOST_SCOPED_PTR