diff options
Diffstat (limited to 'linden/indra/llcommon/llmemory.h')
-rw-r--r-- | linden/indra/llcommon/llmemory.h | 90 |
1 files changed, 44 insertions, 46 deletions
diff --git a/linden/indra/llcommon/llmemory.h b/linden/indra/llcommon/llmemory.h index 7a7996b..b6f42e3 100644 --- a/linden/indra/llcommon/llmemory.h +++ b/linden/indra/llcommon/llmemory.h | |||
@@ -4,6 +4,7 @@ | |||
4 | * | 4 | * |
5 | * Copyright (c) 2002-2007, Linden Research, Inc. | 5 | * Copyright (c) 2002-2007, Linden Research, Inc. |
6 | * | 6 | * |
7 | * Second Life Viewer Source Code | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | 8 | * The source code in this file ("Source Code") is provided by Linden Lab |
8 | * to you under the terms of the GNU General Public License, version 2.0 | 9 | * to you under the terms of the GNU General Public License, version 2.0 |
9 | * ("GPL"), unless you have obtained a separate licensing agreement | 10 | * ("GPL"), unless you have obtained a separate licensing agreement |
@@ -193,6 +194,14 @@ public: | |||
193 | } | 194 | } |
194 | return *this; | 195 | return *this; |
195 | } | 196 | } |
197 | |||
198 | // Just exchange the pointers, which will not change the reference counts. | ||
199 | static void swap(LLPointer<Type>& a, LLPointer<Type>& b) | ||
200 | { | ||
201 | Type* temp = a.mPointer; | ||
202 | a.mPointer = b.mPointer; | ||
203 | b.mPointer = temp; | ||
204 | } | ||
196 | 205 | ||
197 | protected: | 206 | protected: |
198 | void ref() | 207 | void ref() |
@@ -239,29 +248,28 @@ class LLHandle | |||
239 | { | 248 | { |
240 | public: | 249 | public: |
241 | LLHandle() : | 250 | LLHandle() : |
242 | mPointer(sNullFunc()) | 251 | mPointer(NULL) |
243 | { | 252 | { |
244 | ref(); | ||
245 | } | 253 | } |
246 | 254 | ||
247 | LLHandle(Type* ptr) : | 255 | LLHandle(Type* ptr) : |
248 | mPointer(nonNull(ptr)) | 256 | mPointer(NULL) |
249 | { | 257 | { |
250 | ref(); | 258 | assign(ptr); |
251 | } | 259 | } |
252 | 260 | ||
253 | LLHandle(const LLHandle<Type>& ptr) : | 261 | LLHandle(const LLHandle<Type>& ptr) : |
254 | mPointer(ptr.mPointer) | 262 | mPointer(NULL) |
255 | { | 263 | { |
256 | ref(); | 264 | assign(ptr.mPointer); |
257 | } | 265 | } |
258 | 266 | ||
259 | // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed. | 267 | // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed. |
260 | template<typename Subclass> | 268 | template<typename Subclass> |
261 | LLHandle(const LLHandle<Subclass>& ptr) : | 269 | LLHandle(const LLHandle<Subclass>& ptr) : |
262 | mPointer(ptr.get()) | 270 | mPointer(NULL) |
263 | { | 271 | { |
264 | ref(); | 272 | assign(ptr.get()); |
265 | } | 273 | } |
266 | 274 | ||
267 | ~LLHandle() | 275 | ~LLHandle() |
@@ -269,47 +277,39 @@ public: | |||
269 | unref(); | 277 | unref(); |
270 | } | 278 | } |
271 | 279 | ||
280 | const Type* operator->() const { return nonNull(mPointer); } | ||
281 | Type* operator->() { return nonNull(mPointer); } | ||
282 | |||
272 | Type* get() const { return mPointer; } | 283 | Type* get() const { return mPointer; } |
273 | const Type* operator->() const { return mPointer; } | 284 | // we disallow these operations as they expose our null objects to direct manipulation |
274 | Type* operator->() { return mPointer; } | 285 | // and bypass the reference counting semantics |
275 | const Type& operator*() const { return *mPointer; } | 286 | //const Type& operator*() const { return *nonNull(mPointer); } |
276 | Type& operator*() { return *mPointer; } | 287 | //Type& operator*() { return *nonNull(mPointer); } |
277 | 288 | ||
278 | operator BOOL() const { return (mPointer != sNullFunc()); } | 289 | operator BOOL() const { return mPointer != NULL; } |
279 | operator bool() const { return (mPointer != sNullFunc()); } | 290 | operator bool() const { return mPointer != NULL; } |
280 | bool operator!() const { return (mPointer == sNullFunc()); } | 291 | bool operator!() const { return mPointer == NULL; } |
281 | bool isNull() const { return (mPointer == sNullFunc()); } | 292 | bool isNull() const { return mPointer == NULL; } |
282 | bool notNull() const { return (mPointer != sNullFunc()); } | 293 | bool notNull() const { return mPointer != NULL; } |
283 | 294 | ||
284 | 295 | ||
285 | operator Type*() const { return mPointer; } | 296 | operator Type*() const { return mPointer; } |
286 | operator const Type*() const { return mPointer; } | 297 | operator const Type*() const { return mPointer; } |
287 | bool operator !=(Type* ptr) const { return (mPointer != nonNull(ptr)); } | 298 | bool operator !=(Type* ptr) const { return (mPointer != ptr); } |
288 | bool operator ==(Type* ptr) const { return (mPointer == nonNull(ptr)); } | 299 | bool operator ==(Type* ptr) const { return (mPointer == ptr); } |
289 | bool operator ==(const LLHandle<Type>& ptr) const { return (mPointer == ptr.mPointer); } | 300 | bool operator ==(const LLHandle<Type>& ptr) const { return (mPointer == ptr.mPointer); } |
290 | bool operator < (const LLHandle<Type>& ptr) const { return (mPointer < ptr.mPointer); } | 301 | bool operator < (const LLHandle<Type>& ptr) const { return (mPointer < ptr.mPointer); } |
291 | bool operator > (const LLHandle<Type>& ptr) const { return (mPointer > ptr.mPointer); } | 302 | bool operator > (const LLHandle<Type>& ptr) const { return (mPointer > ptr.mPointer); } |
292 | 303 | ||
293 | LLHandle<Type>& operator =(Type* ptr) | 304 | LLHandle<Type>& operator =(Type* ptr) |
294 | { | 305 | { |
295 | if( mPointer != ptr ) | 306 | assign(ptr); |
296 | { | ||
297 | unref(); | ||
298 | mPointer = nonNull(ptr); | ||
299 | ref(); | ||
300 | } | ||
301 | |||
302 | return *this; | 307 | return *this; |
303 | } | 308 | } |
304 | 309 | ||
305 | LLHandle<Type>& operator =(const LLHandle<Type>& ptr) | 310 | LLHandle<Type>& operator =(const LLHandle<Type>& ptr) |
306 | { | 311 | { |
307 | if( mPointer != ptr.mPointer ) | 312 | assign(ptr.mPointer); |
308 | { | ||
309 | unref(); | ||
310 | mPointer = ptr.mPointer; | ||
311 | ref(); | ||
312 | } | ||
313 | return *this; | 313 | return *this; |
314 | } | 314 | } |
315 | 315 | ||
@@ -317,12 +317,7 @@ public: | |||
317 | template<typename Subclass> | 317 | template<typename Subclass> |
318 | LLHandle<Type>& operator =(const LLHandle<Subclass>& ptr) | 318 | LLHandle<Type>& operator =(const LLHandle<Subclass>& ptr) |
319 | { | 319 | { |
320 | if( mPointer != ptr.get() ) | 320 | assign(ptr.get()); |
321 | { | ||
322 | unref(); | ||
323 | mPointer = ptr.get(); | ||
324 | ref(); | ||
325 | } | ||
326 | return *this; | 321 | return *this; |
327 | } | 322 | } |
328 | 323 | ||
@@ -344,9 +339,9 @@ protected: | |||
344 | if (mPointer) | 339 | if (mPointer) |
345 | { | 340 | { |
346 | Type *tempp = mPointer; | 341 | Type *tempp = mPointer; |
347 | mPointer = sNullFunc(); | 342 | mPointer = NULL; |
348 | tempp->unref(); | 343 | tempp->unref(); |
349 | if (mPointer != sNullFunc()) | 344 | if (mPointer != NULL) |
350 | { | 345 | { |
351 | llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl; | 346 | llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl; |
352 | unref(); | 347 | unref(); |
@@ -354,19 +349,22 @@ protected: | |||
354 | } | 349 | } |
355 | } | 350 | } |
356 | 351 | ||
357 | static Type* nonNull(Type* ptr) | 352 | void assign(Type* ptr) |
358 | { | 353 | { |
359 | return ptr == NULL ? sNullFunc() : ptr; | 354 | if( mPointer != ptr ) |
355 | { | ||
356 | unref(); | ||
357 | mPointer = ptr; | ||
358 | ref(); | ||
359 | } | ||
360 | } | 360 | } |
361 | 361 | ||
362 | static Type* defaultNullFunc() | 362 | static Type* nonNull(Type* ptr) |
363 | { | 363 | { |
364 | llerrs << "No null value provided for LLHandle" << llendl; | 364 | return ptr == NULL ? sNullFunc() : ptr; |
365 | return NULL; | ||
366 | } | 365 | } |
367 | 366 | ||
368 | protected: | 367 | protected: |
369 | |||
370 | Type* mPointer; | 368 | Type* mPointer; |
371 | }; | 369 | }; |
372 | 370 | ||