rev |
line source |
nuclear@0
|
1
|
nuclear@0
|
2 #ifndef INCLUDED_AI_BOOST_SHARED_ARRAY
|
nuclear@0
|
3 #define INCLUDED_AI_BOOST_SHARED_ARRAY
|
nuclear@0
|
4
|
nuclear@0
|
5 #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
|
nuclear@0
|
6
|
nuclear@0
|
7 // ------------------------------
|
nuclear@0
|
8 // Internal stub
|
nuclear@0
|
9 namespace boost {
|
nuclear@0
|
10 namespace array_detail {
|
nuclear@0
|
11 class controller {
|
nuclear@0
|
12 public:
|
nuclear@0
|
13
|
nuclear@0
|
14 controller()
|
nuclear@0
|
15 : cnt(1)
|
nuclear@0
|
16 {}
|
nuclear@0
|
17
|
nuclear@0
|
18 public:
|
nuclear@0
|
19
|
nuclear@0
|
20 template <typename T>
|
nuclear@0
|
21 controller* decref(T* pt) {
|
nuclear@0
|
22 if (--cnt <= 0) {
|
nuclear@0
|
23 delete this;
|
nuclear@0
|
24 delete[] pt;
|
nuclear@0
|
25 }
|
nuclear@0
|
26 return NULL;
|
nuclear@0
|
27 }
|
nuclear@0
|
28
|
nuclear@0
|
29 controller* incref() {
|
nuclear@0
|
30 ++cnt;
|
nuclear@0
|
31 return this;
|
nuclear@0
|
32 }
|
nuclear@0
|
33
|
nuclear@0
|
34 long get() const {
|
nuclear@0
|
35 return cnt;
|
nuclear@0
|
36 }
|
nuclear@0
|
37
|
nuclear@0
|
38 private:
|
nuclear@0
|
39 long cnt;
|
nuclear@0
|
40 };
|
nuclear@0
|
41
|
nuclear@0
|
42 struct empty {};
|
nuclear@0
|
43
|
nuclear@0
|
44 template <typename DEST, typename SRC>
|
nuclear@0
|
45 struct is_convertible_stub {
|
nuclear@0
|
46
|
nuclear@0
|
47 struct yes {char s[1];};
|
nuclear@0
|
48 struct no {char s[2];};
|
nuclear@0
|
49
|
nuclear@0
|
50 static yes foo(DEST*);
|
nuclear@0
|
51 static no foo(...);
|
nuclear@0
|
52
|
nuclear@0
|
53 enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};
|
nuclear@0
|
54 };
|
nuclear@0
|
55
|
nuclear@0
|
56 template <bool> struct enable_if {};
|
nuclear@0
|
57 template <> struct enable_if<true> {
|
nuclear@0
|
58 typedef empty result;
|
nuclear@0
|
59 };
|
nuclear@0
|
60
|
nuclear@0
|
61 template <typename DEST, typename SRC>
|
nuclear@0
|
62 struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
|
nuclear@0
|
63 };
|
nuclear@0
|
64 }
|
nuclear@0
|
65
|
nuclear@0
|
66 // ------------------------------
|
nuclear@0
|
67 // Small replacement for boost::shared_array, not threadsafe because no
|
nuclear@0
|
68 // atomic reference counter is in use.
|
nuclear@0
|
69 // ------------------------------
|
nuclear@0
|
70 template <class T>
|
nuclear@0
|
71 class shared_array
|
nuclear@0
|
72 {
|
nuclear@0
|
73 template <typename TT> friend class shared_array;
|
nuclear@0
|
74
|
nuclear@0
|
75 template<class TT> friend bool operator== (const shared_array<TT>& a, const shared_array<TT>& b);
|
nuclear@0
|
76 template<class TT> friend bool operator!= (const shared_array<TT>& a, const shared_array<TT>& b);
|
nuclear@0
|
77 template<class TT> friend bool operator< (const shared_array<TT>& a, const shared_array<TT>& b);
|
nuclear@0
|
78
|
nuclear@0
|
79 public:
|
nuclear@0
|
80
|
nuclear@0
|
81 typedef T element_type;
|
nuclear@0
|
82
|
nuclear@0
|
83 public:
|
nuclear@0
|
84
|
nuclear@0
|
85 // provide a default constructor
|
nuclear@0
|
86 shared_array()
|
nuclear@0
|
87 : ptr()
|
nuclear@0
|
88 , ctr(NULL)
|
nuclear@0
|
89 {
|
nuclear@0
|
90 }
|
nuclear@0
|
91
|
nuclear@0
|
92 // construction from an existing object of type T
|
nuclear@0
|
93 explicit shared_array(T* ptr)
|
nuclear@0
|
94 : ptr(ptr)
|
nuclear@0
|
95 , ctr(ptr ? new array_detail::controller() : NULL)
|
nuclear@0
|
96 {
|
nuclear@0
|
97 }
|
nuclear@0
|
98
|
nuclear@0
|
99 shared_array(const shared_array& r)
|
nuclear@0
|
100 : ptr(r.ptr)
|
nuclear@0
|
101 , ctr(r.ctr ? r.ctr->incref() : NULL)
|
nuclear@0
|
102 {
|
nuclear@0
|
103 }
|
nuclear@0
|
104
|
nuclear@0
|
105 template <typename Y>
|
nuclear@0
|
106 shared_array(const shared_array<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
|
nuclear@0
|
107 : ptr(r.ptr)
|
nuclear@0
|
108 , ctr(r.ctr ? r.ctr->incref() : NULL)
|
nuclear@0
|
109 {
|
nuclear@0
|
110 }
|
nuclear@0
|
111
|
nuclear@0
|
112 // automatic destruction of the wrapped object when all
|
nuclear@0
|
113 // references are freed.
|
nuclear@0
|
114 ~shared_array() {
|
nuclear@0
|
115 if (ctr) {
|
nuclear@0
|
116 ctr = ctr->decref(ptr);
|
nuclear@0
|
117 }
|
nuclear@0
|
118 }
|
nuclear@0
|
119
|
nuclear@0
|
120 shared_array& operator=(const shared_array& r) {
|
nuclear@0
|
121 if (this == &r) {
|
nuclear@0
|
122 return *this;
|
nuclear@0
|
123 }
|
nuclear@0
|
124 if (ctr) {
|
nuclear@0
|
125 ctr->decref(ptr);
|
nuclear@0
|
126 }
|
nuclear@0
|
127 ptr = r.ptr;
|
nuclear@0
|
128 ctr = ptr?r.ctr->incref():NULL;
|
nuclear@0
|
129 return *this;
|
nuclear@0
|
130 }
|
nuclear@0
|
131
|
nuclear@0
|
132 template <typename Y>
|
nuclear@0
|
133 shared_array& operator=(const shared_array<Y>& r) {
|
nuclear@0
|
134 if (this == &r) {
|
nuclear@0
|
135 return *this;
|
nuclear@0
|
136 }
|
nuclear@0
|
137 if (ctr) {
|
nuclear@0
|
138 ctr->decref(ptr);
|
nuclear@0
|
139 }
|
nuclear@0
|
140 ptr = r.ptr;
|
nuclear@0
|
141 ctr = ptr?r.ctr->incref():NULL;
|
nuclear@0
|
142 return *this;
|
nuclear@0
|
143 }
|
nuclear@0
|
144
|
nuclear@0
|
145 // pointer access
|
nuclear@0
|
146 inline operator T*() {
|
nuclear@0
|
147 return ptr;
|
nuclear@0
|
148 }
|
nuclear@0
|
149
|
nuclear@0
|
150 inline T* operator-> () const {
|
nuclear@0
|
151 return ptr;
|
nuclear@0
|
152 }
|
nuclear@0
|
153
|
nuclear@0
|
154 // standard semantics
|
nuclear@0
|
155 inline T* get() {
|
nuclear@0
|
156 return ptr;
|
nuclear@0
|
157 }
|
nuclear@0
|
158
|
nuclear@0
|
159 T& operator[] (std::ptrdiff_t index) const {
|
nuclear@0
|
160 return ptr[index];
|
nuclear@0
|
161 }
|
nuclear@0
|
162
|
nuclear@0
|
163 inline const T* get() const {
|
nuclear@0
|
164 return ptr;
|
nuclear@0
|
165 }
|
nuclear@0
|
166
|
nuclear@0
|
167 inline operator bool () const {
|
nuclear@0
|
168 return ptr != NULL;
|
nuclear@0
|
169 }
|
nuclear@0
|
170
|
nuclear@0
|
171 inline bool unique() const {
|
nuclear@0
|
172 return use_count() == 1;
|
nuclear@0
|
173 }
|
nuclear@0
|
174
|
nuclear@0
|
175 inline long use_count() const {
|
nuclear@0
|
176 return ctr->get();
|
nuclear@0
|
177 }
|
nuclear@0
|
178
|
nuclear@0
|
179 inline void reset (T* t = 0) {
|
nuclear@0
|
180 if (ctr) {
|
nuclear@0
|
181 ctr->decref(ptr);
|
nuclear@0
|
182 }
|
nuclear@0
|
183 ptr = t;
|
nuclear@0
|
184 ctr = ptr?new array_detail::controller():NULL;
|
nuclear@0
|
185 }
|
nuclear@0
|
186
|
nuclear@0
|
187 void swap(shared_array & b) {
|
nuclear@0
|
188 std::swap(ptr, b.ptr);
|
nuclear@0
|
189 std::swap(ctr, b.ctr);
|
nuclear@0
|
190 }
|
nuclear@0
|
191
|
nuclear@0
|
192
|
nuclear@0
|
193 private:
|
nuclear@0
|
194
|
nuclear@0
|
195 // encapsulated object pointer
|
nuclear@0
|
196 T* ptr;
|
nuclear@0
|
197
|
nuclear@0
|
198 // control block
|
nuclear@0
|
199 array_detail::controller* ctr;
|
nuclear@0
|
200 };
|
nuclear@0
|
201
|
nuclear@0
|
202 template<class T>
|
nuclear@0
|
203 inline void swap(shared_array<T> & a, shared_array<T> & b)
|
nuclear@0
|
204 {
|
nuclear@0
|
205 a.swap(b);
|
nuclear@0
|
206 }
|
nuclear@0
|
207
|
nuclear@0
|
208 template<class T>
|
nuclear@0
|
209 bool operator== (const shared_array<T>& a, const shared_array<T>& b) {
|
nuclear@0
|
210 return a.ptr == b.ptr;
|
nuclear@0
|
211 }
|
nuclear@0
|
212 template<class T>
|
nuclear@0
|
213 bool operator!= (const shared_array<T>& a, const shared_array<T>& b) {
|
nuclear@0
|
214 return a.ptr != b.ptr;
|
nuclear@0
|
215 }
|
nuclear@0
|
216
|
nuclear@0
|
217 template<class T>
|
nuclear@0
|
218 bool operator< (const shared_array<T>& a, const shared_array<T>& b) {
|
nuclear@0
|
219 return a.ptr < b.ptr;
|
nuclear@0
|
220 }
|
nuclear@0
|
221
|
nuclear@0
|
222
|
nuclear@0
|
223 } // end of namespace boost
|
nuclear@0
|
224
|
nuclear@0
|
225 #else
|
nuclear@0
|
226 # error "shared_array.h was already included"
|
nuclear@0
|
227 #endif
|
nuclear@0
|
228 #endif // INCLUDED_AI_BOOST_SHARED_ARRAY
|