]> git.saurik.com Git - apple/icu.git/blob - icuSources/common/sharedobject.h
ICU-531.48.tar.gz
[apple/icu.git] / icuSources / common / sharedobject.h
1 /*
2 ******************************************************************************
3 * Copyright (C) 2014, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 ******************************************************************************
6 * sharedobject.h
7 */
8
9 #ifndef __SHAREDOBJECT_H__
10 #define __SHAREDOBJECT_H__
11
12
13 #include "unicode/uobject.h"
14 #include "umutex.h"
15
16 U_NAMESPACE_BEGIN
17
18 /**
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.
23 *
24 * Either stack-allocate, use LocalPointer, or use addRef()/removeRef().
25 * Sharing requires reference-counting.
26 */
27 class U_COMMON_API SharedObject : public UObject {
28 public:
29 /** Initializes refCount to 0. */
30 SharedObject() : refCount(0) {}
31
32 /** Initializes refCount to 0. */
33 SharedObject(const SharedObject &/*other*/) : refCount(0) {}
34 virtual ~SharedObject();
35
36 /**
37 * Increments the number of references to this object. Thread-safe.
38 */
39 void addRef() const;
40
41 /**
42 * Decrements the number of references to this object,
43 * and auto-deletes "this" if the number becomes 0. Thread-safe.
44 */
45 void removeRef() const;
46
47 /**
48 * Returns the reference counter. Uses a memory barrier.
49 */
50 int32_t getRefCount() const;
51
52 void deleteIfZeroRefCount() const;
53
54 /**
55 * Returns a writable version of ptr.
56 * If there is exactly one owner, then ptr itself is returned as a
57 * non-const pointer.
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.
62 *
63 * T must be a subclass of SharedObject.
64 */
65 template<typename T>
66 static T *copyOnWrite(const T *&ptr) {
67 const T *p = ptr;
68 if(p->getRefCount() <= 1) { return const_cast<T *>(p); }
69 T *p2 = new T(*p);
70 if(p2 == NULL) { return NULL; }
71 p->removeRef();
72 ptr = p2;
73 p2->addRef();
74 return p2;
75 }
76
77 /**
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
81 * own its object.
82 *
83 * T must be a subclass of SharedObject.
84 */
85 template<typename T>
86 static void copyPtr(const T *src, const T *&dest) {
87 if(src != dest) {
88 if(dest != NULL) { dest->removeRef(); }
89 dest = src;
90 if(src != NULL) { src->addRef(); }
91 }
92 }
93
94 /**
95 * Equivalent to copy(NULL, dest).
96 */
97 template<typename T>
98 static void clearPtr(const T *&ptr) {
99 if (ptr != NULL) {
100 ptr->removeRef();
101 ptr = NULL;
102 }
103 }
104
105 private:
106 mutable u_atomic_int32_t refCount;
107 };
108
109 U_NAMESPACE_END
110
111 #endif