Agora RTC Objective-C API Reference Refactor

AgoraRefPtr.h
Go to the documentation of this file.
1
2 // Copyright (c) 2019 Agora.io. All rights reserved
3
4 // This program is confidential and proprietary to Agora.io.
5 // And may not be copied, reproduced, modified, disclosed to others, published
6 // or used, in whole or in part, without the express prior written permission
7 // of Agora.io.
8
9 #pragma once
10
11 #include <memory>
12 #if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))
13 #include <cstddef>
14 #endif
15 #ifndef OPTIONAL_ENUM_CLASS
16 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
17 #define OPTIONAL_ENUM_CLASS enum class
18 #else
19 #define OPTIONAL_ENUM_CLASS enum
20 #endif
21 #endif
22
23 namespace agora {
24
25 OPTIONAL_ENUM_CLASS RefCountReleaseStatus { kDroppedLastRef, kOtherRefsRemained };
26
27 // Interfaces where refcounting is part of the public api should
28 // inherit this abstract interface. The implementation of these
29 // methods is usually provided by the RefCountedObject template class,
30 // applied as a leaf in the inheritance tree.
31 class RefCountInterface {
32 public:
33 virtual void AddRef() const = 0;
34 virtual RefCountReleaseStatus Release() const = 0;
35 virtual bool HasOneRef() const = 0;
36
37 // Non-public destructor, because Release() has exclusive responsibility for
38 // destroying the object.
39 protected:
40 virtual ~RefCountInterface() {}
41 };
42
43 template <class T>
44 class agora_refptr {
45 public:
46 agora_refptr() : ptr_(NULL) {}
47
48 agora_refptr(T* p) : ptr_(p) {
49 if (ptr_) ptr_->AddRef();
50 }
51
52 template<typename U>
53 agora_refptr(U* p) : ptr_(p) {
54 if (ptr_) ptr_->AddRef();
55 }
56
57 agora_refptr(const agora_refptr<T>& r) : ptr_(r.get()) {
58 if (ptr_) ptr_->AddRef();
59 }
60
61 template <typename U>
62 agora_refptr(const agora_refptr<U>& r) : ptr_(r.get()) {
63 if (ptr_) ptr_->AddRef();
64 }
65
66 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
67 agora_refptr(agora_refptr<T>&& r) : ptr_(r.move()) {}
68
69 template <typename U>
70 agora_refptr(agora_refptr<U>&& r) : ptr_(r.move()) {}
71 #endif
72
73 ~agora_refptr() {
74 reset();
75 }
76
77 T* get() const { return ptr_; }
78 operator bool() const { return (ptr_ != NULL); }
79
80 T* operator->() const { return ptr_; }
81 T& operator*() const { return *ptr_; }
82
83 // Returns the (possibly null) raw pointer, and makes the agora_refptr hold a
84 // null pointer, all without touching the reference count of the underlying
85 // pointed-to object. The object is still reference counted, and the caller of
86 // move() is now the proud owner of one reference, so it is responsible for
87 // calling Release() once on the object when no longer using it.
88 T* move() {
89 T* retVal = ptr_;
90 ptr_ = NULL;
91 return retVal;
92 }
93
94 agora_refptr<T>& operator=(T* p) {
95 if (ptr_ == p) return *this;
96
97 if (p) p->AddRef();
98 if (ptr_) ptr_->Release();
99 ptr_ = p;
100 return *this;
101 }
102
103 agora_refptr<T>& operator=(const agora_refptr<T>& r) {
104 return *this = r.get();
105 }
106
107 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
108 agora_refptr<T>& operator=(agora_refptr<T>&& r) {
109 agora_refptr<T>(std::move(r)).swap(*this);
110 return *this;
111 }
112
113 template <typename U>
114 agora_refptr<T>& operator=(agora_refptr<U>&& r) {
115 agora_refptr<T>(std::move(r)).swap(*this);
116 return *this;
117 }
118 #endif
119
120 // For working with std::find()
121 bool operator==(const agora_refptr<T>& r) const { return ptr_ == r.ptr_; }
122
123 // For working with std::set
124 bool operator<(const agora_refptr<T>& r) const { return ptr_ < r.ptr_; }
125
126 void swap(T** pp) {
127 T* p = ptr_;
128 ptr_ = *pp;
129 *pp = p;
130 }
131
132 void swap(agora_refptr<T>& r) { swap(&r.ptr_); }
133
134 void reset() {
135 if (ptr_) {
136 ptr_->Release();
137 ptr_ = NULL;
138 }
139 }
140
141 protected:
142 T* ptr_;
143 };
144
145 } // namespace agora
146
147 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
148 namespace std {
149 template <typename T>
150 struct hash<agora::agora_refptr<T>> {
151 std::size_t operator()(const agora::agora_refptr<T>& k) const {
152 return reinterpret_cast<size_t>(k.get());
153 }
154 };
155 } // namespace std
156 #endif
agora::agora_refptr::agora_refptr
agora_refptr(const agora_refptr< U > &r)
Definition: AgoraRefPtr.h:62
agora::agora_refptr::swap
void swap(agora_refptr< T > &r)
Definition: AgoraRefPtr.h:132
agora::agora_refptr::operator==
bool operator==(const agora_refptr< T > &r) const
Definition: AgoraRefPtr.h:121
agora::agora_refptr
Definition: AgoraRefPtr.h:44
agora::agora_refptr::operator=
agora_refptr< T > & operator=(const agora_refptr< T > &r)
Definition: AgoraRefPtr.h:103
agora::agora_refptr::agora_refptr
agora_refptr(T *p)
Definition: AgoraRefPtr.h:48
agora::agora_refptr::operator<
bool operator<(const agora_refptr< T > &r) const
Definition: AgoraRefPtr.h:124
agora
Definition: AgoraAtomicOps.h:21
agora::agora_refptr::ptr_
T * ptr_
Definition: AgoraRefPtr.h:142
agora::agora_refptr::operator=
agora_refptr< T > & operator=(T *p)
Definition: AgoraRefPtr.h:94
agora::agora_refptr::reset
void reset()
Definition: AgoraRefPtr.h:134
agora::agora_refptr::operator->
T * operator->() const
Definition: AgoraRefPtr.h:80
agora::RefCountInterface::AddRef
virtual void AddRef() const =0
agora::agora_refptr::agora_refptr
agora_refptr()
Definition: AgoraRefPtr.h:46
agora::agora_refptr::operator*
T & operator*() const
Definition: AgoraRefPtr.h:81
agora::RefCountInterface::Release
virtual RefCountReleaseStatus Release() const =0
agora::RefCountInterface::HasOneRef
virtual bool HasOneRef() const =0
agora::agora_refptr::agora_refptr
agora_refptr(const agora_refptr< T > &r)
Definition: AgoraRefPtr.h:57
OPTIONAL_ENUM_CLASS
#define OPTIONAL_ENUM_CLASS
Definition: AgoraRefPtr.h:19
agora::agora_refptr::move
T * move()
Definition: AgoraRefPtr.h:88
agora::RefCountInterface
Definition: AgoraRefPtr.h:31
agora::RefCountReleaseStatus
OPTIONAL_ENUM_CLASS RefCountReleaseStatus
Definition: AgoraRefPtr.h:25
agora::agora_refptr::agora_refptr
agora_refptr(U *p)
Definition: AgoraRefPtr.h:53
agora::agora_refptr::swap
void swap(T **pp)
Definition: AgoraRefPtr.h:126
agora::agora_refptr::~agora_refptr
~agora_refptr()
Definition: AgoraRefPtr.h:73
agora::RefCountInterface::~RefCountInterface
virtual ~RefCountInterface()
Definition: AgoraRefPtr.h:40
agora::agora_refptr::get
T * get() const
Definition: AgoraRefPtr.h:77