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 
13 namespace agora {
14 
15 enum class RefCountReleaseStatus { kDroppedLastRef, kOtherRefsRemained };
16 
17 // Interfaces where refcounting is part of the public api should
18 // inherit this abstract interface. The implementation of these
19 // methods is usually provided by the RefCountedObject template class,
20 // applied as a leaf in the inheritance tree.
22  public:
23  virtual void AddRef() const = 0;
24  virtual RefCountReleaseStatus Release() const = 0;
25  virtual bool HasOneRef() const = 0;
26 
27  // Non-public destructor, because Release() has exclusive responsibility for
28  // destroying the object.
29  protected:
30  virtual ~RefCountInterface() {}
31 };
32 
33 template <class T>
34 class agora_refptr {
35  public:
36  agora_refptr() : ptr_(NULL) {}
37 
38  agora_refptr(T* p) : ptr_(p) {
39  if (ptr_) ptr_->AddRef();
40  }
41 
42  template<typename U>
43  agora_refptr(U* p) : ptr_(p) {
44  if (ptr_) ptr_->AddRef();
45  }
46 
47  agora_refptr(const agora_refptr<T>& r) : agora_refptr(r.get()) {}
48 
49  template <typename U>
50  agora_refptr(const agora_refptr<U>& r) : agora_refptr(r.get()) {}
51 
52  agora_refptr(agora_refptr<T>&& r) : ptr_(r.move()) {}
53 
54  template <typename U>
55  agora_refptr(agora_refptr<U>&& r) : ptr_(r.move()) {}
56 
57  ~agora_refptr() {
58  reset();
59  }
60 
61  T* get() const { return ptr_; }
62  operator bool() const { return (ptr_ != NULL); }
63 
64  T* operator->() const { return ptr_; }
65  T& operator*() const { return *ptr_; }
66 
67  // Returns the (possibly null) raw pointer, and makes the agora_refptr hold a
68  // null pointer, all without touching the reference count of the underlying
69  // pointed-to object. The object is still reference counted, and the caller of
70  // move() is now the proud owner of one reference, so it is responsible for
71  // calling Release() once on the object when no longer using it.
72  T* move() {
73  T* retVal = ptr_;
74  ptr_ = NULL;
75  return retVal;
76  }
77 
78  agora_refptr<T>& operator=(T* p) {
79  if (ptr_ == p) return *this;
80 
81  if (p) p->AddRef();
82  if (ptr_) ptr_->Release();
83  ptr_ = p;
84  return *this;
85  }
86 
87  agora_refptr<T>& operator=(const agora_refptr<T>& r) {
88  return *this = r.get();
89  }
90 
91  agora_refptr<T>& operator=(agora_refptr<T>&& r) {
92  agora_refptr<T>(std::move(r)).swap(*this);
93  return *this;
94  }
95 
96  template <typename U>
97  agora_refptr<T>& operator=(agora_refptr<U>&& r) {
98  agora_refptr<T>(std::move(r)).swap(*this);
99  return *this;
100  }
101 
102  // For working with std::find()
103  bool operator==(const agora_refptr<T>& r) const { return ptr_ == r.ptr_; }
104 
105  // For working with std::set
106  bool operator<(const agora_refptr<T>& r) const { return ptr_ < r.ptr_; }
107 
108  void swap(T** pp) {
109  T* p = ptr_;
110  ptr_ = *pp;
111  *pp = p;
112  }
113 
114  void swap(agora_refptr<T>& r) { swap(&r.ptr_); }
115 
116  void reset() {
117  if (ptr_) {
118  ptr_->Release();
119  ptr_ = NULL;
120  }
121  }
122 
123  protected:
124  T* ptr_;
125 };
126 
127 } // namespace agora
128 
129 namespace std {
130 template <typename T>
131 struct hash<agora::agora_refptr<T>> {
132  std::size_t operator()(const agora::agora_refptr<T>& k) const {
133  return reinterpret_cast<size_t>(k.get());
134  }
135 };
136 } // namespace std
agora::agora_refptr
Definition: AgoraRefPtr.h:34
agora::RefCountInterface
Definition: AgoraRefPtr.h:21