Agora Java API Reference for Android
AgoraRefPtr.h
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.
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
Definition: AgoraRefPtr.h:44
agora::RefCountInterface
Definition: AgoraRefPtr.h:31