2 ******************************************************************************
3 * Copyright (C) 2014, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 ******************************************************************************
9 #ifndef __SHAREDOBJECT_H__
10 #define __SHAREDOBJECT_H__
13 #include "unicode/uobject.h"
19 * Base class for shared, reference-counted, auto-deleted objects.
20 * Subclasses can be immutable.
21 * If they are mutable, then they must implement their copy constructor
22 * so that copyOnWrite() works.
24 * Either stack-allocate, use LocalPointer, or use addRef()/removeRef().
25 * Sharing requires reference-counting.
27 class U_COMMON_API SharedObject
: public UObject
{
29 /** Initializes refCount to 0. */
30 SharedObject() : refCount(0) {}
32 /** Initializes refCount to 0. */
33 SharedObject(const SharedObject
&/*other*/) : refCount(0) {}
34 virtual ~SharedObject();
37 * Increments the number of references to this object. Thread-safe.
42 * Decrements the number of references to this object,
43 * and auto-deletes "this" if the number becomes 0. Thread-safe.
45 void removeRef() const;
48 * Returns the reference counter. Uses a memory barrier.
50 int32_t getRefCount() const;
52 void deleteIfZeroRefCount() const;
55 * Returns a writable version of ptr.
56 * If there is exactly one owner, then ptr itself is returned as a
58 * If there are multiple owners, then ptr is replaced with a
59 * copy-constructed clone,
60 * and that is returned.
61 * Returns NULL if cloning failed.
63 * T must be a subclass of SharedObject.
66 static T
*copyOnWrite(const T
*&ptr
) {
68 if(p
->getRefCount() <= 1) { return const_cast<T
*>(p
); }
70 if(p2
== NULL
) { return NULL
; }
78 * Makes dest an owner of the object pointed to by src while adjusting
79 * reference counts and deleting the previous object dest pointed to
80 * if necessary. Before this call is made, dest must either be NULL or
83 * T must be a subclass of SharedObject.
86 static void copyPtr(const T
*src
, const T
*&dest
) {
88 if(dest
!= NULL
) { dest
->removeRef(); }
90 if(src
!= NULL
) { src
->addRef(); }
95 * Equivalent to copy(NULL, dest).
98 static void clearPtr(const T
*&ptr
) {
106 mutable u_atomic_int32_t refCount
;