vrshoot

view libs/assimp/boost/shared_array.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_ARRAY
3 #define INCLUDED_AI_BOOST_SHARED_ARRAY
5 #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
7 // ------------------------------
8 // Internal stub
9 namespace boost {
10 namespace array_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_array, not threadsafe because no
68 // atomic reference counter is in use.
69 // ------------------------------
70 template <class T>
71 class shared_array
72 {
73 template <typename TT> friend class shared_array;
75 template<class TT> friend bool operator== (const shared_array<TT>& a, const shared_array<TT>& b);
76 template<class TT> friend bool operator!= (const shared_array<TT>& a, const shared_array<TT>& b);
77 template<class TT> friend bool operator< (const shared_array<TT>& a, const shared_array<TT>& b);
79 public:
81 typedef T element_type;
83 public:
85 // provide a default constructor
86 shared_array()
87 : ptr()
88 , ctr(NULL)
89 {
90 }
92 // construction from an existing object of type T
93 explicit shared_array(T* ptr)
94 : ptr(ptr)
95 , ctr(ptr ? new array_detail::controller() : NULL)
96 {
97 }
99 shared_array(const shared_array& r)
100 : ptr(r.ptr)
101 , ctr(r.ctr ? r.ctr->incref() : NULL)
102 {
103 }
105 template <typename Y>
106 shared_array(const shared_array<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
107 : ptr(r.ptr)
108 , ctr(r.ctr ? r.ctr->incref() : NULL)
109 {
110 }
112 // automatic destruction of the wrapped object when all
113 // references are freed.
114 ~shared_array() {
115 if (ctr) {
116 ctr = ctr->decref(ptr);
117 }
118 }
120 shared_array& operator=(const shared_array& r) {
121 if (this == &r) {
122 return *this;
123 }
124 if (ctr) {
125 ctr->decref(ptr);
126 }
127 ptr = r.ptr;
128 ctr = ptr?r.ctr->incref():NULL;
129 return *this;
130 }
132 template <typename Y>
133 shared_array& operator=(const shared_array<Y>& r) {
134 if (this == &r) {
135 return *this;
136 }
137 if (ctr) {
138 ctr->decref(ptr);
139 }
140 ptr = r.ptr;
141 ctr = ptr?r.ctr->incref():NULL;
142 return *this;
143 }
145 // pointer access
146 inline operator T*() {
147 return ptr;
148 }
150 inline T* operator-> () const {
151 return ptr;
152 }
154 // standard semantics
155 inline T* get() {
156 return ptr;
157 }
159 T& operator[] (std::ptrdiff_t index) const {
160 return ptr[index];
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 array_detail::controller():NULL;
185 }
187 void swap(shared_array & b) {
188 std::swap(ptr, b.ptr);
189 std::swap(ctr, b.ctr);
190 }
193 private:
195 // encapsulated object pointer
196 T* ptr;
198 // control block
199 array_detail::controller* ctr;
200 };
202 template<class T>
203 inline void swap(shared_array<T> & a, shared_array<T> & b)
204 {
205 a.swap(b);
206 }
208 template<class T>
209 bool operator== (const shared_array<T>& a, const shared_array<T>& b) {
210 return a.ptr == b.ptr;
211 }
212 template<class T>
213 bool operator!= (const shared_array<T>& a, const shared_array<T>& b) {
214 return a.ptr != b.ptr;
215 }
217 template<class T>
218 bool operator< (const shared_array<T>& a, const shared_array<T>& b) {
219 return a.ptr < b.ptr;
220 }
223 } // end of namespace boost
225 #else
226 # error "shared_array.h was already included"
227 #endif
228 #endif // INCLUDED_AI_BOOST_SHARED_ARRAY